diff --git a/lib/bashly/libraries/settings/settings.yml b/lib/bashly/libraries/settings/settings.yml index d5e82d43..2f646c13 100644 --- a/lib/bashly/libraries/settings/settings.yml +++ b/lib/bashly/libraries/settings/settings.yml @@ -120,6 +120,12 @@ show_examples_on_error: false # all the private elements in the usage texts, as if they were public. private_reveal_key: ~ +# When enabling argfile for any command, this setting controls the name of the +# environment variable that can override or disable argfile loading at runtime. +# Set the variable to `0`, `off`, `no` or `false` to disable argfile loading, +# or to a different path to load another argfile instead. +argfile_var: ARGFILE + # Display various usage elements in color by providing the name of the color # function. The value for each property is a name of a function that is # available in your script, for example: `green` or `bold`. diff --git a/lib/bashly/settings.rb b/lib/bashly/settings.rb index 6dd018f7..db2a0611 100644 --- a/lib/bashly/settings.rb +++ b/lib/bashly/settings.rb @@ -4,6 +4,7 @@ class << self include AssetHelper attr_writer( + :argfile_var, :commands_dir, :compact_short_flags, :conjoined_flag_args, @@ -37,6 +38,10 @@ def all_lib_dirs @all_lib_dirs = [full_lib_dir] + extra_lib_dirs end + def argfile_var + @argfile_var ||= get :argfile_var + end + def commands_dir @commands_dir ||= get :commands_dir end diff --git a/lib/bashly/views/command/argfile_filter.gtx b/lib/bashly/views/command/argfile_filter.gtx index ade1d719..abd3cd15 100644 --- a/lib/bashly/views/command/argfile_filter.gtx +++ b/lib/bashly/views/command/argfile_filter.gtx @@ -1,18 +1,29 @@ = view_marker -> local argfile_line argfile_key argfile_value escaped -> [[ -f "{{ argfile }}" ]] || return +> local argfile argfile_line argfile_key argfile_value env_argfile env_argfile_var +> argfile="{{ argfile }}" +> env_argfile_var="{{ Settings.argfile_var }}" +> env_argfile="${!env_argfile_var:-}" > -> while IFS= read -r argfile_line || [[ -n "$argfile_line" ]]; do -> [[ "$argfile_line" =~ ^[[:space:]]*(-{1,2}[^[:space:]]+)([[:space:]]+(.+))?[[:space:]]*$ ]] || continue -> argfile_key="${BASH_REMATCH[1]}" -> argfile_value="${BASH_REMATCH[3]:-}" -> argfile_value="${argfile_value#"${argfile_value%%[![:space:]]*}"}" -> argfile_value="${argfile_value%"${argfile_value##*[![:space:]]}"}" -> [[ "$argfile_value" =~ ^\"(.*)\"$ || "$argfile_value" =~ ^\'(.*)\'$ ]] && argfile_value="${BASH_REMATCH[1]}" +> case "${env_argfile,,}" in +> 0 | off | no | false) +> argfile='' +> ;; +> esac > -> case "$argfile_key" in -= flags.map { |flag| flag.render(:argfile_case) }.join.indent 4 -> esac -> done <"{{ argfile }}" +> [[ -n "$env_argfile" ]] && argfile="$env_argfile" +> if [[ -f "$argfile" ]]; then +> while IFS= read -r argfile_line || [[ -n "$argfile_line" ]]; do +> [[ "$argfile_line" =~ ^[[:space:]]*(-{1,2}[^[:space:]]+)([[:space:]]+(.+))?[[:space:]]*$ ]] || continue +> argfile_key="${BASH_REMATCH[1]}" +> argfile_value="${BASH_REMATCH[3]:-}" +> argfile_value="${argfile_value#"${argfile_value%%[![:space:]]*}"}" +> argfile_value="${argfile_value%"${argfile_value##*[![:space:]]}"}" +> [[ "$argfile_value" =~ ^\"(.*)\"$ || "$argfile_value" =~ ^\'(.*)\'$ ]] && argfile_value="${BASH_REMATCH[1]}" +> +> case "$argfile_key" in += flags.map { |flag| flag.render(:argfile_case) }.join.indent 6 +> esac +> done <"$argfile" +> fi > diff --git a/schemas/settings.json b/schemas/settings.json index e05c0852..0838b429 100644 --- a/schemas/settings.json +++ b/schemas/settings.json @@ -289,6 +289,13 @@ } ] }, + "argfile_var": { + "title": "argfile var", + "description": "The name of the environment variable that can override or disable command argfiles at runtime\nhttps://bashly.dev/usage/settings/#argfile_var", + "type": "string", + "minLength": 1, + "default": "ARGFILE" + }, "watch_evented": { "title": "watch evented", "description": "Whether to use evented file system watch instead of the default polling\nhttps://bashly.dev/usage/settings/#watch_evented", diff --git a/spec/approvals/fixtures/argfile-env-var b/spec/approvals/fixtures/argfile-env-var new file mode 100644 index 00000000..dc785627 --- /dev/null +++ b/spec/approvals/fixtures/argfile-env-var @@ -0,0 +1,30 @@ +creating user files in src +created src/root_command.sh +created ./download +run ./download --help to test your bash script ++ ./download somesource +# This file is located at 'src/root_command.sh'. +# It contains the implementation for the 'download' command. +# The code you write here will be wrapped by a function named 'root_command()'. +# Feel free to edit this file; your changes will persist when regenerating. +args: +- ${args[--force]} = 1 +- ${args[--log]} = from-default.log +- ${args[source]} = somesource ++ DOWNLOAD_ARGFILE=off ++ ./download somesource +# This file is located at 'src/root_command.sh'. +# It contains the implementation for the 'download' command. +# The code you write here will be wrapped by a function named 'root_command()'. +# Feel free to edit this file; your changes will persist when regenerating. +args: +- ${args[source]} = somesource ++ DOWNLOAD_ARGFILE=.alt-download ++ ./download somesource +# This file is located at 'src/root_command.sh'. +# It contains the implementation for the 'download' command. +# The code you write here will be wrapped by a function named 'root_command()'. +# Feel free to edit this file; your changes will persist when regenerating. +args: +- ${args[--log]} = from-override.log +- ${args[source]} = somesource diff --git a/spec/fixtures/workspaces/argfile-env-var/.alt-download b/spec/fixtures/workspaces/argfile-env-var/.alt-download new file mode 100644 index 00000000..9564fed8 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/.alt-download @@ -0,0 +1 @@ +--log from-override.log diff --git a/spec/fixtures/workspaces/argfile-env-var/.download b/spec/fixtures/workspaces/argfile-env-var/.download new file mode 100644 index 00000000..56f1ec21 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/.download @@ -0,0 +1,2 @@ +--force +--log from-default.log diff --git a/spec/fixtures/workspaces/argfile-env-var/.gitignore b/spec/fixtures/workspaces/argfile-env-var/.gitignore new file mode 100644 index 00000000..a3121f79 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/.gitignore @@ -0,0 +1,2 @@ +download +src/*.sh diff --git a/spec/fixtures/workspaces/argfile-env-var/settings.yml b/spec/fixtures/workspaces/argfile-env-var/settings.yml new file mode 100644 index 00000000..429d9019 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/settings.yml @@ -0,0 +1 @@ +argfile_var: DOWNLOAD_ARGFILE diff --git a/spec/fixtures/workspaces/argfile-env-var/src/bashly.yml b/spec/fixtures/workspaces/argfile-env-var/src/bashly.yml new file mode 100644 index 00000000..5cc69cb9 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/src/bashly.yml @@ -0,0 +1,19 @@ +name: download +help: Test argfile env var behavior +version: 0.1.0 + +argfile: .download + +args: +- name: source + required: true + help: URL to download from + +flags: +- long: --force + short: -f + help: Overwrite existing files +- long: --log + short: -l + arg: path + help: Path to log file diff --git a/spec/fixtures/workspaces/argfile-env-var/test.sh b/spec/fixtures/workspaces/argfile-env-var/test.sh new file mode 100644 index 00000000..5d52a164 --- /dev/null +++ b/spec/fixtures/workspaces/argfile-env-var/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +rm -f ./download +rm -f ./src/*.sh + +bundle exec bashly generate + +set -x + +./download somesource +DOWNLOAD_ARGFILE=off ./download somesource +DOWNLOAD_ARGFILE=.alt-download ./download somesource diff --git a/support/schema/settings.yml b/support/schema/settings.yml index 8edbf466..9fa72c80 100644 --- a/support/schema/settings.yml +++ b/support/schema/settings.yml @@ -237,6 +237,14 @@ properties: The name of the environment variable (case sensitive) that, if set, will reveal private commands, flags and environment variables https://bashly.dev/usage/settings/#private_reveal_key oneOf: *optional_string + argfile_var: + title: argfile var + description: |- + The name of the environment variable that can override or disable command argfiles at runtime + https://bashly.dev/usage/settings/#argfile_var + type: string + minLength: 1 + default: ARGFILE watch_evented: title: watch evented description: |-