rbcli 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +10 -8
- data/exe/rbcli +112 -25
- data/lib-sh/lib-rbcli.sh +104 -0
- data/lib/rbcli-tool.rb +3 -2
- data/lib/rbcli-tool/generators.rb +85 -0
- data/lib/rbcli-tool/project.rb +14 -10
- data/lib/rbcli-tool/{erb_renderer.rb → util.rb} +6 -1
- data/lib/rbcli/scriptwrapping/scriptwrapper.rb +33 -13
- data/lib/rbcli/version.rb +1 -1
- data/skeletons/project/application/commands/command.erb +26 -0
- data/skeletons/project/application/commands/script.erb +24 -0
- data/skeletons/project/application/commands/scripts/script.sh +44 -12
- data/skeletons/project/hooks/default_action.rb +1 -1
- metadata +7 -4
- data/skeletons/project/application/commands/command.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f1de334efcc5489a103f4001a64d40a347d8aac715566682001e50600e596af
|
4
|
+
data.tar.gz: ecd300a10c89299f987d1031fff974cf7e45bc31ff56af20871462c98a2e833d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c954de05e3383d692e16cc6eb238add53b4e24758f81440ea5601ec10be780e12df6ed3358dd539494dc731ffca0fe4457021a566003af7ddbb4b21f4ef05b7
|
7
|
+
data.tar.gz: 879bb9c5627c7118ae7bf8c319ade644aa48191eca455ccfeaf7f910e1f56c33b1f2ee38b1ed727a429b4e272e780af0756b940c1782f7ec6f8737751e6e1950
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -31,7 +31,7 @@ Some of its key features include:
|
|
31
31
|
|
32
32
|
## Installation
|
33
33
|
|
34
|
-
RBCli is available on rubygems.org. You can add it to your application's `
|
34
|
+
RBCli is available on rubygems.org. You can add it to your application's `Gemfile` or `gemspec`, or install it manually via `gem install rbcli`.
|
35
35
|
|
36
36
|
|
37
37
|
## The Basics
|
@@ -217,7 +217,8 @@ The user chain has two functions: generating and loading configuration from a YA
|
|
217
217
|
Rbcli will determine the correct location to locate the user configuration based on two factors:
|
218
218
|
|
219
219
|
1. The default location set in the configurate DSL
|
220
|
-
a. `config_userfile '/etc/mytool/config.yml', merge_defaults: true, required: false
|
220
|
+
a. `config_userfile '/etc/mytool/config.yml', merge_defaults: true, required: false`
|
221
|
+
b. (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.
|
221
222
|
2. The location specified on the command line using the `-c <filename>` option
|
222
223
|
b. `yourclitool -c localfile.yml`
|
223
224
|
|
@@ -469,7 +470,7 @@ As you can see above, items which have nested values they are passed in as JSON.
|
|
469
470
|
|
470
471
|
### Variable Path Mode
|
471
472
|
|
472
|
-
Variable Path Mode works the same as Direct Path Mode, only instead of providing a string we provide a block that returns a string. This allows us to generate different commands based on the CLI parameters that the user passed:
|
473
|
+
Variable Path Mode works the same as Direct Path Mode, only instead of providing a string we provide a block that returns a string. This allows us to generate different commands based on the CLI parameters that the user passed, or pass configuration as CLI parameters to the external application:
|
473
474
|
|
474
475
|
```ruby
|
475
476
|
class Test < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
@@ -478,7 +479,7 @@ class Test < Rbcli::Command
|
|
478
479
|
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
479
480
|
|
480
481
|
extern envvars: {MY_OTHER_VAR: 'another_value'} do |params, args, global_opts, config| # Alternate usage. Supplying a block instead of a path allows us to modify the command based on the arguments and configuration supplied by the user.
|
481
|
-
if params[:force]
|
482
|
+
if params[:force]
|
482
483
|
"externalapp --test-script foo --ignore-errors"
|
483
484
|
else
|
484
485
|
"externalapp"
|
@@ -517,10 +518,11 @@ It is highly recommended to __not__ create files in these folders manually, and
|
|
517
518
|
rbcli command -n <name>
|
518
519
|
rbcli script -n <name>
|
519
520
|
rbcli userconf -n <name>
|
520
|
-
rbcli hook -
|
521
|
-
rbcli hook -
|
522
|
-
rbcli hook -
|
523
|
-
rbcli hook -
|
521
|
+
rbcli hook --default # or rbcli hook -d
|
522
|
+
rbcli hook --pre # or rbcli hook -p
|
523
|
+
rbcli hook --post # or rbcli hook -o
|
524
|
+
rbcli hook --firstrun # or rbcli hook -f
|
525
|
+
rbcli hook -dpof # all hooks at once
|
524
526
|
```
|
525
527
|
|
526
528
|
That said, this readme will provide you with the information required to do things manually if you so desire. More details on generators later.
|
data/exe/rbcli
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
3
|
+
require "#{File.dirname(__FILE__)}/../lib/rbcli.rb"
|
4
4
|
|
5
5
|
Rbcli::Configurate.me do
|
6
6
|
scriptname __FILE__.split('/')[-1]
|
@@ -8,7 +8,7 @@ Rbcli::Configurate.me do
|
|
8
8
|
description 'RBCli initialization tool'
|
9
9
|
end
|
10
10
|
|
11
|
-
require
|
11
|
+
require "#{File.dirname(__FILE__)}/../lib/rbcli-tool.rb"
|
12
12
|
|
13
13
|
class Docs < Rbcli::Command
|
14
14
|
description 'Show Documentation (Beta)'
|
@@ -37,7 +37,7 @@ Mini: A single-file RBCli project. All features are supported, but project s
|
|
37
37
|
|
38
38
|
Micro: A single-file, minimal RBCli project. Similar to a mini project, but only the minimal required code is
|
39
39
|
generated. Recommended for rapid prototyping of scripts, for advanced users only.
|
40
|
-
|
40
|
+
EOF
|
41
41
|
|
42
42
|
parameter :name, 'Name of project to generate', type: :string, required: true
|
43
43
|
parameter :type, 'Specify project type', type: :string, permitted: %w(standard micro mini), default: 'standard'
|
@@ -55,47 +55,134 @@ Micro: A single-file, minimal RBCli project. Similar to a mini project, but o
|
|
55
55
|
|
56
56
|
proj = RBCliTool::Project.new(dest, template_vars)
|
57
57
|
|
58
|
-
if proj.exists?
|
59
|
-
|
60
|
-
|
61
|
-
end
|
58
|
+
# if proj.exists?
|
59
|
+
# RBCliTool.continue_confirmation "The project or file #{params[:name]} already exists; contents will be overwritten."
|
60
|
+
# FileUtils.rm_rf dest
|
61
|
+
# end
|
62
62
|
|
63
63
|
case params[:type]
|
64
64
|
when 'micro' # Micro: Single File, simplified
|
65
|
-
|
66
|
-
|
65
|
+
success = proj.create_micro
|
67
66
|
when 'mini' # Mini: Single File
|
68
|
-
|
69
|
-
|
67
|
+
success = proj.create_mini
|
70
68
|
else # Standard; full project structure
|
71
|
-
|
72
|
-
puts "\nInitialization Complete!\n"
|
73
|
-
else
|
74
|
-
puts "\nAn RBCli Project already exists in the current directory tree at: #{proj.exists?}. Aborting.\n"
|
75
|
-
end
|
76
|
-
|
69
|
+
success = proj.create
|
77
70
|
end # END case params[:type]
|
78
71
|
|
72
|
+
if success
|
73
|
+
puts "\nInitialization Complete!\n"
|
74
|
+
else
|
75
|
+
puts "\nAn RBCli Project already exists in the current directory tree at: #{proj.exists?}. Please delete the project or run this command from a different directory.\n"
|
76
|
+
end
|
79
77
|
end
|
80
78
|
end
|
81
79
|
|
82
80
|
class Command < Rbcli::Command
|
83
81
|
description 'Generate an Rbcli Command under the current project'
|
84
82
|
usage <<-EOF
|
85
|
-
This will generate a new
|
83
|
+
This will generate a new command under the current RBCli project.
|
86
84
|
|
85
|
+
Please run this command from within the project's directory structure.
|
86
|
+
EOF
|
87
87
|
|
88
|
-
|
89
|
-
|
88
|
+
parameter :name, 'Name of command to generate', type: :string, required: true
|
89
|
+
parameter :description, 'A short description of the command', type: :string, default: 'TODO: Description goes here'
|
90
|
+
parameter :usagetext, 'Usage help text for the command', type: :string, default: 'TODO: Usage text goes here'
|
90
91
|
|
91
|
-
|
92
|
-
|
92
|
+
action do |params, args, global_opts, config|
|
93
|
+
# First we check that we are working within a project folder
|
94
|
+
project_root = RBCliTool::Project.find_root(Dir.pwd)
|
95
|
+
RBCliTool.exit_with_error("Can't find the project root in the current path. Please `cd` to your project's directory before running this command, and ensure that the `.rbcli` file is present in its root path.") unless project_root
|
93
96
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
+
# Prepare template vars
|
98
|
+
template_vars = {
|
99
|
+
name: params[:name],
|
100
|
+
description: params[:description],
|
101
|
+
usage_text: params[:usagetext],
|
102
|
+
rbcli_version: Rbcli::VERSION
|
103
|
+
}
|
104
|
+
|
105
|
+
generator = RBCliTool::Generator.new(:command, project_root, template_vars)
|
106
|
+
generator.run
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Extern < Rbcli::Command
|
111
|
+
description 'Generate an Rbcli Command with Bash Script under the current project'
|
112
|
+
usage <<-EOF
|
113
|
+
This will generate a new command under the current RBCli project, and a skeleton bash script to code it.
|
114
|
+
|
115
|
+
Use this option if you prefer to use bash (or another shell) to script your command, or if you need to integrate with
|
116
|
+
a third party application.
|
117
|
+
|
118
|
+
Please run this command from within the project's directory structure.
|
119
|
+
EOF
|
97
120
|
|
98
121
|
parameter :name, 'Name of command to generate', type: :string, required: true
|
122
|
+
parameter :description, 'A short description of the command', type: :string, default: 'TODO: Description goes here'
|
123
|
+
parameter :usagetext, 'Usage help text for the command', type: :string, default: 'TODO: Usage text goes here'
|
124
|
+
parameter :skip_script, 'Skip creating a bash script and set executable path manually', type: :boolean, default: false
|
125
|
+
|
126
|
+
action do |params, args, global_opts, config|
|
127
|
+
# First we check that we are working within a project folder
|
128
|
+
project_root = RBCliTool::Project.find_root(Dir.pwd)
|
129
|
+
RBCliTool.exit_with_error("Can't find the project root in the current path. Please `cd` to your project's directory before running this command, and ensure that the `.rbcli` file is present in its root path.") unless project_root
|
130
|
+
|
131
|
+
# Prepare template vars
|
132
|
+
template_vars = {
|
133
|
+
name: params[:name],
|
134
|
+
description: params[:description],
|
135
|
+
usage_text: params[:usagetext],
|
136
|
+
no_script: params[:skip_script],
|
137
|
+
rbcli_version: Rbcli::VERSION
|
138
|
+
}
|
139
|
+
|
140
|
+
generator = RBCliTool::Generator.new(:extern, project_root, template_vars)
|
141
|
+
generator.run
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class Hook < Rbcli::Command
|
146
|
+
description 'Generate an Rbcli Hook under the current project'
|
147
|
+
usage <<-EOF
|
148
|
+
This will generate one or more execution hooks for the current project.
|
149
|
+
|
150
|
+
Default: The default hook runs whenever the user does not specify a command. If the hook is not present, the default
|
151
|
+
behavior is to show the help text (same as -h).
|
152
|
+
|
153
|
+
Pre: The pre-execution hook, which runs code prior to the execution of any command. This allows for actions such
|
154
|
+
as authentiation into remote systems.
|
155
|
+
|
156
|
+
Post: The post-execution hook, which runs code after the execution of any command.
|
157
|
+
|
158
|
+
First-run: The first-run hook will run only on the first time the user runs the application. This is useful for
|
159
|
+
initial setup or for welcome messages to be shown. Note that if you enable the first-run hook, you must
|
160
|
+
also enable local_state (see config/storage.rb).
|
161
|
+
|
162
|
+
Please run this command from within the project's directory structure.
|
163
|
+
EOF
|
164
|
+
|
165
|
+
parameter :default, 'Generate the default (no-command-entered) hook', type: :boolean, default: false
|
166
|
+
parameter :pre, 'Generate the pre-execution hook', type: :boolean, default: false
|
167
|
+
parameter :post, 'Generate the post-execution hook', type: :boolean, default: false
|
168
|
+
parameter :firstrun, 'Generate the first-run hook', type: :boolean, default: false
|
169
|
+
|
170
|
+
action do |params, args, global_opts, config|
|
171
|
+
# First we check that we are working within a project folder
|
172
|
+
project_root = RBCliTool::Project.find_root(Dir.pwd)
|
173
|
+
RBCliTool.exit_with_error("Can't find the project root in the current path. Please `cd` to your project's directory before running this command, and ensure that the `.rbcli` file is present in its root path.") unless project_root
|
174
|
+
|
175
|
+
generated_something = false
|
176
|
+
|
177
|
+
[:default, :pre, :post, :firstrun].each do |pname|
|
178
|
+
next unless params[pname]
|
179
|
+
generator = RBCliTool::Generator.new(:hook, project_root, pname)
|
180
|
+
generator.run
|
181
|
+
generated_something = true
|
182
|
+
end
|
183
|
+
|
184
|
+
RBCliTool.exit_with_error("No hooks specified. Please run `rbcli hooks -h` for details on how to generate hooks.") unless generated_something
|
185
|
+
end
|
99
186
|
end
|
100
187
|
|
101
188
|
|
data/lib-sh/lib-rbcli.sh
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
## Log message
|
4
|
+
function message {
|
5
|
+
if [ "$2" == "err" ]; then
|
6
|
+
COLOR='\033[00;31m'
|
7
|
+
else
|
8
|
+
|
9
|
+
COLOR='\033[00;32m'
|
10
|
+
fi
|
11
|
+
|
12
|
+
if [ "$2" == "no_newline" ]; then
|
13
|
+
printf "${COLOR}[RBCLI-Setup] ${1}\033[0m"
|
14
|
+
else
|
15
|
+
echo -e "${COLOR}[RBCLI-Setup] ${1}\033[0m"
|
16
|
+
fi
|
17
|
+
}
|
18
|
+
|
19
|
+
## Detect OS
|
20
|
+
function detect_os {
|
21
|
+
unameOut="$(uname -s)"
|
22
|
+
case "${unameOut}" in
|
23
|
+
Linux*) machine=Linux;;
|
24
|
+
Darwin*) machine=Darwin;;
|
25
|
+
CYGWIN*) machine=Cygwin;;
|
26
|
+
MINGW*) machine=MinGw;;
|
27
|
+
*) machine="UNKNOWN:${unameOut}"
|
28
|
+
esac
|
29
|
+
echo ${machine}
|
30
|
+
}
|
31
|
+
|
32
|
+
## Install JQ
|
33
|
+
function install_jq {
|
34
|
+
case "$(detect_os)}" in
|
35
|
+
Linux)
|
36
|
+
_tmpdir=$(mktemp -d)
|
37
|
+
_pwd=$(pwd)
|
38
|
+
cd $_tmpdir
|
39
|
+
curl -sOL "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64"
|
40
|
+
mv jq-linux64 /usr/bin/jq
|
41
|
+
cd $_pwd
|
42
|
+
rm -rf $_tmpdir
|
43
|
+
;;
|
44
|
+
Darwin*)
|
45
|
+
message "Apple OSX Detected; homebrew must be installed to continue. Continue? (Y/n): " "no_newline"
|
46
|
+
read -n1 _answer
|
47
|
+
printf "\n"
|
48
|
+
if [[ "${_answer}" =~ ^(y|Y)$ ]]; then
|
49
|
+
brew install jq
|
50
|
+
else
|
51
|
+
message "Installation aborted."
|
52
|
+
exit 0
|
53
|
+
fi
|
54
|
+
;;
|
55
|
+
*)
|
56
|
+
message "Sorry, your machine type ($(detect_os)) is not supported. This script can only install JQ automatically on either Linux or OSX."
|
57
|
+
message "Please visit https://stedolan.github.io/jq/ to install JQ manually on your system."
|
58
|
+
exit 0
|
59
|
+
esac
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
# We need to make sure JQ is installed so that we can parse variables
|
64
|
+
which jq &> /dev/null
|
65
|
+
_RESULT=$?
|
66
|
+
if [[ "${_RESULT}" -ne 0 ]]; then
|
67
|
+
message "Application JQ not found on local system."
|
68
|
+
message "Installing JQ. Sudo access required, please input password if prompted."
|
69
|
+
install_jq
|
70
|
+
fi
|
71
|
+
|
72
|
+
|
73
|
+
######
|
74
|
+
## RBCLI
|
75
|
+
######
|
76
|
+
# This function provides an interface to the variables exposed by RBCli
|
77
|
+
function rbcli {
|
78
|
+
_vargroup=$1
|
79
|
+
_var=$2
|
80
|
+
|
81
|
+
case "${_vargroup}" in
|
82
|
+
params)
|
83
|
+
_groupname='__RBCLI_PARAMS'
|
84
|
+
;;
|
85
|
+
args)
|
86
|
+
_groupname='__RBCLI_ARGS'
|
87
|
+
;;
|
88
|
+
global_opts)
|
89
|
+
_groupname='__RBCLI_GLOBAL'
|
90
|
+
;;
|
91
|
+
config)
|
92
|
+
_groupname='__RBCLI_CONFIG'
|
93
|
+
;;
|
94
|
+
myvars)
|
95
|
+
_groupname='__RBCLI_MYVARS'
|
96
|
+
;;
|
97
|
+
*)
|
98
|
+
message "Invalid RBCLI variable reference. Please reference variables from one of the following groups: params, args, global_opts, config, commandvars." "err"
|
99
|
+
exit 1
|
100
|
+
esac
|
101
|
+
echo $(echo ${!_groupname} | jq -r "${2}")
|
102
|
+
}
|
103
|
+
export -f rbcli
|
104
|
+
|
data/lib/rbcli-tool.rb
CHANGED
@@ -11,6 +11,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
11
11
|
|
12
12
|
module RBCliTool end
|
13
13
|
|
14
|
+
require 'rbcli-tool/util'
|
14
15
|
require 'rbcli-tool/mdless_fix'
|
15
|
-
require 'rbcli-tool/
|
16
|
-
require 'rbcli-tool/
|
16
|
+
require 'rbcli-tool/project'
|
17
|
+
require 'rbcli-tool/generators'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module RBCliTool
|
2
|
+
class Generator
|
3
|
+
def self.inherited(subklass)
|
4
|
+
@@types ||= {}
|
5
|
+
@@types[subklass.name.downcase.split('::')[1]] = subklass
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize type = nil, root_path = nil, template_vars = {}
|
9
|
+
@generator = @@types[type.to_s.downcase].new root_path, template_vars
|
10
|
+
end
|
11
|
+
|
12
|
+
def run *args
|
13
|
+
@generator.run *args
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Command < Generator
|
18
|
+
def initialize root_path, template_vars
|
19
|
+
@srcpath = "#{File.dirname(__FILE__)}/../../skeletons/project/application/commands/command.erb"
|
20
|
+
@dest = "#{root_path}/application/commands/#{template_vars[:name]}.rb"
|
21
|
+
@template_vars = template_vars
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
if File.exists? @dest
|
26
|
+
RBCliTool.continue_confirmation "The command #{@template_vars[:name]} already exists; contents will be overwritten."
|
27
|
+
FileUtils.rm_rf @dest
|
28
|
+
end
|
29
|
+
RBCliTool.cp_file @srcpath, @dest, @template_vars
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Extern < Generator
|
34
|
+
def initialize root_path, template_vars
|
35
|
+
@filepaths = [
|
36
|
+
{
|
37
|
+
src: "#{File.dirname(__FILE__)}/../../skeletons/project/application/commands/script.erb",
|
38
|
+
dest: "#{root_path}/application/commands/#{template_vars[:name]}.rb"
|
39
|
+
}, {
|
40
|
+
src: "#{File.dirname(__FILE__)}/../../skeletons/project/application/commands/scripts/script.sh",
|
41
|
+
dest: "#{root_path}/application/commands/scripts/#{template_vars[:name]}.sh",
|
42
|
+
perms: 0755
|
43
|
+
}
|
44
|
+
]
|
45
|
+
@template_vars = template_vars
|
46
|
+
#@template_vars[:libsh_path] = Pathname.new("#{File.dirname(__FILE__)}/../../lib-sh/lib-rbcli.sh").cleanpath.to_s # We clean this path because it will be visible to the user
|
47
|
+
end
|
48
|
+
|
49
|
+
def run
|
50
|
+
confirmed = false
|
51
|
+
@filepaths.each do |file|
|
52
|
+
next if file[:dest].end_with? '.sh' and @template_vars[:no_script]
|
53
|
+
if File.exists? file[:dest]
|
54
|
+
RBCliTool.continue_confirmation "The script command #{@template_vars[:name]} already exists; contents will be overwritten." unless confirmed
|
55
|
+
confirmed = true
|
56
|
+
FileUtils.rm_rf file[:dest]
|
57
|
+
end
|
58
|
+
RBCliTool.cp_file file[:src], file[:dest], @template_vars
|
59
|
+
File.chmod file[:perms], file[:dest] if file.key? :perms
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Hook < Generator
|
65
|
+
def initialize root_path, hook_type
|
66
|
+
@typename = {
|
67
|
+
default: 'default_action',
|
68
|
+
pre: 'pre_execution',
|
69
|
+
post: 'post_execution',
|
70
|
+
firstrun: 'first_run'
|
71
|
+
}[hook_type]
|
72
|
+
@src = "#{File.dirname(__FILE__)}/../../skeletons/project/hooks/#{@typename}.rb"
|
73
|
+
@dest = "#{root_path}/hooks/#{@typename}.rb"
|
74
|
+
end
|
75
|
+
|
76
|
+
def run
|
77
|
+
if File.exists? @dest
|
78
|
+
RBCliTool.continue_confirmation "The #{@typename} hook already exists; contents will be overwritten."
|
79
|
+
FileUtils.rm_rf @dest
|
80
|
+
end
|
81
|
+
RBCliTool.cp_file @src, @dest
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/lib/rbcli-tool/project.rb
CHANGED
@@ -33,6 +33,7 @@ module RBCliTool
|
|
33
33
|
|
34
34
|
# Create executable
|
35
35
|
RBCliTool.cp_file "#{src}/exe/executable", "#{@dest}/exe/#{@template_vars[:cmdname]}", @template_vars
|
36
|
+
FileUtils.chmod 0755, "#{@dest}/exe/#{@template_vars[:cmdname]}"
|
36
37
|
|
37
38
|
# Create files for Gem package
|
38
39
|
Dir.entries(src).each do |file|
|
@@ -65,23 +66,26 @@ module RBCliTool
|
|
65
66
|
project_exists?
|
66
67
|
end
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# If the specified file already exists...
|
72
|
-
return true if File.exists? @dest
|
73
|
-
|
74
|
-
# Or if the .rbcli file exists anywhere in the tree...
|
75
|
-
searchpath = @dest
|
69
|
+
def self.find_root path
|
70
|
+
# We look for the .rbcli file in the current tree and return the root path
|
71
|
+
searchpath = path
|
76
72
|
while !searchpath.empty?
|
77
73
|
return searchpath if File.directory? searchpath and File.exists? "#{searchpath}/.rbcli"
|
78
74
|
spath = searchpath.split('/')
|
79
75
|
searchpath = (spath.length == 2) ? '/' : spath[0..-2].join('/')
|
80
76
|
end
|
81
|
-
|
82
|
-
# Otherwise we say the project does not exist
|
83
77
|
false
|
84
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def project_exists?
|
83
|
+
# If the specified file already exists...
|
84
|
+
return true if File.exists? @dest
|
85
|
+
|
86
|
+
# Or if the .rbcli file exists anywhere in the tree, we know that we are in a subdirectory of a project
|
87
|
+
Project::find_root(@dest)
|
88
|
+
end
|
85
89
|
end
|
86
90
|
|
87
91
|
end
|
@@ -8,7 +8,7 @@ module RBCliTool
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def render
|
11
|
-
ERB.new(File.read(@filename)).result(binding)
|
11
|
+
ERB.new(File.read(@filename), nil, '-').result(binding)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -40,4 +40,9 @@ module RBCliTool
|
|
40
40
|
exit 0
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
def self.exit_with_error text
|
45
|
+
puts text
|
46
|
+
exit 1
|
47
|
+
end
|
43
48
|
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
class Rbcli::Command
|
2
2
|
def self.extern path: nil, envvars: nil, &block
|
3
|
+
if path == :default
|
4
|
+
callerscript = caller_locations.first.absolute_path
|
5
|
+
path = "#{File.dirname(callerscript)}/scripts/#{File.basename(callerscript, ".*")}.sh"
|
6
|
+
end
|
3
7
|
block = nil unless block_given?
|
4
8
|
@extern = Rbcli::Scriptwrapper.new path, envvars, block
|
5
9
|
end
|
@@ -14,24 +18,35 @@ require 'json'
|
|
14
18
|
class Rbcli::Scriptwrapper
|
15
19
|
def initialize path, envvars = nil, block = nil
|
16
20
|
@path = path
|
17
|
-
@envvars = envvars
|
21
|
+
@envvars = envvars || {}
|
18
22
|
@block = block
|
19
23
|
end
|
20
24
|
|
21
25
|
def execute params, args, global_opts, config
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
####
|
27
|
+
#### The following code will flatten one level of the hashes into separate variables
|
28
|
+
#### It is deprecated in favor of passing along json to be parsed with JQ
|
29
|
+
####
|
30
|
+
# env_hash = {}
|
31
|
+
# {
|
32
|
+
# '__PARAMS' => params,
|
33
|
+
# '__ARGS' => args,
|
34
|
+
# '__GLOBAL' => global_opts,
|
35
|
+
# '__CONFIG' => config
|
36
|
+
# }.each do |name, hsh|
|
37
|
+
# hsh.each do |k, v|
|
38
|
+
# env_hash["#{name}_#{k.upcase}"] = v.to_json
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# env_hash.merge!(@envvars.deep_stringify!) unless @envvars.nil?
|
33
42
|
|
34
|
-
env_hash
|
43
|
+
env_hash = {
|
44
|
+
'__RBCLI_PARAMS' => params.to_json,
|
45
|
+
'__RBCLI_ARGS' => args.to_json,
|
46
|
+
'__RBCLI_GLOBAL' => global_opts.to_json,
|
47
|
+
'__RBCLI_CONFIG' => config.to_json,
|
48
|
+
'__RBCLI_MYVARS' => @envvars.to_json
|
49
|
+
}
|
35
50
|
|
36
51
|
if @block
|
37
52
|
path = @block.call params, args, global_opts, config
|
@@ -39,6 +54,11 @@ class Rbcli::Scriptwrapper
|
|
39
54
|
path = @path
|
40
55
|
end
|
41
56
|
|
57
|
+
# IO.popen(env_hash, path) do |io|
|
58
|
+
# while (line = io.gets) do
|
59
|
+
# puts line
|
60
|
+
# end
|
61
|
+
# end
|
42
62
|
system(env_hash, path)
|
43
63
|
end
|
44
64
|
|
data/lib/rbcli/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
#########################
|
2
|
+
## Command Declaration ##
|
3
|
+
#########################
|
4
|
+
# With rbcli, commands are declared by subclassing
|
5
|
+
# from Rbcli::Command. The name of the class will be
|
6
|
+
# the command that is available to the user.
|
7
|
+
#########################
|
8
|
+
class <%= @vars[:name].capitalize %> < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
9
|
+
description '<%= @vars[:description] %>' # (Required) Short description for the global help
|
10
|
+
usage '<%= @vars[:usage_text] %>' # (Required) Long description for the command-specific help
|
11
|
+
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
12
|
+
|
13
|
+
config_default :myopt2, description: 'My Option #2', default: 'Default Value Here' # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.
|
14
|
+
# Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project that specifies the default values of all options
|
15
|
+
|
16
|
+
action do |params, args, global_opts, config| # (Required) Block to execute if the command is called.
|
17
|
+
Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger
|
18
|
+
puts "\nArgs:\n#{args}" # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz'])
|
19
|
+
puts "Params:\n#{params}" # Parameters, as described through the option statements above
|
20
|
+
puts "Global opts:\n#{global_opts}" # Global Parameters, as descirbed in the Configurate section
|
21
|
+
puts "Config:\n#{config}" # Config file values
|
22
|
+
puts "LocalState:\n#{Rbcli.local_state}" # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil?
|
23
|
+
puts "RemoteState:\n#{Rbcli.remote_state}" # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil?
|
24
|
+
puts "\nDone!!!"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#########################
|
2
|
+
## Command Declaration ##
|
3
|
+
#########################
|
4
|
+
# With rbcli, commands are declared by subclassing
|
5
|
+
# from Rbcli::Command. The name of the class will be
|
6
|
+
# the command that is available to the user.
|
7
|
+
#########################
|
8
|
+
class <%= @vars[:name].capitalize %> < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
9
|
+
description '<%= @vars[:description] %>' # (Required) Short description for the global help
|
10
|
+
usage '<%= @vars[:usage_text] %>' # (Required) Long description for the command-specific help
|
11
|
+
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
12
|
+
|
13
|
+
config_default :myopt2, description: 'Testing this again', default: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config.
|
14
|
+
# Alternatively, you can simply create a yaml file in the `default_user_configs` directory in your project
|
15
|
+
|
16
|
+
<% if @vars[:no_script] -%>
|
17
|
+
extern path: 'path/to/application', envvars: {MYVAR: 'some_value'} # (Required) Runs a given application, with optional environment variables, when the user runs the command.
|
18
|
+
#extern envvars: {MY_OTHER_VAR: 'another_value'} do |params, args, global_opts, config| # Alternate usage. Supplying a block instead of a path allows us to modify the command based on the arguments and configuration supplied by the user. This allows passing config settings as command line arguments to external applications. The block must return a string, which is the command to be executed.
|
19
|
+
# "echo 'Forcing something: #{params[:force].to_s}'"
|
20
|
+
#end
|
21
|
+
<% else -%>
|
22
|
+
extern path: :default # (Required): Do not edit this line. Do delete it if you wish to manually specify a script path and set environment variables.
|
23
|
+
<% end -%>
|
24
|
+
end
|
@@ -1,23 +1,55 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
|
-
|
2
|
+
#
|
3
3
|
###
|
4
|
-
# This is the RBCli script for the command
|
4
|
+
# This is the RBCli script for the command `<%= @vars[:name] %>`
|
5
5
|
###
|
6
6
|
#
|
7
|
-
# You can
|
8
|
-
|
7
|
+
# You can access RBCli's variables via the `rbcli` command, which is imported by this line:
|
8
|
+
source $(echo $(cd "$(dirname $(gem which rbcli))/../lib-sh" && pwd)/lib-rbcli.sh)
|
9
|
+
#
|
10
|
+
# The `rbcli` function is actually a wrapper around `jq` (https://stedolan.github.io/jq/). It can automatically
|
11
|
+
# jq on users' machines if running Linux or OSX, and users have sudo access. If not, users must install it manually.
|
12
|
+
# This is because behind the scenes, RBCli passes in the variable data by populating evironment variables with JSON.
|
13
|
+
#
|
14
|
+
# You can view the entire JSON structures with:
|
15
|
+
#
|
16
|
+
# rbcli params
|
17
|
+
# rbcli args
|
18
|
+
# rbcli global_opts
|
19
|
+
# rbcli config
|
20
|
+
# rbcli myvars
|
21
|
+
#
|
22
|
+
# And to access specific data within that json, you can add some jq syntax as shown below. The first two examples show
|
23
|
+
# how to get data from a nested hash, and the last example shows how to select an item from an array.
|
9
24
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# __CONFIG <config_name>
|
25
|
+
# echo "Log Level: $(rbcli config .logger.log_level)"
|
26
|
+
# echo "Log Target: $(rbcli config .logger.log_target)"
|
27
|
+
# echo "First Argument (if passed): $(rbcli args .[0])"
|
14
28
|
#
|
15
|
-
# If
|
16
|
-
#
|
29
|
+
# If you wish to parse the variables manually and remove the dependency on JQ, you can comment out the line above
|
30
|
+
# and access these variables directly:
|
17
31
|
#
|
18
|
-
#
|
32
|
+
# __RBCLI_PARAMS
|
33
|
+
# __RBCLI_ARGS
|
34
|
+
# __RBCLI_GLOBAL
|
35
|
+
# __RBCLI_CONFIG
|
36
|
+
# __RBCLI_MYVARS
|
19
37
|
#
|
20
38
|
###
|
21
39
|
#
|
22
40
|
|
23
|
-
|
41
|
+
echo "------Params------"
|
42
|
+
rbcli params
|
43
|
+
echo "------Args------"
|
44
|
+
rbcli args
|
45
|
+
echo "------Global Opts------"
|
46
|
+
rbcli global_opts
|
47
|
+
echo "------Config------"
|
48
|
+
rbcli config
|
49
|
+
echo "------MyVars------"
|
50
|
+
rbcli myvars
|
51
|
+
echo ""
|
52
|
+
echo "Usage Examples:"
|
53
|
+
echo "Log Level: $(rbcli config .logger.log_level)"
|
54
|
+
echo "Log Target: $(rbcli config .logger.log_target)"
|
55
|
+
echo "First Argument (if passed): $(rbcli args .[0])"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Khoury
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -172,10 +172,12 @@ files:
|
|
172
172
|
- examples/myscript.sh
|
173
173
|
- examples/mytool
|
174
174
|
- exe/rbcli
|
175
|
+
- lib-sh/lib-rbcli.sh
|
175
176
|
- lib/rbcli-tool.rb
|
176
|
-
- lib/rbcli-tool/
|
177
|
+
- lib/rbcli-tool/generators.rb
|
177
178
|
- lib/rbcli-tool/mdless_fix.rb
|
178
179
|
- lib/rbcli-tool/project.rb
|
180
|
+
- lib/rbcli-tool/util.rb
|
179
181
|
- lib/rbcli.rb
|
180
182
|
- lib/rbcli/autoupdate/autoupdate.rb
|
181
183
|
- lib/rbcli/autoupdate/gem_updater.rb
|
@@ -206,7 +208,8 @@ files:
|
|
206
208
|
- skeletons/project/Gemfile
|
207
209
|
- skeletons/project/README.md
|
208
210
|
- skeletons/project/Rakefile
|
209
|
-
- skeletons/project/application/commands/command.
|
211
|
+
- skeletons/project/application/commands/command.erb
|
212
|
+
- skeletons/project/application/commands/script.erb
|
210
213
|
- skeletons/project/application/commands/scripts/script.sh
|
211
214
|
- skeletons/project/application/options.rb
|
212
215
|
- skeletons/project/config/autoupdate.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
#########################
|
2
|
-
## Command Declaration ##
|
3
|
-
#########################
|
4
|
-
# With rbcli, commands are declared by subclassing
|
5
|
-
# from Rbcli::Command. The name of the class will be
|
6
|
-
# the command that is available to the user.
|
7
|
-
#########################
|
8
|
-
class Test < Rbcli::Command # Declare a new command by subclassing Rbcli::Command
|
9
|
-
description 'This is a short description.' # (Required) Short description for the global help
|
10
|
-
usage 'This is some really long usage text description!' # (Required) Long description for the command-specific help
|
11
|
-
parameter :force, 'Force testing', type: :boolean, default: false, required: false # (Optional, Multiple) Add a command-specific CLI parameter. Can be called multiple times
|
12
|
-
|
13
|
-
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
|
14
|
-
config_default :myopt2, description: 'Testing this again', default: true # (Optional, Multiple) Specify an individual configuration parameter and set a default value. These will also be included in generated user config
|
15
|
-
|
16
|
-
extern path: 'env | grep "^__PARAMS\|^__ARGS\|^__GLOBAL\|^__CONFIG"', envvars: {MYVAR: 'some_value'} # (Required unless `action` defined) Runs a given application, with optional environment variables, when the user runs the command.
|
17
|
-
extern envvars: {MY_OTHER_VAR: 'another_value'} do |params, args, global_opts, config| # Alternate usage. Supplying a block instead of a path allows us to modify the command based on the arguments and configuration supplied by the user.
|
18
|
-
"echo #{params[:force].to_s}__YESSS!!!"
|
19
|
-
end
|
20
|
-
|
21
|
-
action do |params, args, global_opts, config| # (Required unless `extern` defined) Block to execute if the command is called.
|
22
|
-
Rbcli::log.info { 'These logs can go to STDERR, STDOUT, or a file' } # Example log. Interface is identical to Ruby's logger
|
23
|
-
puts "\nArgs:\n#{args}" # Arguments that came after the command on the CLI (i.e.: `mytool test bar baz` will yield args=['bar', 'baz'])
|
24
|
-
puts "Params:\n#{params}" # Parameters, as described through the option statements above
|
25
|
-
puts "Global opts:\n#{global_opts}" # Global Parameters, as descirbed in the Configurate section
|
26
|
-
puts "Config:\n#{config}" # Config file values
|
27
|
-
puts "LocalState:\n#{Rbcli.local_state}" # Local persistent state storage (when available) -- if unsure use Rbcli.local_state.nil?
|
28
|
-
puts "RemoteState:\n#{Rbcli.remote_state}" # Remote persistent state storage (when available) -- if unsure use Rbcli.remote_state.nil?
|
29
|
-
puts "\nDone!!!"
|
30
|
-
end
|
31
|
-
end
|