blackwinter-hen 0.1.5

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.
data/ChangeLog ADDED
@@ -0,0 +1,59 @@
1
+ = Revision history for hen
2
+
3
+ == 0.1.2 [2008-08-12]
4
+
5
+ * Added task to update/create gemspec file (e.g., for github)
6
+
7
+ == 0.1.1 [2008-07-29]
8
+
9
+ * Added task to run specs with RCov
10
+ * Added option to specify spec_helper which will be loaded first
11
+
12
+ == 0.1.0 [2008-05-21]
13
+
14
+ * Adjust for API change in Rubyforge 1.0.0
15
+
16
+ == 0.0.9 [2008-02-29]
17
+
18
+ * Handle author vs. authors in Gem hen
19
+
20
+ == 0.0.8 [2008-02-15]
21
+
22
+ * Fixed Gem spec (include whole example sub-tree)
23
+
24
+ == 0.0.7 [2008-02-01]
25
+
26
+ * Search HENPATH for available hens, allowing to easily add custom hens
27
+ * Added sample custom hen file ('example/hens/sample.rake')
28
+ * Refined 'gem' and 'rdoc' hens
29
+ * Added 'hen version' command
30
+
31
+ == 0.0.6 [2008-01-09]
32
+
33
+ * Added basic sample project tree (skeleton for 'hen create')
34
+ * Lazily find and load .henrc
35
+ * Some polishing and fixes
36
+
37
+ == 0.0.5 [2008-01-08]
38
+
39
+ * Replaced 'hen' executable stub with something actually useful
40
+ * Added Hen::CLI helper module
41
+
42
+ == 0.0.4 [2008-01-07]
43
+
44
+ * Added Test::Unit and RSpec hens (tasks 'test' and 'spec')
45
+ * Removed HenError stuff
46
+
47
+ == 0.0.3 [2008-01-04]
48
+
49
+ * More cleanup and maturing
50
+ * New tasks 'release' (formerly 'upload_gem'), 'publish_docs', and 'debug_gem'
51
+ * All in all: Pretty much inspired by Hoe ;-)
52
+
53
+ == 0.0.2 [2007-12-21]
54
+
55
+ * Cleanup and minor improvements
56
+
57
+ == 0.0.1 [2007-12-20]
58
+
59
+ * Birthday :-)
data/README ADDED
@@ -0,0 +1,42 @@
1
+ = hen - Just a Rake helper
2
+
3
+ == VERSION
4
+
5
+ This documentation refers to hen version 0.1.5
6
+
7
+
8
+ == DESCRIPTION
9
+
10
+ TODO: well, the description... ;-)
11
+
12
+
13
+ == LINKS
14
+
15
+ <b></b>
16
+ Documentation:: <http://prometheus.rubyforge.org/hen>
17
+ Source code (old):: <http://prometheus.rubyforge.org/svn/scratch/hen>
18
+ Source code:: <http://github.com/blackwinter/hen>
19
+ Rubyforge project:: <http://rubyforge.org/projects/prometheus>
20
+
21
+
22
+ == AUTHORS
23
+
24
+ * Jens Wille <mailto:jens.wille@uni-koeln.de>
25
+
26
+
27
+ == LICENSE AND COPYRIGHT
28
+
29
+ Copyright (C) 2007-2008 University of Cologne,
30
+ Albertus-Magnus-Platz, 50932 Cologne, Germany
31
+
32
+ hen is free software: you can redistribute it and/or modify it under the
33
+ terms of the GNU General Public License as published by the Free Software
34
+ Foundation, either version 3 of the License, or (at your option) any later
35
+ version.
36
+
37
+ hen is distributed in the hope that it will be useful, but WITHOUT ANY
38
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
39
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
40
+
41
+ You should have received a copy of the GNU General Public License along with
42
+ hen. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ $:.unshift('lib')
2
+
3
+ require 'hen'
4
+
5
+ Hen.lay! {{
6
+ :rubyforge => {
7
+ :package => 'hen'
8
+ },
9
+
10
+ :gem => {
11
+ :version => Hen::VERSION,
12
+ :summary => "Hoe or Echoe? No, thanks! Just a Rake " <<
13
+ "helper that fits my own personal style.",
14
+ :files => FileList['lib/**/*.rb', 'bin/*'].to_a,
15
+ :extra_files => FileList['[A-Z]*', 'lib/hens/*.rake', 'example/**/*', 'example/.henrc'].to_a,
16
+ :dependencies => ['rubyforge', ['ruby-nuggets', '>= 0.3.3']]
17
+ }
18
+ }}
data/bin/hen ADDED
@@ -0,0 +1,151 @@
1
+ #! /usr/bin/ruby
2
+
3
+ #--
4
+ ###############################################################################
5
+ # #
6
+ # hen -- Just a Rake helper #
7
+ # #
8
+ # Copyright (C) 2007-2008 University of Cologne, #
9
+ # Albertus-Magnus-Platz, #
10
+ # 50932 Cologne, Germany #
11
+ # #
12
+ # Authors: #
13
+ # Jens Wille <jens.wille@uni-koeln.de> #
14
+ # #
15
+ # hen is free software; you can redistribute it and/or modify it under the #
16
+ # terms of the GNU General Public License as published by the Free Software #
17
+ # Foundation; either version 3 of the License, or (at your option) any later #
18
+ # version. #
19
+ # #
20
+ # hen is distributed in the hope that it will be useful, but WITHOUT ANY #
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
22
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
23
+ # details. #
24
+ # #
25
+ # You should have received a copy of the GNU General Public License along #
26
+ # with hen. If not, see <http://www.gnu.org/licenses/>. #
27
+ # #
28
+ ###############################################################################
29
+ #++
30
+
31
+ # TODO: Implement 'list' action -- List available hens with their tasks (?)
32
+
33
+ require 'rubygems'
34
+ require 'nuggets/enumerable/minmax'
35
+
36
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
37
+
38
+ require 'hen'
39
+ require 'hen/cli'
40
+
41
+ include Hen::CLI
42
+
43
+ ACTIONS = {
44
+ 'config' => 'Create a fresh .henrc file',
45
+ 'create' => [
46
+ 'Create a new project directory tree',
47
+ 'Arguments: path [sample-skeleton]'
48
+ ],
49
+ 'list' => 'List available hens with their tasks',
50
+ 'version' => 'Display version number'
51
+ }
52
+
53
+ USAGE = <<EOT
54
+ Usage: #{$0} {#{ACTIONS.keys.sort.join('|')}} [action-arguments]
55
+ #{$0} [-h|--help]
56
+ EOT
57
+
58
+ abort USAGE if ARGV.empty?
59
+
60
+ EXAMPLE = File.join(File.dirname(__FILE__), '..', 'example')
61
+
62
+ case action = ARGV.shift
63
+ when '-h', '--help'
64
+ puts USAGE
65
+ puts
66
+ puts 'Actions:'
67
+
68
+ max = ACTIONS.keys.max(:length)
69
+
70
+ ACTIONS.sort.each { |act, desc|
71
+ desc = [*desc]
72
+ puts " %-#{max}s - %s" % [act, desc.shift]
73
+
74
+ desc.each { |extra|
75
+ puts " %#{max}s + %s" % [' ', extra]
76
+ }
77
+ }
78
+ when 'version', '--version'
79
+ puts "hen v#{Hen::VERSION}"
80
+ when 'config'
81
+ render(File.join(EXAMPLE, '.henrc'), henrc = Hen.henrc(true))
82
+
83
+ puts
84
+ puts "Your .henrc has been created: #{henrc}. Now modify it to your needs."
85
+ when 'create'
86
+ path = File.expand_path(ARGV.shift)
87
+ abort 'Path argument missing!' unless path
88
+
89
+ skel = ARGV.shift || File.join(EXAMPLE, 'project')
90
+ abort "Sample project tree not found: #{skel}" unless File.directory?(skel)
91
+
92
+ if File.directory?(path)
93
+ abort "Target directory already exists: #{path}. Won't touch."
94
+ else
95
+ Dir.mkdir(path)
96
+ end
97
+
98
+ # Parts to be replaced by the user
99
+ replace = {}
100
+
101
+ begin
102
+ # Keep track of what's been created
103
+ created = [path]
104
+
105
+ # We need the name here so ask for it already. Additionally, it's
106
+ # a good opportunity to make sure the user's .henrc is available.
107
+ progname = ask!("Program's name", true)
108
+
109
+ Dir.chdir(skel) {
110
+ Dir['**/*'].each { |sample|
111
+ target = File.join(path, sample.gsub(/__progname__/, progname))
112
+ created << target
113
+
114
+ if File.directory?(sample)
115
+ Dir.mkdir(target)
116
+ else
117
+ replace[target] = render(sample, target).scan(/### .* ###/)
118
+ end
119
+ }
120
+ }
121
+
122
+ # If we got here, everything went fine...
123
+ created.clear
124
+ ensure
125
+ # In case of an exception or premature program exit: Clean up!
126
+ created.reverse.each { |p|
127
+ (File.directory?(p) ? Dir : File).unlink(p) if File.readable?(p)
128
+ }
129
+ end
130
+
131
+ puts
132
+ puts "Your new project directory has been created: #{path}. Have fun!"
133
+
134
+ replace.each { |target, details|
135
+ next if details.empty?
136
+
137
+ puts
138
+ puts "#{target}:"
139
+
140
+ details.each { |detail|
141
+ puts " #{detail}"
142
+ }
143
+ }
144
+ when 'list'
145
+ # How to achieve? Has to list *all* hens and tasks made available therein,
146
+ # *regardless* of any missing prerequisites (preferably indicating whether
147
+ # a particular hen/task is currently available).
148
+ abort 'Sorry, not yet available...'
149
+ else
150
+ abort "Illegal action: #{action}\n#{USAGE}"
151
+ end
data/example/.henrc ADDED
@@ -0,0 +1,30 @@
1
+ ---
2
+
3
+ :rubyforge:
4
+ :username: <%= ask 'Rubyforge user name (Leave empty for none)' %>
5
+ :rdoc_dir: :package
6
+
7
+ :rdoc:
8
+ :rdoc_dir: doc
9
+ :rdoc_files: [README, COPYING, ChangeLog, lib/**/*.rb]
10
+ :main: README
11
+ :line_numbers: true
12
+ :inline_source: true
13
+ :all: true
14
+ :charset: UTF-8
15
+
16
+ :gem:
17
+ :author: <%= ask 'Full name' %>
18
+ :email: <%= ask 'E-mail address' %>
19
+ :has_rdoc: true
20
+ :append_svnversion: true
21
+ :require_path: lib
22
+
23
+ :test:
24
+ :pattern: test/**/*_test.rb
25
+
26
+ :spec:
27
+ :pattern: spec/**/*_spec.rb
28
+ :options: spec.opts
29
+
30
+ # vim: syntax=yaml
@@ -0,0 +1,31 @@
1
+ # Add File.dirname(__FILE__) to your HENPATH environment variable -- et voilà.
2
+
3
+ # Meet your 'sample' hen
4
+ Hen :sample do
5
+
6
+ # Access options set in your .henrc or project Rakefile
7
+ sample_options = config[:sample]
8
+
9
+ # Define your tasks
10
+ desc "Like some tea?"
11
+ task :make_tea do
12
+ puts <<'TEA'
13
+ ( ) ( ) )
14
+ ) ( ) ( (
15
+ ( ) ( ) )
16
+ _____________
17
+ <_____________> ___
18
+ | |/ _ \
19
+ | | | |
20
+ | |_| |
21
+ ___| |\___/
22
+ / \___________/ \
23
+ \_____________________/
24
+
25
+ <http://www.afn.org/~afn39695/potier.htm>
26
+ TEA
27
+ end
28
+
29
+ # and so on...
30
+
31
+ end
@@ -0,0 +1,3 @@
1
+ = License for <%= ask! "Program's name" %>
2
+
3
+ ### PLACE YOUR LICENSE TEXT HERE ###
@@ -0,0 +1,5 @@
1
+ = Revision history for <%= ask! "Program's name" %>
2
+
3
+ == 0.0.1 [<%= Time.now.strftime('%Y-%m-%d') %>]
4
+
5
+ * Birthday :-)
@@ -0,0 +1,20 @@
1
+ = <%= ask! "Program's name" %> - <%= ask "Program's description summary" %>
2
+
3
+ == VERSION
4
+
5
+ This documentation refers to <%= ask! "Program's name" %> version 0.0.1
6
+
7
+
8
+ == DESCRIPTION
9
+
10
+ ### PLACE YOUR DESCRIPTION HERE ###
11
+
12
+
13
+ == AUTHORS
14
+
15
+ * <%= ask "Full name", 'gem/author' %> <mailto:<%= ask "E-mail address", 'gem/email' %>>
16
+
17
+
18
+ == LICENSE AND COPYRIGHT
19
+
20
+ ### PLACE YOUR COPYRIGHT NOTICE HERE ###
@@ -0,0 +1,24 @@
1
+ require %q{lib/<%= ask! "Program's name" %>/version}
2
+
3
+ begin
4
+ require 'hen'
5
+
6
+ Hen.lay! {{
7
+ :rubyforge => {
8
+ :project => %q{<%= ask "Rubyforge project's name (Leave empty for none)" %>},
9
+ :package => %q{<%= ask! "Program's name" %>}
10
+ },
11
+
12
+ :gem => {
13
+ :version => <%= ask! "Module's/Class' name" %>::VERSION,
14
+ :summary => %q{<%= ask "Program's description summary" %>},
15
+ :files => FileList['lib/**/*.rb'].to_a,
16
+ :extra_files => FileList['[A-Z]*'].to_a,
17
+ :dependencies => %w[]
18
+ }
19
+ }}
20
+ rescue LoadError
21
+ abort "Please install the 'hen' gem first."
22
+ end
23
+
24
+ ### Place your custom Rake tasks here.
@@ -0,0 +1,27 @@
1
+ class <%= ask! "Module's/Class' name" %>
2
+
3
+ module Version
4
+
5
+ MAJOR = 0
6
+ MINOR = 0
7
+ TINY = 1
8
+
9
+ class << self
10
+
11
+ # Returns array representation.
12
+ def to_a
13
+ [MAJOR, MINOR, TINY]
14
+ end
15
+
16
+ # Short-cut for version string.
17
+ def to_s
18
+ to_a.join('.')
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ VERSION = Version.to_s
26
+
27
+ end
@@ -0,0 +1,2 @@
1
+ class <%= ask! "Module's/Class' name" %>
2
+ end
data/lib/hen/cli.rb ADDED
@@ -0,0 +1,85 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # hen -- Just a Rake helper #
5
+ # #
6
+ # Copyright (C) 2007-2008 University of Cologne, #
7
+ # Albertus-Magnus-Platz, #
8
+ # 50932 Cologne, Germany #
9
+ # #
10
+ # Authors: #
11
+ # Jens Wille <jens.wille@uni-koeln.de> #
12
+ # #
13
+ # hen is free software; you can redistribute it and/or modify it under the #
14
+ # terms of the GNU General Public License as published by the Free Software #
15
+ # Foundation; either version 3 of the License, or (at your option) any later #
16
+ # version. #
17
+ # #
18
+ # hen is distributed in the hope that it will be useful, but WITHOUT ANY #
19
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
20
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
21
+ # details. #
22
+ # #
23
+ # You should have received a copy of the GNU General Public License along #
24
+ # with hen. If not, see <http://www.gnu.org/licenses/>. #
25
+ # #
26
+ ###############################################################################
27
+ #++
28
+
29
+ require 'erb'
30
+
31
+ require 'rubygems'
32
+ require 'highline/import'
33
+
34
+ module Hen::CLI
35
+
36
+ # Collect user's answers by key, so we don't have to ask again.
37
+ @@values = {}
38
+
39
+ alias_method :original_ask, :ask
40
+
41
+ # Ask the user to enter an appropriate value for +key+. Uses
42
+ # already stored answer if present, unless +cached+ is false.
43
+ def ask(key, config_key = nil, cached = true)
44
+ @@values[key] = nil unless cached
45
+
46
+ @@values[key] ||= config_key && Hen.config(config_key) ||
47
+ original_ask("Please enter your #{key}: ")
48
+ rescue Interrupt
49
+ abort ''
50
+ end
51
+
52
+ # Same as #ask, but requires a non-empty value to be entered.
53
+ def ask!(key, config_key = nil)
54
+ msg = "#{key} is required! Please enter a non-empty value."
55
+ max = 3
56
+
57
+ max.times { |i|
58
+ value = ask(key, config_key, i.zero?)
59
+ return value unless value.empty?
60
+
61
+ puts msg
62
+ }
63
+
64
+ abort "You had #{max} tries -- now be gone!"
65
+ end
66
+
67
+ # Renders the contents of +sample+ as an ERb template,
68
+ # storing the result in +target+. Returns the content.
69
+ def render(sample, target)
70
+ abort "Sample file not found: #{sample}" unless File.readable?(sample)
71
+
72
+ if File.readable?(target)
73
+ abort unless agree("Target file already exists: #{target}. Overwrite? ")
74
+ end
75
+
76
+ content = ERB.new(File.read(sample)).result(binding)
77
+
78
+ File.open(target, 'w') { |f|
79
+ f.puts content unless content.empty?
80
+ }
81
+
82
+ content
83
+ end
84
+
85
+ end
data/lib/hen/dsl.rb ADDED
@@ -0,0 +1,121 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of hen, the Rake helper. #
5
+ # #
6
+ # Copyright (C) 2007-2008 University of Cologne, #
7
+ # Albertus-Magnus-Platz, #
8
+ # 50932 Cologne, Germany #
9
+ # #
10
+ # Authors: #
11
+ # Jens Wille <jens.wille@uni-koeln.de> #
12
+ # #
13
+ # hen is free software; you can redistribute it and/or modify it under the #
14
+ # terms of the GNU General Public License as published by the Free Software #
15
+ # Foundation; either version 3 of the License, or (at your option) any later #
16
+ # version. #
17
+ # #
18
+ # hen is distributed in the hope that it will be useful, but WITHOUT ANY #
19
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
20
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
21
+ # details. #
22
+ # #
23
+ # You should have received a copy of the GNU General Public License along #
24
+ # with hen. If not, see <http://www.gnu.org/licenses/>. #
25
+ # #
26
+ ###############################################################################
27
+ #++
28
+
29
+ require 'nuggets/file/which'
30
+
31
+ class Hen
32
+
33
+ # Some helper methods for use inside of a Hen definition.
34
+ module DSL
35
+
36
+ extend self
37
+
38
+ # The Hen configuration.
39
+ def config
40
+ config = Hen.config
41
+
42
+ # always return a duplicate for a value, hence making the
43
+ # configuration immutable
44
+ def config.[](key)
45
+ fetch(key).dup
46
+ rescue IndexError
47
+ {}
48
+ end
49
+
50
+ config
51
+ end
52
+
53
+ # Define task +t+, but overwrite any existing task of that name!
54
+ # (Rake usually just adds them up)
55
+ def task!(t, &block)
56
+ Rake.application.instance_variable_get(:@tasks).delete(t.to_s)
57
+ task(t, &block)
58
+ end
59
+
60
+ # Find a command that is executable and run it. Intended for
61
+ # platform-dependent alternatives (Command A is not available?
62
+ # Then try B instead).
63
+ def execute(*commands)
64
+ if command = File.which_command(commands)
65
+ sh(command) { |ok, res|
66
+ warn "Error while executing command: #{command} " <<
67
+ "(return code #{res.exitstatus})" unless ok
68
+ }
69
+ else
70
+ warn "Command not found: #{commands.join('; ')}"
71
+ end
72
+ end
73
+
74
+ # Prepare the use of Rubyforge, optionally logging in right away.
75
+ # Returns the RubyForge object.
76
+ def init_rubyforge(login = true)
77
+ require_rubyforge
78
+
79
+ rf = RubyForge.new.configure
80
+ rf.login if login
81
+
82
+ rf
83
+ end
84
+
85
+ # Encapsulates tasks targeting at Rubyforge, skipping those if no
86
+ # Rubyforge project is defined. Yields the Rubyforge configuration
87
+ # hash and, optionally, a proc to obtain RubyForge objects from (via
88
+ # +call+; reaching out to init_rubyforge).
89
+ def rubyforge(&block)
90
+ rf_config = config[:rubyforge]
91
+ rf_project = rf_config[:project]
92
+
93
+ raise 'Skipping Rubyforge tasks' if rf_project.nil? || rf_project.empty?
94
+
95
+ require_rubyforge
96
+
97
+ raise LocalJumpError, 'no block given' unless block
98
+
99
+ block_args = [rf_config]
100
+ block_args << lambda { |*args|
101
+ init_rubyforge(args.empty? || args.first)
102
+ } if block.arity > 1
103
+
104
+ block[*block_args]
105
+ end
106
+
107
+ private
108
+
109
+ # Loads the Rubyforge library, giving a
110
+ # nicer error message if it's not found.
111
+ def require_rubyforge
112
+ begin
113
+ require 'rubyforge'
114
+ rescue LoadError
115
+ raise "Please install the 'rubyforge' gem first."
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,27 @@
1
+ class Hen
2
+
3
+ module Version
4
+
5
+ MAJOR = 0
6
+ MINOR = 1
7
+ TINY = 5
8
+
9
+ class << self
10
+
11
+ # Returns array representation.
12
+ def to_a
13
+ [MAJOR, MINOR, TINY]
14
+ end
15
+
16
+ # Short-cut for version string.
17
+ def to_s
18
+ to_a.join('.')
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ VERSION = Version.to_s
26
+
27
+ end