Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/completions-advanced/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ commands:
## `settings.yml`

````yaml
enable_completions: always
completions: full

````

Expand Down
2 changes: 1 addition & 1 deletion examples/completions-advanced/settings.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
enable_completions: always
completions: full
4 changes: 1 addition & 3 deletions examples/completions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ commands:
## `settings.yml`

````yaml
enable_completions: always
completions: full

````

Expand Down Expand Up @@ -104,5 +104,3 @@ download


````


2 changes: 1 addition & 1 deletion examples/completions/settings.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
enable_completions: always
completions: full
9 changes: 8 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,20 @@ env: development
# - never # do not render this feature
enable_header_comment: always
enable_bash_version_bouncer: always
enable_completions: never
enable_view_markers: development
enable_inspect_args: development
enable_deps_array: always
enable_env_var_names_array: always
enable_sourcing: development

# Generate native runtime completions. Supported values:
# - ~ or false # disable completions (default)
# - minimal # generate the runtime completion engine without shell adapters
# - bash or zsh # generate the runtime engine and one shell adapter
# - bash,zsh # generate the runtime engine and selected shell adapters
# - full # generate the runtime engine and all available shell adapters
completions: ~


#-------------------------------------------------------------------------------
# DEVELOPER OPTIONS
Expand Down
30 changes: 25 additions & 5 deletions lib/bashly/settings.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
module Bashly
class Settings
COMPLETION_SHELLS = %w[bash zsh].freeze

class << self
include AssetHelper

attr_writer(
:argfile_var,
:commands_dir,
:compact_short_flags,
:completions,
:conjoined_flag_args,
:config_path,
:enable_bash_version_bouncer,
:enable_completions,
:enable_deps_array,
:enable_env_var_names_array,
:enable_header_comment,
Expand Down Expand Up @@ -51,6 +53,28 @@ def compact_short_flags
@compact_short_flags ||= get :compact_short_flags
end

def completions
@completions ||= get :completions
end

def completions?
completions == 'minimal' || completion_shells.any?
end

def completion_shells
value = completions
return [] if value.nil? || value == false || value == 'minimal'
return COMPLETION_SHELLS if value == 'full'

shells = value.split(',', -1).map(&:strip) if value.is_a? String
valid = shells&.any? && shells.all? { |shell| COMPLETION_SHELLS.include? shell }
unique = shells&.uniq == shells
return shells if valid && unique

raise ConfigurationError,
"completions must be false, minimal, full, or a comma-separated list of: #{COMPLETION_SHELLS.join ', '}"
end

def conjoined_flag_args
@conjoined_flag_args ||= get :conjoined_flag_args
end
Expand All @@ -69,10 +93,6 @@ def enable_bash_version_bouncer
@enable_bash_version_bouncer ||= get :enable_bash_version_bouncer
end

def enable_completions
@enable_completions ||= get :enable_completions
end

def enable_deps_array
@enable_deps_array ||= get :enable_deps_array
end
Expand Down
14 changes: 9 additions & 5 deletions lib/bashly/views/command/completion_script.gtx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
= view_marker

completion_shells = Settings.completion_shells

> send_completions() {
> local completion_shell="${1:-bash}"
> local completion_shell="${1:-{{ completion_shells.first }}}"
>
> case "$completion_shell" in
> bash) send_completions_bash ;;
> zsh) send_completions_zsh ;;
completion_shells.each do |shell|
> {{ shell }}) send_completions_{{ shell }} ;;
end
> *)
> printf 'unsupported shell: %s\n' "$completion_shell" >&2
> return 1
> ;;
> esac
> }
>
= render :completion_script_bash
= render :completion_script_zsh
completion_shells.each do |shell|
= render :"completion_script_#{shell}"
end
2 changes: 1 addition & 1 deletion lib/bashly/views/command/completions.gtx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
> done <<<"$completion_output"
> }
>
= render :completion_script
= render :completion_script if Settings.completion_shells.any?
= render :completion_function
deep_commands.each do |command|
= command.render :completion_function
Expand Down
6 changes: 3 additions & 3 deletions lib/bashly/views/command/inspect_args.gtx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
> local k
>
> if ((${#args[@]})); then
> readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
> readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | LC_ALL=C sort)
> echo args:
> for k in "${sorted_keys[@]}"; do
> echo "- \${args[$k]} = ${args[$k]}"
Expand All @@ -28,7 +28,7 @@ end

if Settings.enabled? :deps_array
> if ((${#deps[@]})); then
> readarray -t sorted_keys < <(printf '%s\n' "${!deps[@]}" | sort)
> readarray -t sorted_keys < <(printf '%s\n' "${!deps[@]}" | LC_ALL=C sort)
> echo
> echo deps:
> for k in "${sorted_keys[@]}"; do
Expand All @@ -40,7 +40,7 @@ end

if Settings.enabled? :env_var_names_array
> if ((${#env_var_names[@]})); then
> readarray -t sorted_names < <(printf '%s\n' "${env_var_names[@]}" | sort)
> readarray -t sorted_names < <(printf '%s\n' "${env_var_names[@]}" | LC_ALL=C sort)
> echo
> echo "environment variables:"
> for k in "${sorted_names[@]}"; do
Expand Down
2 changes: 1 addition & 1 deletion lib/bashly/views/command/master_script.gtx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
= render :user_lib if user_lib.any?
= render :command_functions
= render :parse_requirements
= render :completions if Settings.enabled? :completions
= render :completions if Settings.completions?
= render :user_hooks
= render :initialize
= render :run
Expand Down
2 changes: 1 addition & 1 deletion lib/bashly/views/command/start.gtx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= view_marker

> command_line_args=("$@")
if Settings.enabled? :completions
if Settings.completions?
> if [[ "${command_line_args[0]:-}" == "__complete" ]]; then
> completion_run "${command_line_args[@]:1}"
> else
Expand Down
25 changes: 15 additions & 10 deletions schemas/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,22 @@
],
"default": "always"
},
"enable_completions": {
"title": "enable_completions",
"description": "Whether to include runtime completion functions in the generated script\nhttps://bashly.dev/usage/settings/#enable_completions",
"type": "string",
"enum": [
"development",
"production",
"always",
"never"
"completions": {
"title": "completions",
"description": "Which runtime completion functions and shell adapters to include in the generated script.\nUse minimal for the runtime engine only, full for all available adapters, or a comma-separated shell list.\nhttps://bashly.dev/usage/settings/#completions",
"oneOf": [
{
"type": "null"
},
{
"const": false
},
{
"type": "string",
"pattern": "^(minimal|full|(bash|zsh)(\\s*,\\s*(bash|zsh))*)$"
}
],
"default": "never"
"default": null
},
"enable_view_markers": {
"title": "enable_view_markers",
Expand Down
2 changes: 1 addition & 1 deletion spec/approvals/examples/commands
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ missing required flag: --user, -u USER
# The code you write here will be wrapped by a function named 'cli_upload_command()'.
# Feel free to edit this file; your changes will persist when regenerating.
args:
- ${args[source]} = sourcefile
- ${args[--user]} = username
- ${args[source]} = sourcefile

environment variables:
- $API_KEY =
2 changes: 1 addition & 1 deletion spec/approvals/examples/validations
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ run ./validate --help to test your bash script
# The code you write here will be wrapped by a function named 'validate_calc_command()'.
# Feel free to edit this file; your changes will persist when regenerating.
args:
- ${args[first]} = 1
- ${args[--save]} = README.md
- ${args[first]} = 1
- ${args[second]} = 2
+ ./validate calc A
validation error in FIRST:
Expand Down
8 changes: 4 additions & 4 deletions spec/approvals/examples/whitelist
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ region must be one of: eu, us
# 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[environment]} = development
- ${args[--protocol]} = ssh
- ${args[region]} = eu
- ${args[--user]} = admin
- ${args[environment]} = development
- ${args[region]} = eu
+ ./login us --user user --protocol icmp
--protocol must be one of: ftp, ssh, http
+ ./login eu production --user admin --protocol ssh
Expand All @@ -64,7 +64,7 @@ args:
# 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[environment]} = production
- ${args[--protocol]} = ssh
- ${args[region]} = eu
- ${args[--user]} = admin
- ${args[environment]} = production
- ${args[region]} = eu
2 changes: 1 addition & 1 deletion spec/approvals/fixtures/default-validations
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ must be an existing file
# 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[file]} = README.md
- ${args[--template]} = cli
- ${args[file]} = README.md
6 changes: 3 additions & 3 deletions spec/approvals/fixtures/required-args-order
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,26 @@ args:
# Feel free to edit this file; your changes will persist when regenerating.
args:
- ${args[--method]} = GET
- ${args[--role]} = admin
- ${args[port]} = 3000
- ${args[protocol]} = http
- ${args[--role]} = admin
+ ./download http --role admin --method GET 3000
# 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[--method]} = GET
- ${args[--role]} = admin
- ${args[port]} = 3000
- ${args[protocol]} = http
- ${args[--role]} = admin
+ ./download --role admin --method GET http 3000
# 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[--method]} = GET
- ${args[--role]} = admin
- ${args[port]} = 3000
- ${args[protocol]} = http
- ${args[--role]} = admin
2 changes: 1 addition & 1 deletion spec/approvals/fixtures/whitelist-optional
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ action must be one of: push, commit
# 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[action]} = push
- ${args[--notify]} = slack
- ${args[action]} = push
8 changes: 4 additions & 4 deletions spec/bashly/integration/completion_script_bash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ def complete_with_bash(*words, trace_options: false)
let(:cli) { File.expand_path 'spec/tmp/cli' }

before(:context) do
Settings.enable_completions = 'always'
Settings.completions = 'full'
reset_tmp_dir
FileUtils.cp_r Dir['spec/fixtures/completions/core/*'], 'spec/tmp'
Commands::Generate.new.execute %w[generate --quiet]
end

after(:context) do
Settings.enable_completions = 'never'
Settings.completions = nil
end

it 'prints Bash completions by default' do
Expand Down Expand Up @@ -68,7 +68,7 @@ def complete_with_bash(*words, trace_options: false)

context 'configured options' do
before(:context) do
Settings.enable_completions = 'always'
Settings.completions = 'full'
reset_tmp_dir
FileUtils.cp_r Dir['spec/fixtures/completions/configured/*'], 'spec/tmp'
Commands::Generate.new.execute %w[generate --quiet]
Expand All @@ -77,7 +77,7 @@ def complete_with_bash(*words, trace_options: false)
end

after(:context) do
Settings.enable_completions = 'never'
Settings.completions = nil
end

it 'adds files when requested' do
Expand Down
8 changes: 4 additions & 4 deletions spec/bashly/integration/completion_script_zsh_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ def complete_with_zsh(*words, trace_files: false)
let(:cli) { File.expand_path 'spec/tmp/cli' }

before(:context) do
Settings.enable_completions = 'always'
Settings.completions = 'full'
reset_tmp_dir
FileUtils.cp_r Dir['spec/fixtures/completions/core/*'], 'spec/tmp'
Commands::Generate.new.execute %w[generate --quiet]
end

after(:context) do
Settings.enable_completions = 'never'
Settings.completions = nil
end

it 'prints Zsh completions' do
Expand Down Expand Up @@ -89,14 +89,14 @@ def complete_with_zsh(*words, trace_files: false)

context 'configured options' do
before(:context) do
Settings.enable_completions = 'always'
Settings.completions = 'full'
reset_tmp_dir
FileUtils.cp_r Dir['spec/fixtures/completions/configured/*'], 'spec/tmp'
Commands::Generate.new.execute %w[generate --quiet]
end

after(:context) do
Settings.enable_completions = 'never'
Settings.completions = nil
end

it 'preserves literal candidates' do
Expand Down
Loading