Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/aripalo/go-delightful

Command-line messaging with colors and emojis
https://github.com/aripalo/go-delightful

cli command-line go golang library ux

Last synced: about 1 month ago
JSON representation

Command-line messaging with colors and emojis

Awesome Lists containing this project

README

        

๐Ÿšง ๐Ÿšง ๐Ÿšง **Work-in-Progress**: See [`v1` Roadmap](https://github.com/aripalo/go-delightful/projects/1); Breaking changes may occur during `v0` development.

---









Got


go-delightful


command-line messaging with colors and emojis




Go library designed for command-line applications interacting with humans, providing delightful end-user experience for _informational messaging_ via colourful, lightly structured messages with emojis.

https://user-images.githubusercontent.com/679146/162841193-f4be9109-907b-457d-8d3c-0702a7243e80.mp4


โœ… ย **This tool is for _Informational messaging_ for the _end-user_ while the command is running:**

Messages are written into standard error stream (`stderr`) to avoid polluting the actual program output in standard output stream (`stdout`); Hence the messages are intended for end-user communication during the program runtime, not for the actual parseable result output:

> _Not everything on stderr is an error though. For example, you can use `curl` to download a file but the progress output is on stderr. This allows you to redirect the stdout while still seeing the progress._
>
> _In short: `stdout` is for **output**, `stderr` is for **messaging**._
>
> โ€“ [12 Factor CLI Apps](https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46)


โŒ ย **This tool is _NOT_ for:**

- _Log Events_ for tracing/debugging the program execution
โ†’ Use logging frameworks such as [zap](https://github.com/uber-go/zap), [zerolog](https://github.com/rs/zerolog) or [logrus](https://github.com/sirupsen/logrus) for more advanced application logging. You still should ensure they write to `stderr` (or to a rotated log file or something).

- _Command Output_ (i.e. the result) written into `stdout` (which could be redirected to a file for example)
โ†’ Use [`fmt.Print`](https://pkg.go.dev/fmt#Print) for that which defaults to writing into standard output.


## Features

- **Coloured output with emoji prefixes** by default

- **Subprocess friendly**: Tries to access the `tty` and print directly into it:
- Useful if you're building a "plugin program" that some other program executes (and you can not control how it redirects the `stderr` of your program); For example the original purpose for this was to support [AWS `credential_process`](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html) where this happens some times.
- In case `tty` not available, prints to Standard Error stream (`stderr`).
- Configurable: You may assign any `io.Writer` as the output target.

- **Respectful of environment**, end-user can set environment variables to:
- disable color
- disable emoji
- enable silent mode
- verbose mode



## Install

```sh
go get github.com/aripalo/go-delightful
```


## Usage

~~For example usage, see [`vegas-credentials`](https://github.com/aripalo/vegas-credentials) which utilizes this library.~~ (Not yet implemented!)


### Getting started

Here are some of the basic methods:
```go
package main

import (
"github.com/aripalo/go-delightful"
)

func main() {

// Initialize
message := delightful.New("demo")

// Purple message line
message.Titleln("๐Ÿ‘ท", "Just showing things around here")

// Gray message line
message.Infoln("โ„น๏ธ", "Good to know")

// Cyan message (without newline)
message.Prompt("๐Ÿ“", "Provide input")

// Green message line
message.Successln("โœ…", "Great Success")

// Red message line
message.Failureln("โŒ", "Error")
}
```


### Real world'ish example

An example command-line application using `aripalo/go-delightful`:
```go
package main

import (
"bufio"
"fmt"
"log"
"os"
"strings"

"github.com/aripalo/go-delightful"
"github.com/enescakir/emoji"
flag "github.com/spf13/pflag"
)

func main() {

// Initialize
message := delightful.New("greet")

// Some setup with spf13/pflag, not really important for this example
var silentMode bool
var verboseMode bool
var noEmoji bool
var noColor bool
flag.BoolVarP(&silentMode, "silent", "s", false, "silent mode (hides everything except prompt/failure messages)")
flag.BoolVar(&verboseMode, "verbose", false, "verbose output (show everything, overrides silent mode)")
flag.BoolVar(&noEmoji, "no-emoji", false, "disable emojis")
flag.BoolVar(&noColor, "no-color", false, "disable colors and emojis")
flag.Parse()

// Configure how messaging works based on above CLI flags
message.SetSilentMode(silentMode)
message.SetVerboseMode(verboseMode)
message.SetEmojiMode(!noEmoji)
message.SetColorMode(!noColor)

// Print a "banner" showing your app name and other (optional) info.
// Banner optional info only printed if in verbose mode.
message.Banner(delightful.BannerOptions{
Version: "v0.0.1",
Website: "http://example.com",
Command: "hello",
Extra: "Some extra info, let's keep it short!",
})

// Print "title" message line in purple.
message.Titleln("๐Ÿ”ฅ", "This is going to be lit!")

// Print "debug" message line in dark gray.
// Only printed if in verbose mode.
message.Debugln("", "This is only visible if in verbose mode") // passing empty string for emoji disables it

// Print "info" message line in gray.
message.Infoln("โ„น๏ธ", "Just something for your information.")

// Print "prompt" message in cyan.
// Does not actually read input, only shows the "question".
message.Prompt("๐Ÿ™‹", "Tell us Your name: ")

// Actually query the name via stdin
reader := bufio.NewReader(os.Stdin)
value, err := reader.ReadString('\n')
if err != nil {
// Print "failure" message line in red.
message.Failure("โŒ", "galaxies exploded")
log.Fatal(err)
}
name := strings.TrimSpace(value)

if strings.ContainsRune(name, '๐Ÿ’ฉ') {

// Unfortunately many environments print gendered/toned emojis incorrectly
// so you might want to use github.com/enescakir/emoji to assign "neutral" emoji
facepalm := emoji.Emoji(emoji.PersonFacepalming.Tone(emoji.Default))

// Print "warning" message line in yellow.
message.Warningln(facepalm, "Really? Your name has a poop emoji? You're being silly...")
} else {
// Print "success" message line in green.
message.Successln("โœ…", "Name received!")
}

// Print horizontal ruler.
// Useful for visually separating the informational messages above from
// actual command output.
// Visible only on verbose mode.
message.HorizontalRuler()

// Finally you often should print some actual command output into standard
// output stream.
fmt.Printf("Hello %s!\n", name)
}
```


### Example Output

Results of running above code with `go run main.go` and various flags:

#### No flags
![default](/assets/screenshots/default.png)

#### `--no-emoji`
![emoji disabled](/assets/screenshots/no-emoji.png)

... or with `NO_EMOJI` or `_NO_EMOJI` environment variables set (to something other than `false` or `0`).

#### `--no-color`
![color disabled](/assets/screenshots/no-color.png)

... or with `NO_COLOR` or `_NO_COLOR` environment variables set (to something other than `false` or `0`).

#### `--silent`
![silent mode](/assets/screenshots/silent.png)

#### `--verbose`
![verbose mode](/assets/screenshots/verbose.png)

... or with `VERBOSE` or `_VERBOSE` environment variables set (to something other than `false` or `0`).


## Emojis

**Unfortunately** not all command-line environments are capable of rendering all emojis as they should be rendered. To ensure best possible compatibility with different systems and fonts:
- Use non-gendered emojis
- Use default skintone emojis
- Avoid complex group emojis such as ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง

Sometimes using [`enescakir/emoji`](https://github.com/enescakir/emoji) can make getting the exactly right emoji easier:
```go
emoji.Emoji(emoji.PersonFacepalming.Tone(emoji.Default))
```

Of course you may use any emoji you wish but note that they may not render as expected in different systems and environments.


## Configuration

### Setting Custom Output Stream

You can provide you own `io.Writer` via `SetMessageTarget` method. This can be useful for testing and for scenarios where you wish to disable the "subprocess friendliness" of writing to `tty` directly.

```go
message.SetMessageTarget(os.Stderr)
```

### Enabling Verbose Mode

1. Set `VERBOSE=true` environment variable
2. Set `_VERBOSE=true` environment variable
3. Use `message.SetVerboseMode(true)` method
(setting this to `false` has no effect if above environment variables present)

### Enabling Silent Mode

1. Use `message.SetSiletMode(true)` method
(setting this to `true` has no effect if _Verbose Mode_ is enabled)

### Disabling Color

1. Set `NO_COLOR=true` environment variable
2. Set `_NO_COLOR=true` environment variable
3. Use `message.SetColorMode(false)` method
(setting this to `true` has no effect if above environment variables present)

### Disabling Emoji

1. Disabling Color will disable Emoji as well
2. Set `NO_EMOJI=true` environment variable
3. Set `_NO_EMOJI=true` environment variable
4. Use `message.SetEmojiMode(false)` method
(setting this to `true` has no effect if above environment variables present)