ore 0.8.1 → 0.9.0

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 (74) hide show
  1. data/.gitignore +10 -0
  2. data/ChangeLog.md +70 -7
  3. data/LICENSE.txt +1 -1
  4. data/README.md +93 -88
  5. data/Rakefile +5 -5
  6. data/data/ore/templates/base/README.md.erb +3 -0
  7. data/data/ore/templates/base/README.rdoc.erb +3 -0
  8. data/data/ore/templates/base/README.tt.erb +3 -0
  9. data/data/ore/templates/base/template.yml +2 -2
  10. data/data/ore/templates/bin/bin/[name].erb +1 -1
  11. data/data/ore/templates/bundler/Gemfile.erb +14 -3
  12. data/data/ore/templates/bundler/template.yml +7 -2
  13. data/data/ore/templates/bundler_tasks/_tasks.erb +1 -0
  14. data/data/ore/templates/bundler_tasks/template.yml +6 -0
  15. data/data/ore/templates/gem_package_task/_tasks.erb +5 -0
  16. data/data/ore/templates/gem_package_task/template.yml +4 -0
  17. data/data/ore/templates/gemspec/[name].gemspec.erb +45 -0
  18. data/data/ore/templates/gemspec/template.yml +2 -0
  19. data/data/ore/templates/{base → gemspec_yml}/[name].gemspec.erb +36 -55
  20. data/data/ore/templates/gemspec_yml/gemspec.yml.erb +41 -0
  21. data/data/ore/templates/gemspec_yml/template.yml +2 -0
  22. data/data/ore/templates/git/.gitignore.erb +3 -0
  23. data/data/ore/templates/git/template.yml +2 -0
  24. data/data/ore/templates/hg/.hgignore.erb +3 -0
  25. data/data/ore/templates/hg/template.yml +2 -0
  26. data/data/ore/templates/jeweler_tasks/_tasks.erb +3 -12
  27. data/data/ore/templates/jeweler_tasks/template.yml +4 -3
  28. data/data/ore/templates/rdoc/_tasks.erb +1 -1
  29. data/data/ore/templates/rdoc/template.yml +3 -0
  30. data/data/ore/templates/rspec/_tasks.erb +1 -1
  31. data/data/ore/templates/rspec/spec/spec_helper.rb.erb +1 -1
  32. data/data/ore/templates/rspec/template.yml +2 -2
  33. data/data/ore/templates/rubygems_tasks/_tasks.erb +14 -0
  34. data/data/ore/templates/rubygems_tasks/template.yml +7 -0
  35. data/data/ore/templates/rvmrc/.rvmrc.erb +9 -15
  36. data/data/ore/templates/yard/_gemfile_development.erb +0 -1
  37. data/data/ore/templates/yard/_tasks.erb +1 -1
  38. data/data/ore/templates/yard/template.yml +5 -2
  39. data/gemspec.yml +5 -7
  40. data/lib/ore.rb +0 -2
  41. data/lib/ore/actions.rb +85 -0
  42. data/lib/ore/cli.rb +2 -32
  43. data/lib/ore/config.rb +20 -20
  44. data/lib/ore/generator.rb +101 -203
  45. data/lib/ore/naming.rb +160 -0
  46. data/lib/ore/options.rb +67 -0
  47. data/lib/ore/template.rb +8 -0
  48. data/lib/ore/template/directory.rb +60 -41
  49. data/lib/ore/template/helpers.rb +55 -7
  50. data/lib/ore/template/template.rb +61 -0
  51. data/ore.gemspec +35 -55
  52. data/spec/gemspec_examples.rb +33 -0
  53. data/spec/generator_spec.rb +188 -70
  54. data/spec/helpers/generator.rb +4 -2
  55. data/spec/helpers/matchers.rb +33 -0
  56. data/spec/naming_spec.rb +56 -0
  57. data/spec/spec_helper.rb +1 -1
  58. metadata +104 -117
  59. data/data/ore/templates/base/.gitignore.erb +0 -3
  60. data/data/ore/templates/base/_gemfile_development.erb +0 -3
  61. data/data/ore/templates/base/gemspec.yml.erb +0 -30
  62. data/data/ore/templates/bundler/_development_dependencies.erb +0 -1
  63. data/data/ore/templates/bundler/_gitignore.erb +0 -2
  64. data/data/ore/templates/bundler/_tasks.erb +0 -3
  65. data/data/ore/templates/jeweler_tasks/_development_dependencies.erb +0 -3
  66. data/data/ore/templates/jeweler_tasks/_gemfile_development.erb +0 -1
  67. data/data/ore/templates/ore_tasks/_development_dependencies.erb +0 -3
  68. data/data/ore/templates/ore_tasks/_gemfile_development.erb +0 -1
  69. data/data/ore/templates/ore_tasks/_tasks.erb +0 -14
  70. data/data/ore/templates/ore_tasks/template.yml +0 -5
  71. data/data/ore/templates/rdoc/_gitignore.erb +0 -1
  72. data/data/ore/templates/rspec/_development_dependencies.erb +0 -3
  73. data/data/ore/templates/rspec/_gemfile_development.erb +0 -1
  74. data/data/ore/templates/yard/_development_dependencies.erb +0 -1
data/lib/ore/naming.rb ADDED
@@ -0,0 +1,160 @@
1
+ module Ore
2
+ #
3
+ # Provides methods for guessing the namespaces and directories
4
+ # of projects. {Naming} uses the naming conventions of project names
5
+ # defined by the
6
+ # [Ruby Packaging Standard (RPS)](http://chneukirchen.github.com/rps/).
7
+ #
8
+ # @since 0.9.0
9
+ #
10
+ module Naming
11
+ # The directory which contains executables for a project
12
+ BIN_DIR = 'bin'
13
+
14
+ # The directory which contains the code for a project
15
+ LIB_DIR = 'lib'
16
+
17
+ # The directory which contains C extension code for a project
18
+ EXT_DIR = 'ext'
19
+
20
+ # The directory which contains data files for a project
21
+ DATA_DIR = 'data'
22
+
23
+ # The directory which contains unit-tests for a project
24
+ TEST_DIR = 'test'
25
+
26
+ # The directory which contains spec-tests for a project
27
+ SPEC_DIR = 'spec'
28
+
29
+ # The directory which contains built packages
30
+ PKG_DIR = 'pkg'
31
+
32
+ # Words used in project names, but never in directory names
33
+ IGNORE_NAMESPACES = %w[core ruby rb java]
34
+
35
+ # Common acronyms used in namespaces
36
+ NAMESPACE_ACRONYMS = %w[
37
+ ffi yard i18n
38
+ http https ftp smtp imap pop3 ssh ssl tcp udp dns rpc
39
+ url uri www css html xhtml xml xsl json yaml csv
40
+ posix unix bsd
41
+ cpp asm
42
+ ]
43
+
44
+ # Common project prefixes and namespaces
45
+ COMMON_NAMESPACES = {
46
+ 'rubygems' => 'Gem',
47
+ 'ar' => 'ActiveRecord',
48
+ 'dm' => 'DataMapper',
49
+ 'js' => 'JavaScript',
50
+ 'msgpack' => 'MsgPack',
51
+ 'github' => 'GitHub',
52
+ 'rdoc' => 'RDoc'
53
+ }
54
+
55
+ #
56
+ # Splits the project name into individual names.
57
+ #
58
+ # @param [String] name
59
+ # The name to split.
60
+ #
61
+ # @return [Array<String>]
62
+ # The individual names of the project name.
63
+ #
64
+ def names_in(name)
65
+ name.split('-').reject do |word|
66
+ IGNORE_NAMESPACES.include?(word)
67
+ end
68
+ end
69
+
70
+ #
71
+ # Guesses the module name for a word within a project name.
72
+ #
73
+ # @param [String] word
74
+ # The word within a project name.
75
+ #
76
+ # @return [String]
77
+ # The module name.
78
+ #
79
+ # @since 0.1.1
80
+ #
81
+ def module_of(word)
82
+ if COMMON_NAMESPACES.has_key?(word)
83
+ COMMON_NAMESPACES[word]
84
+ elsif NAMESPACE_ACRONYMS.include?(word)
85
+ word.upcase
86
+ else
87
+ word.capitalize
88
+ end
89
+ end
90
+
91
+ #
92
+ # Guesses the module names from a project name.
93
+ #
94
+ # @param [String] name
95
+ # The name of the project.
96
+ #
97
+ # @return [Array<String>]
98
+ # The module names for a project.
99
+ #
100
+ def modules_of(name)
101
+ names_in(name).map do |words|
102
+ words.split('_').map { |word| module_of(word) }.join
103
+ end
104
+ end
105
+
106
+ #
107
+ # Guesses the full namespace for a project.
108
+ #
109
+ # @param [String] name
110
+ # The name of the project.
111
+ #
112
+ # @return [String]
113
+ # The full module namespace for a project.
114
+ #
115
+ def namespace_of(name)
116
+ modules_of(name).join('::')
117
+ end
118
+
119
+ #
120
+ # Converts a camel-case name to an underscored file name.
121
+ #
122
+ # @param [String] name
123
+ # The name to underscore.
124
+ #
125
+ # @return [String]
126
+ # The underscored version of the name.
127
+ #
128
+ def underscore(name)
129
+ name.gsub(/[^A-Z_][A-Z][^A-Z_]/) { |cap|
130
+ cap[0,1] + '_' + cap[1..-1]
131
+ }.downcase
132
+ end
133
+
134
+ #
135
+ # Guesses the namespace directories within `lib/` for a project.
136
+ #
137
+ # @param [String] name
138
+ # The name of the project.
139
+ #
140
+ # @return [Array<String>]
141
+ # The namespace directories for the project.
142
+ #
143
+ def namespace_dirs_of(name)
144
+ names_in(name).map { |word| underscore(word) }
145
+ end
146
+
147
+ #
148
+ # Guesses the namespace directory within `lib/` for a project.
149
+ #
150
+ # @param [String] name
151
+ # The name of the project.
152
+ #
153
+ # @return [String]
154
+ # The namespace directory for the project.
155
+ #
156
+ def namespace_path_of(name)
157
+ File.join(namespace_dirs_of(name))
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,67 @@
1
+ require 'ore/config'
2
+ require 'ore/template'
3
+
4
+ module Ore
5
+ #
6
+ # @api semipublic
7
+ #
8
+ # @since 0.9.0
9
+ #
10
+ module Options
11
+ # Default version
12
+ DEFAULT_VERSION = '0.1.0'
13
+
14
+ # Default summary
15
+ DEFAULT_SUMMARY = %q{TODO: Summary}
16
+
17
+ # Default description
18
+ DEFAULT_DESCRIPTION = %q{TODO: Description}
19
+
20
+ # Default License
21
+ DEFAULT_LICENSE = 'MIT'
22
+
23
+ # Default authors
24
+ DEFAULT_AUTHORS = [ENV['USER']]
25
+
26
+ def self.included(base)
27
+ base.extend ClassMethods
28
+ end
29
+
30
+ #
31
+ # Default options for the generator.
32
+ #
33
+ # @return [Hash{Symbol => Object}]
34
+ # The option names and default values.
35
+ #
36
+ def self.defaults
37
+ @@defaults ||= {
38
+ :templates => [],
39
+ :version => DEFAULT_VERSION,
40
+ :summary => DEFAULT_SUMMARY,
41
+ :description => DEFAULT_DESCRIPTION,
42
+ :license => DEFAULT_LICENSE,
43
+ :authors => DEFAULT_AUTHORS,
44
+ :gemspec => true,
45
+ :rubygems_tasks => true,
46
+ :rdoc => true,
47
+ :rspec => true,
48
+ :git => true
49
+ }.merge(Config.options)
50
+ end
51
+
52
+ module ClassMethods
53
+ #
54
+ # Defines a generator option.
55
+ #
56
+ # @param [Symbol] name
57
+ # The name of the option.
58
+ #
59
+ # @param [Hash{Symbol => Object}] options
60
+ # The Thor options of the option.
61
+ #
62
+ def generator_option(name,options={})
63
+ class_option(name,options.merge(:default => Options.defaults[name]))
64
+ end
65
+ end
66
+ end
67
+ end
data/lib/ore/template.rb CHANGED
@@ -1,3 +1,11 @@
1
1
  require 'ore/template/directory'
2
2
  require 'ore/template/interpolations'
3
3
  require 'ore/template/helpers'
4
+ require 'ore/template/template'
5
+ require 'ore/config'
6
+
7
+ # register builtin templates
8
+ Ore::Config.builtin_templates { |path| Ore::Template.register(path) }
9
+
10
+ # register installed templates
11
+ Ore::Config.installed_templates { |path| Ore::Template.register(path) }
@@ -6,22 +6,22 @@ require 'find'
6
6
  module Ore
7
7
  module Template
8
8
  #
9
- # Represents a template directory and the static files, ERb files
9
+ # Represents a template directory and the static files, `.erb` files
10
10
  # and sub-directories within it.
11
11
  #
12
12
  class Directory
13
13
 
14
14
  # The template configuration file
15
- @@config_file = 'template.yml'
15
+ CONFIG_FILE = 'template.yml'
16
16
 
17
17
  # Files or directory names to ignore
18
- @@ignore = ['.git', @@config_file]
18
+ IGNORE = ['.git', CONFIG_FILE]
19
19
 
20
20
  # The known markup languages and file extensions
21
- @@markups = {
21
+ MARKUPS = {
22
22
  :markdown => %w[.md .markdown],
23
- :textile => %w[.tt .textile],
24
- :rdoc => %w[.rdoc]
23
+ :textile => %w[.tt .textile],
24
+ :rdoc => %w[.rdoc]
25
25
  }
26
26
 
27
27
  # The path of the template directory
@@ -48,6 +48,21 @@ module Ore
48
48
  # The variables to use when rendering the template files
49
49
  attr_reader :variables
50
50
 
51
+ # Files to ignore
52
+ #
53
+ # @since 0.9.0
54
+ attr_reader :ignore
55
+
56
+ # Runtime dependencies defined by the template
57
+ #
58
+ # @since 0.9.0
59
+ attr_reader :dependencies
60
+
61
+ # Development dependencies defined by the template
62
+ #
63
+ # @since 0.9.0
64
+ attr_reader :development_dependencies
65
+
51
66
  #
52
67
  # Initializes a new template directory.
53
68
  #
@@ -58,13 +73,17 @@ module Ore
58
73
  @path = File.expand_path(path)
59
74
 
60
75
  @directories = []
61
- @files = {}
62
- @templates = {}
63
- @includes = Hash.new { |hash,key| hash[key] = {} }
76
+ @files = {}
77
+ @templates = {}
78
+ @includes = Hash.new { |hash,key| hash[key] = {} }
64
79
 
65
80
  @disable = []
66
- @enable = []
67
- @variables = {}
81
+ @enable = []
82
+
83
+ @ignore = []
84
+ @dependencies = {}
85
+ @development_dependencies = {}
86
+ @variables = {}
68
87
 
69
88
  load!
70
89
  scan!
@@ -134,41 +153,41 @@ module Ore
134
153
  # @since 0.2.0
135
154
  #
136
155
  def load!
137
- config_path = File.join(@path,@@config_file)
156
+ config_path = File.join(@path,CONFIG_FILE)
138
157
  return false unless File.file?(config_path)
139
158
 
140
159
  config = YAML.load_file(config_path)
160
+ return false unless config.kind_of?(Hash)
141
161
 
142
- unless config.kind_of?(Hash)
143
- raise(InvalidTemplate,"invalid configuration in #{config_path.dump}")
144
- end
162
+ @disable = Array(config['disable']).map(&:to_sym)
163
+ @enable = Array(config['enable']).map(&:to_sym)
145
164
 
146
- if (templates = config['disable'])
147
- if templates.kind_of?(Array)
148
- templates.each { |name| @disable << name.to_sym }
149
- else
150
- @disable << templates.to_sym
151
- end
152
- end
165
+ @ignore = Array(config['ignore'])
153
166
 
154
- if (templates = config['enable'])
155
- if templates.kind_of?(Array)
156
- templates.each { |name| @enable << name.to_sym }
157
- else
158
- @enable << templates.to_sym
159
- end
167
+ case (dependencies = config['dependencies'])
168
+ when Hash
169
+ @dependencies.merge!(dependencies)
170
+ when nil
171
+ else
172
+ raise(InvalidTemplate,"template dependencies must be a Hash: #{config_path.dump}")
160
173
  end
161
174
 
162
- if (variables = config['variables'])
163
- # variables must be a Hash
164
- unless variables.kind_of?(Hash)
165
- raise(InvalidTemplate,"template variables must be a Hash: #{config_path.dump}")
166
- end
175
+ case (dependencies = config['development_dependencies'])
176
+ when Hash
177
+ @development_dependencies.merge!(dependencies)
178
+ when nil
179
+ else
180
+ raise(InvalidTemplate,"template dependencies must be a Hash: #{config_path.dump}")
181
+ end
167
182
 
168
- # load the template variables
183
+ case (variables = config['variables'])
184
+ when Hash
169
185
  variables.each do |name,value|
170
186
  @variables[name.to_sym] = value
171
187
  end
188
+ when nil
189
+ else
190
+ raise(InvalidTemplate,"template variables must be a Hash: #{config_path.dump}")
172
191
  end
173
192
 
174
193
  return true
@@ -188,7 +207,7 @@ module Ore
188
207
  name = File.basename(file)
189
208
 
190
209
  # ignore certain files/directories
191
- Find.prune if @@ignore.include?(name)
210
+ Find.prune if IGNORE.include?(name)
192
211
 
193
212
  if File.directory?(file)
194
213
  @directories << file
@@ -198,14 +217,14 @@ module Ore
198
217
  case File.extname(name)
199
218
  when '.erb'
200
219
  # erb template
201
- if name[0,1] == '_'
220
+ if name.start_with?('_')
202
221
  # partial template
203
- template_dir = File.dirname(file)
204
- template_name = name[1...-4].to_sym
222
+ template_dir = File.dirname(file)
223
+ template_name = name[1..-1].chomp('.erb').to_sym
205
224
 
206
225
  @includes[template_dir][template_name] = src
207
226
  else
208
- dest = file[0...-4]
227
+ dest = file.chomp('.erb')
209
228
 
210
229
  @templates[dest] = src
211
230
  end
@@ -228,7 +247,7 @@ module Ore
228
247
  # Specifies whether the file is formatting.
229
248
  #
230
249
  def formatted?(path)
231
- @@markups.values.any? { |exts| exts.include?(File.extname(path)) }
250
+ MARKUPS.values.any? { |exts| exts.include?(File.extname(path)) }
232
251
  end
233
252
 
234
253
  #
@@ -244,7 +263,7 @@ module Ore
244
263
  # Specifies whether the file contains the given formatting.
245
264
  #
246
265
  def formatted_like?(path,markup)
247
- @@markups[markup].include?(File.extname(path))
266
+ MARKUPS[markup].include?(File.extname(path))
248
267
  end
249
268
 
250
269
  end
@@ -63,7 +63,31 @@ module Ore
63
63
  # @since 0.7.0
64
64
  #
65
65
  def git?
66
- options.git?
66
+ @scm == :git
67
+ end
68
+
69
+ #
70
+ # Determines if Hg is enabled.
71
+ #
72
+ # @return [Boolean]
73
+ # Specifies whether Hg was enabled.
74
+ #
75
+ # @since 0.9.0
76
+ #
77
+ def hg?
78
+ @scm == :hg
79
+ end
80
+
81
+ #
82
+ # Determines if SVN is enabled.
83
+ #
84
+ # @return [Boolean]
85
+ # Specifies whether SVN was enabled.
86
+ #
87
+ # @since 0.9.0
88
+ #
89
+ def svn?
90
+ @scm == :svn
67
91
  end
68
92
 
69
93
  #
@@ -95,7 +119,7 @@ module Ore
95
119
  # Specifies whether the project will contain RDoc documented.
96
120
  #
97
121
  def rdoc?
98
- options.rdoc?
122
+ enabled?(:rdoc)
99
123
  end
100
124
 
101
125
  #
@@ -138,6 +162,30 @@ module Ore
138
162
  enabled?(:bundler)
139
163
  end
140
164
 
165
+ #
166
+ # Determines if the project is using `Bundler::GemHelper`.
167
+ #
168
+ # @return [Boolean]
169
+ # Specifies whether the project is using `Bundler::GemHelper`.
170
+ #
171
+ # @since 0.9.0
172
+ #
173
+ def bundler_tasks?
174
+ enabled?(:bundler_tasks)
175
+ end
176
+
177
+ #
178
+ # Determines if the project is using `Gem::Tasks`.
179
+ #
180
+ # @return [Boolean]
181
+ # Specifies whether the project is using `Gem::Tasks`.
182
+ #
183
+ # @since 0.9.0
184
+ #
185
+ def rubygems_tasks?
186
+ enabled?(:rubygems_tasks)
187
+ end
188
+
141
189
  #
142
190
  # Determines if the project is using `Jeweler::Tasks`.
143
191
  #
@@ -151,15 +199,15 @@ module Ore
151
199
  end
152
200
 
153
201
  #
154
- # Determines if the project is using `Ore::Tasks`.
202
+ # Determines if the project is using `Gem::PackageTask`.
155
203
  #
156
204
  # @return [Boolean]
157
- # Specifies whether the project is using `Ore::Tasks`.
205
+ # Specifies whether the project is using `Gem::PackageTask`.
158
206
  #
159
- # @since 0.3.0
207
+ # @since 0.9.0
160
208
  #
161
- def ore_tasks?
162
- enabled?(:ore_tasks)
209
+ def gem_package_task?
210
+ enabled?(:gem_package_task)
163
211
  end
164
212
 
165
213
  #