dm-is-reflective 0.8.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/.gita/COMMIT_EDITMSG +9 -0
- data/.gita/HEAD +1 -0
- data/.gita/ORIG_HEAD +1 -0
- data/.gita/RENAMED-REF +1 -0
- data/.gita/config +9 -0
- data/.gita/description +1 -0
- data/.gita/gitk.cache +6 -0
- data/.gita/hooks/applypatch-msg +15 -0
- data/.gita/hooks/commit-msg +24 -0
- data/.gita/hooks/post-commit +8 -0
- data/.gita/hooks/post-receive +16 -0
- data/.gita/hooks/post-update +8 -0
- data/.gita/hooks/pre-applypatch +14 -0
- data/.gita/hooks/pre-commit +70 -0
- data/.gita/hooks/pre-rebase +150 -0
- data/.gita/hooks/prepare-commit-msg +36 -0
- data/.gita/hooks/update +107 -0
- data/.gita/index +0 -0
- data/.gita/info/exclude +6 -0
- data/.gita/info/refs +26 -0
- data/.gita/logs/HEAD +40 -0
- data/.gita/logs/refs/heads/dm-mapping +1 -0
- data/.gita/logs/refs/heads/master +40 -0
- data/.gita/logs/refs/heads/return-symbol +0 -0
- data/.gita/logs/refs/remotes/origin/dm-mapping +1 -0
- data/.gita/logs/refs/remotes/origin/master +6 -0
- data/.gita/logs/refs/remotes/origin/return-symbol +0 -0
- data/.gita/objects/5c/91380a1616b7c2d23e14eeb49d9edde58e1f47 +2 -0
- data/.gita/objects/63/71947bcb9c0dd1d3b3d6f449b2d4b4c6c81e63 +0 -0
- data/.gita/objects/73/23ae22118cc54fb0bbb0d6f51cc99191019b96 +0 -0
- data/.gita/objects/81/a0ab6e4dbd148faa0644307b313799027d3344 +2 -0
- data/.gita/objects/b2/9571a21e3bccb60079dfca630dac981f623489 +5 -0
- data/.gita/objects/cb/138acf9efc0f5b3ff91c644cae4dec868442e4 +5 -0
- data/.gita/objects/d5/66699fc7ba5237311cc44648d0cd2abbaa895e +0 -0
- data/.gita/objects/info/packs +2 -0
- data/.gita/objects/pack/pack-c9156ef3406b98f5f12875b13643df7a5f41e42c.idx +0 -0
- data/.gita/objects/pack/pack-c9156ef3406b98f5f12875b13643df7a5f41e42c.pack +0 -0
- data/.gita/packed-refs +27 -0
- data/.gita/refs/heads/master +1 -0
- data/.gita/refs/tags/dm-is-reflective-0.8.0 +1 -0
- data/CHANGES +189 -0
- data/LICENSE +201 -0
- data/NOTICE +30 -0
- data/README +122 -0
- data/Rakefile +45 -0
- data/TODO +7 -0
- data/dm-is-reflective.gemspec +41 -0
- data/lib/dm-is-reflective.rb +10 -0
- data/lib/dm-is-reflective/is/adapters/abstract_adapter.rb +144 -0
- data/lib/dm-is-reflective/is/adapters/mysql_adapter.rb +62 -0
- data/lib/dm-is-reflective/is/adapters/postgres_adapter.rb +84 -0
- data/lib/dm-is-reflective/is/adapters/sqlite3_adapter.rb +61 -0
- data/lib/dm-is-reflective/is/reflective.rb +78 -0
- data/lib/dm-is-reflective/is/version.rb +7 -0
- data/lib/dm-is-reflective/version.rb +7 -0
- 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 +294 -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/abstract.rb +250 -0
- data/test/test_dm-is-reflexible.rb +48 -0
- metadata +203 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
require 'dm-is-reflective/is/adapters/abstract_adapter'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
module Is::Reflective
|
6
|
+
module PostgresAdapter
|
7
|
+
def storages
|
8
|
+
sql = <<-SQL.compress_lines
|
9
|
+
SELECT table_name FROM "information_schema"."tables"
|
10
|
+
WHERE table_schema = current_schema()
|
11
|
+
SQL
|
12
|
+
|
13
|
+
query(sql)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def reflective_query_storage storage
|
18
|
+
sql = <<-SQL.compress_lines
|
19
|
+
SELECT column_name FROM "information_schema"."key_column_usage"
|
20
|
+
WHERE table_schema = current_schema() AND table_name = ?
|
21
|
+
SQL
|
22
|
+
|
23
|
+
keys = query(sql, storage).to_set
|
24
|
+
|
25
|
+
sql = <<-SQL.compress_lines
|
26
|
+
SELECT column_name, column_default, is_nullable,
|
27
|
+
character_maximum_length, udt_name
|
28
|
+
FROM "information_schema"."columns"
|
29
|
+
WHERE table_schema = current_schema() AND table_name = ?
|
30
|
+
SQL
|
31
|
+
|
32
|
+
query(sql, storage).map{ |struct|
|
33
|
+
struct.instance_eval <<-END_EVAL
|
34
|
+
def key?
|
35
|
+
#{keys.member?(struct.column_name)}
|
36
|
+
end
|
37
|
+
END_EVAL
|
38
|
+
struct
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def reflective_field_name field
|
43
|
+
field.column_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def reflective_primitive field
|
47
|
+
field.udt_name
|
48
|
+
end
|
49
|
+
|
50
|
+
def reflective_attributes field, attrs = {}
|
51
|
+
# strip data type
|
52
|
+
field.column_default.gsub!(/(.*?)::[\w\s]*/, '\1') if field.column_default
|
53
|
+
|
54
|
+
attrs[:serial] = true if field.column_default =~ /nextval\('\w+'\)/
|
55
|
+
attrs[:key] = true if field.key?
|
56
|
+
attrs[:nullable] = field.is_nullable == 'YES'
|
57
|
+
# strip string quotation
|
58
|
+
attrs[:default] = field.column_default.gsub(/^'(.*?)'$/, '\1') if
|
59
|
+
field.column_default && !attrs[:serial]
|
60
|
+
|
61
|
+
if field.character_maximum_length
|
62
|
+
attrs[:length] = field.character_maximum_length
|
63
|
+
elsif field.udt_name.upcase == 'TEXT'
|
64
|
+
attrs[:length] = DataMapper::Types::Text.length
|
65
|
+
end
|
66
|
+
|
67
|
+
attrs
|
68
|
+
end
|
69
|
+
|
70
|
+
def reflective_lookup_primitive primitive
|
71
|
+
p = primitive.upcase
|
72
|
+
|
73
|
+
return Integer if p =~ /^INT\d+$/
|
74
|
+
return String if p == 'VARCHAR'
|
75
|
+
return DateTime if p == 'TIMESTAMP'
|
76
|
+
return DataMapper::Types::Text if p == 'TEXT'
|
77
|
+
return DataMapper::Types::Boolean if p == 'BOOL'
|
78
|
+
|
79
|
+
super(primitive)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
require 'dm-is-reflective/is/adapters/abstract_adapter'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
module Is::Reflective
|
6
|
+
module Sqlite3Adapter
|
7
|
+
def storages
|
8
|
+
sql = <<-SQL.compress_lines
|
9
|
+
SELECT name
|
10
|
+
FROM sqlite_master
|
11
|
+
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
12
|
+
SQL
|
13
|
+
|
14
|
+
query sql
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
# alias_method :reflective_query_storages, :query_table
|
19
|
+
def reflective_query_storage *args, &block
|
20
|
+
query_table(*args, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def reflective_field_name field
|
24
|
+
field.name
|
25
|
+
end
|
26
|
+
|
27
|
+
def reflective_primitive field
|
28
|
+
field.type.gsub(/\(\d+\)/, '')
|
29
|
+
end
|
30
|
+
|
31
|
+
def reflective_attributes field, attrs = {}
|
32
|
+
if field.pk != 0
|
33
|
+
attrs[:key] = true
|
34
|
+
attrs[:serial] = true if supports_serial?
|
35
|
+
end
|
36
|
+
attrs[:nullable] = field.notnull != 1
|
37
|
+
attrs[:default] = field.dflt_value[1..-2] if field.dflt_value
|
38
|
+
|
39
|
+
if field.type.upcase == 'TEXT'
|
40
|
+
attrs[:length] = DataMapper::Types::Text.length
|
41
|
+
else
|
42
|
+
ergo = field.type.match(/\((\d+)\)/)
|
43
|
+
size = ergo && ergo[1].to_i
|
44
|
+
attrs[:length] = size if size
|
45
|
+
end
|
46
|
+
|
47
|
+
attrs
|
48
|
+
end
|
49
|
+
|
50
|
+
def reflective_lookup_primitive primitive
|
51
|
+
p = primitive.upcase
|
52
|
+
|
53
|
+
return Integer if p =~ 'INTEGER'
|
54
|
+
return Float if p == 'REAL' || p == 'NUMERIC'
|
55
|
+
return DataMapper::Types::Text if p == 'TEXT'
|
56
|
+
|
57
|
+
super(primitive)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
module DataMapper
|
3
|
+
module Is
|
4
|
+
module Reflective
|
5
|
+
|
6
|
+
def is_reflective
|
7
|
+
extend ClassMethod
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethod
|
11
|
+
# it simply calls Migration#fields(self.storage_name)
|
12
|
+
# e.g.
|
13
|
+
# DataMapper.repository.adapter.fields storage_name
|
14
|
+
def fields repo = default_repository_name
|
15
|
+
DataMapper.repository(repo).adapter.fields(storage_name(repo))
|
16
|
+
end
|
17
|
+
|
18
|
+
# it automaticly creates reflection from storage fields to properties.
|
19
|
+
# i.e. you don't have to specify any property if you are connecting
|
20
|
+
# to an existing database.
|
21
|
+
# you can pass it Regexp to map any field it matched, or just
|
22
|
+
# the field name in Symbol or String, or a Class telling it
|
23
|
+
# map any field which type equals to the Class.
|
24
|
+
# returned value is an array of properties indicating fields it mapped
|
25
|
+
# e.g.
|
26
|
+
# class User
|
27
|
+
# include DataMapper::Resource
|
28
|
+
# # reflect all
|
29
|
+
# reflect /.*/ # e.g. => [#<Property:#<Class:0x18f89b8>:id>,
|
30
|
+
# # #<Property:#<Class:0x18f89b8>:title>,
|
31
|
+
# # #<Property:#<Class:0x18f89b8>:body>,
|
32
|
+
# # #<Property:#<Class:0x18f89b8>:user_id>]
|
33
|
+
#
|
34
|
+
# # reflect all (with no argument at all)
|
35
|
+
# reflect
|
36
|
+
#
|
37
|
+
# # reflect for field name ended with _at, and started with salt_
|
38
|
+
# reflect /_at$/, /^salt_/
|
39
|
+
#
|
40
|
+
# # reflect id and email
|
41
|
+
# reflect :id, :email
|
42
|
+
#
|
43
|
+
# # reflect all fields with type String, and id
|
44
|
+
# reflect String, :id
|
45
|
+
#
|
46
|
+
# # reflect login, and all fields with type Integer
|
47
|
+
# reflect :login, Integer
|
48
|
+
# end
|
49
|
+
def reflect *targets
|
50
|
+
targets << /.*/ if targets.empty?
|
51
|
+
|
52
|
+
fields.map{ |field|
|
53
|
+
name, type, attrs = field
|
54
|
+
|
55
|
+
reflected = targets.each{ |target|
|
56
|
+
case target
|
57
|
+
when Regexp;
|
58
|
+
break name if name.to_s =~ target
|
59
|
+
|
60
|
+
when Symbol, String;
|
61
|
+
break name if name == target.to_sym
|
62
|
+
|
63
|
+
when Class;
|
64
|
+
break name if type == target
|
65
|
+
|
66
|
+
else
|
67
|
+
raise ArgumentError.new("invalid argument: #{target.inspect}")
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
property(reflected, type, attrs) if reflected.kind_of?(Symbol)
|
72
|
+
}.compact
|
73
|
+
end
|
74
|
+
end # of ClassMethod
|
75
|
+
|
76
|
+
end # of Reflective
|
77
|
+
end # of Is
|
78
|
+
end # of DataMapper
|
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
|