{"id":22980985,"url":"https://github.com/rubyworks/executable","last_synced_at":"2025-09-02T11:40:21.885Z","repository":{"id":658650,"uuid":"301464","full_name":"rubyworks/executable","owner":"rubyworks","description":"Add a CLI to any class instantly","archived":false,"fork":false,"pushed_at":"2013-02-06T02:58:24.000Z","size":1424,"stargazers_count":15,"open_issues_count":5,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-25T15:06:21.850Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://rubyworks.github.com/executable","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubyworks.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-09-08T21:41:01.000Z","updated_at":"2020-10-15T17:08:24.000Z","dependencies_parsed_at":"2022-08-16T10:35:19.506Z","dependency_job_id":null,"html_url":"https://github.com/rubyworks/executable","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/rubyworks/executable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubyworks%2Fexecutable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubyworks%2Fexecutable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubyworks%2Fexecutable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubyworks%2Fexecutable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubyworks","download_url":"https://codeload.github.com/rubyworks/executable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubyworks%2Fexecutable/sbom","scorecard":{"id":789005,"data":{"date":"2025-08-11","repo":{"name":"github.com/rubyworks/executable","commit":"34cc5f3ed7ad01a416712876c025608d0fc5cf14"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-23T06:55:46.306Z","repository_id":658650,"created_at":"2025-08-23T06:55:46.306Z","updated_at":"2025-08-23T06:55:46.306Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273279494,"owners_count":25077315,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-15T01:46:30.179Z","updated_at":"2025-09-02T11:40:21.864Z","avatar_url":"https://github.com/rubyworks.png","language":"Ruby","readme":"[Website](http://rubyworks.github.com/executable) |\n[Report Issue](http://github.com/rubyworks/executable/features) |\n[Source Code](http://github.com/rubyworks/executable)\n( [![Build Status](https://secure.travis-ci.org/rubyworks/indexer.png)](http://travis-ci.org/rubyworks/indexer) )\n\n\n# Executable\n\nExecutable is to the commandline, what ActiveRecord is the database. \nYou can think of Executable as a *COM*, a Command-line Object Mapper,\njust as ActiveRecord is an ORM (Object Relational Mapper). Any class\nmixing in Executable or subclassing Executable::Command can define\na complete command line tool using nothing more than Ruby's standard\nsyntax. No special DSL is required. \n\n\n## Features\n\n* Easy to use, just mixin or subclass.\n* Define #call to control the command procedure.\n* Public writers become options.\n* Namespace children become subcommands.\n* Or easily dispatch subcommands to public methods.\n* Generate help in plain text or markdown.\n\n\n## Limitations\n\n* Ruby 1.9+ only.\n* Help doesn't handle aliases well (yet).\n\n\n## Overview\n\nCLIs can be built by using a Executable as a mixin, or by subclassing \n`Executable::Command`. Methods seemlessly handle command-line options.\nWriter methods (those ending in '=') correspond to options and query\nmethods (those ending in '?') modify them to be boolean switches. \n\nFor example, here is a simple \"Hello, World!\" commandline tool.\n\n```ruby\n    require 'executable'\n\n    class HelloCommand\n      include Executable\n\n      # Say it in uppercase?\n      def loud=(bool)\n        @loud = bool\n      end\n\n      #\n      def loud?\n        @loud\n      end\n\n      # Show this message.\n      def help!\n        cli.show_help\n        exit\n      end\n      alias :h! :help!\n\n      # Say hello.\n      def call(name)\n        name = name || 'World'\n        str  = \"Hello, #{name}!\"\n        str  = str.upcase if loud?\n        puts str\n      end\n    end\n```\n\nTo make the command available on the command line, add an executable\nto your project calling the #execute or #run methods.\n\n```ruby\n    #!usr/bin/env ruby\n    require 'hello.rb'\n    HelloCommand.run\n```\n\nIf we named this file `hello`, set its execute flag and made it available\non our systems $PATH, then:\n\n```\n    $ hello\n    Hello, World!\n\n    $ hello John\n    Hello, John!\n\n    $ hello --loud John\n    HELLO, JOHN!\n```\n\nExecutable can also generate help text for commands.\n\n```\n    $ hello --help\n    USAGE: hello [options]\n\n    Say hello.\n\n    --loud      Say it in uppercase?\n    --help      Show this message\n```\n\nIf you look back at the class definition you can see it's pulling\ncomments from the source to provide descriptions. It pulls the \ndescription for the command itself from the `#call` method.\n\nBasic help like this is fine for personal tools, but for public facing\nproduction applications it is desirable to utilize manpages. To this end,\nExecutable provides Markdown formatted help as well. We can access this,\nfor example, via `HelloCommand.help.markdown`. The idea with this is that\nwe can save the output to `man/hello.ronn` or copy it the top of our `bin/`\nfile, edit it to perfection and then use tools such a [ronn](https://github.com/rtomayko/ronn),\n[binman](https://github.com/sunaku/binman) or [md2man](https://github.com/sunaku/md2man)\nto generate the manpages. What's particularly cool about Executable,\nis that once we have a manpage in the standard `man/` location in our project,\nthe `#show_help` method will use it instead of the plain text.\n\nFor a more detailed example see [QED](http://rubyworks.github.com/executable/demo.html),\n[API](http://rubydoc.info/gems/executable/frames) documentation and, in particular,\nthe [Wiki](http://wiki.github.com/rubyworks/).\n\n\n## Installation\n\nInstall with RubyGems in the usual fashion.\n\n```\n    $ gem install executable\n```\n\n## Contributing\n\nExecutable is a [Rubyworks](http://rubyworks.github.com) project. As such it largely\nuses in-house tools for development.\n\n### Submitting Patches\n\nIf it is a very small change, just pasting it to an issue is fine. For anything more than\nthis please send us a traditional patch, but even better use Github pull requests. \nGood contributions have the following:\n\n* Well documented code following the conventions of the project.\n* Clearly written tests with good test coverage written using the project's chosen test framework.\n* Use of a git topic branch to keep the change set well isolated.\n\nThe more of these bullet points a pull request covers, the more likely and quickly it will\nbe accepted and merged.\n\n### Testing\n\n[QED](http://rubyworks.github.com/qed) and [Microtest](http://rubyworks.github.com/microtest)\nare used for this project. To run the QED demos just run the `qed` command, probably with bundler,\nso `bundle exec qed`. And to run the microtests you can use `rubytest test/`, again with bundler,\n`bundle exec rubytest test/`.\n\n### Getting In Touch\n\nFor direct dialog we have an IRC channel, #rubyworks on freenode. But it's not always manned,\nso a [mailing list](http://groups.google.com/groups/rubyworks-mailinglist) is also available.\nOf course these days, the GitHub [issues page](http://github.com/rubyworks/executable) is\ngenerally the place get in touch for anything specific to this project.\n\n\n## Copyrights\n\nExecutable is copyrighted open source software.\n\n    Copyright (c) 2008 Rubyworks (BSD-2-Clause)\n\nIt can be distributed and modified in accordance with the **BSD-2-Clause** license.\n\nSee LICENSE.txt for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyworks%2Fexecutable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubyworks%2Fexecutable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyworks%2Fexecutable/lists"}