blackwinter-hen 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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