From 65388868477c5b2c30df77cb5e74963bc62c6c16 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Tue, 22 Oct 2024 09:12:13 +0000 Subject: [PATCH 1/3] - Add `command.variables` as a convenience utility for defining global command variables --- examples/variables/.gitignore | 1 + examples/variables/README.md | 113 +++++++++++++++++++++ examples/variables/src/bashly.yml | 40 ++++++++ examples/variables/src/compress_command.sh | 5 + examples/variables/src/download_command.sh | 6 ++ examples/variables/test.sh | 10 ++ lib/bashly/config_validator.rb | 10 +- lib/bashly/script/command.rb | 2 +- lib/bashly/views/command/function.gtx | 1 + lib/bashly/views/command/run.gtx | 1 + lib/bashly/views/command/variables.gtx | 30 ++++++ spec/approvals/examples/variables | 17 ++++ 12 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 examples/variables/.gitignore create mode 100644 examples/variables/README.md create mode 100644 examples/variables/src/bashly.yml create mode 100644 examples/variables/src/compress_command.sh create mode 100644 examples/variables/src/download_command.sh create mode 100644 examples/variables/test.sh create mode 100644 lib/bashly/views/command/variables.gtx create mode 100644 spec/approvals/examples/variables diff --git a/examples/variables/.gitignore b/examples/variables/.gitignore new file mode 100644 index 00000000..76ec9f59 --- /dev/null +++ b/examples/variables/.gitignore @@ -0,0 +1 @@ +cli \ No newline at end of file diff --git a/examples/variables/README.md b/examples/variables/README.md new file mode 100644 index 00000000..56117b14 --- /dev/null +++ b/examples/variables/README.md @@ -0,0 +1,113 @@ +# Variables Example + +Demonstrates how to define varaibles from the bashly.yml configuration. + +This example was generated with: + +```bash +$ bashly init +# ... now edit src/bashly.yml to match the example ... +# ... now edit src/download_command.sh to match the example ... +# ... now edit src/compress_command.sh to match the example ... +$ bashly generate +``` + + + +----- + +## `bashly.yml` + +````yaml +name: cli +help: Sample application demonstrating the use of variables +version: 0.1.0 + +# The `build_number` variable will be available globally +variables: +- name: build_number + value: 1337 + +commands: +- name: download + alias: d + help: Download a profile + + args: + - name: profile + required: true + help: Profile to download information from + + # These variables will be declared when the `download` command is executed. + # Note the use of an array value. + variables: + - name: output_folder + value: output + - name: download_sources + value: + - youtube + - instagram + +- name: compress + alias: c + help: Compress data + + # These variables will be declared when the `compress` command is executed. + # Note the use of an associative array value. + variables: + - name: zip_options + value: + pattern: "*.json" + compression_level: fast +```` + +## `src/download_command.sh` + +````bash +echo "build_number: $build_number" +echo "output_folder: $output_folder" +echo "download_sources:" +for value in "${download_sources[@]}"; do + echo "- $value" +done +```` + +## `src/compress_command.sh` + +````bash +echo "build_number: $build_number" +echo "zip_options:" +for key in "${!zip_options[@]}"; do + echo " $key: ${zip_options[$key]}" +done + +```` + + +## Output + +### `$ ./cli download something` + +````shell +build_number: 1337 +output_folder: output +download_sources: +- youtube +- instagram + + +```` + +### `$ ./cli compress` + +````shell +build_number: 1337 +zip_options: + compression_level: fast + pattern: *.json + + +```` + + + diff --git a/examples/variables/src/bashly.yml b/examples/variables/src/bashly.yml new file mode 100644 index 00000000..5cb332a2 --- /dev/null +++ b/examples/variables/src/bashly.yml @@ -0,0 +1,40 @@ +name: cli +help: Sample application demonstrating the use of variables +version: 0.1.0 + +# The `build_number` variable will be available globally +variables: +- name: build_number + value: 1337 + +commands: +- name: download + alias: d + help: Download a profile + + args: + - name: profile + required: true + help: Profile to download information from + + # These variables will be declared when the `download` command is executed. + # Note the use of an array value. + variables: + - name: output_folder + value: output + - name: download_sources + value: + - youtube + - instagram + +- name: compress + alias: c + help: Compress data + + # These variables will be declared when the `compress` command is executed. + # Note the use of an associative array value. + variables: + - name: zip_options + value: + pattern: "*.json" + compression_level: fast diff --git a/examples/variables/src/compress_command.sh b/examples/variables/src/compress_command.sh new file mode 100644 index 00000000..14cc9240 --- /dev/null +++ b/examples/variables/src/compress_command.sh @@ -0,0 +1,5 @@ +echo "build_number: $build_number" +echo "zip_options:" +for key in "${!zip_options[@]}"; do + echo " $key: ${zip_options[$key]}" +done diff --git a/examples/variables/src/download_command.sh b/examples/variables/src/download_command.sh new file mode 100644 index 00000000..c2aa5cc3 --- /dev/null +++ b/examples/variables/src/download_command.sh @@ -0,0 +1,6 @@ +echo "build_number: $build_number" +echo "output_folder: $output_folder" +echo "download_sources:" +for value in "${download_sources[@]}"; do + echo "- $value" +done \ No newline at end of file diff --git a/examples/variables/test.sh b/examples/variables/test.sh new file mode 100644 index 00000000..f8577023 --- /dev/null +++ b/examples/variables/test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -x + +bashly generate + +### Try Me ### + +./cli download something +./cli compress diff --git a/lib/bashly/config_validator.rb b/lib/bashly/config_validator.rb index f08bab5e..5f81f824 100644 --- a/lib/bashly/config_validator.rb +++ b/lib/bashly/config_validator.rb @@ -24,7 +24,7 @@ def assert_version(key, value) def assert_catch_all(key, value) return unless value - assert [TrueClass, String, Hash].include?(value.class), + assert [TrueClass, FalseClass, String, Hash].include?(value.class), "#{key} must be a boolean, a string or a hash" assert_catch_all_hash key, value if value.is_a? Hash @@ -77,7 +77,7 @@ def assert_dependency(key, value) def assert_extensible(key, value) return unless value - assert [TrueClass, String].include?(value.class), + assert [TrueClass, FalseClass, String].include?(value.class), "#{key} must be a boolean or a string" end @@ -173,6 +173,11 @@ def assert_env_var(key, value) refute value['required'] && value['default'], "#{key} cannot have both nub`required` and nub`default`" end + def assert_var(key, value) + assert_hash key, value, keys: %i[name value] + assert_string "#{key}.name", value['name'] + end + def assert_command(key, value) assert_hash key, value, keys: Script::Command.option_keys @@ -207,6 +212,7 @@ def assert_command(key, value) assert_array "#{key}.completions", value['completions'], of: :string assert_array "#{key}.filters", value['filters'], of: :string assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var + assert_array "#{key}.variables", value['variables'], of: :var assert_uniq "#{key}.commands", value['commands'], %w[name alias] assert_uniq "#{key}.flags", value['flags'], 'long' diff --git a/lib/bashly/script/command.rb b/lib/bashly/script/command.rb index 3e8c20e3..0e662f0a 100644 --- a/lib/bashly/script/command.rb +++ b/lib/bashly/script/command.rb @@ -17,7 +17,7 @@ def option_keys default dependencies environment_variables examples extensible expose filename filters flags footer function group help name - private version + private variables version ] end end diff --git a/lib/bashly/views/command/function.gtx b/lib/bashly/views/command/function.gtx index 250867ac..1e91fab0 100644 --- a/lib/bashly/views/command/function.gtx +++ b/lib/bashly/views/command/function.gtx @@ -1,6 +1,7 @@ = view_marker > {{ function_name }}_command() { += render(:variables).indent(2) if variables&.any? = load_user_file(filename).indent 2 > } > diff --git a/lib/bashly/views/command/run.gtx b/lib/bashly/views/command/run.gtx index 8dda6762..e3af52c4 100644 --- a/lib/bashly/views/command/run.gtx +++ b/lib/bashly/views/command/run.gtx @@ -9,6 +9,7 @@ if has_unique_args_or_flags? > declare -A unique_lookup=() end += render(:variables).indent(2) if variables&.any? > normalize_input "$@" > parse_requirements "${input[@]}" if user_file_exist?('before') diff --git a/lib/bashly/views/command/variables.gtx b/lib/bashly/views/command/variables.gtx new file mode 100644 index 00000000..a4676ca3 --- /dev/null +++ b/lib/bashly/views/command/variables.gtx @@ -0,0 +1,30 @@ += view_marker + +variables.each do |var| + case var['value'] + when Array + if var['value'].empty? + > declare -a {{ var['name'] }}=() + else + > declare -a {{ var['name'] }}=( + var['value'].each do |v| + > "{{ v }}" + end + > ) + end + when Hash + if var['value'].empty? + > declare -A {{ var['name'] }}=() + else + > declare -A {{ var['name'] }}=( + var['value'].each do |k, v| + > ["{{ k }}"]="{{ v }}" + end + > ) + end + when String, NilClass + > {{ var['name'] }}="{{ var['value'] }}" + else + > {{ var['name'] }}={{ var['value'] }} + end +end diff --git a/spec/approvals/examples/variables b/spec/approvals/examples/variables new file mode 100644 index 00000000..6557454c --- /dev/null +++ b/spec/approvals/examples/variables @@ -0,0 +1,17 @@ ++ bundle exec bashly generate +creating user files in src +skipped src/download_command.sh (exists) +skipped src/compress_command.sh (exists) +created ./cli +run ./cli --help to test your bash script ++ ./cli download something +build_number: 1337 +output_folder: output +download_sources: +- youtube +- instagram ++ ./cli compress +build_number: 1337 +zip_options: + compression_level: fast + pattern: *.json From e72cfa24ee3c214d084d8369a5a0f81141930b06 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Tue, 22 Oct 2024 11:17:07 +0000 Subject: [PATCH 2/3] update terminal docs --- examples/variables/README.md | 2 +- lib/bashly/docs/command.yml | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/examples/variables/README.md b/examples/variables/README.md index 56117b14..73f6ec17 100644 --- a/examples/variables/README.md +++ b/examples/variables/README.md @@ -1,6 +1,6 @@ # Variables Example -Demonstrates how to define varaibles from the bashly.yml configuration. +Demonstrates how to define variables from the bashly.yml configuration. This example was generated with: diff --git a/lib/bashly/docs/command.yml b/lib/bashly/docs/command.yml index 42909a95..c4cfa400 100644 --- a/lib/bashly/docs/command.yml +++ b/lib/bashly/docs/command.yml @@ -309,6 +309,28 @@ command.private: help: Send bash completions private: true +command.variables: + help: Define a list of global bash variables. + url: https://bashly.dannyb.co/configuration/command/#variables + example: |- + variables: + # Simple value + - name: output_folder + value: output + + # Array + - name: download_sources + value: + - youtube + - instagram + + # Associative array + - name: zip_options + value: + pattern: "*.json" + compression_level: fast + + command.version: help: Specify the version to show when running with `--version`. url: https://bashly.dannyb.co/configuration/command/#version From 0522209b6efc495cd9e0f0a3650e49acb940acf5 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Tue, 22 Oct 2024 12:30:10 +0000 Subject: [PATCH 3/3] approvals --- spec/approvals/cli/doc/full | 23 +++++++++++++++++++++++ spec/approvals/cli/doc/index | 1 + spec/approvals/examples/variables | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/spec/approvals/cli/doc/full b/spec/approvals/cli/doc/full index 67f56ae8..43c7ae86 100644 --- a/spec/approvals/cli/doc/full +++ b/spec/approvals/cli/doc/full @@ -467,6 +467,29 @@ command.private See https://bashly.dannyb.co/configuration/command/#private +command.variables + + Define a list of global bash variables. + + variables: + # Simple value + - name: output_folder + value: output + + # Array + - name: download_sources + value: + - youtube + - instagram + + # Associative array + - name: zip_options + value: + pattern: "*.json" + compression_level: fast + + See https://bashly.dannyb.co/configuration/command/#variables + command.version Specify the version to show when running with --version. diff --git a/spec/approvals/cli/doc/index b/spec/approvals/cli/doc/index index 00791e68..3152055e 100644 --- a/spec/approvals/cli/doc/index +++ b/spec/approvals/cli/doc/index @@ -27,6 +27,7 @@ command.group command.help command.name command.private +command.variables command.version environment_variable environment_variable.default diff --git a/spec/approvals/examples/variables b/spec/approvals/examples/variables index 6557454c..080791a5 100644 --- a/spec/approvals/examples/variables +++ b/spec/approvals/examples/variables @@ -1,4 +1,4 @@ -+ bundle exec bashly generate ++ bashly generate creating user files in src skipped src/download_command.sh (exists) skipped src/compress_command.sh (exists)