hen 0.2.7 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,5 +1,42 @@
1
1
  = Revision history for hen
2
2
 
3
+ == 0.3.2 [2011-02-11]
4
+
5
+ * Fixed the (pseudo-)object eval stuff. So there's hope we finally have a
6
+ working release... *fingerscrossed*
7
+
8
+ == 0.3.1 [2011-02-11]
9
+
10
+ * Fixed the RubyForge release task name in the prerequisite list for the
11
+ <tt>:release</tt> task.
12
+
13
+ == 0.3.0 [2011-02-11]
14
+
15
+ * Implementations for <tt>doc:publish</tt> and <tt>:release</tt> are
16
+ now cumulative.
17
+ * The configuration (through the user's <tt>.henrc</tt> files) is now
18
+ cumulative.
19
+ * It's no longer required to have a <tt>.henrc</tt> file.
20
+ * Changed default namespace in sample skeleton from class to module.
21
+ * Ignoring untracked files when building the official documentation and
22
+ when building the Gem.
23
+ * Added new task <tt>doc:local</tt> for the previous +doc+ behaviour.
24
+ * Renamed <tt>:gemspec</tt> -> <tt>gem:spec</tt>, <tt>gemspec:update</tt>
25
+ -> <tt>gem:spec:update</tt>.
26
+ * New task <tt>gem:install</tt> to install the current Gem locally.
27
+ * Added support for RDoc 2/3.
28
+ * Recognize <tt>:legacy</tt> option in <tt>:spec</tt> options to force
29
+ RSpec 1 even when RSpec 2 is available. Same for RDoc 2 vs. 3.
30
+ * Added support for easy GitHub homepage by setting <tt>:homepage</tt>
31
+ option to a symbol that identifies the GitHub user name.
32
+ * Better defaults for <tt>hen create/config</tt>.
33
+ * Hen::CLI#render makes a backup before overwriting an existing file.
34
+ * The RubyGems (pseudo-)object can now execute arbitrary commands.
35
+ * The +gemcutter+ helper has been deprecated; use +rubygems+ instead.
36
+ * Some defaults are set in Hen files rather than relying on <tt>.henrc</tt>
37
+ file.
38
+ * No longer messing with RubyGems/$LOAD_PATH.
39
+
3
40
  == 0.2.7 [2011-01-24]
4
41
 
5
42
  * RubyGems compatibility (Gem::CommandManager)
data/README CHANGED
@@ -2,12 +2,57 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to hen version 0.2.7
5
+ This documentation refers to hen version 0.3.2
6
6
 
7
7
 
8
8
  == DESCRIPTION
9
9
 
10
- TODO: well, the description... ;-)
10
+ Hen is a Rake helper framework, similar to Hoe[http://seattlerb.rubyforge.org/hoe/]
11
+ or Echoe[http://fauna.github.com/fauna/echoe/]. It provides you with a set of
12
+ common Rake tasks by placing a little snippet like the following in your Rakefile:
13
+
14
+ require 'hen'
15
+ require 'your/lib/version'
16
+
17
+ Hen.lay! {{
18
+ :gem => {
19
+ :name => 'gem_name',
20
+ :version => Your::Lib::VERSION,
21
+ :summary => 'Project summary',
22
+ :author => 'Your Name',
23
+ :email => 'you@e.mail'
24
+ }
25
+ }}
26
+
27
+ === Generate a global configuration file
28
+
29
+ Hen will read configuration options from your global configuration file if
30
+ it's present. You can generate a minimal <tt>.henrc</tt> with the +hen+ script:
31
+
32
+ hen config
33
+
34
+ This will create a new <tt>.henrc</tt> file in your home directory.
35
+
36
+ === Create a new project
37
+
38
+ For new projects, you can also use the +hen+ script to create an initial
39
+ project directory for you that comes with default files and configuration:
40
+
41
+ hen create path/to/your/lib
42
+
43
+ You can even provide a project template of your own:
44
+
45
+ hen create path/to/your/lib path/to/your/template
46
+
47
+ In addition to that, +hen+ can setup your new project with Git support:
48
+
49
+ hen create path/to/your/lib -g
50
+
51
+ See <tt>hen help</tt> for further information.
52
+
53
+ === Extending Hen
54
+
55
+ You can even extend Hen with your own tasks. More on that later. (TODO)
11
56
 
12
57
 
13
58
  == LINKS
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- $:.unshift('lib')
1
+ $:.unshift(File.expand_path('../lib', __FILE__))
2
2
 
3
3
  require 'hen'
4
4
 
@@ -12,8 +12,9 @@ Hen.lay! {{
12
12
  :version => Hen::VERSION,
13
13
  :summary => "Hoe or Echoe? No, thanks! Just a Rake " <<
14
14
  "helper that fits my own personal style.",
15
- :files => FileList['lib/**/*.rb', 'bin/*'].to_a,
16
- :extra_files => FileList['[A-Z]*', 'lib/hens/*.rake', 'example/**/*', 'example/.henrc'].to_a,
17
- :dependencies => [['ruby-nuggets', '>= 0.6.6'], 'highline']
15
+ :author => %q{Jens Wille},
16
+ :email => %q{jens.wille@uni-koeln.de},
17
+ :extra_files => FileList['lib/hens/*.rake'].to_a,
18
+ :dependencies => [['ruby-nuggets', '>= 0.6.9'], 'highline']
18
19
  }
19
20
  }}
data/bin/hen CHANGED
@@ -5,7 +5,7 @@
5
5
  # #
6
6
  # hen -- Just a Rake helper #
7
7
  # #
8
- # Copyright (C) 2007-2009 University of Cologne, #
8
+ # Copyright (C) 2007-2011 University of Cologne, #
9
9
  # Albertus-Magnus-Platz, #
10
10
  # 50923 Cologne, Germany #
11
11
  # #
@@ -30,15 +30,10 @@
30
30
 
31
31
  # TODO: Implement 'list' action -- List available hens with their tasks (?)
32
32
 
33
+ require 'hen/cli'
33
34
  require 'fileutils'
34
- require 'rubygems'
35
35
  require 'nuggets/enumerable/minmax'
36
36
 
37
- $: << File.join(File.dirname(__FILE__), '..', 'lib')
38
-
39
- require 'hen'
40
- require 'hen/cli'
41
-
42
37
  include Hen::CLI
43
38
 
44
39
  ACTIONS = {
@@ -60,7 +55,7 @@ EOT
60
55
 
61
56
  abort USAGE if ARGV.empty?
62
57
 
63
- EXAMPLE = File.join(File.dirname(__FILE__), '..', 'example')
58
+ EXAMPLE = File.expand_path('../../example', __FILE__)
64
59
 
65
60
  case action = ARGV.shift
66
61
  when 'help', '-h', '--help'
@@ -70,21 +65,21 @@ case action = ARGV.shift
70
65
 
71
66
  max = ACTIONS.keys.max(:length)
72
67
 
73
- ACTIONS.sort.each { |act, desc|
74
- desc = [*desc]
75
- puts " %-#{max}s - %s" % [act, desc.shift]
68
+ ACTIONS.sort.each { |action, description|
69
+ description = [*description]
70
+ puts " %-#{max}s - %s" % [action, description.shift]
76
71
 
77
- desc.each { |extra|
72
+ description.each { |extra|
78
73
  puts " %#{max}s + %s" % [' ', extra]
79
74
  }
80
75
  }
81
76
  when 'version', '--version'
82
77
  puts "hen v#{Hen::VERSION}"
83
78
  when 'config'
84
- render(File.join(EXAMPLE, '.henrc'), henrc = Hen.henrc(true))
79
+ render(File.join(EXAMPLE, '_henrc'), henrc = Hen.default_henrc)
85
80
 
86
81
  puts
87
- puts "Your .henrc has been created: #{henrc}. Now modify it to your needs."
82
+ puts "Your .henrc has been created: #{henrc}. Now adjust it to your needs."
88
83
  when 'create'
89
84
  path = File.expand_path(ARGV.shift)
90
85
  abort 'Path argument missing!' unless path
@@ -125,21 +120,21 @@ case action = ARGV.shift
125
120
  replace = {}
126
121
 
127
122
  begin
128
- # We need the name here so ask for it already. Additionally, it's
129
- # a good opportunity to make sure the user's .henrc is available.
130
- progname = ask!("Program's name", true) { |q|
131
- q.default = File.basename(path)
132
- }
123
+ # We need the name here, so ask for it already.
124
+ progname = progname(File.basename(path))
133
125
 
134
126
  Dir.chdir(skel) {
135
127
  Dir['**/*'].each { |sample|
136
128
  target = File.join(path, sample.gsub(/__progname__/, progname))
129
+
130
+ next if target.sub!(%r{(\A|/)[._](git[^/]+)\z}, '\1.\2') && !git
131
+
137
132
  created << target
138
133
 
139
134
  if File.directory?(sample)
140
- Dir.mkdir(target)
135
+ FileUtils.mkdir_p(target)
141
136
  else
142
- replace[target] = render(sample, target).scan(/### .* ###/)
137
+ replace[target] = render(sample, target).scan(/### .+ ###/)
143
138
  end
144
139
  }
145
140
  }
@@ -148,15 +143,13 @@ case action = ARGV.shift
148
143
  created.clear
149
144
  ensure
150
145
  # In case of an exception or premature program exit: Clean up!
151
- created.reverse.each { |p|
146
+ created.reverse.each { |item|
147
+ next unless File.exist?(item)
148
+
152
149
  begin
153
- (File.directory?(p) ? Dir : File).unlink(p) if File.readable?(p)
150
+ (File.directory?(item) ? Dir : File).unlink(item)
154
151
  rescue Errno::ENOTEMPTY => err
155
- if File.basename(p) == '.git'
156
- FileUtils.rm_rf(p)
157
- else
158
- raise err
159
- end
152
+ File.basename(item) == '.git' ? FileUtils.rm_rf(item) : raise(err)
160
153
  end
161
154
  }
162
155
  end
data/example/_henrc ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+
3
+ :gem:
4
+ :author: <%= fullname %>
5
+ :email: <%= emailaddress %>
6
+
7
+ # vim: syntax=yaml
@@ -1,4 +1,4 @@
1
- = License for <%= ask! "Program's name" %>
1
+ = License for <%= progname %>
2
2
 
3
3
  GNU GENERAL PUBLIC LICENSE
4
4
  Version 3, 29 June 2007
@@ -1,4 +1,4 @@
1
- = Revision history for <%= ask! "Program's name" %>
1
+ = Revision history for <%= progname %>
2
2
 
3
3
  == 0.0.1 [<%= Time.now.strftime('%Y-%m-%d') %>]
4
4
 
@@ -1,8 +1,8 @@
1
- = <%= ask! "Program's name" %> - <%= ask "Program's description summary" %>
1
+ = <%= progname %> - <%= progdesc %>
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to <%= ask! "Program's name" %> version 0.0.1
5
+ This documentation refers to <%= progname %> version 0.0.1
6
6
 
7
7
 
8
8
  == DESCRIPTION
@@ -18,21 +18,21 @@ LABEL:: <### PLACE YOUR LINK(S) HERE ###>
18
18
 
19
19
  == AUTHORS
20
20
 
21
- * <%= ask "Full name", 'gem/author' %> <mailto:<%= ask "E-mail address", 'gem/email' %>>
21
+ * <%= fullname %> <mailto:<%= emailaddress %>>
22
22
 
23
23
 
24
24
  == LICENSE AND COPYRIGHT
25
25
 
26
26
  ### PLACE YOUR COPYRIGHT NOTICE HERE ###
27
27
 
28
- <%= ask! "Program's name" %> is free software: you can redistribute it and/or modify it under
28
+ <%= progname %> is free software: you can redistribute it and/or modify it under
29
29
  the terms of the GNU General Public License as published by the Free Software
30
30
  Foundation, either version 3 of the License, or (at your option) any later
31
31
  version.
32
32
 
33
- <%= ask! "Program's name" %> is distributed in the hope that it will be useful, but WITHOUT
33
+ <%= progname %> is distributed in the hope that it will be useful, but WITHOUT
34
34
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
35
35
  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
36
36
 
37
37
  You should have received a copy of the GNU General Public License along with
38
- <%= ask! "Program's name" %>. If not, see <http://www.gnu.org/licenses/>.
38
+ <%= progname %>. If not, see <http://www.gnu.org/licenses/>.
@@ -1,20 +1,18 @@
1
- require %q{lib/<%= ask! "Program's name" %>/version}
1
+ require File.expand_path(%q{../lib/<%= progname %>/version}, __FILE__)
2
2
 
3
3
  begin
4
4
  require 'hen'
5
5
 
6
6
  Hen.lay! {{
7
7
  :gem => {
8
- :name => %q{<%= ask! "Program's name" %>},
9
- :version => <%= ask! "Module's/Class' name" %>::VERSION,
10
- :summary => %q{<%= ask "Program's description summary" %>},
11
- :files => FileList['lib/**/*.rb'].to_a,
12
- :extra_files => FileList['[A-Z]*'].to_a,
8
+ :name => %q{<%= progname %>},
9
+ :version => <%= classname %>::VERSION,
10
+ :summary => %q{<%= progdesc %>},
11
+ :author => %q{<%= fullname %>},
12
+ :email => %q{<%= emailaddress %>},
13
13
  :dependencies => %w[]
14
14
  }
15
15
  }}
16
- rescue LoadError
17
- warn "Please install the `hen' gem."
16
+ rescue LoadError => err
17
+ warn "Please install the `hen' gem. (#{err})"
18
18
  end
19
-
20
- ### Place your custom Rake tasks here.
@@ -0,0 +1,6 @@
1
+ doc
2
+ doc.local
3
+ pkg
4
+ .gh-pages
5
+ *.o
6
+ *.so
@@ -1,2 +1,2 @@
1
- class <%= ask! "Module's/Class' name" %>
1
+ module <%= classname %>
2
2
  end
@@ -1,4 +1,4 @@
1
- class <%= ask! "Module's/Class' name" %>
1
+ module <%= classname %>
2
2
 
3
3
  module Version
4
4
 
data/lib/hen.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  # #
4
4
  # hen -- Just a Rake helper #
5
5
  # #
6
- # Copyright (C) 2007-2008 University of Cologne, #
6
+ # Copyright (C) 2007-2011 University of Cologne, #
7
7
  # Albertus-Magnus-Platz, #
8
8
  # 50923 Cologne, Germany #
9
9
  # #
@@ -26,42 +26,52 @@
26
26
  ###############################################################################
27
27
  #++
28
28
 
29
- require 'yaml'
30
- require 'forwardable'
31
-
32
- require 'rubygems'
33
29
  require 'rake'
30
+ require 'yaml'
34
31
  require 'nuggets/env/user_home'
32
+ require 'nuggets/hash/deep_merge'
35
33
  require 'nuggets/proc/bind'
36
34
 
37
35
  require 'hen/dsl'
38
36
  require 'hen/version'
39
37
 
38
+ # The class handling the program logic. This is what you use in your Rakefile.
39
+ # See the README for more information.
40
+
40
41
  class Hen
41
42
 
42
- # The directories which contain the hen files
43
- HENDIRS = [File.join(File.dirname(__FILE__), 'hens')] +
44
- (ENV['HENPATH'] || '').split(File::PATH_SEPARATOR)
43
+ # The directories to search for hen files. Set
44
+ # environment variable +HENPATH+ to add more.
45
+ HENDIRS = [File.expand_path('../hens', __FILE__)]
45
46
 
46
- # All hens found, mapped by their name
47
- HENS = Dir[*HENDIRS.map { |d| "#{d}/*.rake" }].uniq.inject(
48
- Hash.new { |h, k| h[k] = [] }
49
- ) { |hash, hen|
50
- hash[File.basename(hen, '.rake')] << hen; hash
51
- }
47
+ ENV['HENPATH'].split(File::PATH_SEPARATOR).each { |dir|
48
+ HENDIRS << File.expand_path(dir)
49
+ } if ENV['HENPATH']
52
50
 
53
- # Directories to search for .henrc
54
- RCDIRS = ['.', ENV.user_home]
51
+ HENDIRS.uniq!
55
52
 
56
- # A container for all loaded hens
57
- @hens = {}
53
+ # All hens found, mapped by their name.
54
+ HENS = Hash.new { |h, k| h[k] = [] }
58
55
 
59
- # The verbosity concerning errors and warnings
60
- @verbose = true
56
+ HENDIRS.each { |dir| Dir["#{dir}/*.rake"].each { |hen|
57
+ HENS[File.basename(hen, '.rake')] << hen
58
+ } }
59
+
60
+ # Directories to search for <tt>.henrc</tt> files.
61
+ RCDIRS = [ENV.user_home, '.']
62
+
63
+ # The name of the <tt>.henrc</tt> file.
64
+ HENRC_NAME = '.henrc'
65
+
66
+ @hens, @verbose = {}, $VERBOSE
61
67
 
62
68
  class << self
63
69
 
64
- attr_reader :hens, :verbose
70
+ # The global container for all loaded hens.
71
+ attr_reader :hens
72
+
73
+ # The verbosity concerning errors and warnings.
74
+ attr_reader :verbose
65
75
 
66
76
  # call-seq:
67
77
  # lay!
@@ -77,24 +87,18 @@ class Hen
77
87
 
78
88
  @verbose = options[:verbose] if options.has_key?(:verbose)
79
89
 
80
- if block_given?
81
- yield.each { |key, value| (config[key] ||= {}).update(value) }
82
- end
90
+ yield.each { |key, value| config[key].update(value) } if block_given?
83
91
 
84
92
  # Handle include/exclude requirements
85
93
  excl = options[:exclude]
86
94
  args, default = args.empty? ? [excl ? [*excl] : [], true] : [args, false]
87
95
 
88
96
  inclexcl = Hash.new(default)
89
- args.each { |arg|
90
- inclexcl[arg.to_s] = !default
91
- }
97
+ args.each { |arg| inclexcl[arg.to_s] = !default }
92
98
 
93
99
  # Load all available hens (as far as the
94
100
  # include/exclude conditions are met)
95
- load_hens { |hen|
96
- inclexcl[hen]
97
- }
101
+ load_hens { |hen| inclexcl[hen] }
98
102
 
99
103
  # Execute each hen definition
100
104
  hens.each { |name, hen|
@@ -127,62 +131,81 @@ class Hen
127
131
  # call-seq:
128
132
  # Hen[hen] => aHen
129
133
  #
130
- # Get hen by name.
134
+ # Get +hen+ by name.
131
135
  def [](hen)
132
136
  @hens[hen]
133
137
  end
134
138
 
135
139
  # call-seq:
136
- # henrc => aString
140
+ # henrc => anArray
141
+ #
142
+ # The paths to the user's <tt>.henrc</tt> files.
143
+ def henrc
144
+ @henrc ||= find_henrc
145
+ end
146
+
147
+ # call-seq:
148
+ # default_henrc => aString
137
149
  #
138
- # The path to the user's .henrc
139
- def henrc(location_only = false)
140
- @henrc ||= find_henrc(location_only)
150
+ # The path to a suitable default <tt>.henrc</tt> location.
151
+ def default_henrc
152
+ find_henrc(false).first
141
153
  end
142
154
 
143
155
  # call-seq:
144
156
  # config => aHash
145
- # config(key) => aValue
157
+ # config(key) => anObject
146
158
  #
147
- # The configuration resulting from the user's .henrc. Takes optional
148
- # +key+ argument as "path" into the config hash, returning the thusly
149
- # retrieved value.
159
+ # The configuration resulting from the user's <tt>.henrc</tt>. Takes
160
+ # optional +key+ argument as "path" into the config hash, returning
161
+ # the thusly retrieved value.
150
162
  #
151
163
  # Example:
152
164
  # config('a/b/c') #=> @config[:a][:b][:c]
153
165
  def config(key = nil)
154
- @config ||= YAML.load_file(henrc)
166
+ @config ||= load_config
155
167
  return @config unless key
156
168
 
157
- key.split('/').inject(@config) { |value, k|
158
- value.fetch(k.to_sym)
159
- }
169
+ key.split('/').inject(@config) { |value, k| value.fetch(k.to_sym) }
160
170
  rescue IndexError, NoMethodError
161
171
  end
162
172
 
163
173
  private
164
174
 
165
175
  # call-seq:
166
- # find_henrc(location_only = false) => aString
176
+ # load_config => aHash
167
177
  #
168
- # Search for a readable .henrc, or, if +location_only+ is true, just return
169
- # a suitable default location.
170
- def find_henrc(location_only = false)
171
- return ENV['HENRC'] || File.join(RCDIRS.last, '.henrc') if location_only
172
-
173
- if henrc = ENV['HENRC']
174
- abort "The specified .henrc file could not be found: #{henrc}" \
175
- unless File.readable?(henrc)
176
- elsif henrc = RCDIRS.find { |dir|
177
- h = File.join(dir, '.henrc')
178
- break h if File.readable?(h)
178
+ # Load the configuration from the user's <tt>.henrc</tt> files.
179
+ def load_config
180
+ hash = Hash.new { |h, k| h[k] = {} }
181
+
182
+ henrc.each { |path|
183
+ yaml = YAML.load_file(path)
184
+ hash.deep_update(yaml) if yaml.is_a?(Hash)
179
185
  }
180
- else
181
- abort "No .henrc file could be found! Please " <<
182
- "create one first by running 'hen config'."
186
+
187
+ hash
188
+ end
189
+
190
+ # call-seq:
191
+ # find_henrc(must_exist = true) => anArray
192
+ #
193
+ # Returns all readable <tt>.henrc</tt> files found in the (optional)
194
+ # environment variable +HENRC+ and in each directory named in RCDIRS.
195
+ # If +must_exist+ is false, no readability checks will be performed.
196
+ def find_henrc(must_exist = true)
197
+ found = []
198
+
199
+ if env_henrc = ENV['HENRC']
200
+ found << env_henrc if !must_exist || File.readable?(env_henrc)
183
201
  end
184
202
 
185
- henrc
203
+ RCDIRS.each { |dir|
204
+ dir_henrc = File.join(dir, HENRC_NAME)
205
+ found << dir_henrc if !must_exist || File.readable?(dir_henrc)
206
+ }
207
+
208
+ found
186
209
  end
187
210
 
188
211
  # call-seq:
@@ -198,20 +221,20 @@ class Hen
198
221
 
199
222
  (hens.empty? ? HENS.keys : hens).each { |hen|
200
223
  hen = hen.to_s
201
- next unless block[hen]
202
-
203
- HENS[hen].each { |h| load h }
224
+ HENS[hen].each { |h| load h } if block[hen]
204
225
  }
205
226
  end
206
227
 
207
228
  end
208
229
 
209
- extend Forwardable
230
+ # The hen's name.
231
+ attr_reader :name
210
232
 
211
- # Forward to the class
212
- def_delegators self, :verbose
233
+ # The list of the hen's dependencies.
234
+ attr_reader :dependencies
213
235
 
214
- attr_reader :name, :dependencies, :block
236
+ # The hen's definition block.
237
+ attr_reader :block
215
238
 
216
239
  # call-seq:
217
240
  # new(args, overwrite = false) { ... }
@@ -229,6 +252,8 @@ class Hen
229
252
  return
230
253
  end
231
254
 
255
+ @laid = false
256
+
232
257
  self.class.add_hen(self, overwrite)
233
258
  end
234
259
 
@@ -240,17 +265,24 @@ class Hen
240
265
  return if laid?
241
266
 
242
267
  # Call dependencies first
243
- dependencies.each { |hen|
244
- self.class[hen].lay!
245
- }
268
+ dependencies.each { |hen| self.class[hen].lay! }
246
269
 
247
270
  block.bind(DSL).call
248
271
  rescue => err
249
- warn "#{name}: #{err} (#{err.class})" if verbose
272
+ warn "#{name}: #{err} (#{err.class})" if $DEBUG || verbose
273
+ warn err.backtrace.join("\n ") if $DEBUG
250
274
  end
251
275
 
252
276
  private
253
277
 
278
+ # call-seq:
279
+ # verbose => true or false
280
+ #
281
+ # Delegates to Hen.verbose.
282
+ def verbose
283
+ self.class.verbose
284
+ end
285
+
254
286
  # call-seq:
255
287
  # resolve_args(args) => [name, dependencies]
256
288
  #
@@ -260,17 +292,18 @@ class Hen
260
292
  def resolve_args(args)
261
293
  name, dependencies = case args
262
294
  when Hash
263
- raise ArgumentError, "Too many hen names: #{args.keys.join(' ')}" \
264
- if args.size > 1
265
- raise ArgumentError, 'No hen name given' \
266
- if args.size < 1
295
+ if args.empty?
296
+ raise ArgumentError, 'No hen name given'
297
+ elsif args.size > 1
298
+ raise ArgumentError, "Too many hen names: #{args.keys.join(' ')}"
299
+ end
267
300
 
268
301
  [args.keys.first, [*args.values.first]]
269
302
  else
270
303
  [args, []]
271
304
  end
272
305
 
273
- [name.to_sym, dependencies.map { |d| d.to_sym }]
306
+ [name.to_sym, dependencies.map { |dependency| dependency.to_sym }]
274
307
  end
275
308
 
276
309
  # call-seq:
@@ -289,7 +322,7 @@ end
289
322
  # call-seq:
290
323
  # Hen(args) { ... }
291
324
  #
292
- # Just forwards to Hen.new.
325
+ # Delegates to Hen.new.
293
326
  def Hen(args, &block)
294
327
  Hen.new(args, &block)
295
328
  end
@@ -297,7 +330,8 @@ end
297
330
  # call-seq:
298
331
  # Hen!(args) { ... }
299
332
  #
300
- # Same as above, but overwrites any existing hen with the same name.
333
+ # Delegates to Hen.new, but overwrites
334
+ # any existing hen with the same name.
301
335
  def Hen!(args, &block)
302
336
  Hen.new(args, true, &block)
303
337
  end