planter-cli 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5445d6dfa3c8e0663006ce933f45f6e0717ccb4be51c67da0901c9606a5c70c
4
- data.tar.gz: 0ee188813bbc0bb274837b130231dd937f403484d1a26adccee36b8126d2ee3f
3
+ metadata.gz: 5318772de94f6948e72fcf61709d9b0cf42c3518a775e47eaa816e8d432cf0f0
4
+ data.tar.gz: fcc04239c8d4c74af78f7da138d862f3a01ee053740cda5ad28e8e1019c11a29
5
5
  SHA512:
6
- metadata.gz: 78a345ff2396c29c7beeadda989780003b5cc63174e4b9bcfcd0344350d8160fbb403231208ba1c3ca0d4bb66083711e675f5aad7dff5d14b226d59f31be6554
7
- data.tar.gz: 1dc8ab448b3674319f6a469439d7b8dd6657a9c85061358fee7c7280a1fe9bb5910e4bf5d69e3223511bfccbd77c9e09c666b1441619ec0489e25d9c934fc048
6
+ metadata.gz: 55fd5cdd6bbede37bd171df3c6686fc4ca14c869895cf122f7a38997b46121516e32342ab7f8625b26762fba668cd73611c0edeac101fdf3d2d6ec325460dbfa
7
+ data.tar.gz: 865480b6ed5efda83cba2b0314bf1afd685eed88c2c930e6b705e4fb104da3fadc0afd85211ea2a4930370d0c786df342a6dbf7c4f0ab371b9122f6df895150b
data/.gitignore CHANGED
@@ -41,4 +41,5 @@ Gemfile.lock
41
41
 
42
42
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
43
43
  .rvmrc
44
- test
44
+ /test
45
+ .history
data/.rubocop.yml CHANGED
@@ -23,10 +23,6 @@ Style/MutableConstant:
23
23
  Style/SpecialGlobalVars:
24
24
  Enabled: false
25
25
 
26
- Security/YAMLLoad:
27
- Exclude:
28
- - 'lib/**/*.rb'
29
-
30
26
  Style/StringLiterals:
31
27
  Enabled: true
32
28
  EnforcedStyle: single_quotes
@@ -67,8 +63,7 @@ Metrics/ModuleLength:
67
63
  Max: 174
68
64
 
69
65
  Security/YAMLLoad:
70
- Exclude:
71
- - '**/*.rb'
66
+ Enabled: false
72
67
 
73
68
  Style/ModuleFunction:
74
69
  Exclude:
@@ -76,3 +71,6 @@ Style/ModuleFunction:
76
71
 
77
72
  Style/RaiseArgs:
78
73
  EnforcedStyle: compact
74
+
75
+ Style/SlicingWithRange:
76
+ Enabled: false
data/Rakefile CHANGED
@@ -107,10 +107,10 @@ task :dockertest, :version, :login, :attempt do |_, args|
107
107
  dir_args = dirs.map { |s, d| " -v '#{s}:#{d}'" }.join(' ')
108
108
  exec "docker run #{dir_args} -it #{img} /bin/bash -l" if args[:login]
109
109
 
110
- spinner = TTY::Spinner.new("[:spinner] Running tests (#{args[:version]})...", hide_cursor: true)
110
+ spinner = TTY::Spinner.new("[:spinner] Running tests (#{version})...", hide_cursor: true)
111
111
 
112
112
  spinner.auto_spin
113
- res = `docker run --rm #{dir_args} -it #{img}`
113
+ `docker run --rm #{dir_args} -it #{img}`
114
114
  # raise DockerError.new('Error running docker image') unless $?.success?
115
115
 
116
116
  # commit = puts `bash -c "docker commit $(docker ps -a|grep #{img}|awk '{print $1}'|head -n 1) #{img}"`.strip
data/bin/plant CHANGED
@@ -22,6 +22,7 @@ options = {
22
22
  # min: 1
23
23
  # max: 5
24
24
  Planter.variables = {}
25
+ Planter.base_dir = ENV['PLANTER_DIR'] || File.expand_path('~/.config/planter')
25
26
  Planter::Color.coloring = $stdout.isatty
26
27
 
27
28
  opts = OptionParser.new
@@ -53,6 +54,10 @@ opts.on('-o', '--overwrite', 'Overwrite existing files') do
53
54
  Planter.overwrite = true
54
55
  end
55
56
 
57
+ opts.on_tail('--base-dir', 'Use an alternate base directory for config and templates') do |opt|
58
+ Planter.base_dir = opt
59
+ end
60
+
56
61
  opts.on_tail('-d', '--debug', 'Display version number') do
57
62
  Planter.debug = true
58
63
  end
@@ -100,6 +105,7 @@ elsif ARGV.count.zero?
100
105
  end
101
106
 
102
107
  ARGV.each do |template|
108
+ Planter.spinner.update(title: 'Initializing configuration')
103
109
  Planter.config = template
104
110
  app = Planter::Plant.new
105
111
  app.plant
data/lib/planter/array.rb CHANGED
@@ -24,5 +24,39 @@ module Planter
24
24
  end.join('{dw}/')
25
25
  out << '{dw}]{x}'
26
26
  end
27
+
28
+ ##
29
+ ## Stringify keys in an array of hashes or arrays
30
+ ##
31
+ ## @return [Array] Array with nested hash keys stringified
32
+ ##
33
+ def stringify_keys
34
+ each_with_object([]) do |v, arr|
35
+ arr << if v.is_a?(Hash)
36
+ v.stringify_keys
37
+ elsif v.is_a?(Array)
38
+ v.map { |x| x.is_a?(Hash) || x.is_a?(Array) ? x.stringify_keys : x }
39
+ else
40
+ v
41
+ end
42
+ end
43
+ end
44
+
45
+ ##
46
+ ## Symbolize keys in an array of hashes or arrays
47
+ ##
48
+ ## @return [Array] Array with nested hash keys symbolized
49
+ ##
50
+ def symbolize_keys
51
+ each_with_object([]) do |v, arr|
52
+ arr << if v.is_a?(Hash)
53
+ v.symbolize_keys
54
+ elsif v.is_a?(Array)
55
+ v.map { |x| x.is_a?(Hash) || x.is_a?(Array) ? x.symbolize_keys : x }
56
+ else
57
+ v
58
+ end
59
+ end
60
+ end
27
61
  end
28
62
  end
data/lib/planter/color.rb CHANGED
@@ -81,7 +81,7 @@ module Planter
81
81
  [:default, '0;39']
82
82
  ].map(&:freeze).freeze
83
83
 
84
- # Array of attribute keys only
84
+ # @return [Array<String>] all available color names
85
85
  ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
86
86
 
87
87
  # Returns true if Color supports the +feature+.
@@ -7,6 +7,7 @@ module Planter
7
7
  EXIT_CODES = {
8
8
  argument: 12,
9
9
  canceled: 1,
10
+ script: 10,
10
11
  config: 127,
11
12
  git: 129
12
13
  }.deep_freeze
@@ -55,5 +56,18 @@ module Planter
55
56
  super(msg)
56
57
  end
57
58
  end
59
+
60
+ #
61
+ # Script error
62
+ #
63
+ class ScriptError < StandardError
64
+ def initialize(msg = nil)
65
+ msg = msg ? "Script: #{msg}" : 'Script error'
66
+ Planter.spinner.error('(Error)')
67
+ Planter.notify(msg, :error, exit_code: EXIT_CODES[:script])
68
+
69
+ super(msg)
70
+ end
71
+ end
58
72
  end
59
73
  end
data/lib/planter/file.rb CHANGED
@@ -2,10 +2,93 @@
2
2
 
3
3
  # Main module
4
4
  module Planter
5
- def File.binary?(name)
6
- IO.read(name) do |f|
7
- f.each_byte { |x| x.nonzero? or return true }
5
+ # File helpers
6
+ class ::File
7
+ #
8
+ # Test if file is text
9
+ #
10
+ # @param name [String] file path
11
+ #
12
+ # @return [Boolean] File is text
13
+ #
14
+ def self.text?(name)
15
+ !binary?(name)
16
+ end
17
+
18
+ #
19
+ # Test if file is binary
20
+ #
21
+ # @param name [String] File path
22
+ #
23
+ # @return [Boolean] file is binary
24
+ #
25
+ def self.binary?(name)
26
+ return true if name.nil? || name.empty? || !File.exist?(name)
27
+
28
+ ascii = control = binary = 0
29
+
30
+ bytes = File.open(name, 'rb') { |io| io.read(1024) }
31
+ return true if bytes.nil? || bytes.empty?
32
+
33
+ bytes.each_byte do |bt|
34
+ case bt
35
+ when 0...32
36
+ control += 1
37
+ when 32...128
38
+ ascii += 1
39
+ else
40
+ binary += 1
41
+ end
42
+ end
43
+
44
+ first_test = binary.to_f / ascii > 0.05
45
+
46
+ first_test || second_test(name)
47
+ end
48
+
49
+ # Allowable text file types
50
+ TEXT_TYPES = %w[text ansi xml json yaml csv empty].freeze
51
+
52
+ #
53
+ # Secondary test with file command
54
+ #
55
+ # @param name [String] file path
56
+ #
57
+ # @return [Boolean] file is binary according to file command
58
+ #
59
+ def self.second_test(name)
60
+ if TTY::Which.exist?('file')
61
+ file_type, status = Open3.capture2e('file', name)
62
+ file_type = file_type.split(':')[1..-1].join(':').strip
63
+ if file_type =~ /Apple binary property list/ && TTY::Which.exist?('plutil')
64
+ `plutil -convert xml1 "#{name}"`
65
+ File.binary?(name)
66
+ else
67
+ status.success? && !text_type?(file_type)
68
+ end
69
+ else
70
+ false
71
+ end
72
+ end
73
+
74
+ #
75
+ # Tertiary test for binary file
76
+ #
77
+ # @param name [String] file path
78
+ #
79
+ # @return [Boolean] file is binary according to mdls
80
+ #
81
+ def self.third_test(name)
82
+ if TTY::Which.exist?('mdls')
83
+ file_type, status = Open3.capture2e('mdls', '-name', 'kMDItemContentTypeTree', name)
84
+ status.success? && !text_type?(file_type)
85
+ else
86
+ false
87
+ end
88
+ end
89
+
90
+ def self.text_type?(name)
91
+ TEXT_TYPES.any? { |type| name.downcase.include?(type) } || name.empty?
8
92
  end
9
- false
10
93
  end
11
94
  end
@@ -10,7 +10,7 @@ module Planter
10
10
  ##
11
11
  ## @param path [String] The base path for template
12
12
  ##
13
- def initialize(path)
13
+ def initialize(path = Planter.base_dir)
14
14
  @basedir = File.realdirpath(path)
15
15
 
16
16
  search_path = File.join(@basedir, '**/*')
@@ -30,9 +30,9 @@ module Planter
30
30
  end
31
31
 
32
32
  ##
33
- ## Public method for copying files based on their operator
33
+ ## Public method for copying @files to target based on their operator
34
34
  ##
35
- ## @return [Boolean] success
35
+ ## @return [Boolean] success or failure
36
36
  ##
37
37
  def copy
38
38
  @files.each do |file|
@@ -89,36 +89,53 @@ module Planter
89
89
  end
90
90
 
91
91
  ##
92
- ## Copy tagged merge sections from source to target
92
+ ## Copy tagged merge sections from source to target. If merge tags do not exist in the file,
93
+ ## append the entire file contents to the target.
93
94
  ##
94
95
  ## @param entry [FileEntry] The file entry
95
96
  ##
97
+ ## @return [Boolean] success
98
+ ##
96
99
  def merge(entry)
97
100
  return copy_file(entry) if File.directory?(entry.file)
98
101
 
102
+ # Get the file type
99
103
  type = `file #{entry.file}`
100
104
  case type.sub(/^#{Regexp.escape(entry.file)}: /, '').split(/:/).first
101
105
  when /Apple binary property list/
106
+ # Convert to XML1 format
102
107
  `plutil -convert xml1 #{entry.file}`
103
108
  `plutil -convert xml1 #{entry.target}`
104
109
  content = IO.read(entry.file)
105
110
  when /data/
111
+ # Simply copy the file
106
112
  return copy_file(entry)
107
113
  else
114
+ # Copy the file if it is binary
108
115
  return copy_file(entry) if File.binary?(entry.file)
109
116
 
117
+ # Read the file content
110
118
  content = IO.read(entry.file)
111
119
  end
112
120
 
121
+ # Get the merge sections from the file, delimited by merge and /merge
113
122
  merges = content.scan(%r{(?<=\A|\n).{,4}merge *\n(.*?)\n.{,4}/merge}m)
114
123
  &.map { |m| m[0].strip.apply_variables.apply_regexes }
124
+ # If no merge sections are found, use the entire file
115
125
  merges = [content] if !merges || merges.empty?
116
- new_content = IO.read(entry.target)
117
- merges.delete_if { |m| new_content =~ /#{Regexp.escape(m)}/ }
126
+
127
+ # Get the existing content of the target file
128
+ target_content = IO.read(entry.target)
129
+
130
+ # Remove any merges that already exist in the target file
131
+ merges.delete_if { |m| target_content =~ /#{Regexp.escape(m)}/ }
132
+
133
+ # If there are any merge sections left, merge them with the target file
118
134
  if merges.count.positive?
119
- File.open(entry.target, 'w') { |f| f.puts "#{new_content.chomp}\n\n#{merges.join("\n\n")}" }
135
+ File.open(entry.target, 'w') { |f| f.puts "#{target_content.chomp}\n\n#{merges.join("\n\n")}" }
120
136
  Planter.notify("Merged #{entry.file} => #{entry.target} (#{merges.count} merges)", :debug)
121
137
  else
138
+ # If there are no merge sections left, copy the file instead
122
139
  copy_file(entry)
123
140
  end
124
141
  end
@@ -129,14 +146,25 @@ module Planter
129
146
  ## @param file [FileEntry] The file entry
130
147
  ## @param overwrite [Boolean] Force overwrite
131
148
  ##
149
+ ## @return [Boolean] success
150
+ ##
132
151
  def copy_file(file, overwrite: false)
152
+ # Check if the target file already exists
153
+ # If it does and overwrite is true, or Planter.overwrite is true,
154
+ # or if the file doesn't exist, then copy the file
133
155
  if !File.exist?(file.target) || overwrite || Planter.overwrite
156
+ # Make sure the target directory exists
134
157
  FileUtils.mkdir_p(File.dirname(file.target))
158
+ # Copy the file if it isn't a directory
135
159
  FileUtils.cp(file.file, file.target) unless File.directory?(file.file)
160
+ # Log a message to the console
136
161
  Planter.notify("Copied #{file.file} => #{file.target}", :debug)
162
+ # Return true to indicate success
137
163
  true
138
164
  else
165
+ # Log a message to the console
139
166
  Planter.notify("Skipped #{file.file} => #{file.target}", :debug)
167
+ # Return false to indicate that the copy was skipped
140
168
  false
141
169
  end
142
170
  end
data/lib/planter/hash.rb CHANGED
@@ -1,103 +1,84 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Hash helpers
4
- class ::Hash
5
- ## Turn all keys into string
6
- ##
7
- ## @return [Hash] copy of the hash where all its keys are strings
8
- ##
9
- def stringify_keys
10
- each_with_object({}) do |(k, v), hsh|
11
- hsh[k.to_s] = if v.is_a?(Hash)
12
- v.stringify_keys
13
- elsif v.is_a?(Array)
14
- v.map(&:symbolize_keys)
15
- else
16
- v
17
- end
18
- end
19
- end
20
-
21
- ##
22
- ## Turn all keys into symbols
23
- ##
24
- ## @return [Hash] hash with symbolized keys
25
- ##
26
- def symbolize_keys
27
- each_with_object({}) do |(k, v), hsh|
28
- hsh[k.to_sym] = if v.is_a?(Hash)
29
- v.symbolize_keys
30
- elsif v.is_a?(Array)
31
- v.map(&:symbolize_keys)
4
+ module Planter
5
+ ## Hash helpers
6
+ class ::Hash
7
+ ## Turn all keys into string
8
+ ##
9
+ ## @return [Hash] copy of the hash where all its keys are strings
10
+ ##
11
+ def stringify_keys
12
+ each_with_object({}) do |(k, v), hsh|
13
+ hsh[k.to_s] = if v.is_a?(Hash) || v.is_a?(Array)
14
+ v.stringify_keys
32
15
  else
33
16
  v
34
17
  end
18
+ end
35
19
  end
36
- end
37
20
 
38
- ##
39
- ## Deep merge a hash
40
- ##
41
- ## @param second [Hash] The hash to merge into self
42
- ##
43
- def deep_merge(second)
44
- merger = proc do |_, v1, v2|
45
- if v1.is_a?(Hash) && v2.is_a?(Hash)
46
- v1.merge(v2, &merger)
47
- elsif v1.is_a?(Array) && v2.is_a?(Array)
48
- v1 | v2
49
- elsif [:undefined, nil, :nil].include?(v2)
50
- v1
51
- else
52
- v2
21
+ ##
22
+ ## Turn all keys into symbols
23
+ ##
24
+ ## @return [Hash] hash with symbolized keys
25
+ ##
26
+ def symbolize_keys
27
+ each_with_object({}) do |(k, v), hsh|
28
+ hsh[k.to_sym] = if v.is_a?(Hash) || v.is_a?(Array)
29
+ v.symbolize_keys
30
+ else
31
+ v
32
+ end
53
33
  end
54
34
  end
55
- merge(second.to_h, &merger)
56
- end
57
35
 
58
- ##
59
- ## Freeze all values in a hash
60
- ##
61
- ## @return [Hash] Hash with all values frozen
62
- ##
63
- def deep_freeze
64
- chilled = {}
65
- each do |k, v|
66
- chilled[k] = v.is_a?(Hash) ? v.deep_freeze : v.freeze
36
+ ##
37
+ ## Deep merge a hash
38
+ ##
39
+ ## @param second [Hash] The hash to merge into self
40
+ ##
41
+ def deep_merge(second)
42
+ merger = proc do |_, v1, v2|
43
+ if v1.is_a?(Hash) && v2.is_a?(Hash)
44
+ v1.merge(v2, &merger)
45
+ elsif v1.is_a?(Array) && v2.is_a?(Array)
46
+ v1 | v2
47
+ elsif [:undefined, nil, :nil].include?(v2)
48
+ v1
49
+ else
50
+ v2
51
+ end
52
+ end
53
+ merge(second.to_h, &merger)
67
54
  end
68
55
 
69
- chilled.freeze
70
- end
71
-
72
- ##
73
- ## Destructive version of #deep_freeze
74
- ##
75
- ## @return [Hash] Hash with all values frozen
76
- ##
77
- def deep_freeze!
78
- replace deep_thaw.deep_freeze
79
- end
56
+ ##
57
+ ## Freeze all values in a hash
58
+ ##
59
+ ## @return [Hash] Hash with all values frozen
60
+ ##
61
+ def deep_freeze
62
+ chilled = {}
63
+ each do |k, v|
64
+ chilled[k] = v.is_a?(Hash) ? v.deep_freeze : v.freeze
65
+ end
80
66
 
81
- ##
82
- ## Unfreeze a hash and all nested values
83
- ##
84
- ## @return [Hash] unfrozen hash
85
- ##
86
- def deep_thaw
87
- chilled = {}
88
- each do |k, v|
89
- chilled[k] = v.is_a?(Hash) ? v.deep_thaw : v.dup
67
+ chilled.freeze
90
68
  end
91
69
 
92
- chilled.dup
93
- end
70
+ ##
71
+ ## Unfreeze a hash and all nested values
72
+ ##
73
+ ## @return [Hash] unfrozen hash
74
+ ##
75
+ def deep_thaw
76
+ chilled = {}
77
+ each do |k, v|
78
+ chilled[k] = v.is_a?(Hash) ? v.deep_thaw : v.dup
79
+ end
94
80
 
95
- ##
96
- ## Destructive version of #deep_thaw
97
- ##
98
- ## @return [Hash] unfrozen hash
99
- ##
100
- def deep_thaw!
101
- replace deep_thaw
81
+ chilled.dup
82
+ end
102
83
  end
103
84
  end
data/lib/planter/plant.rb CHANGED
@@ -13,7 +13,7 @@ module Planter
13
13
  Planter.variables = variables if variables.is_a?(Hash)
14
14
  Planter.config = template if template
15
15
 
16
- @basedir = File.join(Planter::BASE_DIR, 'templates', Planter.template)
16
+ @basedir = File.join(Planter.base_dir, 'templates', Planter.template)
17
17
  @target = Planter.target || Dir.pwd
18
18
 
19
19
  @git = Planter.config[:git_init] || false
@@ -177,15 +177,7 @@ module Planter
177
177
  files = Dir.glob('**/*', File::FNM_DOTMATCH).reject { |f| File.directory?(f) || f =~ /^(\.git|config\.yml)/ }
178
178
 
179
179
  files.each do |file|
180
- type = `file #{file}`
181
- case type.sub(/^#{Regexp.escape(file)}: /, '').split(/:/).first
182
- when /Apple binary property list/
183
- `plutil -convert xml1 #{file}`
184
- when /data/
185
- next
186
- else
187
- next if File.binary?(file)
188
- end
180
+ next if File.binary?(file)
189
181
 
190
182
  content = IO.read(file)
191
183
  new_content = content.apply_variables.apply_regexes
@@ -34,7 +34,7 @@ module Planter
34
34
  def ask
35
35
  return nil if @prompt.nil?
36
36
 
37
- return @value.to_s.apply_variables.apply_regexes.coerce(@type) if @value
37
+ return @value.to_s.apply_variables.apply_regexes.coerce(@type) if @value && @type != :date
38
38
 
39
39
  res = case @type
40
40
  when :integer
@@ -133,7 +133,7 @@ module Planter
133
133
  ## @return [String] the single-line response
134
134
  ##
135
135
  def read_line(prompt: nil)
136
- prompt ||= read_lines @prompt
136
+ prompt ||= @prompt
137
137
  default = @default ? " {bw}[#{@default}]" : ''
138
138
  Planter.notify("{by}#{prompt}#{default}")
139
139
 
@@ -249,7 +249,7 @@ module Planter
249
249
  return default unless $stdout.isatty
250
250
 
251
251
  # If --defaults is set, return default
252
- return default if Planter.accept_defaults
252
+ return default if Planter.accept_defaults || ENV['PLANTER_DEBUG']
253
253
 
254
254
  # clear the buffer
255
255
  if ARGV&.length
@@ -316,6 +316,9 @@ module Planter
316
316
  default_response
317
317
  end
318
318
 
319
+ # if PLANTER_DEBUG is set, answer default
320
+ return true if ENV['PLANTER_DEBUG']
321
+
319
322
  # if this isn't an interactive shell, answer default
320
323
  return default unless $stdout.isatty
321
324
 
@@ -13,15 +13,24 @@ module Planter
13
13
  ## @param script [String] The script name
14
14
  ##
15
15
  def initialize(template_dir, output_dir, script)
16
- found = find_script(template_dir, output_dir, script)
17
- Planter.notify("Script #{script} not found", :error, exit_code: 10) unless found
16
+ found = find_script(template_dir, script)
17
+ raise ScriptError.new("Script #{script} not found") unless found
18
+
18
19
  @script = found
20
+ make_executable
21
+
22
+ raise ScriptError.new("Output directory #{output_dir} not found") unless File.directory?(output_dir)
19
23
 
20
- Planter.notify("Directory #{output_dir} not found", :error, exit_code: 10) unless File.directory?(output_dir)
21
24
  @template_directory = template_dir
22
25
  @directory = output_dir
23
26
  end
24
27
 
28
+ ## Make a script executable if it's not already
29
+ def make_executable
30
+ File.chmod(0o755, @script) unless File.executable?(@script)
31
+ File.executable?(@script)
32
+ end
33
+
25
34
  ##
26
35
  ## Locate a script in either the base directory or template directory
27
36
  ##
@@ -31,13 +40,15 @@ module Planter
31
40
  ## @return [String] Path to script
32
41
  ##
33
42
  def find_script(template_dir, script)
34
- parts = Shellwords.split(script).first
35
- return script if File.exist?(parts[0])
43
+ parts = Shellwords.split(script)
44
+ script_name = parts[0]
45
+ args = parts[1..-1].join(' ')
46
+ return script if File.exist?(script_name)
36
47
 
37
- if File.exist?(File.join(template_dir, '_scripts', parts[0]))
38
- return "#{File.join(template_dir, '_scripts', parts[0])} #{parts[1..-1]}"
39
- elsif File.exist?(File.join(BASE_DIR, 'scripts', parts[0]))
40
- return "#{File.join(BASE_DIR, 'scripts', parts[0])} #{parts[1..-1]}"
48
+ if File.exist?(File.join(template_dir, '_scripts', script_name))
49
+ return "#{File.join(template_dir, '_scripts', script_name)} #{args}".strip
50
+ elsif File.exist?(File.join(Planter.base_dir, 'scripts', script_name))
51
+ return "#{File.join(Planter.base_dir, 'scripts', script_name)} #{args}".strip
41
52
  end
42
53
 
43
54
  nil
@@ -49,9 +60,10 @@ module Planter
49
60
  ## @return [Boolean] true if success?
50
61
  ##
51
62
  def run
52
- `#{@script} "#{@template_directory}" "#{@directory}"`
53
-
54
- Planter.notify("Error running #{File.basename(@script)}", :error, exit_code: 128) unless $?.success?
63
+ stdout, stderr, status = Open3.capture3(@script, @template_directory, @directory)
64
+ Planter.notify("STDOUT:\n#{stdout}", :debug) unless stdout.empty?
65
+ Planter.notify("STDERR:\n#{stderr}", :debug) unless stderr.empty?
66
+ raise ScriptError.new("Error running #{@script}") unless status.success?
55
67
 
56
68
  true
57
69
  end