roo 1.3.11 → 1.9.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.
- data/History.txt +15 -6
- data/Manifest.txt +53 -0
- data/README.txt +97 -0
- data/Rakefile +45 -0
- data/bin/roo +8 -0
- data/lib/roo.rb +55 -9
- data/lib/roo/excel.rb +44 -40
- data/lib/roo/excelx.rb +99 -60
- data/lib/roo/generic_spreadsheet.rb +29 -1
- data/lib/roo/google.rb +71 -117
- data/lib/roo/openoffice.rb +79 -27
- data/lib/roo/version.rb +9 -9
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/1900_base.xls +0 -0
- data/test/1904_base.xls +0 -0
- data/test/Bibelbund.csv +0 -0
- data/test/bode-v1.ods.zip +0 -0
- data/test/bode-v1.xls.zip +0 -0
- data/test/boolean.xls +0 -0
- data/test/datetime.xls +0 -0
- data/test/named_cells.ods +0 -0
- data/test/numbers1.csv +0 -0
- data/test/{bad_excel_date.xls → prova.xls} +0 -0
- data/test/test_helper.rb +1 -1
- data/test/test_roo.rb +365 -256
- data/test/whitespace.xls +0 -0
- metadata +48 -30
- data/README.markdown +0 -55
- data/examples/roo_soap_client.rb +0 -53
- data/examples/roo_soap_server.rb +0 -29
- data/examples/write_me.rb +0 -33
- data/test/formula_parse_error.xls +0 -0
- data/test/skipped_tests.rb +0 -789
data/lib/roo/openoffice.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'zip/zipfilesystem'
|
4
4
|
require 'date'
|
5
5
|
require 'base64'
|
6
|
-
require '
|
6
|
+
require 'nokogiri'
|
7
7
|
|
8
8
|
class Openoffice < GenericSpreadsheet
|
9
9
|
|
@@ -36,7 +36,8 @@ class Openoffice < GenericSpreadsheet
|
|
36
36
|
@file_nr = @@nr
|
37
37
|
extract_content
|
38
38
|
file = File.new(File.join(@tmpdir, @file_nr.to_s+"_roo_content.xml"))
|
39
|
-
@doc = XML::Parser.io(file).parse
|
39
|
+
#TODO: @doc = XML::Parser.io(file).parse
|
40
|
+
@doc = Nokogiri::XML(file)
|
40
41
|
file.close
|
41
42
|
ensure
|
42
43
|
#if ENV["roo_local"] != "thomas-p"
|
@@ -55,6 +56,7 @@ class Openoffice < GenericSpreadsheet
|
|
55
56
|
@style_defaults = Hash.new { |h,k| h[k] = [] }
|
56
57
|
@style_definitions = Hash.new
|
57
58
|
@header_line = 1
|
59
|
+
@labels = {}
|
58
60
|
end
|
59
61
|
|
60
62
|
# creates a new empty openoffice-spreadsheet file
|
@@ -78,7 +80,8 @@ class Openoffice < GenericSpreadsheet
|
|
78
80
|
read_cells(sheet) unless @cells_read[sheet]
|
79
81
|
row,col = normalize(row,col)
|
80
82
|
if celltype(row,col,sheet) == :date
|
81
|
-
yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
83
|
+
#TODO: yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
|
84
|
+
yyyy,mm,dd = @cell[sheet][[row,col]].to_s.split('-')
|
82
85
|
return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
|
83
86
|
end
|
84
87
|
@cell[sheet][[row,col]]
|
@@ -170,8 +173,10 @@ class Openoffice < GenericSpreadsheet
|
|
170
173
|
|
171
174
|
def sheets
|
172
175
|
return_sheets = []
|
173
|
-
@doc.find("//*[local-name()='table']").each do |sheet|
|
174
|
-
|
176
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |sheet|
|
177
|
+
@doc.xpath("//*[local-name()='table']").each do |sheet|
|
178
|
+
#TODO: return_sheets << sheet.attributes['name']
|
179
|
+
return_sheets << sheet['name']
|
175
180
|
end
|
176
181
|
return_sheets
|
177
182
|
end
|
@@ -213,12 +218,29 @@ class Openoffice < GenericSpreadsheet
|
|
213
218
|
theformulas
|
214
219
|
end
|
215
220
|
|
221
|
+
# returns the row,col values of the labelled cell
|
222
|
+
# (nil,nil) if label is not defined
|
223
|
+
# sheet parameter is not really needed because label names are global
|
224
|
+
# to the whole spreadsheet
|
225
|
+
def label(labelname,sheet=nil)
|
226
|
+
sheet = @default_sheet unless sheet
|
227
|
+
read_cells(sheet) unless @cells_read[sheet]
|
228
|
+
if @labels.has_key? labelname
|
229
|
+
return @labels[labelname][1].to_i,
|
230
|
+
GenericSpreadsheet.letter_to_number(@labels[labelname][2]),
|
231
|
+
@labels[labelname][0]
|
232
|
+
else
|
233
|
+
return nil,nil,nil
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
216
237
|
private
|
217
238
|
|
218
239
|
# read the version of the OO-Version
|
219
240
|
def oo_version
|
220
|
-
@doc.find("//*[local-name()='document-content']").each do |office|
|
221
|
-
|
241
|
+
#TODO: @doc.find("//*[local-name()='document-content']").each do |office|
|
242
|
+
@doc.xpath("//*[local-name()='document-content']").each do |office|
|
243
|
+
@officeversion = office.attributes['version'].to_s
|
222
244
|
end
|
223
245
|
end
|
224
246
|
|
@@ -238,10 +260,11 @@ class Openoffice < GenericSpreadsheet
|
|
238
260
|
when :string
|
239
261
|
@cell[sheet][key] = str_v
|
240
262
|
when :date
|
241
|
-
if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
263
|
+
#TODO: if table_cell.attributes['date-value'].size != "XXXX-XX-XX".size
|
264
|
+
if table_cell.attributes['date-value'].to_s.size != "XXXX-XX-XX".size
|
242
265
|
#-- dann ist noch eine Uhrzeit vorhanden
|
243
266
|
#-- "1961-11-21T12:17:18"
|
244
|
-
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'])
|
267
|
+
@cell[sheet][key] = DateTime.parse(table_cell.attributes['date-value'].to_s)
|
245
268
|
@cell_type[sheet][key] = :datetime
|
246
269
|
else
|
247
270
|
@cell[sheet][key] = table_cell.attributes['date-value']
|
@@ -267,31 +290,59 @@ class Openoffice < GenericSpreadsheet
|
|
267
290
|
raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
|
268
291
|
raise RangeError unless self.sheets.include? sheet
|
269
292
|
|
270
|
-
|
271
|
-
|
293
|
+
#-
|
294
|
+
# Labels
|
295
|
+
# should be factored out in separate method because labels are global
|
296
|
+
# to the whole spreadsheet file (and not to specific sheet)
|
297
|
+
#+
|
298
|
+
@doc.xpath("//table:named-range").each do |ne|
|
299
|
+
#-
|
300
|
+
# $Sheet1.$C$5
|
301
|
+
#+
|
302
|
+
name = ne.attribute('name').to_s
|
303
|
+
sheetname,coords = ne.attribute('cell-range-address').to_s.split('.')
|
304
|
+
col = coords.split('$')[1]
|
305
|
+
row = coords.split('$')[2]
|
306
|
+
sheetname = sheetname[1..-1] if sheetname[0,1] == '$'
|
307
|
+
@labels[name] = [sheetname,row,col]
|
308
|
+
end
|
309
|
+
|
310
|
+
#TODO: @doc.find("//*[local-name()='table']").each do |ws|
|
311
|
+
@doc.xpath("//*[local-name()='table']").each do |ws|
|
312
|
+
#TODO: if sheet == ws.attributes['name']
|
313
|
+
if sheet == ws['name']
|
272
314
|
sheet_found = true
|
273
315
|
col = 1
|
274
316
|
row = 1
|
275
|
-
ws.each_element do |table_element|
|
317
|
+
#TODO: ws.each_element do |table_element|
|
318
|
+
ws.children.each do |table_element|
|
276
319
|
case table_element.name
|
277
320
|
when 'table-column'
|
278
321
|
@style_defaults[sheet] << table_element.attributes['default-cell-style-name']
|
279
322
|
when 'table-row'
|
280
323
|
if table_element.attributes['number-rows-repeated']
|
281
|
-
skip_row = table_element.attributes['number-rows-repeated'].to_i
|
324
|
+
#TODO: skip_row = table_element.attributes['number-rows-repeated'].to_i
|
325
|
+
skip_row = table_element.attributes['number-rows-repeated'].to_s.to_i
|
282
326
|
row = row + skip_row - 1
|
283
327
|
end
|
284
|
-
table_element.each_element do |cell|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
328
|
+
#TODO: table_element.each_element do |cell|
|
329
|
+
table_element.children.each do |cell|
|
330
|
+
#TODO: skip_col = cell.attributes['number-columns-repeated']
|
331
|
+
skip_col = cell['number-columns-repeated']
|
332
|
+
#TODO: formula = cell.attributes['formula']
|
333
|
+
formula = cell['formula']
|
334
|
+
#TODO: vt = cell.attributes['value-type']
|
335
|
+
vt = cell['value-type']
|
336
|
+
#TODO: v = cell.attributes['value']
|
337
|
+
v = cell['value']
|
338
|
+
#TODO: style_name = cell.attributes['style-name']
|
339
|
+
style_name = cell['style-name']
|
290
340
|
if vt == 'string'
|
291
341
|
str_v = ''
|
292
342
|
# insert \n if there is more than one paragraph
|
293
343
|
para_count = 0
|
294
|
-
cell.each_element do |str|
|
344
|
+
#TODO: cell.each_element do |str|
|
345
|
+
cell.children.each do |str|
|
295
346
|
if str.name == 'p'
|
296
347
|
v = str.content
|
297
348
|
str_v += "\n" if para_count > 0
|
@@ -306,9 +357,10 @@ class Openoffice < GenericSpreadsheet
|
|
306
357
|
str_v.gsub!(/'/,"'") # special case not supported by unescapeHTML
|
307
358
|
str_v = CGI.unescapeHTML(str_v)
|
308
359
|
end # == 'p'
|
309
|
-
|
360
|
+
end
|
310
361
|
elsif vt == 'time'
|
311
|
-
cell.each_element do |str|
|
362
|
+
#TODO: cell.each_element do |str|
|
363
|
+
cell.children.each do |str|
|
312
364
|
if str.name == 'p'
|
313
365
|
v = str.content
|
314
366
|
end
|
@@ -322,8 +374,7 @@ class Openoffice < GenericSpreadsheet
|
|
322
374
|
elsif vt == 'float'
|
323
375
|
#
|
324
376
|
elsif vt == 'boolean'
|
325
|
-
v = cell.attributes['boolean-value']
|
326
|
-
#
|
377
|
+
v = cell.attributes['boolean-value'].to_s
|
327
378
|
else
|
328
379
|
# raise "unknown type #{vt}"
|
329
380
|
end
|
@@ -345,7 +396,8 @@ class Openoffice < GenericSpreadsheet
|
|
345
396
|
end
|
346
397
|
end
|
347
398
|
|
348
|
-
@doc.find("//*[local-name()='automatic-styles']").each do |style|
|
399
|
+
#TODO: @doc.find("//*[local-name()='automatic-styles']").each do |style|
|
400
|
+
@doc.xpath("//*[local-name()='automatic-styles']").each do |style|
|
349
401
|
read_styles(style)
|
350
402
|
end
|
351
403
|
if !sheet_found
|
@@ -434,7 +486,7 @@ class Openoffice < GenericSpreadsheet
|
|
434
486
|
result = result + child.content
|
435
487
|
else
|
436
488
|
if child.name == 's'
|
437
|
-
compressed_spaces = child.attributes['c'].to_i
|
489
|
+
compressed_spaces = child.attributes['c'].to_s.to_i
|
438
490
|
# no explicit number means a count of 1:
|
439
491
|
if compressed_spaces == 0
|
440
492
|
compressed_spaces = 1
|
data/lib/roo/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
module Roo #:nodoc:
|
2
|
-
module VERSION #:nodoc:
|
3
|
-
MAJOR = 1
|
4
|
-
MINOR = 3
|
5
|
-
TINY =
|
6
|
-
|
7
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
-
end
|
9
|
-
end
|
1
|
+
#module Roo #:nodoc:
|
2
|
+
# module VERSION #:nodoc:
|
3
|
+
# MAJOR = 1
|
4
|
+
# MINOR = 3
|
5
|
+
# TINY = 6
|
6
|
+
#
|
7
|
+
# STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
+
# end
|
9
|
+
#end
|
data/tasks/ann.rake
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones/smtp_tls'
|
4
|
+
rescue LoadError
|
5
|
+
require 'net/smtp'
|
6
|
+
end
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
namespace :ann do
|
10
|
+
|
11
|
+
# A prerequisites task that all other tasks depend upon
|
12
|
+
task :prereqs
|
13
|
+
|
14
|
+
file PROJ.ann.file do
|
15
|
+
ann = PROJ.ann
|
16
|
+
puts "Generating #{ann.file}"
|
17
|
+
File.open(ann.file,'w') do |fd|
|
18
|
+
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
19
|
+
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
20
|
+
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
21
|
+
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
22
|
+
fd.puts
|
23
|
+
fd.puts("== DESCRIPTION")
|
24
|
+
fd.puts
|
25
|
+
fd.puts(PROJ.description)
|
26
|
+
fd.puts
|
27
|
+
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
28
|
+
fd.puts
|
29
|
+
ann.paragraphs.each do |p|
|
30
|
+
fd.puts "== #{p.upcase}"
|
31
|
+
fd.puts
|
32
|
+
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
33
|
+
fd.puts
|
34
|
+
end
|
35
|
+
fd.puts ann.text if ann.text
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Create an announcement file"
|
40
|
+
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
41
|
+
|
42
|
+
desc "Send an email announcement"
|
43
|
+
task :email => ['ann:prereqs', PROJ.ann.file] do
|
44
|
+
ann = PROJ.ann
|
45
|
+
from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
|
46
|
+
to = Array(ann.email[:to])
|
47
|
+
|
48
|
+
### build a mail header for RFC 822
|
49
|
+
rfc822msg = "From: #{from}\n"
|
50
|
+
rfc822msg << "To: #{to.join(',')}\n"
|
51
|
+
rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
|
52
|
+
rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
|
53
|
+
rfc822msg << "\n"
|
54
|
+
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
55
|
+
rfc822msg << "Message-Id: "
|
56
|
+
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
57
|
+
rfc822msg << File.read(ann.file)
|
58
|
+
|
59
|
+
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
60
|
+
ann.email[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
params[3] = PROJ.email if params[3].nil?
|
64
|
+
|
65
|
+
if params[4].nil?
|
66
|
+
STDOUT.write "Please enter your e-mail password (#{params[3]}): "
|
67
|
+
params[4] = STDIN.gets.chomp
|
68
|
+
end
|
69
|
+
|
70
|
+
### send email
|
71
|
+
Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
|
72
|
+
end
|
73
|
+
end # namespace :ann
|
74
|
+
|
75
|
+
desc 'Alias to ann:announcement'
|
76
|
+
task :ann => 'ann:announcement'
|
77
|
+
|
78
|
+
CLOBBER << PROJ.ann.file
|
79
|
+
|
80
|
+
# EOF
|
data/tasks/bones.rake
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
if HAVE_BONES
|
3
|
+
|
4
|
+
namespace :bones do
|
5
|
+
|
6
|
+
desc 'Show the PROJ open struct'
|
7
|
+
task :debug do |t|
|
8
|
+
atr = if t.application.top_level_tasks.length == 2
|
9
|
+
t.application.top_level_tasks.pop
|
10
|
+
end
|
11
|
+
|
12
|
+
if atr then Bones::Debug.show_attr(PROJ, atr)
|
13
|
+
else Bones::Debug.show PROJ end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # namespace :bones
|
17
|
+
|
18
|
+
end # HAVE_BONES
|
19
|
+
|
20
|
+
# EOF
|
data/tasks/gem.rake
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
|
2
|
+
require 'find'
|
3
|
+
require 'rake/packagetask'
|
4
|
+
require 'rubygems/user_interaction'
|
5
|
+
require 'rubygems/builder'
|
6
|
+
|
7
|
+
module Bones
|
8
|
+
class GemPackageTask < Rake::PackageTask
|
9
|
+
# Ruby GEM spec containing the metadata for this package. The
|
10
|
+
# name, version and package_files are automatically determined
|
11
|
+
# from the GEM spec and don't need to be explicitly provided.
|
12
|
+
#
|
13
|
+
attr_accessor :gem_spec
|
14
|
+
|
15
|
+
# Tasks from the Bones gem directory
|
16
|
+
attr_reader :bones_files
|
17
|
+
|
18
|
+
# Create a GEM Package task library. Automatically define the gem
|
19
|
+
# if a block is given. If no block is supplied, then +define+
|
20
|
+
# needs to be called to define the task.
|
21
|
+
#
|
22
|
+
def initialize(gem_spec)
|
23
|
+
init(gem_spec)
|
24
|
+
yield self if block_given?
|
25
|
+
define if block_given?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialization tasks without the "yield self" or define
|
29
|
+
# operations.
|
30
|
+
#
|
31
|
+
def init(gem)
|
32
|
+
super(gem.name, gem.version)
|
33
|
+
@gem_spec = gem
|
34
|
+
@package_files += gem_spec.files if gem_spec.files
|
35
|
+
@bones_files = []
|
36
|
+
|
37
|
+
local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
|
38
|
+
if !test(?e, local_setup)
|
39
|
+
Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create the Rake tasks and actions specified by this
|
44
|
+
# GemPackageTask. (+define+ is automatically called if a block is
|
45
|
+
# given to +new+).
|
46
|
+
#
|
47
|
+
def define
|
48
|
+
super
|
49
|
+
task :prereqs
|
50
|
+
task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
|
51
|
+
file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
|
52
|
+
when_writing("Creating GEM") {
|
53
|
+
chdir(package_dir_path) do
|
54
|
+
Gem::Builder.new(gem_spec).build
|
55
|
+
verbose(true) {
|
56
|
+
mv gem_file, "../#{gem_file}"
|
57
|
+
}
|
58
|
+
end
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
file package_dir_path => bones_files do
|
63
|
+
mkdir_p package_dir rescue nil
|
64
|
+
|
65
|
+
gem_spec.files = (gem_spec.files +
|
66
|
+
bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
|
67
|
+
|
68
|
+
bones_files.each do |fn|
|
69
|
+
base_fn = File.join('tasks', File.basename(fn))
|
70
|
+
f = File.join(package_dir_path, base_fn)
|
71
|
+
fdir = File.dirname(f)
|
72
|
+
mkdir_p(fdir) if !File.exist?(fdir)
|
73
|
+
if File.directory?(fn)
|
74
|
+
mkdir_p(f)
|
75
|
+
else
|
76
|
+
raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f)
|
77
|
+
safe_ln(fn, f)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def gem_file
|
84
|
+
if @gem_spec.platform == Gem::Platform::RUBY
|
85
|
+
"#{package_name}.gem"
|
86
|
+
else
|
87
|
+
"#{package_name}-#{@gem_spec.platform}.gem"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end # class GemPackageTask
|
91
|
+
end # module Bones
|
92
|
+
|
93
|
+
namespace :gem do
|
94
|
+
|
95
|
+
PROJ.gem._spec = Gem::Specification.new do |s|
|
96
|
+
s.name = PROJ.name
|
97
|
+
s.version = PROJ.version
|
98
|
+
s.summary = PROJ.summary
|
99
|
+
s.authors = Array(PROJ.authors)
|
100
|
+
s.email = PROJ.email
|
101
|
+
s.homepage = Array(PROJ.url).first
|
102
|
+
s.rubyforge_project = PROJ.rubyforge.name
|
103
|
+
|
104
|
+
s.description = PROJ.description
|
105
|
+
|
106
|
+
PROJ.gem.dependencies.each do |dep|
|
107
|
+
s.add_dependency(*dep)
|
108
|
+
end
|
109
|
+
|
110
|
+
PROJ.gem.development_dependencies.each do |dep|
|
111
|
+
s.add_development_dependency(*dep)
|
112
|
+
end
|
113
|
+
|
114
|
+
s.files = PROJ.gem.files
|
115
|
+
s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
|
116
|
+
s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
|
117
|
+
|
118
|
+
s.bindir = 'bin'
|
119
|
+
dirs = Dir["{#{PROJ.libs.join(',')}}"]
|
120
|
+
s.require_paths = dirs unless dirs.empty?
|
121
|
+
|
122
|
+
incl = Regexp.new(PROJ.rdoc.include.join('|'))
|
123
|
+
excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
|
124
|
+
excl = Regexp.new(excl.join('|'))
|
125
|
+
rdoc_files = PROJ.gem.files.find_all do |fn|
|
126
|
+
case fn
|
127
|
+
when excl; false
|
128
|
+
when incl; true
|
129
|
+
else false end
|
130
|
+
end
|
131
|
+
s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
|
132
|
+
s.extra_rdoc_files = rdoc_files
|
133
|
+
s.has_rdoc = true
|
134
|
+
|
135
|
+
if test ?f, PROJ.test.file
|
136
|
+
s.test_file = PROJ.test.file
|
137
|
+
else
|
138
|
+
s.test_files = PROJ.test.files.to_a
|
139
|
+
end
|
140
|
+
|
141
|
+
# Do any extra stuff the user wants
|
142
|
+
PROJ.gem.extras.each do |msg, val|
|
143
|
+
case val
|
144
|
+
when Proc
|
145
|
+
val.call(s.send(msg))
|
146
|
+
else
|
147
|
+
s.send "#{msg}=", val
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end # Gem::Specification.new
|
151
|
+
|
152
|
+
Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg|
|
153
|
+
pkg.need_tar = PROJ.gem.need_tar
|
154
|
+
pkg.need_zip = PROJ.gem.need_zip
|
155
|
+
end
|
156
|
+
|
157
|
+
desc 'Show information about the gem'
|
158
|
+
task :debug => 'gem:prereqs' do
|
159
|
+
puts PROJ.gem._spec.to_ruby
|
160
|
+
end
|
161
|
+
|
162
|
+
desc 'Write the gemspec '
|
163
|
+
task :spec => 'gem:prereqs' do
|
164
|
+
File.open("#{PROJ.name}.gemspec", 'w') do |f|
|
165
|
+
f.write PROJ.gem._spec.to_ruby
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
desc 'Install the gem'
|
170
|
+
task :install => [:clobber, 'gem:package'] do
|
171
|
+
sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
|
172
|
+
|
173
|
+
# use this version of the command for rubygems > 1.0.0
|
174
|
+
#sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
|
175
|
+
end
|
176
|
+
|
177
|
+
desc 'Uninstall the gem'
|
178
|
+
task :uninstall do
|
179
|
+
installed_list = Gem.source_index.find_name(PROJ.name)
|
180
|
+
if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
|
181
|
+
sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
desc 'Reinstall the gem'
|
186
|
+
task :reinstall => [:uninstall, :install]
|
187
|
+
|
188
|
+
desc 'Cleanup the gem'
|
189
|
+
task :cleanup do
|
190
|
+
sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
|
191
|
+
end
|
192
|
+
end # namespace :gem
|
193
|
+
|
194
|
+
|
195
|
+
desc 'Alias to gem:package'
|
196
|
+
task :gem => 'gem:package'
|
197
|
+
|
198
|
+
task :clobber => 'gem:clobber_package'
|
199
|
+
remove_desc_for_task 'gem:clobber_package'
|
200
|
+
|
201
|
+
# EOF
|