{"id":28630940,"url":"https://github.com/piotrmurach/tty-exit","last_synced_at":"2025-06-12T13:09:24.185Z","repository":{"id":59158171,"uuid":"236201897","full_name":"piotrmurach/tty-exit","owner":"piotrmurach","description":"Terminal exit codes.","archived":false,"fork":false,"pushed_at":"2025-05-03T20:18:18.000Z","size":99,"stargazers_count":99,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-01T02:59:18.774Z","etag":null,"topics":["exit-codes","exitcode","gem","rubygem","terminal","tty","ttytoolkit"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/piotrmurach.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"piotrmurach"}},"created_at":"2020-01-25T17:13:33.000Z","updated_at":"2025-05-03T20:18:21.000Z","dependencies_parsed_at":"2024-02-05T23:25:11.367Z","dependency_job_id":"da51677f-fb7b-477d-8c9d-b270ad5dc9ec","html_url":"https://github.com/piotrmurach/tty-exit","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/piotrmurach/tty-exit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-exit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-exit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-exit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-exit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piotrmurach","download_url":"https://codeload.github.com/piotrmurach/tty-exit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-exit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259470951,"owners_count":22862999,"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":["exit-codes","exitcode","gem","rubygem","terminal","tty","ttytoolkit"],"created_at":"2025-06-12T13:09:23.298Z","updated_at":"2025-06-12T13:09:24.171Z","avatar_url":"https://github.com/piotrmurach.png","language":"Ruby","funding_links":["https://github.com/sponsors/piotrmurach"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://piotrmurach.github.io/tty\" target=\"_blank\"\u003e\u003cimg width=\"130\" src=\"https://github.com/piotrmurach/tty/raw/master/images/tty.png\" alt=\"tty logo\" /\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n# TTY::Exit\n\n[![Gem Version](https://badge.fury.io/rb/tty-exit.svg)][gem]\n[![Actions CI](https://github.com/piotrmurach/tty-exit/actions/workflows/ci.yml/badge.svg)][gh_actions_ci]\n[![Build status](https://ci.appveyor.com/api/projects/status/rtm3po27ouarfrhf?svg=true)][appveyor]\n[![Code Climate](https://codeclimate.com/github/piotrmurach/tty-exit/badges/gpa.svg)][codeclimate]\n[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-exit/badge.svg)][coverage]\n\n[gem]: https://badge.fury.io/rb/tty-exit\n[gh_actions_ci]: https://github.com/piotrmurach/tty-exit/actions/workflows/ci.yml\n[appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-exit\n[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-exit\n[coverage]: https://coveralls.io/github/piotrmurach/tty-exit\n\n\u003e Terminal exit codes for humans and machines.\n\nThe goal of this library is to provide human friendly and standard way to use exit status codes in command line applications. Instead of saying `exit(64)`, you can say `exit_with(:usage_error)`. Both indicate a failure to the parent process but the `:usage_error` is so much nicer! Wouldn't you agree? That's why `tty-exit` gathers a list of all the most common exit codes as used by POSIX-compliant tools on different Unix systems for you to use.\n\nThe exit statuses range from 0 to 255 (inclusive). Any other exit status than 0 indicates a failure of some kind. The exit codes in the range 64-78 are adapted from the OpenBSD [sysexits.h](https://man.openbsd.org/sysexits.3). The codes between 125 and 128 are reserved for shell statuses as defined in [Advanced Bash Scripting Guide, Appendix E](http://tldp.org/LDP/abs/html/exitcodes.html). The codes in the 129-154 range correspond with the fatal signals as defined in [signal](https://man.openbsd.org/signal.3).\n\n**TTY::Exit** provides independent terminal exit codes component for [TTY](https://github.com/piotrmurach/tty) toolkit.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'tty-exit'\n```\n\nAnd then execute:\n\n    $ bundle install\n\nOr install it yourself as:\n\n    $ gem install tty-exit\n\n## Contents\n\n* [1. Usage](#1-usage)\n* [2. API](#2-api)\n  * [2.1 exit_code](#21-exit_code)\n  * [2.2 exit_message](#22-exit_message)\n  * [2.3 exit_with](#23-exit_with)\n  * [2.4 register_exit](#24-register_exit)\n  * [2.5 exit_reserved?](#25-exit_reserved)\n  * [2.6 exit_valid?](#26-exit_valid)\n  * [2.7 exit_success?](#27-exit_success)\n  * [2.8 exit_codes](#28-exit_codes)\n  * [2.9 exit_messages](#29-exit_messages)\n\n## 1. Usage\n\nTo exit from any program use `exit_with` method. Instead of a number, you can use a readable name for the exit status:\n\n```ruby\nTTY::Exit.exit_with(:usage_error)\n```\n\nThe above will exit program immediately with an exit code indicating a failure:\n\n```ruby\nputs $?.exitstatus\n# =\u003e 64\n```\n\nAll the reserved exit statuses have a matching exit message. To display a default message, as a second argument to `exit_with` you can pass `:default` value:\n\n```ruby\nTTY::Exit.exit_with(:usage_error, :default)\n```\n\nThat will produce the following user friendly message:\n\n```ruby\n# =\u003e \"ERROR(64): Command line usage error\"\n```\n\nThe preferred way is to include **TTY::Exit** module in your code:\n\n```ruby\nclass Command\n  include TTY::Exit\n\n  def execute\n    exit_with(:config_error, :default)\n  end\nend\n```\n\nThis will print an error message and return appropriate exit status:\n\n```ruby\ncmd = Command.new\ncmd.execute\n# =\u003e \"ERROR(78): Configuration Error\"\nputs $?.exitstatus\n# =\u003e 78\n```\n\nTo see the full list of reserved exit codes go to [2.8 exit_codes](#28-exit-codes) section.\n\n## 2. API\n\n### 2.1 exit_code\n\nThere are many built-in exit codes that can be referenced using a name.\n\nFor example to return an exit code denoting success, you can use `:ok` or `:success`:\n\n```ruby\nTTY::Exit.exit_code(:ok) # =\u003e 0\nTTY::Exit.exit_code(:success) # =\u003e 0\n```\n\nAny other exit status than 0 indicates a failure of some kind. For example, when a command cannot be found use `:not_found`:\n\n```ruby\nTTY::Exit.exit_code(:not_found)\n# =\u003e 127\n```\n\nYou can also use an exit code directly:\n\n```ruby\nTTY::Exit.exit_code(127)\n# =\u003e 127\n```\n\n### 2.2 exit_message\n\nOne of the downsides of exit codes is that they are not very communicative to the user. Why not have both? An exit code and a user friendly message. That's what `exit_message` is for. All the reserved exit codes have corresponding user friendly messages.\n\nFor example, when returning exit code `64` for usage error:\n\n```ruby\nTTY::Exit.exit_message(:usage_error)\nTTY::Exit.exit_message(64)\n```\n\nWill return:\n\n```ruby\n# =\u003e \"ERROR(64): Command line usage error\"\n```\n\nThe default messages are used by the `exit_with` method and can be overwritten by a custom one.\n\n### 2.3 exit_with\n\nTo exit program with an exit code use `exit_with`. This method accepts a name or a code for the exit status. \n\n```ruby\nTTY::Exit.exit_with(:usage_error)\nTTY::Exit.exit_with(64)\n```\n\nBoth will produce the same outcome.\n\nAs a second argument you can specify a user friendly message to be printed to `stderr` before exit. To use predefined messages use `:default` as a value:\n\n```ruby\nTTY::Exit.exit_with(:usage_error, :default)\n# =\u003e \"ERROR(64): Command line usage error\"\n```\n\nOptionally, you can provide a custom message to display to the user.\n\n```ruby\nTTY::Exit.exit_with(:usge_error, \"Wrong arguments\")\n# =\u003e \"Wrong arguments\"\n```\n\nFinally, you can redirect output to a different stream using `:io` option. By default, message is printed to `stderr`:\n\n```ruby\nTTY::Exit.exit_with(:usage_error, io: $stdout)\n```\n\nSince `TTY::Exit` is a module, you can include it in your code to get access to all the methods:\n\n```ruby\nclass Command\n  include TTY::Exit\n\n  def execute\n    exit_with(:usage_error, :default)\n  end\nend\n```\n\n### 2.4 register_exit\n\nIf the provided exit codes don't match your needs, you can add your own using the `register_exit` method. \n\nFor example, to register a custom exit with `:too_long` name and the status `7` that will notify user and programs about too many arguments do:\n\n```ruby\nclass Command\n  include TTY::Exit\n\n  register_exit(:too_long, 7, \"Argument list too long\")\n\n  def execute\n    exit_with(:too_long, :default)\n  end\nend\n```\n\nThen when the command gets run:\n\n```ruby\ncmd = Command.new\ncmd.execute\n# =\u003e\n# ERROR(7): Argument list too long\n```\n\n### 2.5 exit_reserved?\n\nTo check if an exit code is already reserved by Unix system use `exit_reserved?`. This is useful in situations where you want to add it your command line application custom exit codes. The check accepts only integer numbers in range 0 to 255 inclusive:\n\n```ruby\nTTY::Exit.exit_reserved?(126) # =\u003e true\nTTY::Exit.exit_reserved?(100) # =\u003e false\n```\n\n### 2.6 exit_valid?\n\nThe exit statuses range from 0 to 255 (inclusive). The `exit_valid?` method helps you check if an exit status is within the range or not.\n\n```ruby\nTTY::Exit.exit_valid?(11) # =\u003e true\nTTY::Exit.exit_valid?(522) # =\u003e false\n```\n\n### 2.7 exit_success?\n\nAny other exit status than 0 indicates a failure of some kind. The `exit_success?` is a more descriptive way to determine if a program succeeded or not.\n\n```ruby\nTTY::Exit.exit_success?(0) # =\u003e true\nTTY::Exit.exit_success?(7) # =\u003e false\n```\n\n### 2.8 exit_codes\n\nYou can access all the predefined exit codes and their names with `exit_codes` method:\n\n```ruby\nTTY::Exit.exit_codes\n# =\u003e\n# \"{:ok=\u003e0, :success=\u003e0, :error=\u003e1, :shell_misuse=\u003e2, :usage_error=\u003e64, :data_error=\u003e65, ... }\"\n```\n\n### 2.9 exit_messages\n\nTo see what default messages are for the predefined exit codes use `exit_messages`:\n\n```ruby\nTTY::Exit.exit_messages\n# =\u003e\n# \"{0=\u003e\"Successful termination\", 1=\u003e\"An error occurred\", 2=\u003e\"Misuse of shell builtins\", 64=\u003e\"Command line usage error\", ... }\"\n```\n\nThe exit statuses range from 0 to 255 (inclusive). Any other exit status than 0 indicates a failure of some kind. The exit codes in the range 64-78 are adapted from the OpenBSD [sysexits.h](https://man.openbsd.org/sysexits.3). The codes between 125 and 128 are reserved for shell statuses as defined in [Advanced Bash Scripting Guide, Appendix E](http://tldp.org/LDP/abs/html/exitcodes.html). The codes in the 129-154 range correspond with the fatal signals as defined in [signal](https://man.openbsd.org/signal.3).\n\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-exit. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/piotrmurach/tty-exit/blob/master/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the TTY::Exit project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-exit/blob/master/CODE_OF_CONDUCT.md).\n\n## Copyright\n\nCopyright (c) 2020 Piotr Murach. See LICENSE for further details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Ftty-exit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiotrmurach%2Ftty-exit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Ftty-exit/lists"}