Skip to content

Commit bb05f71

Browse files
authored
Merge pull request #143 from DannyBen/refactor/library-functions
Refactor library functions
2 parents dff45f4 + 97cd432 commit bb05f71

File tree

27 files changed

+401
-90
lines changed

27 files changed

+401
-90
lines changed

examples/completions/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -x
44

5-
bashly add comp function
5+
bashly add comp function --force
66
bashly generate
77

88
### Try Me ###

lib/bashly.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
requires 'bashly/exceptions'
1212
requires 'bashly/script/base'
1313
requires 'bashly/commands/base'
14+
requires 'bashly/library/base'
1415
requires 'bashly'

lib/bashly/commands/add.rb

Lines changed: 36 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Add < Base
99
usage "bashly add colors [--force]"
1010
usage "bashly add yaml [--force]"
1111
usage "bashly add validations [--force]"
12-
usage "bashly add comp FORMAT [OUTPUT]"
12+
usage "bashly add comp FORMAT [OUTPUT --force]"
1313
usage "bashly add (-h|--help)"
1414

1515
option "-f --force", "Overwrite existing files"
@@ -32,129 +32,81 @@ class Add < Base
3232
environment "BASHLY_SOURCE_DIR", "The path containing the bashly configuration and source files [default: src]"
3333

3434
def strings_command
35-
safe_copy asset("templates/strings.yml"), "#{Settings.source_dir}/bashly-strings.yml"
35+
add_lib Library::Strings.new
3636
end
3737

3838
def lib_command
39-
safe_copy_file "sample_function.sh"
39+
add_lib Library::Sample.new
4040
end
4141

4242
def config_command
43-
safe_copy_file "config.sh"
43+
add_lib Library::Config.new
4444
end
4545

4646
def colors_command
47-
safe_copy_file "colors.sh"
47+
add_lib Library::Colors.new
4848
end
4949

5050
def yaml_command
51-
safe_copy_file "yaml.sh"
51+
add_lib Library::YAML.new
5252
end
5353

5454
def validations_command
55-
safe_copy_dir "validations"
55+
add_lib Library::Validations.new
5656
end
5757

5858
def comp_command
5959
format = args['FORMAT']
6060
output = args['OUTPUT']
61-
61+
6262
case format
63+
when "script"
64+
path = output || "#{Settings.target_dir}/completions.bash"
65+
add_lib Library::CompletionsScript.new(path)
66+
6367
when "function"
64-
save_comp_function output
68+
function = output || "send_completions"
69+
path = "#{Settings.source_dir}/lib/#{function}.sh"
70+
add_lib Library::CompletionsFunction.new(path, function: function)
71+
6572
when "yaml"
66-
save_comp_yaml output
67-
when "script"
68-
save_comp_script output
73+
path = output || "#{Settings.target_dir}/completions.yml"
74+
add_lib Library::CompletionsYAML.new(path)
75+
6976
else
7077
raise Error, "Unrecognized format: #{format}"
78+
7179
end
7280

7381
end
7482

7583
private
7684

77-
def safe_copy_dir(dir)
78-
Dir[asset("templates/lib/#{dir}/*.sh")].sort.each do |file|
79-
safe_copy_file "#{dir}/#{File.basename file}"
85+
def add_lib(handler)
86+
files_created = 0
87+
handler.files.each do |file|
88+
created = safe_write file[:path], file[:content]
89+
files_created += 1 if created
8090
end
91+
message = handler.post_install_message
92+
say "\n#{message}" if message and files_created > 0
8193
end
8294

83-
def safe_copy_file(file)
84-
safe_copy asset("templates/lib/#{file}"), "#{Settings.source_dir}/lib/#{file}"
85-
end
86-
87-
def safe_copy(source, target)
95+
def safe_write(path, content)
8896
if !Dir.exist? Settings.source_dir
8997
raise InitError, "Directory !txtgrn!#{Settings.source_dir}!txtrst! does not exist\nRun !txtpur!bashly init!txtrst! first"
9098
end
9199

92-
if File.exist? target and !args['--force']
93-
say "skipped !txtgrn!#{target}!txtrst! (exists)"
100+
if File.exist? path and !args['--force']
101+
say "skipped !txtgrn!#{path}!txtrst! (exists)"
102+
false
103+
94104
else
95-
deep_copy source, target
96-
say "created !txtgrn!#{target}"
97-
end
98-
end
99-
100-
def deep_copy(source, target)
101-
target_dir = File.dirname target
102-
FileUtils.mkdir_p target_dir unless Dir.exist? target_dir
103-
FileUtils.cp source, target
104-
end
105-
106-
def config
107-
@config ||= Config.new "#{Settings.source_dir}/bashly.yml"
108-
end
109-
110-
def command
111-
@command ||= Script::Command.new config
112-
end
113-
114-
def completions
115-
@completions ||= command.completion_data
116-
end
117-
118-
def completions_script
119-
@completions_script ||= command.completion_script
120-
end
121-
122-
def completions_function
123-
@completions_function ||= command.completion_function
124-
end
125-
126-
def save_comp_yaml(filename = nil)
127-
filename ||= "#{Settings.target_dir}/completions.yml"
128-
File.write filename, completions.to_yaml
129-
say "created !txtgrn!#{filename}"
130-
say ""
131-
say "This file can be converted to a completions script using the !txtgrn!completely!txtrst! gem."
132-
end
133-
134-
def save_comp_script(filename = nil)
135-
filename ||= "#{Settings.target_dir}/completions.bash"
136-
File.write filename, completions_script
137-
say "created !txtgrn!#{filename}"
138-
say ""
139-
say "In order to enable completions, run:"
140-
say ""
141-
say " !txtpur!$ source #{filename}"
142-
end
143-
144-
def save_comp_function(name = nil)
145-
name ||= "send_completions"
146-
target_dir = "#{Settings.source_dir}/lib"
147-
filename = "#{target_dir}/#{name}.sh"
105+
File.deep_write path, content
106+
say "created !txtgrn!#{path}"
107+
true
148108

149-
FileUtils.mkdir_p target_dir unless Dir.exist? target_dir
150-
File.write filename, completions_function
151-
152-
say "created !txtgrn!#{filename}"
153-
say ""
154-
say "In order to use it in your script, create a command or a flag (for example: !txtgrn!#{command.name} completions!txtrst! or !txtgrn!#{command.name} --completions!txtrst!) that calls the !txtgrn!#{name}!txtrst! function."
155-
say "Your users can then run something like this to enable completions:"
156-
say ""
157-
say " !txtpur!$ eval \"$(#{command.name} completions)\""
109+
end
158110
end
159111

160112
end

lib/bashly/concerns/asset_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ module AssetHelper
33
def asset(path)
44
File.expand_path "../#{path}", __dir__
55
end
6+
7+
def asset_content(path)
8+
File.read asset(path)
9+
end
610
end
711
end

lib/bashly/extensions/file.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require "fileutils"
2+
3+
class File
4+
def self.deep_write(file, content)
5+
dir = File.dirname file
6+
FileUtils.mkdir_p dir unless Dir.exist? dir
7+
File.write file, content
8+
end
9+
end

lib/bashly/library/base.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
module Bashly
2+
module Library
3+
class Base
4+
include AssetHelper
5+
6+
attr_reader :target_path, :options
7+
8+
def initialize(target_path = nil, options = nil)
9+
@target_path = target_path || Settings.source_dir
10+
@options = options || {}
11+
end
12+
13+
def files
14+
case content
15+
when String then content_from_string content
16+
when Hash then [content]
17+
else content
18+
end
19+
end
20+
21+
def post_install_message
22+
nil
23+
end
24+
25+
def content
26+
raise NotImplementedError, "Please implement either #content"
27+
end
28+
29+
private
30+
31+
def content_from_string(string)
32+
if File.directory? asset("templates/lib/#{string}")
33+
content_for_dir string
34+
else
35+
[content_for_file(string)]
36+
end
37+
end
38+
39+
def content_for_file(file)
40+
{
41+
path: "#{target_path}/lib/#{file}",
42+
content: asset_content("templates/lib/#{file}")
43+
}
44+
end
45+
46+
def content_for_dir(dir)
47+
Dir[asset("templates/lib/#{dir}/*.sh")].sort.map do |file|
48+
{
49+
path: "#{target_path}/lib/#{dir}/#{File.basename file}",
50+
content: File.read(file)
51+
}
52+
end
53+
end
54+
55+
end
56+
end
57+
end

lib/bashly/library/colors.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Bashly
2+
module Library
3+
class Colors < Base
4+
def content
5+
"colors.sh"
6+
end
7+
end
8+
end
9+
end

lib/bashly/library/completions.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module Bashly
2+
module Library
3+
class Completions < Base
4+
def content
5+
{ path: target_path, content: file_content }
6+
end
7+
8+
def file_content
9+
raise NotImplementedError, "Please implement #file_content"
10+
end
11+
12+
protected
13+
14+
def completions
15+
@completions ||= command.completion_data
16+
end
17+
18+
def config
19+
@config ||= Bashly::Config.new "#{Settings.source_dir}/bashly.yml"
20+
end
21+
22+
def command
23+
@command ||= Script::Command.new config
24+
end
25+
26+
end
27+
end
28+
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Bashly
2+
module Library
3+
class CompletionsFunction < Completions
4+
def file_content
5+
command.completion_function function_name
6+
end
7+
8+
def post_install_message
9+
<<~EOF
10+
In order to enable completions in your script, create a command or a flag (for example: !txtgrn!#{command.name} completions!txtrst! or !txtgrn!#{command.name} --completions!txtrst!) that calls the !txtgrn!#{function_name}!txtrst! function.
11+
12+
Your users can then run something like this to enable completions:
13+
14+
!txtpur!$ eval \"$(#{command.name} completions)\"
15+
EOF
16+
end
17+
18+
def function_name
19+
options[:function]
20+
end
21+
end
22+
end
23+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module Bashly
2+
module Library
3+
class CompletionsScript < Completions
4+
def file_content
5+
command.completion_script
6+
end
7+
8+
def post_install_message
9+
<<~EOF
10+
In order to enable completions, run:
11+
12+
!txtpur!$ source #{target_path}
13+
EOF
14+
end
15+
end
16+
end
17+
end

0 commit comments

Comments
 (0)