diff --git a/lib/bashly/models/script.rb b/lib/bashly/models/script.rb index ab90eacb..8914d486 100644 --- a/lib/bashly/models/script.rb +++ b/lib/bashly/models/script.rb @@ -29,10 +29,16 @@ def header! if File.exist? custom_header_path File.read custom_header_path else - render('header') + default_header end end + def default_header + result = render('header') + result += render('bash3_bouncer') unless function_name + result + end + def body @body ||= command.render('master_script') end diff --git a/lib/bashly/views/command/initialize.erb b/lib/bashly/views/command/initialize.erb index 4835e38e..985abc02 100644 --- a/lib/bashly/views/command/initialize.erb +++ b/lib/bashly/views/command/initialize.erb @@ -4,10 +4,5 @@ initialize() { long_usage='' set -e - if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then - printf "<%= strings[:unsupported_bash_version] -%>\n" - exit 1 - fi - <%= load_user_file("initialize.sh", placeholder: false).indent 2 %> } diff --git a/lib/bashly/views/script/bash3_bouncer.erb b/lib/bashly/views/script/bash3_bouncer.erb new file mode 100644 index 00000000..d78f2565 --- /dev/null +++ b/lib/bashly/views/script/bash3_bouncer.erb @@ -0,0 +1,5 @@ +# :script.bash3_bouncer +if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then + printf "<%= strings[:unsupported_bash_version] -%>\n" + exit 1 +fi diff --git a/lib/bashly/views/script/header.erb b/lib/bashly/views/script/header.erb index 150036b6..51c1f39c 100644 --- a/lib/bashly/views/script/header.erb +++ b/lib/bashly/views/script/header.erb @@ -1,3 +1,4 @@ #!/usr/bin/env bash # This script was generated by bashly (https://github.com/DannyBen/bashly) # Modifying it manually is not recommended + diff --git a/spec/approvals/cli/generate/wrap-script b/spec/approvals/cli/generate/wrap-script new file mode 100644 index 00000000..5f515964 --- /dev/null +++ b/spec/approvals/cli/generate/wrap-script @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# This script was generated by bashly (https://github.com/DannyBen/bashly) +# Modifying it manually is not recommended + +# :script.wrapper +function() { + + # :command.version_command + version_command() { + echo "$version" + } diff --git a/spec/approvals/examples/bash-3-syntax b/spec/approvals/examples/bash-3-syntax new file mode 100644 index 00000000..6f1d93ec --- /dev/null +++ b/spec/approvals/examples/bash-3-syntax @@ -0,0 +1,15 @@ +creating user files in src +skipped src/initialize.sh (exists) +skipped src/test_command.sh (exists) +created ./cli +run ./cli --help to test your bash script +cli - Sample application + +Usage: + cli [command] + cli [command] --help | -h + cli --version | -v + +Commands: + test Run test + diff --git a/spec/approvals/models/script/code b/spec/approvals/models/script/code new file mode 100644 index 00000000..19eb8d5b --- /dev/null +++ b/spec/approvals/models/script/code @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# This script was generated by bashly (https://github.com/DannyBen/bashly) +# Modifying it manually is not recommended + +# :script.bash3_bouncer +if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then + printf "bash version 4 or higher is required\n" + exit 1 +fi + +# :command.root_command +root_command() { + # :spec/tmp/src/root_command.sh \ No newline at end of file diff --git a/spec/approvals/models/script/code-wrapped b/spec/approvals/models/script/code-wrapped new file mode 100644 index 00000000..d2a8c629 --- /dev/null +++ b/spec/approvals/models/script/code-wrapped @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# This script was generated by bashly (https://github.com/DannyBen/bashly) +# Modifying it manually is not recommended + +# :script.wrapper +my_super_function() { + # :command.root_command + root_command() { + # :spec/tmp/src/root_command.sh + echo "error: cannot load file" + } + + # :command.version_command \ No newline at end of file diff --git a/spec/bashly/commands/generate_spec.rb b/spec/bashly/commands/generate_spec.rb index 256df250..232f1632 100644 --- a/spec/bashly/commands/generate_spec.rb +++ b/spec/bashly/commands/generate_spec.rb @@ -75,11 +75,11 @@ expect(success).to be true end - it "generates the cli script wrapped in a function" do + it "generates the cli script wrapped in a function without bash3 bouncer" do expect { subject.run %w[generate -w function] }.to output_approval('cli/generate/wrap-function') expect(File).to exist(cli_script) lines = File.readlines cli_script - expect(lines[5]).to eq "function() {\n" + expect(lines[0..10].join).to match_approval('cli/generate/wrap-script') end end diff --git a/spec/bashly/integration/bash_spec.rb b/spec/bashly/integration/bash_spec.rb index 2aeff74b..ad99ef64 100644 --- a/spec/bashly/integration/bash_spec.rb +++ b/spec/bashly/integration/bash_spec.rb @@ -5,9 +5,9 @@ before { system "docker pull bash:3 >/dev/null" } it "errors gracefully" do - command = "docker run --rm -v $PWD:/app bash:3 bash /app/download" + command = "docker run --rm -v $PWD:/app bash:3 bash /app/cli" - Dir.chdir "examples/minimal" do + Dir.chdir "spec/fixtures/workspaces/bash-3-syntax" do system "bashly generate 2>&1 >/dev/null" expect(`#{command} 2>&1`).to match_approval('bash/error') end diff --git a/spec/bashly/models/script_spec.rb b/spec/bashly/models/script_spec.rb index e7fa2965..023e222c 100644 --- a/spec/bashly/models/script_spec.rb +++ b/spec/bashly/models/script_spec.rb @@ -10,9 +10,7 @@ context "without function name" do it "returns the complete script" do lines = subject.code.split "\n" - expect(lines[0]).to eq '#!/usr/bin/env bash' - expect(lines[1]).to start_with '# This script was generated by' - expect(lines[5]).to eq 'root_command() {' + expect(lines[0..12].join("\n")).to match_approval('models/script/code') expect(lines[-1]).to eq 'run "$@"' end end @@ -20,12 +18,9 @@ context "with function name" do subject { described_class.new command, 'my_super_function' } - it "returns the complete script wrapped in a function" do + it "returns the complete script wrapped in a function without a bash3 bouncer" do lines = subject.code.split "\n" - expect(lines[0]).to eq '#!/usr/bin/env bash' - expect(lines[1]).to start_with '# This script was generated by' - expect(lines[5]).to eq 'my_super_function() {' - expect(lines[6]).to eq ' # :command.root_command' + expect(lines[0..12].join("\n")).to match_approval('models/script/code-wrapped') expect(lines[-1]).to eq '(return 0 2>/dev/null) || my_super_function "$@"' end end diff --git a/spec/fixtures/workspaces/bash-3-syntax/.gitignore b/spec/fixtures/workspaces/bash-3-syntax/.gitignore new file mode 100644 index 00000000..573c0c4f --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/.gitignore @@ -0,0 +1 @@ +cli diff --git a/spec/fixtures/workspaces/bash-3-syntax/README.md b/spec/fixtures/workspaces/bash-3-syntax/README.md new file mode 100644 index 00000000..537233b5 --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/README.md @@ -0,0 +1 @@ +This fixture tests that bash 3 exits with a helpful error even when faced with syntax it doesn't understand diff --git a/spec/fixtures/workspaces/bash-3-syntax/src/bashly.yml b/spec/fixtures/workspaces/bash-3-syntax/src/bashly.yml new file mode 100644 index 00000000..e0e29a52 --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/src/bashly.yml @@ -0,0 +1,7 @@ +name: cli +help: Sample application +version: 0.1.0 + +commands: +- name: test + help: Run test diff --git a/spec/fixtures/workspaces/bash-3-syntax/src/initialize.sh b/spec/fixtures/workspaces/bash-3-syntax/src/initialize.sh new file mode 100644 index 00000000..f2dbc52c --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/src/initialize.sh @@ -0,0 +1,6 @@ +# Code here runs inside the initialize() function +# Use it for anything that you need to run before any other function, like +# setting environment vairables: +# CONFIG_FILE=settings.ini +# +# Feel free to empty (but not delete) this file. diff --git a/spec/fixtures/workspaces/bash-3-syntax/src/test_command.sh b/spec/fixtures/workspaces/bash-3-syntax/src/test_command.sh new file mode 100644 index 00000000..2abfb888 --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/src/test_command.sh @@ -0,0 +1,4 @@ +# this syntax (`[[ -v`) cannot be parsed by bash 3 +if [[ -v missingno ]]; then + echo the variable was not defined +fi diff --git a/spec/fixtures/workspaces/bash-3-syntax/test.sh b/spec/fixtures/workspaces/bash-3-syntax/test.sh new file mode 100644 index 00000000..12640d99 --- /dev/null +++ b/spec/fixtures/workspaces/bash-3-syntax/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# This fixture tests Bash 4+-only syntax +# It is executed as part of the Runfile examples test + +bundle exec bashly generate + +./cli diff --git a/spec/fixtures/workspaces/flag-args-with-dash/argflag b/spec/fixtures/workspaces/flag-args-with-dash/argflag old mode 100644 new mode 100755 index e4b2a7cd..4659955e --- a/spec/fixtures/workspaces/flag-args-with-dash/argflag +++ b/spec/fixtures/workspaces/flag-args-with-dash/argflag @@ -2,6 +2,12 @@ # This script was generated by bashly (https://github.com/DannyBen/bashly) # Modifying it manually is not recommended +# :script.bash3_bouncer +if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then + printf "bash version 4 or higher is required\n" + exit 1 +fi + # :command.root_command root_command() { # :src/root_command.sh @@ -170,11 +176,6 @@ initialize() { long_usage='' set -e - if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then - printf "bash version 4 or higher is required\n" - exit 1 - fi - # :src/initialize.sh # Code here runs inside the initialize() function # Use it for anything that you need to run before any other function, like