proutils 0.3.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/CHANGES +17 -0
- data/COPYING +674 -0
- data/README +78 -0
- data/RELEASE +7 -0
- data/TODO +4 -0
- data/bin/icli +278 -0
- data/bin/mint +139 -0
- data/bin/rtar +69 -0
- data/bin/xact +121 -0
- data/data/mint/cherry/_scaffold.rb +4 -0
- data/data/mint/roll/name-1.0.0.roll +26 -0
- data/data/mint/ruby/README +17 -0
- data/data/mint/ruby/README.first +10 -0
- data/data/mint/ruby/README.license +403 -0
- data/data/mint/ruby/meta/MANIFEST +2 -0
- data/data/mint/ruby/meta/name-1.0.0.roll +26 -0
- data/data/mint/ruby/script/finish_scaffold +8 -0
- data/data/mint/ruby/script/setup +1600 -0
- data/data/mint/website/css/clean.css +5 -0
- data/data/mint/website/index.html +0 -0
- data/demo/demo_rtar/Lorem_ipsum.txt +233 -0
- data/demo/demo_rtar/lib/demo_rock/tryme.rb +2 -0
- data/demo/demo_rtar/meta/data +6 -0
- data/demo/demo_rtar/web/index.html +13 -0
- data/demo/demo_rtar/web/rocklobster.jpg +0 -0
- data/demo/mint/loremipsum.txt +9 -0
- data/demo/mint/tryme.rb +33 -0
- data/lib/proutils/icli/abstract_host.rb +71 -0
- data/lib/proutils/icli/gforge.rb +668 -0
- data/lib/proutils/icli/rubyforge.rb +26 -0
- data/lib/proutils/icli/tool.rb +128 -0
- data/lib/proutils/icli/uploadutils.rb +410 -0
- data/lib/proutils/mint/copier.rb +324 -0
- data/lib/proutils/mint/fileutils.rb +47 -0
- data/lib/proutils/mint/help.txt +0 -0
- data/lib/proutils/rtar/rtar.rb +309 -0
- data/lib/proutils/rtar/vendor/archive/tar/minitar/command.rb +814 -0
- data/lib/proutils/rtar/vendor/archive/tar/minitar.rb +979 -0
- data/lib/proutils/xact/extract.rb +211 -0
- data/lib/proutils/xact/save.rb +151 -0
- data/meta/MANIFEST +100 -0
- data/meta/config.yaml +12 -0
- data/meta/icli.yaml +16 -0
- data/meta/project.yaml +27 -0
- data/meta/proutils.roll +3 -0
- data/test/fixture.rb +6 -0
- data/test/lib/test_exacto.rb +54 -0
- data/work/ANN +14 -0
- data/work/icli/icli +223 -0
- data/work/icli/rake.rb +82 -0
- data/work/icli/utils/consoleutils.rb +67 -0
- data/work/icli/utils/emailutils.rb +85 -0
- data/work/icli/utils/fileutils.rb +47 -0
- data/work/mint/command-old.rb +48 -0
- data/work/mint/lazyfile.rb +97 -0
- data/work/mint/part.rb +316 -0
- data/work/mint/scaffold-old.rb +420 -0
- data/work/rtar/index.html +68 -0
- data/work/rtar/old-index.html +63 -0
- data/work/xact/xact-ginsu +5 -0
- data/work/xact/xact-ruby.rb +155 -0
- metadata +178 -0
data/work/icli/icli
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'facets/command'
|
5
|
+
|
6
|
+
module ICli
|
7
|
+
|
8
|
+
class Command < Console::Command
|
9
|
+
|
10
|
+
class CommonOptions < Console::Command::Options
|
11
|
+
attr_accessor :host,
|
12
|
+
:domain,
|
13
|
+
:username
|
14
|
+
end
|
15
|
+
|
16
|
+
class ReleaseOptions < CommonOptions
|
17
|
+
attr_accessor :store, # Package folder.
|
18
|
+
:files, # Files to release.
|
19
|
+
:package, # Package name.
|
20
|
+
:version, # Package version.
|
21
|
+
:release, # Release name. Defaults to +version+.
|
22
|
+
:date, # Release Date. Defaults to +Time.now+.
|
23
|
+
:processor, # Processor type. Deafults to +Any+.
|
24
|
+
:changelog, # ChangeLog file.
|
25
|
+
:notelog, # Notes file.
|
26
|
+
:is_public # Is this release public?
|
27
|
+
end
|
28
|
+
|
29
|
+
class PublishOptions < CommonOptions
|
30
|
+
attr_accessor :root # directory with website files
|
31
|
+
end
|
32
|
+
|
33
|
+
class AnnounceOptions < CommonOptions
|
34
|
+
attr_accessor :subject,
|
35
|
+
:message
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
|
40
|
+
options :publish, PublishOptions
|
41
|
+
options :release, ReleaseOptions
|
42
|
+
options :announce, AnnounceOptions
|
43
|
+
options :touch, CommonOptions
|
44
|
+
|
45
|
+
# Publish
|
46
|
+
#
|
47
|
+
# root directory with website files
|
48
|
+
|
49
|
+
def publish
|
50
|
+
options = config_load('publish')
|
51
|
+
|
52
|
+
# merge in any commandline options
|
53
|
+
options.merge!(PublishOptions.parse.to_h)
|
54
|
+
|
55
|
+
name = options['host'] || options['domain']
|
56
|
+
host = host_class(name).new(options)
|
57
|
+
|
58
|
+
host.publish(options)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Release options. This is a hash of options:
|
62
|
+
#
|
63
|
+
# store Location of packages.
|
64
|
+
# version Package version.
|
65
|
+
# files Files to release. (defaults to source/package-version.*)
|
66
|
+
# package Package name (defaults to +project+).
|
67
|
+
# release Release name (defaults to +version+).
|
68
|
+
# date Release Date (defaults to to +Time.now+).
|
69
|
+
# processor Processor type (deafults to +Any+).
|
70
|
+
# changelog ChangeLog file.
|
71
|
+
# notelog Notes file.
|
72
|
+
# is_public Is this release public?
|
73
|
+
#
|
74
|
+
|
75
|
+
def release
|
76
|
+
options = config_load('release')
|
77
|
+
|
78
|
+
# merge in any commandline options
|
79
|
+
options.merge!(@options.to_h) #(ReleaseOptions.parse.to_h)
|
80
|
+
|
81
|
+
#options = {}
|
82
|
+
#options.update info.gather('rubyforge')
|
83
|
+
#options.update info.gather('release')
|
84
|
+
#options.update info.select('version', 'changelog', 'notelog', 'processor'=>'arch')
|
85
|
+
#options['files'] = Dir[File.join(info.package_store,"*#{options['version']}.*")]
|
86
|
+
|
87
|
+
store = options['store']
|
88
|
+
name = options['package']
|
89
|
+
vers = options['version']
|
90
|
+
|
91
|
+
options['files'] ||= Dir[File.join(store,"#{name}-#{ver}.*")]
|
92
|
+
|
93
|
+
name = options['host'] || options['domain']
|
94
|
+
host = host_class(name).new(options)
|
95
|
+
|
96
|
+
host.release(options)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Annouce to news.
|
100
|
+
|
101
|
+
def announce
|
102
|
+
options = config_load('announce')
|
103
|
+
|
104
|
+
# merge in any commandline options
|
105
|
+
options.merge!(AnnounceOptions.parse.to_h)
|
106
|
+
|
107
|
+
name = options['host'] || options['domain']
|
108
|
+
host = host_class(name).new(options)
|
109
|
+
|
110
|
+
host.announce(options)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Test connection. Simply login and logout.
|
114
|
+
|
115
|
+
def touch
|
116
|
+
options = config_load
|
117
|
+
|
118
|
+
# merge in any commandline options
|
119
|
+
options.merge!(@options.to_h) #(CommonOptions.parse.to_h)
|
120
|
+
|
121
|
+
name = options['host'] || options['domain']
|
122
|
+
host = host_class(name).new(options)
|
123
|
+
|
124
|
+
host.touch
|
125
|
+
end
|
126
|
+
|
127
|
+
# Help
|
128
|
+
|
129
|
+
def help
|
130
|
+
puts DATA.read
|
131
|
+
end
|
132
|
+
|
133
|
+
# Default action (no subcommand)
|
134
|
+
|
135
|
+
alias_method :default, :help
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def host_class(name)
|
140
|
+
Forge.factory(name)
|
141
|
+
#raise "unrecognized host" unless host
|
142
|
+
#host.send(args)
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
|
147
|
+
def config_load(section=nil)
|
148
|
+
if file = config_file
|
149
|
+
options = YAML::load(File.open(file))
|
150
|
+
else
|
151
|
+
options = {}
|
152
|
+
end
|
153
|
+
# merge in the selected section
|
154
|
+
if section
|
155
|
+
options.merge!(options[section.to_s] || {})
|
156
|
+
end
|
157
|
+
# remove subsections (should we bother?)
|
158
|
+
options = options.delete_if{ |k,v| Hash === v }
|
159
|
+
# return
|
160
|
+
return options
|
161
|
+
end
|
162
|
+
|
163
|
+
def config_file
|
164
|
+
Dir.glob("{meta/,.}forge{.yaml,.yml,}")[0]
|
165
|
+
end
|
166
|
+
|
167
|
+
# def start
|
168
|
+
# config = File.file?(CONFIG_FILE) ? YAML::load(f) : {}
|
169
|
+
# section = (@args[0] || 'all').to_s.downcase
|
170
|
+
#
|
171
|
+
# if section == 'all'
|
172
|
+
# config.each do |name, settings|
|
173
|
+
# settings.update(@keys)
|
174
|
+
# press(settings)
|
175
|
+
# end
|
176
|
+
# else
|
177
|
+
# settings = config[section]
|
178
|
+
# settings.update(@keys)
|
179
|
+
# press(settings)
|
180
|
+
# end
|
181
|
+
# end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
Forge::Command.start
|
187
|
+
|
188
|
+
|
189
|
+
__END__
|
190
|
+
|
191
|
+
Forge v0.2.0
|
192
|
+
|
193
|
+
Usage: forge <command> <options>
|
194
|
+
|
195
|
+
Commands:
|
196
|
+
|
197
|
+
touch
|
198
|
+
Test connection. This simply attempts to login and logout.
|
199
|
+
|
200
|
+
release
|
201
|
+
Release a package.
|
202
|
+
|
203
|
+
announce
|
204
|
+
Make an announcement via news.
|
205
|
+
|
206
|
+
publish
|
207
|
+
Publish website files.
|
208
|
+
|
209
|
+
Common Options:
|
210
|
+
|
211
|
+
--host
|
212
|
+
The host name (eg. rubyforge). If LaForge supports the
|
213
|
+
host name then a specialized adatapter will be used.
|
214
|
+
|
215
|
+
--domain
|
216
|
+
The domain name of the host. If the host is not build in
|
217
|
+
you can supply the domain name instead of the host name.
|
218
|
+
The generic GForge adapter will be used.
|
219
|
+
|
220
|
+
--username
|
221
|
+
Your username on the host.
|
222
|
+
|
223
|
+
For more information, http://proutils.rubyforge.org.
|
data/work/icli/rake.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Define rubyforge tasks.
|
2
|
+
|
3
|
+
def task_rubyforge
|
4
|
+
|
5
|
+
desc "Release packages (Rubyforge)"
|
6
|
+
task :release do
|
7
|
+
project.release
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Publish website (Rubyforge)"
|
11
|
+
task :publish do
|
12
|
+
project.publish
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
# # Publish
|
18
|
+
#
|
19
|
+
# def publish
|
20
|
+
# options = {}
|
21
|
+
# options.update info.gather('rubyforge')
|
22
|
+
# options.update info.gather('publish')
|
23
|
+
#
|
24
|
+
# rubyforge.publish(options)
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Release options. This is a hash of options:
|
28
|
+
# #
|
29
|
+
# # files Files to release.
|
30
|
+
# # version Package version.
|
31
|
+
# # package Package name. Defaults to +project+.
|
32
|
+
# # release Release name. Defaults to +version+.
|
33
|
+
# # date Release Date. Defaults to +Time.now+.
|
34
|
+
# # processor Processor type. Deafults to +Any+.
|
35
|
+
# # changelog ChangeLog file.
|
36
|
+
# # notelog Notes file.
|
37
|
+
# # is_public Is this release public?
|
38
|
+
# #
|
39
|
+
#
|
40
|
+
# def release
|
41
|
+
# options = {}
|
42
|
+
# options.update info.gather('rubyforge')
|
43
|
+
# options.update info.gather('release')
|
44
|
+
# options.update info.select('version', 'changelog', 'notelog', 'processor'=>'arch')
|
45
|
+
# options['files'] = Dir[File.join(info.package_store,"*#{options['version']}.*")]
|
46
|
+
#
|
47
|
+
# rubyforge.release(options)
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # Rubyforge object.
|
51
|
+
#
|
52
|
+
# def rubyforge
|
53
|
+
# # rubyforge_info = {
|
54
|
+
# # 'domain' => rubyforge_info['domain'],
|
55
|
+
# # 'project' => rubyforge_info['project'],
|
56
|
+
# # 'username' => rubyforge_info['username'],
|
57
|
+
# # 'group_id' => rubyforge_info['group_id'] || rubyforge_info['groupid'],
|
58
|
+
# # 'release' => release_info,
|
59
|
+
# # 'publish' => publish_info
|
60
|
+
# # }
|
61
|
+
#
|
62
|
+
# #rubyforge_info = {}
|
63
|
+
# #rubyforge_info.update info.select('project')
|
64
|
+
# #rubyforge_info.update info.gather('rubyforge')
|
65
|
+
#
|
66
|
+
# domain = info.rubyforge_domain
|
67
|
+
# project = info.rubyforge_project
|
68
|
+
# username = info.rubyforge_username
|
69
|
+
# group_id = info.rubyforge_group_id
|
70
|
+
#
|
71
|
+
# #domain ||= 'rubyforge.org'
|
72
|
+
# project ||= info.project
|
73
|
+
#
|
74
|
+
# @rubyforge ||= RubyForge.new(
|
75
|
+
# :domain => domain,
|
76
|
+
# :project => project,
|
77
|
+
# :username => username,
|
78
|
+
# :group_id => group_id
|
79
|
+
# )
|
80
|
+
# end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
module ConsoleUtils
|
3
|
+
|
4
|
+
# Convenient method to get simple console reply.
|
5
|
+
|
6
|
+
def ask(question, answers=nil)
|
7
|
+
print "#{question}"
|
8
|
+
print " [#{answers}] " if answers
|
9
|
+
until inp = $stdin.gets ; sleep 1 ; end
|
10
|
+
inp
|
11
|
+
end
|
12
|
+
|
13
|
+
# Ask for a password. (FIXME: only for unix so far)
|
14
|
+
|
15
|
+
def password(prompt=nil)
|
16
|
+
msg ||= "Enter Password: "
|
17
|
+
inp = ''
|
18
|
+
|
19
|
+
print "#{prompt} "
|
20
|
+
|
21
|
+
begin
|
22
|
+
system "stty -echo"
|
23
|
+
#inp = gets.chomp
|
24
|
+
until inp = $stdin.gets
|
25
|
+
sleep 1
|
26
|
+
end
|
27
|
+
ensure
|
28
|
+
system "stty echo"
|
29
|
+
end
|
30
|
+
|
31
|
+
return inp.chomp
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
class Array
|
38
|
+
|
39
|
+
# Convert an array into command line parameters.
|
40
|
+
# The array is accepted in the format of Ruby
|
41
|
+
# method arguments --ie. [arg1, arg2, ..., hash]
|
42
|
+
|
43
|
+
def to_params
|
44
|
+
flags = (Hash===last ? pop : {})
|
45
|
+
flags = flags.collect do |f,v|
|
46
|
+
m = f.to_s.size == 1 ? '-' : '--'
|
47
|
+
case v
|
48
|
+
when Array
|
49
|
+
v.collect{ |e| "#{m}#{f} '#{e}'" }.join(' ')
|
50
|
+
when true
|
51
|
+
"#{m}#{f}"
|
52
|
+
when false, nil
|
53
|
+
''
|
54
|
+
else
|
55
|
+
"#{m}#{f} '#{v}'"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return (flags + self).join(" ")
|
59
|
+
end
|
60
|
+
|
61
|
+
# Not empty?
|
62
|
+
|
63
|
+
def not_empty?
|
64
|
+
!empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
begin
|
2
|
+
require 'facets/net/smtp_tls'
|
3
|
+
rescue LoadError
|
4
|
+
require 'net/smtp'
|
5
|
+
end
|
6
|
+
|
7
|
+
#module Rivets
|
8
|
+
module EmailUtils
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# Email function to easily send out an email.
|
13
|
+
#
|
14
|
+
# Settings:
|
15
|
+
#
|
16
|
+
# subject Subject of email message.
|
17
|
+
# from Message FROM address [email].
|
18
|
+
# to Email address to send announcemnt.
|
19
|
+
# server Email server to route message.
|
20
|
+
# port Email server's port.
|
21
|
+
# domain Email server's domain name.
|
22
|
+
# account Email account name.
|
23
|
+
# login Login type: plain, cram_md5 or login [plain].
|
24
|
+
# secure Uses TLS security, true or false? [false]
|
25
|
+
# message Mesage to send -or-
|
26
|
+
# file File that contains message.
|
27
|
+
#
|
28
|
+
# (Square brackets indicate defaults taken from Project information.
|
29
|
+
# if used via Project class.)
|
30
|
+
|
31
|
+
def email(message, settings)
|
32
|
+
server = settings['server']
|
33
|
+
account = settings['account']
|
34
|
+
login = settings['login'].to_sym
|
35
|
+
subject = settings['subject']
|
36
|
+
mail_to = settings['to'] || settings['mail_to']
|
37
|
+
mail_from = settings['from'] || settings['mail_from']
|
38
|
+
secure = settings['secure']
|
39
|
+
domain = settings['domain'] || server
|
40
|
+
|
41
|
+
port ||= (secure ? 465 : 25)
|
42
|
+
account ||= mail_from
|
43
|
+
login ||= :plain
|
44
|
+
|
45
|
+
#mail_to = nil if mail_to.empty?
|
46
|
+
|
47
|
+
raise ArgumentError, "missing email field -- server" unless server
|
48
|
+
raise ArgumentError, "missing email field -- account" unless account
|
49
|
+
raise ArgumentError, "missing email field -- subject" unless subject
|
50
|
+
raise ArgumentError, "missing email field -- to" unless mail_to
|
51
|
+
raise ArgumentError, "missing email field -- from" unless mail_from
|
52
|
+
|
53
|
+
passwd = password(account)
|
54
|
+
|
55
|
+
mail_to = [mail_to].flatten.compact
|
56
|
+
|
57
|
+
msg = ""
|
58
|
+
msg << "From: #{mail_from}\n"
|
59
|
+
msg << "To: #{mail_to.join(';')}\n"
|
60
|
+
msg << "Subject: #{subject}\n"
|
61
|
+
msg << ""
|
62
|
+
msg << message
|
63
|
+
|
64
|
+
begin
|
65
|
+
Net::SMTP.enable_tls if Net::SMTP.respond_to?(:enable_tls) and secure
|
66
|
+
Net::SMTP.start(server, port, domain, account, passwd, login) do |s|
|
67
|
+
s.send_message( msg, mail_from, mail_to )
|
68
|
+
end
|
69
|
+
puts "Email sent successfully to #{mail_to.join(';')}."
|
70
|
+
return true
|
71
|
+
rescue => e
|
72
|
+
if trace?
|
73
|
+
raise e
|
74
|
+
else
|
75
|
+
abort "Email delivery failed."
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#def password( account )
|
81
|
+
# @password || ENV['PASSWORD'] || ask("Password for #{account}: ")
|
82
|
+
#end
|
83
|
+
|
84
|
+
end
|
85
|
+
#end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
module FileTest
|
5
|
+
module_function
|
6
|
+
|
7
|
+
BUF_SIZE = 1024*1024
|
8
|
+
|
9
|
+
# Are two files identical? This compares size and then checksum.
|
10
|
+
def identical?(file1, file2)
|
11
|
+
size(file1) == size(file2) && md5(file1) == md5(file2)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return an md5 checkum. If a directory is given, will
|
15
|
+
# return a nested array of md5 checksums for all entries.
|
16
|
+
|
17
|
+
def md5(path)
|
18
|
+
if File.directory?(path)
|
19
|
+
md5_list = []
|
20
|
+
crt_dir = Dir.new(path)
|
21
|
+
crt_dir.each do |file_name|
|
22
|
+
next if file_name == '.' || file_name == '..'
|
23
|
+
md5_list << md5("#{crt_dir.path}#{file_name}")
|
24
|
+
end
|
25
|
+
md5_list
|
26
|
+
else
|
27
|
+
hasher = Digest::MD5.new
|
28
|
+
open(path, "r") do |io|
|
29
|
+
counter = 0
|
30
|
+
while (!io.eof)
|
31
|
+
readBuf = io.readpartial(BUF_SIZE)
|
32
|
+
counter+=1
|
33
|
+
#putc '.' if ((counter+=1) % 3 == 0)
|
34
|
+
hasher.update(readBuf)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return hasher.hexdigest
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Show diff of two files.
|
42
|
+
|
43
|
+
def diff(file1, file2)
|
44
|
+
`diff #{file1} #{file2}`.strip
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ratchets/scaffold/controller'
|
4
|
+
|
5
|
+
module ProUtils
|
6
|
+
|
7
|
+
class ScaffoldCommand #< Console::Command
|
8
|
+
|
9
|
+
def self.start
|
10
|
+
new.start
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
args, opts = Console::Arguments.new.parse
|
15
|
+
|
16
|
+
help if opts['help']
|
17
|
+
|
18
|
+
@type = args[0].to_s.downcase
|
19
|
+
|
20
|
+
exit -1 if @type == ''
|
21
|
+
|
22
|
+
@dryrun = opts['dryrun'] || opts['noharm'] || opts['n']
|
23
|
+
end
|
24
|
+
|
25
|
+
def __help
|
26
|
+
$stdout << File.read(File.join(File.dirname(__FILE__), 'help.txt'))
|
27
|
+
exit 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def __dryrun
|
31
|
+
@dryrun = true
|
32
|
+
end
|
33
|
+
alias :__noharm, :__dryrun
|
34
|
+
alias :_n, :__dryrun
|
35
|
+
|
36
|
+
def start
|
37
|
+
Architect.scaffold(@type, :dryrun => @dryrun)
|
38
|
+
end
|
39
|
+
|
40
|
+
def help
|
41
|
+
$stdout << File.read(File.join(File.dirname(__FILE__), 'help.txt'))
|
42
|
+
exit 0
|
43
|
+
end
|
44
|
+
|
45
|
+
end #class Command
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Scaffold Builder is a specialized class that acts
|
2
|
+
# as a restricted space with a limited command set
|
3
|
+
# for preforming scaffolding.
|
4
|
+
#
|
5
|
+
# The default behavior is simply to copy all the contents
|
6
|
+
# of the selected scaffold to the currrent directory.
|
7
|
+
# But if a scaffold.rb file is provided with the scaffolding
|
8
|
+
# this script will be run in the Builder context instead.
|
9
|
+
|
10
|
+
class Builder
|
11
|
+
|
12
|
+
def self.create( folder, options=nil )
|
13
|
+
i = new
|
14
|
+
Dir.chdir(folder) do
|
15
|
+
if File.exist?('scaffold.rb')
|
16
|
+
code = "def self.install( options=nil )\n" << File.read('scaffold.rb') << "\nend"
|
17
|
+
i.instance_eval code
|
18
|
+
end
|
19
|
+
i.install( options.to_openobject )
|
20
|
+
end
|
21
|
+
return *i.results
|
22
|
+
end
|
23
|
+
|
24
|
+
# FIXME Need to improve undefining most instance methods for this context.
|
25
|
+
instance_methods.each{ |m| undef_method m unless m =~ /__|send|class|object|instance/ }
|
26
|
+
|
27
|
+
def initialize( options=nil )
|
28
|
+
@note = []
|
29
|
+
@dirs = []
|
30
|
+
@copy = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return results.
|
34
|
+
|
35
|
+
def results
|
36
|
+
return @note, @dirs, @copy
|
37
|
+
end
|
38
|
+
|
39
|
+
# Change directory in project as it is being build.
|
40
|
+
# This makes it easy to conditionally build tiers of
|
41
|
+
# structure.
|
42
|
+
|
43
|
+
def cd( dir )
|
44
|
+
if dir == '..'
|
45
|
+
@cwd = File.dirname(@cdir)
|
46
|
+
else
|
47
|
+
@cwd = [@cwd,dir].to_path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Make a new project directory.
|
52
|
+
|
53
|
+
def mkdir(dir)
|
54
|
+
@dirs << [@cwd,dir].to_path
|
55
|
+
end
|
56
|
+
|
57
|
+
# Copy +glob+ of files from scaffolding +dir+ to project.
|
58
|
+
#
|
59
|
+
# If +to+ is omitted copies the files as named.
|
60
|
+
# If +to+ is given then the files are renamed or
|
61
|
+
# relocated accordingly. Use '*' in +to+ to substitute
|
62
|
+
# for the file name. For example:
|
63
|
+
#
|
64
|
+
# copy 'standard', '**/*, 'src/*'
|
65
|
+
#
|
66
|
+
# This would copy all the files in the scaffoldings subdirectory,
|
67
|
+
# +standard/+, to the project directory +src/+.
|
68
|
+
|
69
|
+
def copy(dir, glob, to=nil)
|
70
|
+
Dir.chdir(dir) do
|
71
|
+
Dir.glob(glob).collect do |file|
|
72
|
+
if File.file?(file)
|
73
|
+
from = File.join(dir, file)
|
74
|
+
if to
|
75
|
+
tofile = [@cwd, to.gsub('*', file)].to_path
|
76
|
+
else
|
77
|
+
tofile = [@cwd, file].to_path
|
78
|
+
end
|
79
|
+
@copy[from] = tofile
|
80
|
+
else
|
81
|
+
@dirs << [@cwd, file].to_path
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def note( str )
|
88
|
+
@note << str
|
89
|
+
end
|
90
|
+
|
91
|
+
# default installation routine
|
92
|
+
|
93
|
+
def install( options=nil )
|
94
|
+
copy '.', '**/*'
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|