reap 4.5.2 → 5.0.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.
@@ -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
+
@@ -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
@@ -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
@@ -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 v#{Reap::Version}"
66
+ puts "Reap v#{Reap::Version}"
72
67
  exit 0
73
68
  end
74
69
 
75
70
  # display help
76
71
 
77
- def help(*args)
78
- unless args.empty?
79
- t = Reap.tasks[args[0]]
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
- #if Reap.projectfile?
99
- tasklist = []
100
- taskhash = {}
101
- Reap.tasks.each { |key,taskclass|
102
- taskhash[key] = taskclass #if taskclass.available?
103
- }
104
- if taskhash.empty?
105
- puts "No tasks available."
106
- else
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
- #else
118
- # puts "No project information file found."
119
- #end
120
- #exit 0
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.register
127
-
128
- Reap.tasks.each { |sym,taskclass|
129
- #if taskclass.available? #taskclass.section_required? or (taskclass.section_required? and pi)
130
- define_method(sym) { |*args|
131
- taskclass.new(*args).execute
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 v#{::Reap::Version}
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 action if no command
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
- is given, it will provide help information
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
- -v --version
170
- Display the current version.
171
-
172
- -V --verbose
173
- Provides extra verbose processing information.
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
@@ -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
- #def add_file( f )
79
- # INFO_FILES.unshift( f )
80
- #end
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, report=true )
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