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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75d0190f4a13b9cb6b42eb88b481d30490e5c1cc033cbb55d9d80894e2765ccd
4
- data.tar.gz: 2aebd4cf49b7c61107bdcbac02e2caf2f8572705231a5481b482709efbb7419d
3
+ metadata.gz: 3f1de334efcc5489a103f4001a64d40a347d8aac715566682001e50600e596af
4
+ data.tar.gz: ecd300a10c89299f987d1031fff974cf7e45bc31ff56af20871462c98a2e833d
5
5
  SHA512:
6
- metadata.gz: 4bb27dbc682773ee1e9b5c29ffc4da1dcd68c89b3f42acf0818459bee9b1aba0c6a9885c4b5b52b9fb7ddacb96cf34c5d327b935e4ca6bcdab316fd780e42b5e
7
- data.tar.gz: 25a891ccf9beb709c898d4c1951c6ee3cc703b2991a2259b175fe61c2e100a716ab8bc9b2b2f1f025a2e3fa51863a2211712059025803a19f9b8d64aef29721b
6
+ metadata.gz: 1c954de05e3383d692e16cc6eb238add53b4e24758f81440ea5601ec10be780e12df6ed3358dd539494dc731ffca0fe4457021a566003af7ddbb4b21f4ef05b7
7
+ data.tar.gz: 879bb9c5627c7118ae7bf8c319ade644aa48191eca455ccfeaf7f910e1f56c33b1f2ee38b1ed727a429b4e272e780af0756b940c1782f7ec6f8737751e6e1950
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbcli (0.1.9)
4
+ rbcli (0.1.10)
5
5
  aws-sdk-dynamodb (~> 1.6)
6
6
  colorize (~> 0.8)
7
7
  deep_merge (~> 1.2)
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 `Gemrile` or `gemspec`, or install it manually via `gem install rbcli`.
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 # (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.`
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].to_s
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 -t pre
521
- rbcli hook -t post
522
- rbcli hook -t default
523
- rbcli hook -t runonce
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 'rbcli'
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 'rbcli-tool'
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
- EOF
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
- RBCliTool.continue_confirmation "The project or file #{params[:name]} already exists; contents will be overwritten."
60
- FileUtils.rm_rf dest
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
- puts "\nInitialization Complete!\n" if proj.create_micro
66
-
65
+ success = proj.create_micro
67
66
  when 'mini' # Mini: Single File
68
- puts "\nInitialization Complete!\n" if proj.create_mini
69
-
67
+ success = proj.create_mini
70
68
  else # Standard; full project structure
71
- if proj.create
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 project structure under the current directory. Use -t to specify the type:
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
- Standard: A complete RBCli project structure. Recommended for most applications, it provides
89
- a framework for organizing code and creating a gem to be installed/distributed.
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
- Mini: A single-file RBCli project. All features are supported, but project structure is left to the developer.
92
- Recommended for smaller applications, or for integrating RBCli into an existing application.
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
- Micro: A single-file, minimal RBCli project. Similar to a mini project, but only the minimal required code is
95
- generated. Recommended for rapid prototyping of scripts, for advanced users only.
96
- EOF
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
 
@@ -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
+
@@ -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/erb_renderer'
16
- require 'rbcli-tool/project'
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
@@ -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
- private
69
-
70
- def project_exists?
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
- env_hash = {}
23
- {
24
- '__PARAMS' => params,
25
- '__ARGS' => args,
26
- '__GLOBAL' => global_opts,
27
- '__CONFIG' => config
28
- }.each do |name, hsh|
29
- hsh.each do |k, v|
30
- env_hash["#{name}_#{k.upcase}"] = v.to_json
31
- end
32
- end
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.merge!(@envvars.deep_stringify!) unless @envvars.nil?
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
 
@@ -1,3 +1,3 @@
1
1
  module Rbcli
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.10"
3
3
  end
@@ -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 {{**CMDNAME**}}
4
+ # This is the RBCli script for the command `<%= @vars[:name] %>`
5
5
  ###
6
6
  #
7
- # You can find RBCli's params, args, global_opts, and config through environment
8
- # variables. They are passed in the formats:
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
- # __PARAMS_<param_name>
11
- # __ARGS_<arg_name>
12
- # __GOBAL <global_opt_name>
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 any of the options given had nested values in your RBCli application they
16
- # will be passed as JSON. You can parse them using jq ( https://stedolan.github.io/jq/ )
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
- # If you specified any environment variables to be set manually, they will be found unmodified.
32
+ # __RBCLI_PARAMS
33
+ # __RBCLI_ARGS
34
+ # __RBCLI_GLOBAL
35
+ # __RBCLI_CONFIG
36
+ # __RBCLI_MYVARS
19
37
  #
20
38
  ###
21
39
  #
22
40
 
23
- env | grep "^__PARAMS\|^__ARGS\|^__GLOBAL\|^__CONFIG"
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])"
@@ -10,7 +10,7 @@ Rbcli::Configurate.me do
10
10
  # If not present, the help is shown (same as -h)
11
11
 
12
12
  default_action do |opts|
13
- puts "Hello, #{opts[:name]}."
13
+ puts "Hello, sir."
14
14
  puts "To see the help, use -h"
15
15
  end
16
16
  end
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.9
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-12 00:00:00.000000000 Z
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/erb_renderer.rb
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.rb
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