{"id":17617771,"url":"https://github.com/ullaakut/disgo","last_synced_at":"2025-04-30T17:30:25.979Z","repository":{"id":57485422,"uuid":"173933964","full_name":"Ullaakut/disgo","owner":"Ullaakut","description":"🕺🏽Simple output library for go CLIs.","archived":false,"fork":false,"pushed_at":"2019-11-11T18:38:51.000Z","size":3224,"stargazers_count":37,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T07:47:08.660Z","etag":null,"topics":["cli","format","gui","library","logging","output","terminal","ux"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ullaakut.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-05T11:28:40.000Z","updated_at":"2024-06-25T07:25:51.000Z","dependencies_parsed_at":"2022-09-01T23:11:15.517Z","dependency_job_id":null,"html_url":"https://github.com/Ullaakut/disgo","commit_stats":null,"previous_names":["ullaakut/colog"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ullaakut%2Fdisgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ullaakut%2Fdisgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ullaakut%2Fdisgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ullaakut%2Fdisgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ullaakut","download_url":"https://codeload.github.com/Ullaakut/disgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251751026,"owners_count":21637842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","format","gui","library","logging","output","terminal","ux"],"created_at":"2024-10-22T19:15:40.350Z","updated_at":"2025-04-30T17:30:25.937Z","avatar_url":"https://github.com/Ullaakut.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Disgo\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"400px\" src=\"images/logo-with-label-light.png\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"#license\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://godoc.org/github.com/Ullaakut/disgo\"\u003e\n        \u003cimg src=\"https://godoc.org/github.com/Ullaakut/disgo?status.svg\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/Ullaakut/disgo\"\u003e\n        \u003cimg src=\"https://goreportcard.com/badge/github.com/Ullaakut/disgo\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Ullaakut/disgo/releases/latest\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/release/Ullaakut/disgo.svg?style=flat\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nSimple library for building Go command-line interfaces.\n\nDisgo provides four essential features for most user-friendly CLI applications:\n\n1. Simple output levels\n2. Output formatting\n3. Step-by-step outputs\n4. Simple user prompting\n\n## Table of content\n\n1. [Examples](#examples)\n2. [Terminal](#terminal)\n    1. [Terminal options](#terminal-options)\n    2. [Writing to the Terminal](#writing-to-the-terminal)\n    3. [Step-by-step Processes](#step-by-step-processes)\n    4. [Confirmation Prompt](#confirmation-prompt)\n    5. [String Input Prompt](#string-input-prompt)\n3. [Style](#style)\n    1. [Output Formatting](#output-formatting)\n    2. [Symbols](#symbols)\n4. [License](#license)\n\n## Examples\n\nHere are a few examples of Disgo's output, used by other repositories:\n\n\u003cp align=\"left\"\u003e\n    \u003cimg width=\"70%\" src=\"images/cameradar.png\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"right\"\u003e\n    \u003cimg width=\"70%\" src=\"images/gorsair.gif\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"left\"\u003e\n    \u003cimg width=\"70%\" src=\"images/astronomer.png\" /\u003e\n\u003c/p\u003e\n\n## Terminal\n\nThe disgo `Terminal` provides an easy way to build user-friendly command-line interfaces.\n\nYou can use it globally within your application, or you can instantiate your own `Terminal`.\n\n### Terminal options\n\nWhen creating a `Terminal` instance or when using the global `Terminal` that this package provides, you might want to give it some options, such as:\n\n- **`WithDebug`**, which lets you enable or disable the debug output _(it is disabled by default)_\n- **`WithDefaultWriter`**, which lets you specify an `io.Writer` on which `Debug` and `Info`-level outputs should be written _(it is set to `os.Stdout` by default)_\n- **`WithErrorWriter`**, which lets you specify an `io.Writer` on which `Error`-level outputs should be written _(it is set to `os.Stderr` by default)_\n- **`WithReader`**, which lets you specify an `io.Reader` from which the Terminal will be able to prompt the user _(it is set to `os.Stdin` by default)_\n- **`WithColors`**, which lets you explicitely enable or disable colors in your output _(it is enabled by default)_\n- **`WithInteractive`**, which specifies whether the Terminal should run in an interactive way, meaning prompts should wait for user input. If set to false, prompts will instantaneously returns their configured default value _(it is set to `true` by default)_\n\nYou can either pass those options to `disgo.NewTerminal()` when creating a `Terminal` instance, like so:\n\n```go\n    term := disgo.NewTerminal(disgo.WithDebug(true))\n```\n\nOr, if you are using the global terminal, you will simply need to call the `SetTerminalOptions` function:\n\n```go\n    disgo.SetTerminalOptions(disgo.WithDebug(true))\n```\n\n### Writing to the Terminal\n\nNow that your terminal is set up, you can start writing to it.\n\nHere is how to use them on an instantiated terminal:\n\n```go\n    // All of those give the same output:\n    // \"Number of days in a year: 365\" followed by a newline.\n    term.Infoln(\"Number of days in a year:\", 365)\n    term.Infof(\"Number of days in a year: %d\\n\", 365)\n    term.Info(\"Number of days in a year: 365\\n\")\n\n    // Debug methods are similar to info, except that they are not printed\n    // if debug outputs are not enabled on the terminal.\n    term.Debugln(\"Number of days in a year:\", 365)\n    term.Debugf(\"Number of days in a year: %d\\n\", 365)\n    term.Debug(\"Number of days in a year: 365\\n\")\n\n    // Error methods are similar to info, except that they are written on\n    // the error writer (os.Stderr by default).\n    term.Errorln(\"Number of days in a year:\", 365)\n    term.Errorf(\"Number of days in a year: %d\\n\", 365)\n    term.Error(\"Number of days in a year: 365\\n\")\n```\n\nWhen using the global terminal, call the terminal printing functions directly:\n\n```go\n    // All of those give the same output:\n    // \"Number of days in a year: 365\" followed by a newline.\n    disgo.Infoln(\"Number of days in a year:\", 365)\n    disgo.Infof(\"Number of days in a year: %d\\n\", 365)\n    disgo.Info(\"Number of days in a year: 365\\n\")\n\n    // Debug methods are similar to info, except that they are not printed\n    // if debug outputs are not enabled on the terminal.\n    disgo.Debugln(\"Number of days in a year:\", 365)\n    disgo.Debugf(\"Number of days in a year: %d\\n\", 365)\n    disgo.Debug(\"Number of days in a year: 365\\n\")\n\n\n    // Error methods are similar to info, except that they are written on\n    // the error writer (os.Stderr by default).\n    disgo.Errorln(\"Number of days in a year:\", 365)\n    disgo.Errorf(\"Number of days in a year: %d\\n\", 365)\n    disgo.Error(\"Number of days in a year: 365\\n\")\n```\n\n### Step-by-step processes\n\nA lot of command-line interfaces describe **step-by-step processes** to the user, but it's difficult to combine clean code, clear output and elegant user interfaces. Disgo attempts to solve that problem by associating _steps_ to its terminal.\n\nFor example, when beginning a task, you can use `StartStep` and specify the description of that step. Then, until that task is over, all calls to Disgo's printing functions will be queued. Once the task is complete (by calling `EndStep`, `FailStep` or by starting another step with `StartStep`), the task status is printed and all of the outputs that were queued during the task are printed with an indent, under the task, like so:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"70%\" src=\"images/example_step_by_step.png\" /\u003e\n\u003c/p\u003e\n\nIt is also important to note that **`FailStep` and `FailStepf` can be used to return errors** at the same time as they report a step as having failed. This allows you to write:\n\n```go\n    disgo.StartStep(\"Doing something\")\n    if err := doSomething(); err != nil {\n        return disgo.FailStepf(\"unable to do something: %v\", err)\n    }\n```\n\nInstead of having to call `FailStep` in your error handling before returning. You are still free to do so if you prefer, though.\n\nUsing the global terminal for step management is not thread-safe though, as it was built with simplicity in mind and can only handle one step at a time.\n\n### Confirmation prompt\n\nThe confirmation prompt lets you **prompt users** for a yes or no answer.\n\n```go\n    result, err := disgo.Confirm(disgo.Confirmation{\n        Label:              \"Install with current database?\",\n    })\n```\n\nWill produce the following output:\n\n```bash\nInstall with current database? [y/n]\n```\n\nTo which the user can answer by `y`, `n`, `Y`, `N`, `yes`, `no`, `YES,` `NO`, `0`, `1`, `true`, `false`, etc.\n\nThe confirmation prompt supports default values, like so:\n\n```go\n    result, err := disgo.Confirm(disgo.Confirmation{\n        EnableDefaultValue: true,\n        DefaultValue:       false,\n        Label:              \"Install with current database?\",\n    })\n```\n\nThis will set the default value to false, so that when the user does not have access to a TTY or that he simply presses enter to skip the prompt, a value of your choosing is used.\n\nIt's also possible to add **your own confirmation parsers**, if you don't want the user to answer to a yes/no question for example. This also means that you can customize the choices that will be presented to the user:\n\n```go\n    result, err := disgo.Confirm(disgo.Confirmation{\n        Label:              \"Install with current database?\",\n        Choices:            []string{\"yes\", \"no\"},\n        Parser:             func(input string) (bool, error) {\n            switch input {\n            case \"yes\":\n                return true, nil\n            case \"no\":\n                return false, nil\n            default:\n                return false, fmt.Errorf(\"invalid input %q\", input)\n            }\n        },\n    })\n```\n\nThis will output:\n\n```bash\nInstall with current database? [yes/no]\n```\n\nAnd will use a custom parser for parsing the user's answer.\n\n### String input prompt\n\nNot implemented yet.\n\n## Style\n\nThe `style` package provides simple output formatting functions as well as some cherry-picked UTF-8 symbols that can be useful for building rich command-line interfaces.\n\n### Output Formatting\n\nThe `style` package exposes six different output formats, which print its argument with a specific color, font-weight and font-style depending on what the output's content should convey to the user. For example, if you want to attract a user's attention to an error, you might use the `style.Failure()` formatting function, like so:\n\n```go\n    if err := validateConfiguration; err != nil {\n        disgo.Errorln(\"Invalid configuration detected:\", style.Failure(err))\n        return err\n    }\n```\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"images/output_failure.png\" /\u003e\n\u003c/p\u003e\n\nOther output formats include `Success`, `Trace`, `Important` and `Link`.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"40%\" src=\"images/output_all.png\" /\u003e\n\u003c/p\u003e\n\nYou can of course combine those formats in elegant ways, like shown in the [examples](#examples) section.\n\n### Symbols\n\nDisgo provides **aliases to UTF-8 characters** that could be useful to build your command-line interfaces.\n\n```go\n    disgo.Infoln(style.SymbolCheck) // ✔\n    disgo.Infoln(style.SymbolCross) // ✖\n    disgo.Infoln(style.SymbolLeftArrow) // ❮\n    disgo.Infoln(style.SymbolRightArrow) // ❯\n    disgo.Infoln(style.SymbolLeftTriangle) // ◀\n    disgo.Infoln(style.SymbolRightTriangle) // ▶\n```\n\n## License\n\nMIT License\n\nCopyright (c) 2019\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fullaakut%2Fdisgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fullaakut%2Fdisgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fullaakut%2Fdisgo/lists"}