Skip to content

Commit 1373894

Browse files
authored
Merge pull request #62 from DannyBen/add/function-wrapper
Add generate --wrap FUNCTION_NAME option to generate sourcing-friendly output
2 parents 91ccdc6 + cfafdcf commit 1373894

File tree

10 files changed

+122
-9
lines changed

10 files changed

+122
-9
lines changed

lib/bashly/commands/generate.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ module Commands
33
class Generate < Base
44
help "Generate the bash script and required files"
55

6-
usage "bashly generate [--force]"
6+
usage "bashly generate [--force --wrap FUNCTION]"
77
usage "bashly generate (-h|--help)"
88

99
option "-f --force", "Overwrite existing files"
10+
option "-w --wrap FUNCTION", "Wrap the entire script in a function so it can also be sourced"
1011

1112
environment "BASHLY_SOURCE_DIR", "The path containing the bashly configuration and source files [default: src]"
1213
environment "BASHLY_TARGET_DIR", "The path to use for creating the bash script [default: .]"
1314

15+
example "bashly generate --force"
16+
example "bashly generate --wrap my_function"
17+
1418
def run
1519
create_user_files
1620
create_master_script
@@ -54,12 +58,15 @@ def create_file(file, content)
5458
end
5559

5660
def create_master_script
57-
master_script = command.render('master_script').lint
58-
File.write master_script_path, master_script
61+
File.write master_script_path, script.code
5962
FileUtils.chmod "+x", master_script_path
6063
say "created !txtgrn!#{master_script_path}"
6164
end
6265

66+
def script
67+
@script ||= Models::Script.new(command, args['--wrap'])
68+
end
69+
6370
def master_script_path
6471
"#{Settings.target_dir}/#{command.name}"
6572
end

lib/bashly/commands/preview.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ class Preview < Base
1111
def run
1212
config = Config.new "#{Settings.source_dir}/bashly.yml"
1313
command = Models::Command.new(config)
14-
puts command.render 'master_script'
14+
script = Models::Script.new command
15+
puts script.code
1516
end
1617
end
1718
end

lib/bashly/models/script.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module Bashly
2+
module Models
3+
class Script
4+
include Renderable
5+
6+
attr_reader :command, :function_name
7+
8+
def initialize(command, function_name = nil)
9+
@command, @function_name = command, function_name
10+
end
11+
12+
def code
13+
if function_name
14+
result = [header, render('wrapper')].join "\n"
15+
else
16+
result = [header, body].join "\n"
17+
end
18+
19+
result.lint
20+
end
21+
22+
private
23+
24+
def header
25+
@header ||= render('header')
26+
end
27+
28+
def body
29+
@body ||= command.render('master_script')
30+
end
31+
end
32+
end
33+
end

lib/bashly/views/command/master_script.erb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#!/usr/bin/env bash
2-
# This script was generated by bashly (https://github.com/DannyBen/bashly)
3-
# Modifying it manually is not recommended
4-
51
<%= render :root_command if commands.empty? %>
62
<%= render :version_command %>
73
<%= render :usage %>

lib/bashly/views/script/header.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
# This script was generated by bashly (https://github.com/DannyBen/bashly)
3+
# Modifying it manually is not recommended

lib/bashly/views/script/wrapper.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# :script.wrapper
2+
<%= function_name %>() {
3+
<%= body.indent 2 %>
4+
}
5+
6+
(return 0 2>/dev/null) || <%= function_name %> "$@"

spec/approvals/cli/generate/help

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
Generate the bash script and required files
22

33
Usage:
4-
bashly generate [--force]
4+
bashly generate [--force --wrap FUNCTION]
55
bashly generate (-h|--help)
66

77
Options:
88
-f --force
99
Overwrite existing files
1010

11+
-w --wrap FUNCTION
12+
Wrap the entire script in a function so it can also be sourced
13+
1114
-h --help
1215
Show this help
1316

@@ -17,3 +20,7 @@ Environment Variables:
1720

1821
BASHLY_TARGET_DIR
1922
The path to use for creating the bash script [default: .]
23+
24+
Examples:
25+
bashly generate --force
26+
bashly generate --wrap my_function
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
creating user files in spec/tmp/src
2+
created spec/tmp/src/initialize.sh
3+
created spec/tmp/src/download_command.sh
4+
created spec/tmp/src/upload_command.sh
5+
created spec/tmp/cli
6+
run spec/tmp/cli --help to test your bash script

spec/bashly/commands/generate_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,21 @@
5151
end
5252
end
5353

54+
context "with --wrap function" do
55+
let(:cli_script) { "#{target_dir}/cli" }
56+
57+
before do
58+
reset_tmp_dir
59+
success = system "mkdir -p #{source_dir} && cp lib/bashly/templates/bashly.yml #{source_dir}/bashly.yml"
60+
expect(success).to be true
61+
end
62+
63+
it "generates the cli script wrapped in a function" do
64+
expect { subject.run %w[generate -w function] }.to output_approval('cli/generate/wrap-function')
65+
expect(File).to exist(cli_script)
66+
lines = File.readlines cli_script
67+
expect(lines[5]).to eq "function() {\n"
68+
end
69+
end
70+
5471
end

spec/bashly/models/script_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'spec_helper'
2+
3+
describe Models::Script do
4+
let(:command) { Models::Command.new config }
5+
let(:config) { load_fixture('models/commands')[fixture] }
6+
let(:fixture) { :basic_command }
7+
8+
context "without function name" do
9+
subject { described_class.new command }
10+
11+
describe '#code' do
12+
it "returns the complete script" do
13+
lines = subject.code.split "\n"
14+
expect(lines[0]).to eq '#!/usr/bin/env bash'
15+
expect(lines[1]).to start_with '# This script was generated by'
16+
expect(lines[5]).to eq 'root_command() {'
17+
expect(lines[-1]).to eq 'run "$@"'
18+
end
19+
end
20+
end
21+
22+
context "with function name" do
23+
subject { described_class.new command, 'my_super_function' }
24+
25+
describe '#code' do
26+
it "returns the complete script wrapped in a function" do
27+
lines = subject.code.split "\n"
28+
expect(lines[0]).to eq '#!/usr/bin/env bash'
29+
expect(lines[1]).to start_with '# This script was generated by'
30+
expect(lines[5]).to eq 'my_super_function() {'
31+
expect(lines[6]).to eq ' # :command.root_command'
32+
expect(lines[-1]).to eq '(return 0 2>/dev/null) || my_super_function "$@"'
33+
end
34+
end
35+
end
36+
37+
end

0 commit comments

Comments
 (0)