bundlegem 1.1.1 → 1.2.0.pre.rc.2

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +26 -37
  4. data/Rakefile +3 -5
  5. data/bin/bundlegem +45 -40
  6. data/bundlegem.gemspec +5 -11
  7. data/changelog +14 -3
  8. data/config/config +1 -1
  9. data/lib/bundlegem/cli/cli.rb +0 -4
  10. data/lib/bundlegem/cli/dir_to_template.rb +25 -13
  11. data/lib/bundlegem/cli/gem.rb +75 -158
  12. data/lib/bundlegem/strings.rb +1 -1
  13. data/lib/bundlegem/template_manager.rb +2 -2
  14. data/lib/bundlegem/templates/test_template/#{name}.rb.tt +1 -0
  15. data/lib/bundlegem/version.rb +1 -1
  16. data/lib/bundlegem.rb +27 -15
  17. data/spec/bundlegem_spec.rb +30 -29
  18. data/spec/data/variable_manifest_test.rb +1 -0
  19. data/spec/spec_helper.rb +1 -2
  20. data/spec/template_manager_spec.rb +1 -1
  21. metadata +7 -113
  22. data/.travis.yml +0 -3
  23. data/lib/bundlegem/cli.rb +0 -166
  24. data/lib/bundlegem/friendly_errors.rb +0 -79
  25. data/lib/bundlegem/templates/Executable +0 -16
  26. data/lib/bundlegem/templates/Executable.standalone +0 -12
  27. data/lib/bundlegem/templates/Gemfile +0 -4
  28. data/lib/bundlegem/templates/c_extension_gem/#{name}.gemspec.tt +0 -28
  29. data/lib/bundlegem/templates/c_extension_gem/.travis.yml.tt +0 -3
  30. data/lib/bundlegem/templates/c_extension_gem/CODE_OF_CONDUCT.md.tt +0 -13
  31. data/lib/bundlegem/templates/c_extension_gem/Gemfile.tt +0 -4
  32. data/lib/bundlegem/templates/c_extension_gem/LICENSE.txt.tt +0 -21
  33. data/lib/bundlegem/templates/c_extension_gem/README.md.tt +0 -39
  34. data/lib/bundlegem/templates/c_extension_gem/Rakefile.tt +0 -13
  35. data/lib/bundlegem/templates/c_extension_gem/bin/#{name}.tt +0 -3
  36. data/lib/bundlegem/templates/c_extension_gem/bin/console.tt +0 -14
  37. data/lib/bundlegem/templates/c_extension_gem/changelog.tt +0 -7
  38. data/lib/bundlegem/templates/c_extension_gem/ext/#{name}/#{name}.c.tt +0 -9
  39. data/lib/bundlegem/templates/c_extension_gem/ext/#{name}/#{name}.h.tt +0 -6
  40. data/lib/bundlegem/templates/c_extension_gem/ext/#{name}/extconf.rb.tt +0 -3
  41. data/lib/bundlegem/templates/c_extension_gem/gitignore.tt +0 -16
  42. data/lib/bundlegem/templates/c_extension_gem/lib/#{name}/version.rb.tt +0 -7
  43. data/lib/bundlegem/templates/c_extension_gem/lib/#{name}.rb.tt +0 -12
  44. data/lib/bundlegem/templates/c_extension_gem/rspec.tt +0 -2
  45. data/lib/bundlegem/templates/c_extension_gem/spec/#{name}_spec.rb.tt +0 -11
  46. data/lib/bundlegem/templates/c_extension_gem/spec/spec_helper.rb.tt +0 -2
  47. data/lib/bundlegem/templates/cli_gem/#{name}.gemspec.tt +0 -42
  48. data/lib/bundlegem/templates/cli_gem/CODE_OF_CONDUCT.md.tt +0 -13
  49. data/lib/bundlegem/templates/cli_gem/Gemfile.tt +0 -4
  50. data/lib/bundlegem/templates/cli_gem/LICENSE.txt.tt +0 -3
  51. data/lib/bundlegem/templates/cli_gem/README.md.tt +0 -38
  52. data/lib/bundlegem/templates/cli_gem/Rakefile.tt +0 -31
  53. data/lib/bundlegem/templates/cli_gem/bin/console.tt +0 -14
  54. data/lib/bundlegem/templates/cli_gem/changelog.tt +0 -7
  55. data/lib/bundlegem/templates/cli_gem/exe/#{name}.tt +0 -12
  56. data/lib/bundlegem/templates/cli_gem/ext/#{name}/#{name}.c.tt +0 -9
  57. data/lib/bundlegem/templates/cli_gem/ext/#{name}/#{name}.h.tt +0 -6
  58. data/lib/bundlegem/templates/cli_gem/ext/#{name}/extconf.rb.tt +0 -3
  59. data/lib/bundlegem/templates/cli_gem/gitignore.tt +0 -15
  60. data/lib/bundlegem/templates/cli_gem/lib/#{name}/config.rb.tt +0 -40
  61. data/lib/bundlegem/templates/cli_gem/lib/#{name}/constants.rb.tt +0 -9
  62. data/lib/bundlegem/templates/cli_gem/lib/#{name}/version.rb.tt +0 -7
  63. data/lib/bundlegem/templates/cli_gem/lib/#{name}.rb.tt +0 -26
  64. data/lib/bundlegem/templates/cli_gem/rspec.tt +0 -2
  65. data/lib/bundlegem/templates/cli_gem/spec/#{name}/config_spec.rb.tt +0 -25
  66. data/lib/bundlegem/templates/cli_gem/spec/#{name}_int.rb.tt +0 -16
  67. data/lib/bundlegem/templates/cli_gem/spec/#{name}_spec.rb.tt +0 -17
  68. data/lib/bundlegem/templates/cli_gem/spec/data/sample_data.json.tt +0 -1
  69. data/lib/bundlegem/templates/cli_gem/spec/spec_helper.rb.tt +0 -2
  70. data/lib/bundlegem/templates/newgem/#{name}.gemspec.tt +0 -33
  71. data/lib/bundlegem/templates/newgem/.gitignore.tt +0 -16
  72. data/lib/bundlegem/templates/newgem/.travis.yml.tt +0 -3
  73. data/lib/bundlegem/templates/newgem/CODE_OF_CONDUCT.md.tt +0 -13
  74. data/lib/bundlegem/templates/newgem/Gemfile.tt +0 -10
  75. data/lib/bundlegem/templates/newgem/LICENSE.txt.tt +0 -21
  76. data/lib/bundlegem/templates/newgem/README.md.tt +0 -41
  77. data/lib/bundlegem/templates/newgem/Rakefile.tt +0 -40
  78. data/lib/bundlegem/templates/newgem/bin/#{name}.tt +0 -3
  79. data/lib/bundlegem/templates/newgem/bin/console.tt +0 -14
  80. data/lib/bundlegem/templates/newgem/changelog.tt +0 -7
  81. data/lib/bundlegem/templates/newgem/lib/#{name}/version.rb.tt +0 -7
  82. data/lib/bundlegem/templates/newgem/lib/#{name}.rb.tt +0 -12
  83. data/lib/bundlegem/templates/newgem/rspec.tt +0 -2
  84. data/lib/bundlegem/templates/newgem/spec/#{name}_spec.rb.tt +0 -11
  85. data/lib/bundlegem/templates/newgem/spec/spec_helper.rb.tt +0 -2
@@ -1,8 +1,11 @@
1
1
  require 'pathname'
2
2
  require 'yaml'
3
+ require 'erb'
3
4
 
4
- module Bundlegem
5
- class CLI::Gem
5
+ $TRACE = false
6
+
7
+ module Bundlegem::CLI
8
+ class Gem
6
9
  attr_reader :options, :gem_name, :name, :target
7
10
 
8
11
  def initialize(options, gem_name)
@@ -11,14 +14,15 @@ module Bundlegem
11
14
 
12
15
  @name = @gem_name
13
16
  @target = Pathname.pwd.join(gem_name)
14
- @template_src = TemplateManager.get_template_src(options)
17
+ @template_src = ::Bundlegem::TemplateManager.get_template_src(options)
15
18
 
16
19
  @tconf = load_template_configs
17
20
 
18
- validate_ext_name if options[:ext]
21
+ validate_ext_name if options[:ext] # FIXME: Useless now?
19
22
  end
20
23
 
21
24
  def build_interpolation_config
25
+ title = name.tr('-', '_').split('_').map(&:capitalize).join(" ")
22
26
  pascal_name = name.tr('-', '_').split('_').map(&:capitalize).join
23
27
  unprefixed_name = name.sub(/^#{@tconf[:prefix]}/, '')
24
28
  underscored_name = name.tr('-', '_')
@@ -28,7 +32,7 @@ module Bundlegem
28
32
  git_user_name = `git config user.name`.chomp
29
33
  git_user_email = `git config user.email`.chomp
30
34
 
31
- # domain = provider.com
35
+ # git_repo_domain = provider.com
32
36
  git_repo_domain = `git config user.repo-domain`.chomp
33
37
 
34
38
  if git_repo_domain.empty?
@@ -38,18 +42,19 @@ module Bundlegem
38
42
  if git_user_name.empty?
39
43
  raise "git config user.name didn't return a value. Please double check your username configurations in ~/.gitconfig"
40
44
  else
41
- # path = provider.com/user/name
45
+ # git_repo_path = provider.com/user/name
42
46
  git_repo_path = "#{git_repo_domain}/#{git_user_name}/#{name}".downcase # downcasing for languages like go that are creative
43
47
  end
44
48
 
45
- # url = https://provider.com/user/name
49
+ # git_repo_url = https://provider.com/user/name
46
50
  git_repo_url = "https://#{git_repo_domain}/#{git_user_name}/#{name}"
47
51
 
48
52
  config = {
49
53
  :name => name,
54
+ :title => title,
50
55
  :unprefixed_name => unprefixed_name,
51
- :unprefixed_pascal=> unprefixed_name.tr('-', '_').split('_').map(&:capitalize).join,
52
- :underscored_name => underscored_name,
56
+ unprefixed_pascal: unprefixed_name.tr('-', '_').split('_').map(&:capitalize).join,
57
+ underscored_name: underscored_name,
53
58
  :pascal_name => pascal_name,
54
59
  :camel_name => pascal_name.sub(/^./, &:downcase),
55
60
  :screamcase_name => name.tr('-', '_').upcase,
@@ -62,10 +67,10 @@ module Bundlegem
62
67
  :git_repo_domain => git_repo_domain,
63
68
  :git_repo_url => git_repo_url,
64
69
  :git_repo_path => git_repo_path,
65
- :template => options[:template],
66
- :test => options[:test],
67
- :ext => options[:ext],
68
- :bin => options[:bin],
70
+ :template => @options[:template],
71
+ :test => @options[:test],
72
+ :ext => @options[:ext],
73
+ :bin => @options[:bin],
69
74
  :bundler_version => bundler_dependency_version
70
75
  }
71
76
  end
@@ -75,16 +80,24 @@ module Bundlegem
75
80
  end
76
81
 
77
82
  def run
83
+ puts "Beginning run" if $TRACE
78
84
  raise_project_with_that_name_already_exists! if File.exist?(target)
79
85
 
86
+ puts "ensure_safe_gem_name" if $TRACE
80
87
  ensure_safe_gem_name(name, config[:constant_array])
81
88
 
82
89
  template_src = match_template_src
83
- template_directories = dynamically_generate_template_directories
90
+
91
+ puts "dynamically_generate_template_directories" if $TRACE
92
+ time_it("dynamically_generate_template_directories") do
93
+ @template_directories = dynamically_generate_template_directories
94
+ end
95
+
96
+ puts "dynamically_generate_templates_files" if $TRACE
84
97
  templates = dynamically_generate_templates_files
85
98
 
86
99
  puts "Creating new project folder '#{name}'\n\n"
87
- create_template_directories(template_directories, target)
100
+ create_template_directories(@template_directories, target)
88
101
 
89
102
  templates.each do |src, dst|
90
103
  template("#{template_src}/#{src}", target.join(dst), config)
@@ -95,9 +108,10 @@ module Bundlegem
95
108
 
96
109
  if @tconf[:bootstrap_command]
97
110
  puts "Executing bootstrap_command"
98
- puts @tconf[:bootstrap_command]
111
+ cmd = safe_gsub_template_variables(@tconf[:bootstrap_command])
112
+ puts cmd
99
113
  Dir.chdir(target) do
100
- `#{@tconf[:bootstrap_command]}`
114
+ `#{cmd}`
101
115
  end
102
116
  end
103
117
 
@@ -106,6 +120,10 @@ module Bundlegem
106
120
 
107
121
  private
108
122
 
123
+ def safe_gsub_template_variables(user_string)
124
+ user_string.gsub(/\#{\s*config\[\s*:(\w+)\s*\]\s*}/) { |m| config[$1.to_sym] }
125
+ end
126
+
109
127
  # TODO: Extract these notes to the docs or delete them
110
128
  # The language and purpose configurations of the bundlegem.yml file
111
129
  # can be used to make sure when you create a folder named
@@ -136,53 +154,39 @@ module Bundlegem
136
154
  end
137
155
 
138
156
  # Returns a hash of source directory names and their destination mappings
157
+ # This might not be needed???
139
158
  def dynamically_generate_template_directories
140
- template_dirs = {}
141
- Dir.glob("#{@template_src}/**/*", File::FNM_DOTMATCH).each do |f|
142
- next if f == "#{@template_src}/." || f == "#{@template_src}/.."
143
- next unless File.directory? f
159
+ template_dirs = Dir.glob("#{@template_src}/**/*", File::FNM_DOTMATCH).filter_map do |f|
144
160
  base_path = f[@template_src.length+1..-1]
145
- next if ignored_by_git?(@template_src, base_path)
146
- template_dirs.merge!(base_path => substitute_template_values(base_path))
147
- end
161
+ next if base_path.start_with?(".git" + File::SEPARATOR) || base_path == ".git"
162
+ next if f == "#{@template_src}/." || f == "#{@template_src}/.."
163
+ next unless File.directory?(f)
164
+ # next if ignored_by_git?(@template_src, base_path)
165
+
166
+ [base_path, substitute_template_values(base_path)]
167
+ end.to_h
168
+ filter_ignored_files!(@template_src, template_dirs)
169
+
148
170
  template_dirs
149
171
  end
150
172
 
151
- # This function should be eliminated over time so that other methods conform to the
152
- # new algo for generating templates automatically.
153
- # Really, this function generates a template_src to template_dst naming
154
- # structure so that a later method can copy all the template files from the
155
- # source and rename them properly
156
- def generate_templates_for_built_in_gems(config)
157
- # Hmmm... generate dynamically instead? Yes, overwritten below
158
- templates = {
159
- 'Gemfile.tt' => "Gemfile",
160
- 'changelog.tt' => "changelog",
161
- 'gitignore.tt' => ".gitignore",
162
- 'lib/#{name}.rb.tt' => "lib/#{config[:namespaced_path]}.rb",
163
- 'lib/#{name}/version.rb.tt' => "lib/#{config[:namespaced_path]}/version.rb",
164
- '#{name}.gemspec.tt' => "#{config[:name]}.gemspec",
165
- 'Rakefile.tt' => "Rakefile",
166
- 'README.md.tt' => "README.md",
167
- 'bin/console.tt' => "bin/console"
168
- }
173
+ # Figures out the translation between all the .tt file to their
174
+ # destination names
175
+ def dynamically_generate_templates_files
176
+ template_files = Dir.glob("#{@template_src}/**/*.tt", File::FNM_DOTMATCH).filter_map do |f|
177
+ base_path = f[@template_src.length+1..-1]
178
+ # next if ignored_by_git?(@template_src, base_path)
169
179
 
170
- prompt_coc!(templates)
171
- prompt_mit!(templates, config)
172
- prompt_test_framework!(templates, config)
180
+ [base_path, substitute_template_values(base_path).sub(/\.tt$/, "")]
181
+ end.to_h
173
182
 
174
- templates.merge!("exe/newgem.tt" => "exe/#{config[:name]}") if config[:bin]
183
+ raise_no_files_in_template_error! if template_files.empty?
184
+ filter_ignored_files!(@template_src, template_files)
175
185
 
176
- if config[:ext]
177
- templates.merge!(
178
- "ext/newgem/extconf.rb.tt" => "ext/#{config[:name]}/extconf.rb",
179
- "ext/newgem/newgem.h.tt" => "ext/#{config[:name]}/#{config[:underscored_name]}.h",
180
- "ext/newgem/newgem.c.tt" => "ext/#{config[:name]}/#{config[:underscored_name]}.c"
181
- )
182
- end
183
- templates
186
+ return template_files
184
187
  end
185
188
 
189
+
186
190
  # Applies every possible substitution within config to the fs_obj_name
187
191
  def substitute_template_values(fs_obj_name)
188
192
  config.keys.inject(fs_obj_name) do |accu, key|
@@ -194,19 +198,12 @@ module Bundlegem
194
198
  end
195
199
  end
196
200
 
197
- # Figures out the translation between all the .tt file to their
198
- # destination names
199
- def dynamically_generate_templates_files
200
- templates = {}
201
- Dir.glob("#{@template_src}/**/*.tt", File::FNM_DOTMATCH).each do |f|
202
- base_path = f[@template_src.length+1..-1]
203
- next if ignored_by_git?(@template_src, base_path)
204
- templates.merge!( base_path => substitute_template_values(base_path).sub(/\.tt$/, "") )
205
- end
206
-
207
- raise_no_files_in_template_error! if templates.empty?
201
+ def filter_ignored_files!(repo_root, path_hash)
202
+ cmd = "git -C #{repo_root} check-ignore #{Shellwords.join(path_hash.keys)}"
203
+ stdout, _, status = Open3.capture3(cmd)
204
+ filter_these_paths = stdout.split
208
205
 
209
- return templates
206
+ path_hash.delete_if { |key, _| filter_these_paths.include?(key) }
210
207
  end
211
208
 
212
209
  def ignored_by_git?(repo_root, path)
@@ -224,7 +221,7 @@ module Bundlegem
224
221
 
225
222
  # returns the full path of the template source
226
223
  def match_template_src
227
- template_src = TemplateManager.get_template_src(options)
224
+ template_src = ::Bundlegem::TemplateManager.get_template_src(@options)
228
225
 
229
226
  if File.exist?(template_src)
230
227
  return template_src # 'newgem' refers to the built in template that comes with the gem
@@ -248,7 +245,7 @@ module Bundlegem
248
245
  end
249
246
 
250
247
  def bundler_dependency_version
251
- v = Gem::Version.new(Bundler::VERSION)
248
+ v = ::Gem::Version.new(Bundler::VERSION)
252
249
  req = v.segments[0..1]
253
250
  req << 'a' if v.prerelease?
254
251
  req.join(".")
@@ -265,7 +262,7 @@ module Bundlegem
265
262
  # ==== Parameters
266
263
  # source<String>:: the relative path to the source root.
267
264
  # destination<String>:: the relative path to the destination root.
268
- # config<Hash>:: give :verbose => false to not log the status.
265
+ # config<Hash>:: give verbose: false to not log the status.
269
266
  #
270
267
  # ==== Examples
271
268
  #
@@ -277,7 +274,7 @@ module Bundlegem
277
274
  config = args.last.is_a?(Hash) ? args.pop : {}
278
275
  destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
279
276
 
280
- source = File.expand_path(TemplateManager.find_in_source_paths(source.to_s))
277
+ source = File.expand_path(::Bundlegem::TemplateManager.find_in_source_paths(source.to_s))
281
278
  context = instance_eval("binding")
282
279
 
283
280
  make_file(destination, config) do
@@ -290,21 +287,15 @@ module Bundlegem
290
287
  File.chmod(original_mode, destination)
291
288
  end
292
289
 
293
-
294
- #
295
- # EDIT: Reworked from Thor to not rely on Thor (or do so much unneeded stuff)
296
- #
297
290
  def make_file(destination, config, &block)
298
291
  FileUtils.mkdir_p(File.dirname(destination))
299
292
  puts " Writing #{destination} ..."
300
293
  File.open(destination, "wb") { |f| f.write block.call }
301
294
  end
302
295
 
303
-
304
-
305
296
  def raise_no_files_in_template_error!
306
297
  err_no_files_in_template = <<-HEREDOC
307
- Ooops, the template was found for '#{options['template']}' in ~/.bundlegem/templates,
298
+ Ooops, the template was found for '#{@options[:template]}' in ~/.bundlegem/templates,
308
299
  but no files within it ended in .tt. Did you forget to rename the extensions of your files?
309
300
 
310
301
  Exiting...
@@ -325,92 +316,18 @@ Exiting...
325
316
  end
326
317
 
327
318
  def raise_template_not_found!
328
- err_missing_template = "Could not find template folder '#{options["template"]}' in `~/.bundle/templates/`. Please check to make sure your desired template exists."
319
+ err_missing_template = "Could not find template folder '#{@options[:template]}' in `~/.bundle/templates/`. Please check to make sure your desired template exists."
329
320
  puts err_missing_template
330
321
  Bundler.ui.error err_missing_template
331
322
  raise
332
323
  end
333
324
 
334
-
335
- ############# STUFF THAT SHOULD BE REMOVED DOWN THE ROAD
336
-
337
- # This asks the user if they want to setup rspec or test...
338
- # It's not class based, it's additive based... Plus bundlegem does this already
339
- def ask_and_set_test_framework
340
- test_framework = options[:test] || Bundler.settings["gem.test"]
341
-
342
- if test_framework.nil?
343
- Bundler.ui.confirm "Do you want to generate tests with your gem?"
344
- result = Bundler.ui.ask "Type 'rspec' or 'minitest' to generate those test files now and " \
345
- "in the future. rspec/minitest/(none):"
346
- if result =~ /rspec|minitest/
347
- test_framework = result
348
- else
349
- test_framework = false
350
- end
351
- end
352
-
353
- if Bundler.settings["gem.test"].nil?
354
- Bundler.settings.set_global("gem.test", test_framework)
355
- end
356
-
357
- test_framework
358
- end
359
-
360
- def ask_and_set(key, header, message)
361
- choice = options[key] # || Bundler.settings["gem.#{key}"]
362
-
363
- if choice.nil?
364
- Bundler.ui.confirm header
365
- choice = (Bundler.ui.ask("#{message} y/(n):") =~ /y|yes/)
366
- Bundler.settings.set_global("gem.#{key}", choice)
367
- end
368
-
369
- choice
370
- end
371
-
372
- def prompt_coc!(templates)
373
- if ask_and_set(:coc, "Do you want to include a code of conduct in gems you generate?",
374
- "Codes of conduct can increase contributions to your project by contributors who " \
375
- "prefer collaborative, safe spaces. You can read more about the code of conduct at " \
376
- "contributor-covenant.org. Having a code of conduct means agreeing to the responsibility " \
377
- "of enforcing it, so be sure that you are prepared to do that. For suggestions about " \
378
- "how to enforce codes of conduct, see bit.ly/coc-enforcement."
379
- )
380
- templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
381
- end
382
- end
383
-
384
- def prompt_mit!(templates, config)
385
- if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?",
386
- "This means that any other developer or company will be legally allowed to use your code " \
387
- "for free as long as they admit you created it. You can read more about the MIT license " \
388
- "at choosealicense.com/licenses/mit."
389
- )
390
- config[:mit] = true
391
- templates.merge!("LICENSE.txt.tt" => "LICENSE.txt")
392
- end
393
- end
394
-
395
- def prompt_test_framework!(templates, config)
396
- namespaced_path = config[:namespaced_path]
397
- if test_framework = ask_and_set_test_framework
398
- templates.merge!(".travis.yml.tt" => ".travis.yml")
399
-
400
- case test_framework
401
- when 'rspec'
402
- templates.merge!(
403
- "rspec.tt" => ".rspec",
404
- "spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
405
- 'spec/#{name}_spec.rb.tt' => "spec/#{namespaced_path}_spec.rb"
406
- )
407
- when 'minitest'
408
- templates.merge!(
409
- "test/minitest_helper.rb.tt" => "test/minitest_helper.rb",
410
- "test/test_newgem.rb.tt" => "test/test_#{namespaced_path}.rb"
411
- )
412
- end
413
- end
325
+ def time_it(label = nil)
326
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
327
+ yield
328
+ end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
329
+ elapsed_ms = ((end_time - start_time) * 1000).round(2)
330
+ puts "#{label || 'Elapsed'}: #{elapsed_ms} ms"
414
331
  end
415
332
 
416
333
  # This checks to see that the gem_name is a valid ruby gem name and will 'work'
@@ -6,7 +6,7 @@ Use bundlegem to start a new project folder based on a predefined template.
6
6
  Usage Examples:
7
7
 
8
8
  # Download all my template files (configured in ~/.bundlegem/config)
9
- $ bundlegem --install-best-templates
9
+ $ bundlegem --install-public-templates
10
10
 
11
11
  # List available teplates
12
12
  $ bundlegem --list
@@ -10,10 +10,10 @@ module Bundlegem
10
10
 
11
11
  def internal_template_location() = File.expand_path("#{File.dirname(__FILE__)}/templates")
12
12
  def custom_template_location() = File.expand_path("~/.bundlegem/templates")
13
- def default_template_name() = "cli_gem"
13
+ def default_template_name() = "ruby-cli-gem"
14
14
 
15
15
  def get_template_src(options)
16
- template_name = options["template"] || default_template_name
16
+ template_name = options[:template] || default_template_name
17
17
  template_location = template_exists_within_repo?(template_name) ?
18
18
  internal_template_location :
19
19
  custom_template_location
@@ -2,6 +2,7 @@ This file shows all the variables in one place!
2
2
  See "lib/bundlegem/templates/test_template/#{name}.rb.tt"
3
3
 
4
4
  config[:name]: <%= config[:name] %>
5
+ config[:title]: <%= config[:title] %>
5
6
  config[:unprefixed_name]: <%= config[:unprefixed_name] %>
6
7
  config[:unprefixed_pascal]:<%= config[:unprefixed_pascal] %>
7
8
  config[:underscored_name]: <%= config[:underscored_name] %>
@@ -1,3 +1,3 @@
1
1
  module Bundlegem
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0-rc.2"
3
3
  end
data/lib/bundlegem.rb CHANGED
@@ -6,7 +6,7 @@ require 'bundlegem/template_manager'
6
6
  require 'bundlegem/core/core'
7
7
  require 'bundlegem/cli/cli'
8
8
 
9
- require 'bundlegem/cli'
9
+ require 'uri'
10
10
 
11
11
  SOURCE_ROOT = File.expand_path("#{File.dirname(__FILE__)}/..")
12
12
 
@@ -28,11 +28,12 @@ module Bundlegem
28
28
  mark_default_template(output_string, configurator.default_template)
29
29
  end
30
30
 
31
- def install_best_templates
31
+ def install_public_templates
32
+ validate_git_is_installed!
32
33
  configurator = Configurator.new
33
34
  config_file_data = configurator.config_file_data
34
- puts "Downloading templates from the following locations: \n #{config_file_data['best_templates'].split(" ").join("\n ")}"
35
- config_file_data['best_templates'].split.each do |url|
35
+ puts "Downloading templates from the following locations: \n #{config_file_data['public_templates'].split(" ").join("\n ")}"
36
+ config_file_data['public_templates'].split.each do |url|
36
37
  uri = URI.parse(url)
37
38
  template_folder_name = File.basename(uri.path).sub(/\.git$/, "")
38
39
  if !File.exist?("#{ENV['HOME']}/.bundlegem/templates/#{template_folder_name}")
@@ -45,12 +46,24 @@ module Bundlegem
45
46
  end
46
47
  end
47
48
 
49
+ def validate_git_is_installed!
50
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
51
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
52
+ exts.each do |ext|
53
+ exe = File.join(path, "git#{ext}")
54
+ return if File.executable?(exe) && !File.directory?(exe)
55
+ end
56
+ end
57
+
58
+ puts "Error: `git` command not found. Please install Git and ensure it's in your PATH."
59
+ exit 1
60
+ end
61
+
48
62
  def dir_to_template
49
- puts Cli::DirToTemplate.go
63
+ puts CLI::DirToTemplate.go
50
64
  end
51
65
 
52
66
  def gem(options, gem_name)
53
- require 'bundlegem/cli'
54
67
  require 'bundlegem/cli/gem'
55
68
 
56
69
  Bundlegem::CLI::Gem.new(options, gem_name).run
@@ -80,17 +93,16 @@ module Bundlegem
80
93
  # { "MISC" => ["my_thing"] }
81
94
  # ]
82
95
  def convert_grouped_hashes_to_output(available_templates)
83
- s = ""
84
- available_templates.each do |hash|
85
- k = hash.first.upcase
86
- a = hash.last
87
- s << " #{k}:\n"
88
- a.each do |el|
89
- s << " #{el}\n"
96
+ template_list_output = ""
97
+ available_templates.each do |category, template_names|
98
+
99
+ template_list_output << " #{category&.upcase || "UNSPECIFIED"}:\n"
100
+ template_names.each do |el|
101
+ template_list_output << " #{el}\n"
90
102
  end
91
- s << "\n"
103
+ template_list_output << "\n"
92
104
  end
93
- s
105
+ template_list_output
94
106
  end
95
107
 
96
108
  def mark_default_template(output_string, default_template)
@@ -46,25 +46,8 @@ describe Bundlegem do
46
46
 
47
47
  # Generate
48
48
 
49
- # This bulids the default gem template
50
- it "can generate the default built-in gem fine" do
51
- options = {"bin"=>false, "ext"=>false, :coc=> false}
52
- gem_name = "tmp_gem"
53
-
54
- capture_stdout { Bundlegem.gem(options, gem_name) }
55
- expect(File).to exist("#{@dst_dir}/#{gem_name}/README.md")
56
- end
57
-
58
- it "can generate the c_ext gem fine" do
59
- options = {"bin"=>false, "ext"=>false, :coc=> false, "template" => "c_extension_gem"}
60
- gem_name = "tmp_gem"
61
-
62
- capture_stdout { Bundlegem.gem(options, gem_name) }
63
- expect(File).to exist("#{@dst_dir}/#{gem_name}/ext/tmp_gem/#{gem_name}.c")
64
- end
65
-
66
49
  it "finds the template-test template even if the template- prefix was omitted" do
67
- options = {"bin"=>false, "ext"=>false, :coc=> false, "template" => "test"}
50
+ options = {bin: false, ext: false, coc: false, template: "test"}
68
51
  gem_name = "tmp_gem"
69
52
 
70
53
  capture_stdout { Bundlegem.gem(options, gem_name) }
@@ -73,7 +56,7 @@ describe Bundlegem do
73
56
  end
74
57
 
75
58
  it "has a useful dynamically_generate_template_directories method" do
76
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "test_template" }
59
+ options = { bin: false, ext: false, coc: false, template: "test_template" }
77
60
  gem_name = "good-dog"
78
61
  my_gem = Bundlegem::CLI::Gem.new(options, gem_name)
79
62
 
@@ -85,7 +68,7 @@ describe Bundlegem do
85
68
  end
86
69
 
87
70
  it "returns the expected interpolated string when substitute_template_values is called" do
88
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "test_template" }
71
+ options = { bin: false, ext: false, coc: false, template: "test_template" }
89
72
  gem_name = "good-dog"
90
73
  my_gem = Bundlegem::CLI::Gem.new(options, gem_name)
91
74
 
@@ -100,7 +83,7 @@ describe Bundlegem do
100
83
  end
101
84
 
102
85
  it "has a useful dynamically_generate_templates_files method" do
103
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "test_template" }
86
+ options = { bin: false, ext: false, coc: false, template: "test_template" }
104
87
  gem_name = "good-dog"
105
88
  my_gem = Bundlegem::CLI::Gem.new(options, gem_name)
106
89
 
@@ -114,7 +97,7 @@ describe Bundlegem do
114
97
 
115
98
  it "won't generate template files that are listed under the gitignore" do
116
99
  template_dir = create_user_defined_template("testing", "template-user-supplied")
117
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "template-user-supplied" }
100
+ options = { bin: false, ext: false, coc: false, template: "template-user-supplied" }
118
101
  gem_name = "good-dog"
119
102
 
120
103
  File.write("#{template_dir}/.gitignore", "node_modules/")
@@ -131,7 +114,7 @@ describe Bundlegem do
131
114
 
132
115
  it "executes the bootstrap_command if supplied" do
133
116
  template_dir = create_user_defined_template("testing", "template-user-supplied")
134
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "template-user-supplied" }
117
+ options = { bin: false, ext: false, coc: false, template: "template-user-supplied" }
135
118
  gem_name = "good-dog"
136
119
 
137
120
  File.write("#{template_dir}/bundlegem.yml", "bootstrap_command: echo hihihi")
@@ -143,16 +126,34 @@ describe Bundlegem do
143
126
  expect(output).to include "hihihi"
144
127
  end
145
128
 
129
+ it "interpolates variables into the bootstrap_command" do
130
+ # this is quite pointless, we're literally allowing the user to execute a command on their shell...
131
+ template_dir = create_user_defined_template("testing", "template-user-supplied")
132
+ options = { bin: false, ext: false, coc: false, template: "template-user-supplied" }
133
+ gem_name = "good-dog"
134
+
135
+ File.write("#{template_dir}/bundlegem.yml", 'bootstrap_command: "echo #{config[:name]}"')
136
+ File.write("#{template_dir}/README.md.tt", "# Readme...")
137
+ `git init #{template_dir}`
138
+
139
+ output = capture_stdout { Bundlegem.gem(options, gem_name) }
140
+
141
+ expect(output).to include "echo #{gem_name}"
142
+ end
143
+
146
144
  it "has a test proving every interpolation in one file" do
147
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "test_template" }
145
+ expected_manifest = File.read("#{ENV['SPEC_DATA_DIR']}/variable_manifest_test.rb")
146
+ options = { bin: false, ext: false, coc: false, template: "test_template" }
148
147
  gem_name = "good-dog"
149
148
 
150
149
  capture_stdout { Bundlegem.gem(options, gem_name) }
151
- expect(File.read("#{@dst_dir}/#{gem_name}/#{gem_name}.rb")).to eq File.read("#{ENV['SPEC_DATA_DIR']}/variable_manifest_test.rb")
150
+
151
+ resulting_manifest = File.read("#{@dst_dir}/#{gem_name}/#{gem_name}.rb")
152
+ expect(resulting_manifest).to eq expected_manifest
152
153
  end
153
154
 
154
155
  it "has config[:unprefixed_name] removing purpose-tool- from name" do
155
- options = { "bin"=>false, "ext"=>false, :coc=> false, "template" => "test_template" }
156
+ options = { bin: false, ext: false, coc: false, template: "test_template" }
156
157
  gem_name = "tool-go-good-dog"
157
158
  my_gem = Bundlegem::CLI::Gem.new(options, gem_name)
158
159
 
@@ -161,7 +162,7 @@ describe Bundlegem do
161
162
  expect(config[:unprefixed_name]).to eq "good-dog"
162
163
  end
163
164
 
164
- describe "install best templates" do
165
+ describe "install public templates" do
165
166
  before :each do
166
167
  setup_mock_web_template
167
168
  end
@@ -169,8 +170,8 @@ describe Bundlegem do
169
170
  remove_mock_web_template
170
171
  end
171
172
 
172
- it "can download best templates from the web" do
173
- capture_stdout { Bundlegem.install_best_templates }
173
+ it "can download public templates from the web" do
174
+ capture_stdout { Bundlegem.install_public_templates }
174
175
  expect(File).to exist("#{ENV['HOME']}/.bundlegem/templates/template-arduino/README.md")
175
176
  end
176
177
  end
@@ -2,6 +2,7 @@ This file shows all the variables in one place!
2
2
  See "lib/bundlegem/templates/test_template/#{name}.rb.tt"
3
3
 
4
4
  config[:name]: good-dog
5
+ config[:title]: Good Dog
5
6
  config[:unprefixed_name]: good-dog
6
7
  config[:unprefixed_pascal]:GoodDog
7
8
  config[:underscored_name]: good_dog
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  $test_env = true
3
3
  require 'bundlegem'
4
- require 'bundlegem/cli'
5
4
  require 'bundlegem/cli/gem'
6
5
  require 'fileutils'
7
6
  require 'pry'
@@ -12,7 +11,7 @@ ENV['SPEC_DATA_DIR'] = File.expand_path("./spec/data") # I fell into this from s
12
11
 
13
12
 
14
13
  def setup_mock_web_template
15
- ENV['best_templates'] = "#{ENV['HOME']}/arduino.git"
14
+ ENV['public_templates'] = "#{ENV['HOME']}/arduino.git"
16
15
  FileUtils.mkdir("#{ENV['HOME']}/arduino.git")
17
16
  FileUtils.touch("#{ENV['HOME']}/arduino.git/README.md")
18
17