reap 4.5.2 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ProjectInfo +34 -24
- data/Rakefile +5 -113
- data/{COPYING → doc/COPYING} +0 -0
- data/doc/ChangeLog +17 -0
- data/doc/LATEST +24 -4
- data/{README → doc/README} +17 -23
- data/doc/note/Rakefile.0 +118 -0
- data/doc/note/application.rb +124 -0
- data/doc/note/intro.txt +42 -0
- data/{package.rb → doc/note/package.rb} +0 -0
- data/lib/reap/app.rb +74 -0
- data/lib/reap/bin/reap.rb +40 -76
- data/lib/reap/projectinfo.rb +20 -52
- data/lib/reap/rake.rb +12 -0
- data/lib/reap/reap.rb +4 -1
- data/lib/reap/task.rb +51 -81
- data/lib/reap/task/announce.rb +1 -1
- data/lib/reap/task/custom.rb +12 -0
- data/lib/reap/task/doap.rb +2 -2
- data/lib/reap/task/extest.rb +1 -1
- data/lib/reap/task/fileperm.rb +1 -3
- data/lib/reap/task/info.rb +1 -1
- data/lib/reap/task/install.rb +3 -4
- data/lib/reap/task/manifest.rb +1 -3
- data/lib/reap/task/package.rb +10 -8
- data/lib/reap/task/publish.rb +1 -1
- data/lib/reap/task/rdoc.rb +3 -5
- data/lib/reap/task/release.rb +1 -1
- data/lib/reap/task/scaffold.rb +1 -1
- data/lib/reap/task/template.rb +3 -1
- data/lib/reap/task/test.rb +1 -3
- data/task/noop.rb +1 -2
- metadata +12 -6
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Reap
|
4
|
+
|
5
|
+
class Application
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@tasks = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
attr :tasks
|
12
|
+
attr_accessor :last_desc
|
13
|
+
|
14
|
+
def define_task( args, &block )
|
15
|
+
raise ArgumentError, "#{args.size} for 1" if Hash===args and args.size != 1
|
16
|
+
name, deps = parse_args( args )
|
17
|
+
new_task = Task.new( last_desc, deps, &block )
|
18
|
+
new_task.application = self
|
19
|
+
last_desc = nil
|
20
|
+
@tasks[name] = new_task
|
21
|
+
end
|
22
|
+
|
23
|
+
def attach_help( task, doc )
|
24
|
+
raise unless @tasks.has_key?(task.to_sym)
|
25
|
+
@tasks[task].help = doc
|
26
|
+
end
|
27
|
+
|
28
|
+
def run( task )
|
29
|
+
@tasks[task.to_sym].call
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def parse_args( args )
|
35
|
+
if Hash === args
|
36
|
+
raise ArgumentError, "#{args.size} for 1" if args.size != 1
|
37
|
+
name, deps = *(args.to_a.flatten)
|
38
|
+
name = name.to_sym
|
39
|
+
deps = [deps].compact.collect{ |e| e.to_sym }
|
40
|
+
else
|
41
|
+
name, deps = args.to_sym, []
|
42
|
+
end
|
43
|
+
return name, deps
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
class Task
|
50
|
+
|
51
|
+
def initialize( name, deps, &action )
|
52
|
+
@name = name
|
53
|
+
@dependencies = deps
|
54
|
+
@action = action
|
55
|
+
@complete = false
|
56
|
+
end
|
57
|
+
|
58
|
+
attr :dependencies
|
59
|
+
attr_accessor :help, :application
|
60
|
+
|
61
|
+
def complete?
|
62
|
+
@complete
|
63
|
+
end
|
64
|
+
|
65
|
+
def call
|
66
|
+
@dependencies.each{ |d|
|
67
|
+
application.tasks[d].call unless application.tasks[d].complete?
|
68
|
+
}
|
69
|
+
@action.call
|
70
|
+
@complete = true
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_proc
|
74
|
+
@action
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
module Reap
|
84
|
+
|
85
|
+
def application
|
86
|
+
@application ||= Reap::Application.new
|
87
|
+
end
|
88
|
+
|
89
|
+
def desc( line )
|
90
|
+
application.last_desc = line.gsub("\n",'')
|
91
|
+
end
|
92
|
+
|
93
|
+
def task( args, &block )
|
94
|
+
application.define_task( args, &block )
|
95
|
+
end
|
96
|
+
|
97
|
+
# Define help documentation for a task.
|
98
|
+
def help( task_name, doc )
|
99
|
+
application.attach_help( task_name, doc )
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
include Reap
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
desc "Milk the cow!"
|
111
|
+
task :milk do
|
112
|
+
puts "milk"
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Jump over the moon!"
|
116
|
+
task :jump => [ :milk, :milk ] do
|
117
|
+
#milk; milk
|
118
|
+
puts "jump"
|
119
|
+
end
|
120
|
+
|
121
|
+
task :package, Package
|
122
|
+
|
123
|
+
application.run( :jump )
|
124
|
+
|
data/doc/note/intro.txt
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
An Introduction to Reap
|
3
|
+
A Ruby Package Assitant
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
task :name do
|
8
|
+
|
9
|
+
when { projectfile? }
|
10
|
+
|
11
|
+
help <<-end
|
12
|
+
Help information.
|
13
|
+
end
|
14
|
+
|
15
|
+
run do |x|
|
16
|
+
# do the task
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
desc "This is a description"
|
25
|
+
|
26
|
+
task :name do |x|
|
27
|
+
# do the task
|
28
|
+
end
|
29
|
+
|
30
|
+
cont do
|
31
|
+
|
32
|
+
help <<-end
|
33
|
+
This is help text.
|
34
|
+
end
|
35
|
+
|
36
|
+
when do
|
37
|
+
projectfile?
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
File without changes
|
data/lib/reap/app.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
module Reap
|
3
|
+
|
4
|
+
def self.application
|
5
|
+
Application.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
class Application
|
9
|
+
|
10
|
+
def self.instance
|
11
|
+
@application ||= self.new
|
12
|
+
end
|
13
|
+
|
14
|
+
attr :tasks, :projectfile
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@tasks = {}
|
18
|
+
@projectfile = ProjectInfo.find
|
19
|
+
if @projectfile
|
20
|
+
@projectdir = File.dirname( @projectfile )
|
21
|
+
Dir.chdir( @projectdir )
|
22
|
+
end
|
23
|
+
require_custom_tasks
|
24
|
+
if @projectfile
|
25
|
+
require_custom_project_tasks
|
26
|
+
@projectinfo = ProjectInfo.load( @projectfile )
|
27
|
+
end
|
28
|
+
initialize_tasks
|
29
|
+
initialize_special_tasks
|
30
|
+
end
|
31
|
+
|
32
|
+
def projectfile?() @projectfile end
|
33
|
+
|
34
|
+
def add_task( task )
|
35
|
+
@tasks[task.task_name] = task
|
36
|
+
end
|
37
|
+
|
38
|
+
# Load custom tasks.
|
39
|
+
def require_custom_tasks
|
40
|
+
# Universal custom tasks for all projects.
|
41
|
+
dir = File.join( Config::CONFIG['datadir'], 'reap/task' )
|
42
|
+
require_all( File.join(dir, '*') ) if File.directory?(dir)
|
43
|
+
# Personal tasks for all projects.
|
44
|
+
dir = File.expand_path( '~/.share/reap/task' )
|
45
|
+
require_all( File.join(dir, '*') ) if File.directory?(dir)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Project specific tasks.
|
49
|
+
def require_custom_project_tasks
|
50
|
+
require_all('task/*') if File.directory?('task')
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize_tasks
|
54
|
+
return unless @projectinfo
|
55
|
+
@projectinfo.each { |key, value|
|
56
|
+
add_task( value ) if Reap::Task === value
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Load special tasks. There are tasks that don't require
|
61
|
+
# a ProjectInfo section or other special requirements.
|
62
|
+
def initialize_special_tasks
|
63
|
+
Reap.registry.each { |taskclass|
|
64
|
+
if taskclass.available?( self )
|
65
|
+
task = taskclass.new({})
|
66
|
+
task.task_name = taskclass.task_class
|
67
|
+
tasks[task.task_name] = task
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/reap/bin/reap.rb
CHANGED
@@ -6,11 +6,8 @@ require 'facets'
|
|
6
6
|
require 'consoleapp'
|
7
7
|
#require 'console/command'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
9
|
require 'reap/reap'
|
12
10
|
|
13
|
-
|
14
11
|
class ReapCommand < Console::Command
|
15
12
|
|
16
13
|
# to do first for every task
|
@@ -57,8 +54,6 @@ class ReapCommand < Console::Command
|
|
57
54
|
#def _f( pif ) ; $PROJECT_FILE = pif ; end
|
58
55
|
#alias_method :_f, :__file
|
59
56
|
|
60
|
-
# Commands
|
61
|
-
|
62
57
|
# default action
|
63
58
|
|
64
59
|
def default
|
@@ -68,15 +63,19 @@ class ReapCommand < Console::Command
|
|
68
63
|
# display version
|
69
64
|
|
70
65
|
def version
|
71
|
-
puts "Reap
|
66
|
+
puts "Reap v#{Reap::Version}"
|
72
67
|
exit 0
|
73
68
|
end
|
74
69
|
|
75
70
|
# display help
|
76
71
|
|
77
|
-
def help(
|
78
|
-
|
79
|
-
t = Reap.tasks[
|
72
|
+
def help(tsk=nil)
|
73
|
+
if tsk
|
74
|
+
t = Reap.application.tasks[tsk]
|
75
|
+
unless t
|
76
|
+
puts "Unknown task '#{tsk}'."
|
77
|
+
exit 0
|
78
|
+
end
|
80
79
|
s = "\n"
|
81
80
|
s << "#{args[0]}: "
|
82
81
|
s << t.task_desc.sub(/^\n+/, '').rstrip
|
@@ -95,93 +94,58 @@ class ReapCommand < Console::Command
|
|
95
94
|
# list available tasks
|
96
95
|
|
97
96
|
def tasks
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
sorted = taskhash.keys.sort
|
108
|
-
margin = sorted.collect{ |n| n.size }.max + 6
|
109
|
-
sorted.each do |name|
|
110
|
-
taskclass = taskhash[name]
|
111
|
-
tasklist << " #{name}".ljust(margin) + "#{taskclass.task_desc}"
|
112
|
-
end
|
113
|
-
puts
|
114
|
-
puts tasklist.join("\n")
|
115
|
-
puts
|
97
|
+
app = Reap.application
|
98
|
+
tasklist = []
|
99
|
+
if app.tasks.empty?
|
100
|
+
puts "No tasks available."
|
101
|
+
else
|
102
|
+
sorted = app.tasks.keys.sort
|
103
|
+
margin = sorted.collect{ |t| t.size }.max + 6
|
104
|
+
sorted.each do |name|
|
105
|
+
tasklist << " #{name}".ljust(margin) + "#{app.tasks[name].task_desc}"
|
116
106
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
107
|
+
puts "(#{Dir.pwd})"
|
108
|
+
puts
|
109
|
+
puts tasklist.join("\n")
|
110
|
+
puts
|
111
|
+
end
|
121
112
|
end
|
122
|
-
alias_method :ls, :tasks
|
113
|
+
#alias_method :ls, :tasks
|
123
114
|
|
124
115
|
# Add all the reap tasks.
|
125
116
|
|
126
|
-
Reap.
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
#end
|
134
|
-
}
|
117
|
+
app = Reap.application
|
118
|
+
app.tasks.each do |name, task|
|
119
|
+
define_method(name) { |*args|
|
120
|
+
#puts "(#{Dir.pwd})"
|
121
|
+
task.execute( *args )
|
122
|
+
}
|
123
|
+
end
|
135
124
|
|
136
125
|
end
|
137
126
|
|
138
127
|
|
139
128
|
HELP = <<-HERE
|
140
129
|
|
141
|
-
reap
|
142
|
-
|
143
|
-
USAGE: reap [options...] <command> [arguments...]
|
130
|
+
reap [options...] <command> [arguments...]
|
144
131
|
|
145
132
|
COMMANDS:
|
146
133
|
|
147
134
|
tasks
|
148
135
|
List all the current tasks with descriptions.
|
149
|
-
This is the default
|
150
|
-
is given. (Also aliased as 'ls'.)
|
136
|
+
(This is the default if no command is given.)
|
151
137
|
|
152
138
|
help [task]
|
153
|
-
Displays this help information. If a task name
|
154
|
-
|
155
|
-
specific to that task.
|
156
|
-
|
157
|
-
template
|
158
|
-
Copies a ProjectInfo template into the current
|
159
|
-
directory (if it does not already exist).
|
160
|
-
|
161
|
-
scaffold [type]
|
162
|
-
Builds a starter project in the current directory.
|
163
|
-
There are two types: 'standard' and 'subversion'.
|
164
|
-
These can be abbreviated 'std' and 'svn', repectively.
|
165
|
-
If no type is given then standard is used.
|
139
|
+
Displays this help information. If a task name is given,
|
140
|
+
it will provide help information specific to that task.
|
166
141
|
|
167
142
|
OPTIONS:
|
168
143
|
|
169
|
-
-
|
170
|
-
|
171
|
-
|
172
|
-
-
|
173
|
-
|
174
|
-
|
175
|
-
-f --force
|
176
|
-
Forces certain operations to be performed.
|
177
|
-
|
178
|
-
-D --debug
|
179
|
-
Provides extra verbose processing information.
|
180
|
-
|
181
|
-
-f --file
|
182
|
-
Specify alternate project file.
|
183
|
-
|
184
|
-
-h --help
|
185
|
-
Display this help information.
|
144
|
+
-h --help Display this help information.
|
145
|
+
-v --version Display the current version.
|
146
|
+
-V --verbose Provides extra verbose processing information.
|
147
|
+
-f --force Forces certain operations to be performed.
|
148
|
+
-D --debug Provides extra verbose processing information.
|
149
|
+
-f --file Specify alternate project file.
|
186
150
|
|
187
151
|
HERE
|
data/lib/reap/projectinfo.rb
CHANGED
@@ -9,21 +9,6 @@ require 'facet/kernel/require_all'
|
|
9
9
|
require 'facet/basicobject'
|
10
10
|
|
11
11
|
|
12
|
-
module Reap
|
13
|
-
|
14
|
-
def self.register #( alternative_project_file=nil )
|
15
|
-
pi = ProjectInfo.load( nil, true )
|
16
|
-
pi.require_custom_tasks if pi
|
17
|
-
pi
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.projectfile?
|
21
|
-
ProjectInfo.instance.info_file
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
12
|
# Project information, generally read from a file.
|
28
13
|
# Simply by calling 'ProjectInfo.load'.
|
29
14
|
#
|
@@ -49,20 +34,6 @@ class ProjectInfo
|
|
49
34
|
@instance ||= new( *args, &block )
|
50
35
|
end
|
51
36
|
|
52
|
-
# Load the project information from a file. Generally
|
53
|
-
# no file needs to be specified; the file will be found
|
54
|
-
# by ascending up the current path until a default
|
55
|
-
# file name is found (eg. ProjectInfo or Reapfile).
|
56
|
-
|
57
|
-
def load( fpath=nil, report=false )
|
58
|
-
if fpath
|
59
|
-
new.read( fpath, report )
|
60
|
-
else
|
61
|
-
fpath = find
|
62
|
-
instance.read( fpath, report )
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
37
|
# Find project information file.
|
67
38
|
|
68
39
|
def find
|
@@ -75,9 +46,14 @@ class ProjectInfo
|
|
75
46
|
return File.join( info_dir, info_file )
|
76
47
|
end
|
77
48
|
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
49
|
+
# Load the project information from a file. Generally
|
50
|
+
# no file needs to be specified; the file will be found
|
51
|
+
# by ascending up the current path until a default
|
52
|
+
# file name is found (eg. ProjectInfo or Reapfile).
|
53
|
+
|
54
|
+
def load( fpath=nil )
|
55
|
+
instance.read( fpath )
|
56
|
+
end
|
81
57
|
|
82
58
|
end
|
83
59
|
|
@@ -111,7 +87,7 @@ class ProjectInfo
|
|
111
87
|
|
112
88
|
# Load project information from YAML file.
|
113
89
|
|
114
|
-
def read( fpath
|
90
|
+
def read( fpath )
|
115
91
|
return unless fpath
|
116
92
|
|
117
93
|
@info_dir = File.dirname( fpath )
|
@@ -119,14 +95,15 @@ class ProjectInfo
|
|
119
95
|
@info_stream = File.read( fpath ).strip
|
120
96
|
@info = YAML::load( info_stream ).traverse{ |k,v| [k.to_s.downcase, v] }
|
121
97
|
|
122
|
-
Dir.chdir(@info_dir)
|
123
|
-
if report
|
124
|
-
puts "(in #{Dir.pwd})" #unless dir == Dir.pwd
|
125
|
-
end
|
126
|
-
|
127
98
|
#validate
|
128
99
|
defaults
|
129
100
|
|
101
|
+
@info.each do |key, value|
|
102
|
+
case value when Reap::Task
|
103
|
+
value.task_name = key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
130
107
|
self
|
131
108
|
end
|
132
109
|
|
@@ -177,19 +154,6 @@ class ProjectInfo
|
|
177
154
|
self['homepage'] ||= self['rubyforge'] ? self['rubyforge']['homepage'] : nil
|
178
155
|
end
|
179
156
|
|
180
|
-
# Load custom tasks.
|
181
|
-
|
182
|
-
def require_custom_tasks
|
183
|
-
# Universal custom tasks for all projects.
|
184
|
-
dir = File.join( Config::CONFIG['datadir'], 'reap/task' )
|
185
|
-
require_all( File.join(dir, '*') ) if File.directory?(dir)
|
186
|
-
# Personal tasks for all projects.
|
187
|
-
dir = File.expand_path( '~/.share/reap/task' )
|
188
|
-
require_all( File.join(dir, '*') ) if File.directory?(dir)
|
189
|
-
# Project specific tasks.
|
190
|
-
require_all('task/*') if File.directory?('task')
|
191
|
-
end
|
192
|
-
|
193
157
|
# Convert to a CascadinOpenObject.
|
194
158
|
|
195
159
|
def to_cascading_open_object
|
@@ -208,10 +172,14 @@ class ProjectInfo
|
|
208
172
|
info[name] = x
|
209
173
|
end
|
210
174
|
|
175
|
+
def each( &block )
|
176
|
+
@info.each( &block )
|
177
|
+
end
|
178
|
+
|
211
179
|
# Information to hash.
|
212
180
|
|
213
181
|
def to_h
|
214
|
-
@info
|
182
|
+
@info.dup
|
215
183
|
end
|
216
184
|
|
217
185
|
end
|