reap 6.0.2 → 9.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/CHANGES +6 -0
  2. data/COPYING +666 -395
  3. data/MANIFEST +139 -0
  4. data/NOTES +12 -0
  5. data/README +19 -163
  6. data/bin/reap-announce +7 -0
  7. data/bin/reap-check-load +8 -0
  8. data/bin/reap-check-syntax +7 -0
  9. data/bin/reap-clean +7 -0
  10. data/bin/reap-clobber +7 -0
  11. data/bin/reap-doc +7 -0
  12. data/bin/reap-doc-rdoc +7 -0
  13. data/bin/reap-doc-ri +7 -0
  14. data/bin/reap-init +69 -0
  15. data/bin/reap-inspect +7 -0
  16. data/bin/reap-install +8 -0
  17. data/bin/reap-install-gem +8 -0
  18. data/bin/reap-log +7 -0
  19. data/bin/reap-log-changes +8 -0
  20. data/bin/reap-log-notes +8 -0
  21. data/bin/reap-make +7 -0
  22. data/bin/reap-make-clean +7 -0
  23. data/bin/reap-make-distclean +7 -0
  24. data/bin/reap-make-extconf +7 -0
  25. data/bin/reap-make-static +8 -0
  26. data/bin/reap-package +8 -0
  27. data/bin/reap-package-gem +7 -0
  28. data/bin/reap-package-tgz +7 -0
  29. data/bin/reap-package-zip +7 -0
  30. data/bin/reap-prepare +7 -0
  31. data/bin/reap-publish +7 -0
  32. data/bin/reap-release +7 -0
  33. data/bin/reap-scaffold +8 -0
  34. data/bin/reap-scm-branch +7 -0
  35. data/bin/reap-scm-tag +7 -0
  36. data/bin/reap-spec +7 -0
  37. data/bin/reap-spec-doc +8 -0
  38. data/bin/reap-stamp +7 -0
  39. data/bin/reap-stats +7 -0
  40. data/bin/reap-test +7 -0
  41. data/bin/reap-test-cross +7 -0
  42. data/bin/reap-test-load +9 -0
  43. data/bin/reap-test-solo +7 -0
  44. data/bin/reap-uninstall +7 -0
  45. data/bin/reap-uninstall-gem +7 -0
  46. data/data/reap/base/CHANGES +19 -0
  47. data/data/reap/base/COPYING +674 -0
  48. data/data/reap/base/NOTES +12 -0
  49. data/data/reap/base/README +8 -0
  50. data/data/reap/build/rake/Rakefile +130 -0
  51. data/{forge/reference/installers → data/reap/build/rake}/setup.rb +155 -97
  52. data/data/reap/build/rake-lite/install.rb +79 -0
  53. data/data/reap/build/tasks/task/rdoc +211 -0
  54. data/data/reap/{setup.rb → build/tasks/task/setup} +248 -200
  55. data/data/reap/build/tasks/task/test +38 -0
  56. data/data/reap/init/meta/project.yaml +21 -0
  57. data/demo/README +15 -0
  58. data/demo/lib/foo/foo.rb +7 -0
  59. data/demo/meta/VERSION +1 -0
  60. data/demo/meta/project.yaml +21 -0
  61. data/lib/reap/application.rb +80 -0
  62. data/lib/reap/default.yaml +77 -0
  63. data/lib/reap/extensions/array.rb +50 -0
  64. data/lib/reap/extensions/hash.rb +63 -0
  65. data/lib/reap/extensions/string.rb +31 -0
  66. data/lib/reap/extensions.rb +6 -0
  67. data/lib/reap/iobject.rb +264 -0
  68. data/lib/reap/manager/announce.rb +193 -0
  69. data/lib/reap/manager/check.rb +109 -0
  70. data/lib/reap/manager/clean.rb +58 -0
  71. data/lib/reap/manager/gem.rb +200 -0
  72. data/lib/reap/manager/html.rb +69 -0
  73. data/lib/reap/manager/log.rb +214 -0
  74. data/lib/reap/manager/make.rb +109 -0
  75. data/lib/reap/manager/pack.rb +232 -0
  76. data/lib/reap/manager/publish.rb +72 -0
  77. data/lib/reap/manager/rdoc.rb +194 -0
  78. data/lib/reap/manager/release.rb +78 -0
  79. data/lib/reap/manager/rubyforge.rb +44 -0
  80. data/lib/reap/manager/scaffold.rb +138 -0
  81. data/lib/reap/manager/scm.rb +66 -0
  82. data/lib/reap/manager/site.rb +27 -0
  83. data/lib/reap/manager/spec.rb +94 -0
  84. data/lib/reap/manager/stats.rb +145 -0
  85. data/lib/reap/manager/svn.rb +76 -0
  86. data/lib/reap/manager/test.rb +389 -0
  87. data/lib/reap/manager.rb +74 -0
  88. data/lib/reap/metadata.rb +603 -0
  89. data/lib/reap/project.rb +165 -0
  90. data/lib/reap/settings.rb +67 -0
  91. data/lib/reap/systems/rubyforge.rb +737 -0
  92. data/lib/reap/systems/subversion.rb +333 -0
  93. data/lib/reap/utilities/fileutils.rb +304 -0
  94. data/lib/reap/utilities/netutils.rb +221 -0
  95. data/lib/reap/utilities/setuputils.rb +124 -0
  96. data/lib/reap/utilities/shellutils.rb +175 -0
  97. data/log/Changelog.txt +107 -0
  98. data/log/FIXME.txt +25 -0
  99. data/log/TODO.txt +72 -0
  100. data/meta/VERSION +1 -0
  101. data/meta/description +4 -0
  102. data/meta/project.yaml +20 -0
  103. data/task/man +14 -0
  104. data/task/rdoc +20 -0
  105. data/{data/reap/scaffold/standard/setup.rb → task/setup} +248 -200
  106. metadata +225 -153
  107. data/ProjectInfo +0 -105
  108. data/bin/reap +0 -5
  109. data/bin/rubytest +0 -5
  110. data/data/reap/install.rb +0 -62
  111. data/data/reap/scaffold/standard/COPYING +0 -403
  112. data/data/reap/scaffold/standard/ChangeLog +0 -0
  113. data/data/reap/scaffold/standard/INSTALL +0 -14
  114. data/data/reap/scaffold/standard/ProjectInfo +0 -77
  115. data/data/reap/scaffold/standard/README +0 -3
  116. data/data/reap/scaffold/standard/Rakefile +0 -10
  117. data/data/reap/scaffold/standard/TODO +0 -0
  118. data/data/reap/scaffold/subversion/trunk/COPYING +0 -403
  119. data/data/reap/scaffold/subversion/trunk/ChangeLog +0 -0
  120. data/data/reap/scaffold/subversion/trunk/INSTALL +0 -14
  121. data/data/reap/scaffold/subversion/trunk/ProjectInfo +0 -76
  122. data/data/reap/scaffold/subversion/trunk/README +0 -3
  123. data/data/reap/scaffold/subversion/trunk/Rakefile +0 -10
  124. data/data/reap/scaffold/subversion/trunk/TODO +0 -0
  125. data/data/reap/scaffold/subversion/trunk/setup.rb +0 -1568
  126. data/forge/ProjectInfo +0 -38
  127. data/forge/ProjectInfo.rb +0 -76
  128. data/forge/TODO +0 -10
  129. data/forge/installer.rb +0 -250
  130. data/forge/reference/Rakefile +0 -124
  131. data/forge/reference/Rakefile.htm +0 -69
  132. data/forge/reference/aRakefile +0 -60
  133. data/forge/reference/compositepublisher.rb +0 -24
  134. data/forge/reference/ftptools.rb +0 -139
  135. data/forge/reference/installers/package.rb +0 -629
  136. data/forge/reference/license-each.rb +0 -85
  137. data/forge/reference/publisher.rb +0 -75
  138. data/forge/reference/rubyforge.rb +0 -247
  139. data/forge/reference/rubyforgepublisher.rb +0 -18
  140. data/forge/reference/sshpublisher.rb +0 -47
  141. data/forge/reference/suby-cvs.rb +0 -46
  142. data/forge/scaffold.rb +0 -126
  143. data/forge/unit_runner/README +0 -6
  144. data/forge/unit_runner/commentrunner.rb +0 -62
  145. data/forge/unit_runner/cunit.rb +0 -17
  146. data/forge/unit_runner/forkedrunner.rb +0 -91
  147. data/forge/unit_runner/sample.rb +0 -16
  148. data/lib/reap/bin/reap.rb +0 -230
  149. data/lib/reap/bin/rubytest.rb +0 -53
  150. data/lib/reap/class/announce.rb +0 -220
  151. data/lib/reap/class/doap.rb +0 -80
  152. data/lib/reap/class/extest.rb +0 -146
  153. data/lib/reap/class/filer.rb +0 -62
  154. data/lib/reap/class/manifest.rb +0 -68
  155. data/lib/reap/class/package.rb +0 -576
  156. data/lib/reap/class/publish.rb +0 -152
  157. data/lib/reap/class/rdoc.rb +0 -123
  158. data/lib/reap/class/test.rb +0 -264
  159. data/lib/reap/projectinfo.rb +0 -208
  160. data/lib/reap/rake.rb +0 -42
  161. data/lib/reap/reap.rb +0 -89
  162. data/lib/reap/tasks.rb +0 -756
  163. data/lib/reap/taskutils.rb +0 -122
  164. data/note/LATEST +0 -44
  165. data/note/doap.xml +0 -28
  166. data/note/history/Rakefile-0.1 +0 -308
  167. data/sample/ProjectInfo +0 -96
  168. data/sample/Rakefile +0 -9
  169. data/sample/Reapfile +0 -11
  170. data/sample/task/demo.rb +0 -15
  171. data/setup.rb +0 -1568
  172. data/web/ProjectInfo.html +0 -75
  173. data/web/images/grape.jpg +0 -0
  174. data/web/index.html +0 -312
@@ -0,0 +1,193 @@
1
+ module Reap
2
+
3
+ class Manager
4
+
5
+ # Make a release announcement. Generates and can email release
6
+ # announcements. The announcement if built from the README file
7
+ # unless another file is specified.
8
+ #
9
+ # This will subsititue the first line mathing /please see notes/i
10
+ # for the notelog. And /please see change/i for the changelog.
11
+ #
12
+ # The following settings apply:
13
+ #
14
+ # title Project title.
15
+ # subtitle Brief one-line description.
16
+ # version Project version.
17
+ # description Long description of project.
18
+ # homepage Project homepage web address.
19
+ # slogan Motto for you project.
20
+ # memo File that contains announcement message.
21
+ # template Announcement template file, rather then README.
22
+ # mail_to Email address(es) to send announcemnt.
23
+ #
24
+ # If <em>mail_to</em> is set then these also apply:
25
+ #
26
+ # from Message FROM address [email].
27
+ # subject Subject of email message ([ANN] title verison).
28
+ # server Email server to route message.
29
+ # port Email server's port.
30
+ # domain Email server's domain name.
31
+ # account Email account name [email].
32
+ # login Login type: plain, cram_md5 or login.
33
+ # secure Uses TLS security, true or false?
34
+ #
35
+ # A template file can be specified that uses "$setting" as
36
+ # substitutes for poject information.
37
+
38
+ def announce(options=nil)
39
+ options = configure_options(options, 'announce', 'mail')
40
+
41
+ message = announce_message(options)
42
+
43
+ options = options.to_ostruct
44
+
45
+ mail_to = options.mail_to
46
+ mail_from = options.mail_from
47
+ subject = options.subject # Subject line (default is "ANN: project version").
48
+ server = options.server # Email server
49
+ port = options.port # Emails server port (default is usually correct).
50
+ account = options.account # Email account name (defaults to mail_from).
51
+ domain = options.domain # User domain (not sure why SMTP requires this?)
52
+ login = options.login # Login type (plain, login)
53
+ secure = options.secure # Use TLS/SSL true or false?
54
+ password = options.password || ENV['EMAIL_PASSWORD']
55
+
56
+ title = options.title || metadata.title
57
+ version = options.versoin || metadata.version
58
+
59
+ # defaults
60
+ subject ||= "ANN: #{title}, v#{version}"
61
+ account ||= mail_from
62
+
63
+ subject = subject % [title, version]
64
+
65
+ puts "\n#{message}\n\n"
66
+
67
+ if mail_to and !dryrun?
68
+ ans = ask("Would you like to email this announcement?", "yN")
69
+ case ans.downcase
70
+ when 'y', 'yes'
71
+ email(message,
72
+ :to => mail_to,
73
+ :from => mail_from,
74
+ :subject => subject,
75
+ :server => server,
76
+ :port => port,
77
+ :domain => domain,
78
+ :account => account,
79
+ :login => login,
80
+ :secure => secure,
81
+ :password => password
82
+ )
83
+ end
84
+ end
85
+ end
86
+
87
+ # Make a release announcement. Generates and can email a release
88
+ # announcements. These are nicely formated message and can
89
+ # email the message to the specified address(es).
90
+ #
91
+ # The following settings apply:
92
+ #
93
+ # template Announcement file/template.
94
+ # cutoff Max number of lines of changelog to show.
95
+ #
96
+ # A template file can be specified that uses "$setting" as
97
+ # substitutes for poject information.
98
+
99
+ def announce_message(options={})
100
+ config = settings['announce'] || {}
101
+ options = config.merge(options).to_ostruct
102
+
103
+ cutoff = options.cutoff || 30
104
+ template = options.template || "{ANNOUNCE,README}{,.txt}"
105
+
106
+ #config['mail_to'] = nil if keys['mail_to'].empty?
107
+
108
+ # Build message
109
+
110
+ # template
111
+ template = Dir.glob(options.template.to_s, File::FNM_CASEFOLD).first
112
+ abort "No announcememnt template." unless template
113
+
114
+ #
115
+ readme = File.read(template)
116
+ readme = unfold_paragraphs(readme)
117
+
118
+ # changelog
119
+ file = Dir.glob('change{s,log}{,.txt}', File::FNM_CASEFOLD)[0]
120
+ changelog = file ? File.read(file).strip : ''
121
+ #changelog = unfold_paragraphs(changelog)
122
+ changelog = changelog.split("\n")[0..cutoff].join("\n")
123
+
124
+ # noteslog
125
+ file = Dir.glob('note{s,log}{,.txt}', File::FNM_CASEFOLD)[0]
126
+ notelog = file ? File.read(file).strip : ''
127
+ notelog = unfold_paragraphs(notelog)
128
+
129
+ # Strip tiny version zero.
130
+ #if keys['version'] =~ /[.].*?[.]/
131
+ # keys['version'] = keys['version'].chomp('.0')
132
+ #end
133
+
134
+ # Make announcement message
135
+ message = readme.dup
136
+
137
+ #message.gsub!('$readme$', readme || '')
138
+ message.sub!(/^\s*please\ see(\ the)?\ notes(.*?)$/i, "\n" + notelog) if notelog
139
+ message.sub!(/^\s*please\ see(\ the)?\ change(.*?)$/i, "\n" + changelog) if changelog
140
+
141
+ template = message.dup
142
+
143
+ template.scan(/[$](.*?)[$]/m) do |key|
144
+ #key = key.strip
145
+ name = $1.strip #key[1..-1]
146
+ if metadata.respond_to?(name.downcase)
147
+ value = metadata.send(name.downcase)
148
+ message.gsub!("$#{name}$", value.to_s.strip)
149
+ else
150
+ puts "Warning: Unknown project field -- #{name}."
151
+ end
152
+ end
153
+
154
+ message.gsub!(/(^|[ ])[$].*?(?=[ ]|$)/,'') # remove unused vars
155
+ message.gsub!(/\n\s*\n\s*\n/m,"\n\n") # remove any triple blank lines
156
+ message.rstrip!
157
+
158
+ return message
159
+ end
160
+
161
+ def unfold_paragraphs(string)
162
+ blank = false
163
+ text = ''
164
+ string.split(/\n/).each do |line|
165
+ if /\S/ !~ line
166
+ text << "\n\n"
167
+ blank = true
168
+ else
169
+ if /^(\s+|[*])/ =~ line
170
+ text << (line.rstrip + "\n")
171
+ else
172
+ text << (line.rstrip + " ")
173
+ end
174
+ blank = false
175
+ end
176
+ end
177
+ return text
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ # keys = {}
185
+ # keys['from'] = info.email
186
+ # keys.update info.gather('mail')
187
+ # keys.update info.gather('announce')
188
+ # keys.update info.select(
189
+ # :project, :version, :title, :subtitle, :description,
190
+ # :homepage, :download, :slogan
191
+ # )
192
+ # keys.update override if override
193
+
@@ -0,0 +1,109 @@
1
+ module Reap
2
+
3
+ class Manager
4
+
5
+ # Verify syntax of ruby scripts.
6
+ #
7
+ # This takes one option +:scripts+ which is a glob or list of globs
8
+ # of the scripts to check. By default this is all scripts in the libpath(s).
9
+
10
+ def check_syntax(options=nil)
11
+ options = configure_options(options, 'check-syntax', 'check')
12
+
13
+ libpath = options['loadpath'] || metadata.loadpath
14
+ exclude = options['exclude']
15
+
16
+ #libpath = libpath.split(/[:;]/) unless Array===libpath
17
+ libpath = list_option(libpath)
18
+ exclude = list_option(exclude)
19
+
20
+ files = multiglob_r(*libpath) - multiglob_r(exclude)
21
+ files = files.select{ |f| File.extname(f) == '.rb' }
22
+ max = files.collect{ |f| f.size }.max
23
+ list = []
24
+
25
+ files.each do |s|
26
+ next unless File.file?(s)
27
+ #if not system "ruby -c -Ibin:lib:test #{s} &> /dev/null" then
28
+ r = system "ruby -c -I#{libpath} #{s} > /dev/null 2>&1"
29
+ if r
30
+ puts("%-#{max}s [PASS]" % [s]) #if verbose?
31
+ else
32
+ puts("%-#{max}s [FAIL]" % [s]) #if verbose?
33
+ list << s #:syntax
34
+ end
35
+ end
36
+
37
+ puts " #{list.size} Syntax Errors"
38
+
39
+ if verbose?
40
+ unless list.empty?
41
+ puts "\n-- Syntax Errors --\n"
42
+ list.each do |f|
43
+ print "* "
44
+ system "ruby -c -I#{libpath} #{f} 2>&1"
45
+ #puts
46
+ end
47
+ puts
48
+ end
49
+ end
50
+ end
51
+
52
+ # Load each script independently to ensure there are no
53
+ # require dependency issues.
54
+ #
55
+ # WARNING! You should only run this on scripts that have no
56
+ # toplevel side-effects!!!
57
+ #
58
+ # This takes one option +:scripts+ which is a glob or list of globs
59
+ # of the scripts to check. By default this is all scripts in the libpath(s).
60
+ #
61
+ # FIXME: This isn't routing output to dev/null as expected.
62
+
63
+ def check_load(options=nil)
64
+ options = configure_options(options, 'check-load', 'check')
65
+
66
+ make if compiles?
67
+
68
+ libpath = options['libpath'] || metadata.libpath
69
+ exclude = options['exclude']
70
+
71
+ libpath = list_option(libpath)
72
+ exclude = list_option(exclude)
73
+
74
+ files = multiglob_r(*libpath) - multiglob_r(exclude)
75
+ files = files.select{ |f| File.extname(f) == '.rb' }
76
+ max = files.collect{ |f| f.size }.max
77
+ list = []
78
+
79
+ files.each do |s|
80
+ next unless File.file?(s)
81
+ #if not system "ruby -c -Ibin:lib:test #{s} &> /dev/null" then
82
+ cmd = "ruby -I#{libpath.join(':')} #{s} > /dev/null 2>&1"
83
+ puts cmd if debug?
84
+ if r = system(cmd)
85
+ puts "%-#{max}s [PASS]" % [s]
86
+ else
87
+ puts "%-#{max}s [FAIL]" % [s]
88
+ list << s #:load
89
+ end
90
+ end
91
+
92
+ puts " #{list.size} Load Failures"
93
+
94
+ if verbose?
95
+ unless list.empty?
96
+ puts "\n-- Load Failures --\n"
97
+ list.each do |f|
98
+ print "* "
99
+ system "ruby -I#{libpath} #{f} 2>&1"
100
+ #puts
101
+ end
102
+ puts
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,58 @@
1
+ module Reap
2
+
3
+ class Manager
4
+
5
+ # Clean scrap products. All directory paths and or file globs
6
+ # listed under the clean configuration entry, can be removed via
7
+ # this method. By default all files ending with "~" or .back
8
+ # are removed. To specifcy an alternate provide a list of files
9
+ # and/or glibs under +remove:+ sub-entry. You can also provide
10
+ # an +exclude:+ sub-entry to isolate files not to be removed.
11
+ # For example, on might do:
12
+ #
13
+ # clean:
14
+ # remove [ '**/*~', '**/*.bak', '.config' ]
15
+ #
16
+ # Clean is run as a prerequiste to #release via #prepare.
17
+
18
+ def clean(options=nil)
19
+ options = configure_options(options, 'clean')
20
+
21
+ remove = options['remove']
22
+ exclude = options['exclude']
23
+
24
+ remove = list_option(remove)
25
+ exclude = list_option(exclude)
26
+
27
+ files = multiglob_r(*remove) - multiglob_r(exclude)
28
+
29
+ return if files.empty?
30
+
31
+ puts files.join("\n")
32
+
33
+ if verbose?
34
+ ans = ask("Remove files?", "yN").downcase
35
+ return unless ans == 'y' or ans == 'yes'
36
+ end
37
+
38
+ files.each do |f|
39
+ rm(f) if File.exist?(f)
40
+ end
41
+ end
42
+
43
+ # Run all clobber methods. This method literally looks for all other
44
+ # methods starting with the phrase "clobber_" and calls them, then
45
+ # runs #clean as well.
46
+
47
+ def clobber(options=nil)
48
+ clobber_methods = methods.select{ |m| m.to_s =~ /^clobber_/ }
49
+ clobber_methods.each do |m|
50
+ send(m)
51
+ end
52
+ clean
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,200 @@
1
+ module Reap
2
+
3
+ class Manager
4
+
5
+ # Remove gem package products.
6
+
7
+ def gem_clobber(options=nil)
8
+ store = "pkg"
9
+
10
+ packages = glob(File.join(store, '*.gem'))
11
+
12
+ packages.each do |path|
13
+ File.directory?(path) ? rm_r(path) : rm(path)
14
+ end
15
+ end
16
+
17
+ # Create a Gem package.
18
+ #
19
+ # TODO: Should this use staging too, like zip/tgz?
20
+
21
+ def gem_package(options=nil)
22
+ begin
23
+ require 'rubygems/specification'
24
+ Gem::manage_gems
25
+ rescue LoadError
26
+ #raise LoadError, "RubyGems is not installed?"
27
+ end
28
+
29
+ status "Creating .gem package"
30
+
31
+ options = configure_options(options, 'package-gem', 'package')
32
+
33
+ package = metadata.clone
34
+ package.update(options)
35
+
36
+ abort "No name" unless package.name
37
+ abort "No version" unless package.version
38
+
39
+ store = 'pkg' #package.package_directory
40
+ fname = package.stage_name
41
+ files = package.filelist
42
+
43
+ stage = File.join(store, fname)
44
+ pfile = stage + ".gem"
45
+
46
+ unless out_of_date?(pfile, *files) or force?
47
+ report_package_already_built(pfile)
48
+ return
49
+ end
50
+
51
+ rm_r(stage) if File.exist?(stage) # remove old stage
52
+ stage(stage, files) # make new stage
53
+ package_manifest(stage) # generate manifest
54
+
55
+ if dryrun?
56
+ status "gem build #{stage}"
57
+ else
58
+ file = nil
59
+ cd(stage) do
60
+ #status "vi #{metadata.name}.gemspec"
61
+ builder = ::Gem::Builder.new(gemspec(package))
62
+ status "gem build #{stage}"
63
+ unless dryrun?
64
+ file = builder.build
65
+ file = File.expand_path(file)
66
+ end
67
+ end
68
+ # transfer gem package to package store
69
+ mkdir_p(store)
70
+ destination = File.join(store, File.basename(file))
71
+ mv(file, store) unless File.expand_path(file) == File.expand_path(destination)
72
+ end
73
+
74
+ return destination
75
+ end
76
+
77
+ # Install gem package, creating the package if not already created.
78
+ #
79
+ # TODO: Endure that we even need a gem package using #out_of_date?
80
+
81
+ def gem_install(options=nil)
82
+ file = gem_package(options)
83
+ sh "gem install #{file}"
84
+ end
85
+
86
+ # Uninstall gem package.
87
+ #
88
+ # TODO: Sepcify version?
89
+
90
+ def gem_uninstall
91
+ i = metadata.package_name.rindex('-')
92
+ name, version = metadata.package_name[0...i], metadata.package_name[i+1..-1]
93
+ sh "gem uninstall #{name} -v #{version}"
94
+ end
95
+
96
+ private
97
+
98
+ # Create Gem::Specification.
99
+
100
+ def gemspec(package)
101
+ distribute = package.filelist
102
+ #distribute = Dir.multiglob_with_default( '**/*', distribute )
103
+
104
+ # I don't quite get how Rubygems deals with authors. It turns a singel value into an array. Why?
105
+ #author = [package.author, package.contact].flatten.compact.first
106
+
107
+ if md = /(\w+).rubyforge.org/.match(package.homepage)
108
+ rubyforge_project = md[1]
109
+ else
110
+ rubyforge_project = package.project # b/c it has to be something according to Eric Hodel.
111
+ end
112
+
113
+ ::Gem::Specification.new do |spec|
114
+ spec.name = package.package
115
+ spec.version = package.version
116
+ spec.summary = package.brief
117
+ spec.description = package.description
118
+ spec.author = package.contact
119
+ spec.email = package.email
120
+ spec.rubyforge_project = rubyforge_project
121
+ spec.homepage = package.homepage
122
+
123
+ # Platform: ruby, mswin32, i586-linux, powerpc-darwin, current
124
+ spec.platform = 'ruby' # TODO current support!
125
+
126
+ spec.require_paths = [package.gem_path].flatten.reverse
127
+
128
+ #if package.platform != 'ruby'
129
+ # spec.require_paths.concat(spec.require_paths.collect{ |d| File.join(d, platform) })
130
+ #end
131
+
132
+ spec.bindir = "bin"
133
+ spec.executables = package.executables
134
+ spec.requirements = package.requirements
135
+ spec.has_rdoc = !(FalseClass===package.document)
136
+
137
+ if package.dependencies
138
+ package.dependencies.each do |d,v|
139
+ spec.add_dependency(*[d,v].compact)
140
+ end
141
+ end
142
+
143
+ spec.extensions = package.compile
144
+
145
+ spec.files = distribute
146
+
147
+ spec.test_files = distribute.select{ |f| f =~ /^test\// } # TODO make test_files configurable
148
+ end
149
+ end
150
+
151
+ # Report that a package has been built.
152
+ # FIXME
153
+
154
+ def report_package_built(type, file)
155
+ r = ''
156
+ r << "\n Successfully built #{type}"
157
+ r << "\n Name: #{package.name}"
158
+ r << "\n Version: #{package.version}"
159
+ r << "\n File: #{File.basename(file)}"
160
+ say r
161
+ end
162
+
163
+ end
164
+ end
165
+
166
+ # # Build packages.
167
+ # # TODO Move this to Manager ?
168
+ #
169
+ # def generate_packages
170
+ # package_files = formats.collect do |format|
171
+ # #format = clean_type(format)
172
+ # say '' if format == 'gem' # FIXME This is here b/c Gems outputs on it's own.
173
+ # file = create_package(format)
174
+ # unless dryrun? or (format == 'gem')
175
+ # report_package_built(format, file) if file
176
+ # end
177
+ # file
178
+ # end
179
+ # report_packaging_complete(package_files.size)
180
+ # end
181
+ #
182
+ # # Create package.
183
+ #
184
+ # def create_package(type)
185
+ # package.format = type
186
+ #
187
+ # builder_class = FormatBuilder.registry[type]
188
+ # builder = builder_class.new(package, stage_directory, options)
189
+ # file = builder.build
190
+ #
191
+ # transfer(file) unless dryrun?
192
+ #
193
+ # return file
194
+ # end
195
+ #
196
+ # # Report that packaging is complete.
197
+ #
198
+ # def report_packaging_complete(size)
199
+ # say "\nSuccessfully built #{size} packages at #{store}/."
200
+ # end
@@ -0,0 +1,69 @@
1
+ module Reap
2
+
3
+ class Manager
4
+
5
+ # Create web index.html from README. (Not yet used)
6
+
7
+ def html
8
+ require 'rdoc/markup/simple_markup'
9
+ require 'rdoc/markup/simple_markup/to_html'
10
+
11
+ options = configure_options(options, 'html')
12
+
13
+ output = options['output']
14
+ files = options['files']
15
+ style = options['css']
16
+
17
+ output ||= 'doc'
18
+ files ||= '[A-Z]*'
19
+ style ||= Dir.glob('*.css').first
20
+
21
+ files = Dir.glob(files)
22
+
23
+ s = SM::SimpleMarkup.new
24
+ h = SM::ToHtml.new
25
+
26
+ files.each do |file|
27
+ unless File.exist?(file)
28
+ puts "Warning: file does not exist -- #{file}"
29
+ end
30
+ end
31
+
32
+ mkdir_p(output) unless dryrun?
33
+
34
+ files.each do |file|
35
+ name = file.downcase.chomp('.txt')
36
+ if /^readme/ =~ name
37
+ name = "index"
38
+ end
39
+ path = File.join(output, name + '.html')
40
+
41
+ if dryrun?
42
+ puts "[DRYRUN] Create #{path}"
43
+ else
44
+ next unless out_of_date?(path, file)
45
+
46
+ title = "#{package.title} #{name.upcase}"
47
+
48
+ input = File.read(file)
49
+ output = s.convert(input, h)
50
+
51
+ File.open(path, 'w') do |f|
52
+ f << %{<html>}
53
+ f << %{<head>}
54
+ f << %{ <title>#{title}<title>}
55
+ f << %{ <link rel="stylesheet" TYPE="text/css" HREF="#{style}">} if style
56
+ f << %{</head>}
57
+ f << %{<body>}
58
+ f << output
59
+ f << %{</body>}
60
+ f << %{</html>}
61
+ end
62
+ puts "Created #{path}"
63
+ end
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end