rbcli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +60 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +28 -0
- data/LICENSE.txt +21 -0
- data/README.md +207 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/defaults.yml +4 -0
- data/examples/mytool +70 -0
- data/exe/rbcli +30 -0
- data/lib/rbcli/configurate.rb +91 -0
- data/lib/rbcli/engine/command.rb +179 -0
- data/lib/rbcli/engine/parser.rb +68 -0
- data/lib/rbcli/util/config.rb +140 -0
- data/lib/rbcli/util/hash_deep_symbolize.rb +28 -0
- data/lib/rbcli/util/logging.rb +73 -0
- data/lib/rbcli/util/string_colorize.rb +25 -0
- data/lib/rbcli/util.rb +4 -0
- data/lib/rbcli/version.rb +3 -0
- data/lib/rbcli.rb +11 -0
- data/rbcli.gemspec +42 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f693140670cf6500039ed8201c5be45e2dccde591ef47b83687d1bd80a638b64
|
4
|
+
data.tar.gz: bb386ad56f5358f6cdd25d6fedba51c872084ecc705a92b1fad7bae969466429
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 56089e16775977cad480e6575cb1852c2cddb0228e6c7e35f2aff7b813e13fa6daa339822f9981e89fba78823b01de6e0519eb9e618604fd0af925400b7cbbaf
|
7
|
+
data.tar.gz: 52f1cf70c8dcc080216f2ef3b522664752ffc4935cd1e0e75af16b7bc34fc1c79686a3ed5b475cf16280d4d0206d40c751009cccf523aac925e6de91ca442ac2
|
data/.gitignore
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Created by https://www.gitignore.io/api/git,ruby
|
2
|
+
|
3
|
+
### Git ###
|
4
|
+
*.orig
|
5
|
+
|
6
|
+
### Ruby ###
|
7
|
+
*.gem
|
8
|
+
*.rbc
|
9
|
+
/.config
|
10
|
+
/coverage/
|
11
|
+
/InstalledFiles
|
12
|
+
/pkg/
|
13
|
+
/spec/reports/
|
14
|
+
/spec/examples.txt
|
15
|
+
/test/tmp/
|
16
|
+
/test/version_tmp/
|
17
|
+
/tmp/
|
18
|
+
|
19
|
+
# Used by dotenv library to load environment variables.
|
20
|
+
# .env
|
21
|
+
|
22
|
+
## Specific to RubyMotion:
|
23
|
+
.dat*
|
24
|
+
.repl_history
|
25
|
+
build/
|
26
|
+
*.bridgesupport
|
27
|
+
build-iPhoneOS/
|
28
|
+
build-iPhoneSimulator/
|
29
|
+
|
30
|
+
## Specific to RubyMotion (use of CocoaPods):
|
31
|
+
#
|
32
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
33
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
34
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
35
|
+
#
|
36
|
+
# vendor/Pods/
|
37
|
+
|
38
|
+
## Documentation cache and generated files:
|
39
|
+
/.yardoc
|
40
|
+
/.yardoc/
|
41
|
+
/_yardoc/
|
42
|
+
/doc/
|
43
|
+
/rdoc/
|
44
|
+
|
45
|
+
## Environment normalization:
|
46
|
+
/.bundle/
|
47
|
+
/vendor/bundle
|
48
|
+
/lib/bundler/man/
|
49
|
+
|
50
|
+
# for a library or gem, you might want to ignore these files since the code is
|
51
|
+
# intended to run in multiple environments; otherwise, check them in:
|
52
|
+
# Gemfile.lock
|
53
|
+
.ruby-version
|
54
|
+
.ruby-gemset
|
55
|
+
|
56
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
57
|
+
.rvmrc
|
58
|
+
|
59
|
+
|
60
|
+
# End of https://www.gitignore.io/api/git,ruby
|
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at akhoury@live.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rbcli (0.1.0)
|
5
|
+
colorize (~> 0.8)
|
6
|
+
deep_merge (~> 1.2)
|
7
|
+
trollop (~> 2.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
colorize (0.8.1)
|
13
|
+
deep_merge (1.2.1)
|
14
|
+
minitest (5.11.3)
|
15
|
+
rake (10.5.0)
|
16
|
+
trollop (2.1.2)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
bundler (~> 1.16)
|
23
|
+
minitest (~> 5.0)
|
24
|
+
rake (~> 10.0)
|
25
|
+
rbcli!
|
26
|
+
|
27
|
+
BUNDLED WITH
|
28
|
+
1.16.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Andrew Khoury
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
# RBCli
|
2
|
+
|
3
|
+
RBCli is a framework to quickly develop advanced command-line tools in Ruby. It has been written from the ground up with the needs of the modern technologist in mind, designed to make advanced CLI tool development as painless as possible.
|
4
|
+
|
5
|
+
Some of its key features include:
|
6
|
+
|
7
|
+
* __Simple DSL Interface__: To cut down on the amount of code that needs to be written, RBCli has a DSL that is designed to cut to the chase. This makes the work a lot less tedious.
|
8
|
+
|
9
|
+
* __Multiple Levels of Parameters and Arguments__: Forget about writing parsers for command-line options, or about having to differentiate between parameters and arguments. All of that work is taken care of.
|
10
|
+
|
11
|
+
* __Config File Generation__: Easily piece together a default configuration even with declarations in different parts of the code. Then the user can generate their own configuration, and it gets stored in whatever location you'd like.
|
12
|
+
|
13
|
+
* __Logging__: Keep track of all instances of your tool through logging. Logs can go to STDOUT, STDERR, or a given file, making them compatible with log aggregators such as Splunk, Logstash, and many others.
|
14
|
+
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
RBCli is available on rubygems.org. You can add it to your application's `Gemrile` or `gemspec`, or install it manually via `gem install rbcli`.
|
19
|
+
|
20
|
+
## The Basics
|
21
|
+
|
22
|
+
RBCli enforces a general command-line structure:
|
23
|
+
|
24
|
+
```
|
25
|
+
toolname [options] command [parameters] [lineitem]
|
26
|
+
```
|
27
|
+
|
28
|
+
* __Options__ are command line parameters such as `-f`, or `--force`. These are available globally to every command. You can create your own, but several options are already built-in:
|
29
|
+
* `-c <filename> / --config-file=<filename>` allows specifying a config file manually
|
30
|
+
* `-g / --generate-config` generates a config file by writing out the defaults to a YAML file (location is configurable, more on that below)
|
31
|
+
* `-v / --version` shows the version`
|
32
|
+
* `-h / --help` shows the help
|
33
|
+
* __Command__ represents the subcommands that you will create, such as `test` or `apply`
|
34
|
+
* __Parameters__ are the same as options, but only apply to the specific subcommand being executed. In this case only the `-h / --help` parameter is provided.
|
35
|
+
* __Lineitems__ are strings that don't begin with a '-', and are passed to the command's code. These can be used as subcommands or additional parameters for your code.
|
36
|
+
|
37
|
+
So a valid command could look something like these:
|
38
|
+
|
39
|
+
```shell
|
40
|
+
mytool -n load --filename=foo.txt
|
41
|
+
mytool parse foo.txt
|
42
|
+
mytool show -l
|
43
|
+
```
|
44
|
+
|
45
|
+
Note that all options and parameters will have both a short and long version of the parameter available for use.
|
46
|
+
|
47
|
+
## Getting Started
|
48
|
+
|
49
|
+
Creating a new skeleton command is as easy as running `rbcli init <filename>`. It will have three key items:
|
50
|
+
|
51
|
+
* The configuration
|
52
|
+
* A command declaration
|
53
|
+
* The parse command
|
54
|
+
|
55
|
+
|
56
|
+
### Configuration
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
require 'rbcli'
|
60
|
+
|
61
|
+
Rbcli::configurate do
|
62
|
+
scriptname __FILE__.split('/')[-1] # (Required) This line identifies the tool's executable. You can change it if needed, but this should work for most cases.
|
63
|
+
version '0.1.0' # (Required) The version number
|
64
|
+
description 'This is my test CLI tool.' # (Requierd) A description that will appear when the user looks at the help with -h. This can be as long as needed.
|
65
|
+
|
66
|
+
log_level :info # (Optional) Set the default log_level for users. 0-5, or DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
67
|
+
log_target 'stderr' # (Optional) Set the target for logs. Valid values are STDOUT, STDERR, or a file path (as strings)
|
68
|
+
|
69
|
+
config_userfile '/etc/mytool/config.yml', merge_defaults: true, required: false # (Optional) Set location of user's config file. If merge_defaults=true, user settings override default settings, and if false, defaults are not loaded at all. If required=true, application will not run if file does not exist.
|
70
|
+
config_defaults 'defaults.yml' # (Optional, Multiple) Load a YAML file as part of the default config. This can be called multiple times, and the YAML files will be merged. User config is generated from these
|
71
|
+
config_default :myopt, description: 'Testing this', value: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config
|
72
|
+
|
73
|
+
option :name, 'Give me your name', type: :string, default: 'Stranger' # (Optional, Multiple) Add a global CLI parameter. Supported types are :string, :boolean, :integer, :float, :date, and :io. Can be called multiple times.
|
74
|
+
|
75
|
+
default_action do |opts| # (Optional) The default code to execute when no subcommand is given. If not present, the help is shown (same as -h)
|
76
|
+
puts "Hello, #{opts[:name]}."
|
77
|
+
puts "To see the help, use -h"
|
78
|
+
end
|
79
|
+
|
80
|
+
pre_hook do |opts| # (Optional) Allows providing a block of code that runs before any command
|
81
|
+
puts 'This is a pre-command hook. It executes before the command.'
|
82
|
+
end
|
83
|
+
|
84
|
+
post_hook do |opts| # (Optional) Allows providing a block of code that runs after any command
|
85
|
+
puts 'This is a post-command hook. It executes after the command.'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
```
|
90
|
+
|
91
|
+
### Command Declaration
|
92
|
+
|
93
|
+
Commands are added by subclassing `Rbcli::Command`. There are a few parameters to set for it, which get used by the different components of Rbcli.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
class Test < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
97
|
+
description 'This is a short description.' # (Required) Short description for the global help
|
98
|
+
usage 'This is some really long usage text description!' # (Required) Long description for the command-specific help
|
99
|
+
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
100
|
+
|
101
|
+
config_defaults 'defaults.yml' # (Optional, Multiple) Load a YAML file as part of the default config. This can be called multiple times, and the YAML files will be merged. User config is generated from these
|
102
|
+
config_default :myopt2, description: 'Testing this again', value: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config
|
103
|
+
|
104
|
+
action do |params, args, global_opts, config| # (Required) Block to execute if the command is called.
|
105
|
+
Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger
|
106
|
+
puts "\nArgs:\n#{args}" # Arguments that came after the command on the CLI
|
107
|
+
puts "Params:\n#{params}" # Parameters, as described through the option statements above
|
108
|
+
puts "Global opts:\n#{global_opts}" # Global Parameters, as descirbed in the Configurate section
|
109
|
+
puts "Config:\n#{config}" # Config file values
|
110
|
+
puts "\nDone!!!"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
```
|
115
|
+
|
116
|
+
### Parse Command
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
Rbcli.parse # Parse CLI and execute
|
120
|
+
```
|
121
|
+
|
122
|
+
## Execution Chain
|
123
|
+
|
124
|
+
RBCli takes actions in a specific order when `parse` is run.
|
125
|
+
|
126
|
+
1. The default config is loaded
|
127
|
+
2. The user config is loaded if present
|
128
|
+
3. CLI is parsed for global options, which are then stored in a hash and passed on to the other parts of the code. Built-in options, however, may cause the code to branch and exit.
|
129
|
+
4. The CLI is parsed for a command.
|
130
|
+
a. If no command is entered, RBCLI will check if a `default_acction` block has been provided.
|
131
|
+
i. If the block is defined, execute it
|
132
|
+
ii. Otherwise, show the help
|
133
|
+
b. If a command has been entered, the rest of the CLI is parsed for parameters and lineitems, and the code block for the command is called
|
134
|
+
|
135
|
+
## Configuration Files
|
136
|
+
|
137
|
+
RBCli has two chains to manage configuration: the __defaults chain__ and the __user chain__.
|
138
|
+
|
139
|
+
### Defaults chain
|
140
|
+
|
141
|
+
The defaults chain allows you to specify sane defaults for your CLI tool throughout your code. This gives you the ability to declare configuration alongside the code, and allows RBCli to generate a user config automatically given your defaults. There are two ways to set them:
|
142
|
+
|
143
|
+
* YAML Files
|
144
|
+
* You can store your defaults in one or more YAML files and RBCli will import and combine them. Note that when generating the user config, RBCli will use the YAML text as-is, so comments are transferred as well. This allows you to write descriptions for the options directly in the file that the user can see.
|
145
|
+
* This is good for tools with large or complex configuration that needs user documentation written inline
|
146
|
+
* `config_defaults "<filename>"` in the DSL
|
147
|
+
* DSL Statements
|
148
|
+
* In the DSL, you can specify options individually by providing a name, description, and default value
|
149
|
+
* This is good for simpler configuration, as the descriptions provided are written out as comments in the generated user config
|
150
|
+
* `config_default :name, description: '<description_text>', value: <default_value>` in the DSL
|
151
|
+
|
152
|
+
Users can generate configs by running `yourclitool -g`. This will generate a config file at the tool's default location specified in the DSL. A specific location can be used via the `-c` parameter. You can test how this works by running `examples/mytool -c test.yml -g`.
|
153
|
+
|
154
|
+
### User chain
|
155
|
+
|
156
|
+
The user chain has two functions: generating and loading configuration from a YAML file.
|
157
|
+
|
158
|
+
Rbcli will determine the correct location to locate the user configuration based on two factors:
|
159
|
+
|
160
|
+
1. The default location set in the configurate DSL
|
161
|
+
a. `config_userfile '/etc/mytool/config.yml', merge_defaults: true, required: false # (Optional) Set location of user's config file. If merge_defaults=true, user settings override default settings, and if false, defaults are not loaded at all. If required=true, application will not run if file does not exist.`
|
162
|
+
2. The location specified on the command line using the `-c <filename>` option
|
163
|
+
b. `yourclitool -c localfile.yml`
|
164
|
+
|
165
|
+
Users can generate configs by running `yourclitool -g`. This will generate a config file at the tool's default location specified in the DSL. A specific location can be used via the `-c` parameter. You can test how this works by running `examples/mytool -c test.yml -g`.
|
166
|
+
|
167
|
+
## Logging
|
168
|
+
|
169
|
+
Logging with RBCli is straightforward - it looks at the config file for logging settings, and instantiates a single, globally accessible [Logger](https://ruby-doc.org/stdlib-2.4.0/libdoc/logger/rdoc/Logger.html)` object. You can access it as such:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' }
|
173
|
+
```
|
174
|
+
|
175
|
+
Default values can be set in the configurate DSL:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
log_level :info # (Optional) Set the default log_level for users. 0-5, or DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
179
|
+
log_target 'stderr' # (Optional) Set the target for logs. Valid values are STDOUT, STDERR, or a file path (as strings)
|
180
|
+
```
|
181
|
+
|
182
|
+
Two configuration options will always be placed in a user's YAML file to override defaults:
|
183
|
+
|
184
|
+
```yaml
|
185
|
+
# Log Settings
|
186
|
+
logger:
|
187
|
+
log_level: warn # 0-5, or DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
188
|
+
log_target: stderr # STDOUT, STDERR, or a file path
|
189
|
+
```
|
190
|
+
|
191
|
+
## Development
|
192
|
+
|
193
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
194
|
+
|
195
|
+
To install this gem onto your local machine from source, 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).
|
196
|
+
|
197
|
+
## Contributing
|
198
|
+
|
199
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/akhoury6/rbcli. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
200
|
+
|
201
|
+
## License
|
202
|
+
|
203
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
204
|
+
|
205
|
+
## Code of Conduct
|
206
|
+
|
207
|
+
Everyone interacting in the Rbcli project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/akhoury6/rbcli/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rbcli"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/examples/mytool
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbcli'
|
4
|
+
|
5
|
+
#########################
|
6
|
+
## Configuration Block ##
|
7
|
+
#########################
|
8
|
+
# This block is where rbcli is configured.
|
9
|
+
#########################
|
10
|
+
|
11
|
+
Rbcli::configurate do
|
12
|
+
scriptname __FILE__.split('/')[-1] # (Required) This line identifies the tool's executable. You can change it if needed, but this should work for most cases.
|
13
|
+
version '0.1.0' # (Required) The version number
|
14
|
+
description 'This is my test CLI tool.' # (Requierd) A description that will appear when the user looks at the help with -h. This can be as long as needed.
|
15
|
+
|
16
|
+
log_level :info # (Optional) Set the default log_level for users. 0-5, or DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
17
|
+
log_target 'stderr' # (Optional) Set the target for logs. Valid values are STDOUT, STDERR, or a file path (as strings)
|
18
|
+
|
19
|
+
config_userfile '/etc/mytool/config.yml', merge_defaults: true, required: false # (Optional) Set location of user's config file. If merge_defaults=true, user settings override default settings, and if false, defaults are not loaded at all. If required=true, application will not run if file does not exist.
|
20
|
+
config_defaults 'defaults.yml' # (Optional, Multiple) Load a YAML file as part of the default config. This can be called multiple times, and the YAML files will be merged. User config is generated from these
|
21
|
+
config_default :myopt, description: 'Testing this', value: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config
|
22
|
+
|
23
|
+
option :name, 'Give me your name', type: :string, default: 'Stranger' # (Optional, Multiple) Add a global CLI parameter. Supported types are :string, :boolean, :integer, :float, :date, and :io. Can be called multiple times.
|
24
|
+
|
25
|
+
default_action do |opts| # (Optional) The default code to execute when no subcommand is given. If not present, the help is shown (same as -h)
|
26
|
+
puts "Hello, #{opts[:name]}."
|
27
|
+
puts "To see the help, use -h"
|
28
|
+
end
|
29
|
+
|
30
|
+
pre_hook do |opts| # (Optional) Allows providing a block of code that runs before any command
|
31
|
+
puts 'This is a pre-command hook. It executes before the command.'
|
32
|
+
end
|
33
|
+
|
34
|
+
post_hook do |opts| # (Optional) Allows providing a block of code that runs after any command
|
35
|
+
puts 'This is a post-command hook. It executes after the command.'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
#########################
|
40
|
+
## Command Declaration ##
|
41
|
+
#########################
|
42
|
+
# With rbcli, commands are declared by subclassing
|
43
|
+
# from Rbcli::Command. The name of the class will be
|
44
|
+
# the command that is available to the user.
|
45
|
+
#########################
|
46
|
+
class Test < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
47
|
+
description 'This is a short description.' # (Required) Short description for the global help
|
48
|
+
usage 'This is some really long usage text description!' # (Required) Long description for the command-specific help
|
49
|
+
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
50
|
+
|
51
|
+
config_defaults 'defaults.yml' # (Optional, Multiple) Load a YAML file as part of the default config. This can be called multiple times, and the YAML files will be merged. User config is generated from these
|
52
|
+
config_default :myopt2, description: 'Testing this again', value: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config
|
53
|
+
|
54
|
+
action do |params, args, global_opts, config| # (Required) Block to execute if the command is called.
|
55
|
+
Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger
|
56
|
+
puts "\nArgs:\n#{args}" # Arguments that came after the command on the CLI
|
57
|
+
puts "Params:\n#{params}" # Parameters, as described through the option statements above
|
58
|
+
puts "Global opts:\n#{global_opts}" # Global Parameters, as descirbed in the Configurate section
|
59
|
+
puts "Config:\n#{config}" # Config file values
|
60
|
+
puts "\nDone!!!"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#####################
|
65
|
+
## Parse Statement ##
|
66
|
+
#####################
|
67
|
+
# When this statement is called, the CLI will be
|
68
|
+
# parsed and code executed as
|
69
|
+
#####################
|
70
|
+
Rbcli.parse # Parse CLI and execute
|
data/exe/rbcli
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require '../lib/rbcli'
|
4
|
+
|
5
|
+
Rbcli::configurate do
|
6
|
+
scriptname __FILE__.split('/')[-1]
|
7
|
+
version Rbcli::VERSION
|
8
|
+
description 'RBCli initialization tool'
|
9
|
+
end
|
10
|
+
|
11
|
+
class Init < Rbcli::Command
|
12
|
+
description 'Initialize a skeleton RBCli executable.'
|
13
|
+
usage 'This will generate a new file in the current folder'
|
14
|
+
parameter :filename, 'Name of file to generate', type: :string, required: true
|
15
|
+
|
16
|
+
action do |params, args, global_opts, config|
|
17
|
+
src = "#{File.dirname(__FILE__)}/../examples/mytool"
|
18
|
+
dest = "#{Dir.pwd}/#{params[:filename]}"
|
19
|
+
if File.exists? dest
|
20
|
+
puts "File #{params[:filename]} already exists. Please delete and try again."
|
21
|
+
else
|
22
|
+
puts "Generating file #{params[:filename]}..."
|
23
|
+
FileUtils.cp src, dest
|
24
|
+
puts "Done!"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
Rbcli.parse
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Rbcli
|
2
|
+
|
3
|
+
@data = {
|
4
|
+
scriptname: nil,
|
5
|
+
version: nil,
|
6
|
+
description: nil,
|
7
|
+
config_userfile: 'config.yml',
|
8
|
+
allow_json: false,
|
9
|
+
options: {},
|
10
|
+
default_action: nil,
|
11
|
+
pre_hook: nil,
|
12
|
+
post_hook: nil
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.configurate &block
|
16
|
+
@self_before_instance_eval = eval "self", block.binding
|
17
|
+
instance_eval &block
|
18
|
+
end
|
19
|
+
|
20
|
+
# def self.method_missing(method, *args, &block)
|
21
|
+
# @self_before_instance_eval.send method, *args, &block
|
22
|
+
# end
|
23
|
+
|
24
|
+
##
|
25
|
+
# DSL Functions
|
26
|
+
##
|
27
|
+
def self.scriptname name
|
28
|
+
@data[:scriptname] = name
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.version vsn
|
32
|
+
@data[:version] = vsn
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.description desc
|
36
|
+
@data[:description] = desc
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.log_level level
|
40
|
+
Rbcli::Logger::save_defaults level: level
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.log_target target
|
44
|
+
Rbcli::Logger::save_defaults target: target
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.config_userfile *params
|
48
|
+
Rbcli::Config::set_userfile *params
|
49
|
+
@data[:config_userfile] = params[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.config_defaults filename
|
53
|
+
Rbcli::Config::add_defaults filename
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.config_default *params
|
57
|
+
Rbcli::Config::add_default *params
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.allow_json_output allow_json
|
61
|
+
@data[:allow_json] = allow_json
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.option name, description, type: :boolean, default: false
|
65
|
+
@data[:options][name.to_sym] = {
|
66
|
+
description: description,
|
67
|
+
type: type,
|
68
|
+
default: default
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.default_action &block
|
73
|
+
@data[:default_action] = block
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.pre_hook &block
|
77
|
+
@data[:pre_hook] = block
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.post_hook &block
|
81
|
+
@data[:post_hook] = block
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Data Retrieval
|
86
|
+
##
|
87
|
+
def self.configuration
|
88
|
+
@data
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|