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.
Files changed (62) hide show
  1. data/CHANGES +17 -0
  2. data/COPYING +674 -0
  3. data/README +78 -0
  4. data/RELEASE +7 -0
  5. data/TODO +4 -0
  6. data/bin/icli +278 -0
  7. data/bin/mint +139 -0
  8. data/bin/rtar +69 -0
  9. data/bin/xact +121 -0
  10. data/data/mint/cherry/_scaffold.rb +4 -0
  11. data/data/mint/roll/name-1.0.0.roll +26 -0
  12. data/data/mint/ruby/README +17 -0
  13. data/data/mint/ruby/README.first +10 -0
  14. data/data/mint/ruby/README.license +403 -0
  15. data/data/mint/ruby/meta/MANIFEST +2 -0
  16. data/data/mint/ruby/meta/name-1.0.0.roll +26 -0
  17. data/data/mint/ruby/script/finish_scaffold +8 -0
  18. data/data/mint/ruby/script/setup +1600 -0
  19. data/data/mint/website/css/clean.css +5 -0
  20. data/data/mint/website/index.html +0 -0
  21. data/demo/demo_rtar/Lorem_ipsum.txt +233 -0
  22. data/demo/demo_rtar/lib/demo_rock/tryme.rb +2 -0
  23. data/demo/demo_rtar/meta/data +6 -0
  24. data/demo/demo_rtar/web/index.html +13 -0
  25. data/demo/demo_rtar/web/rocklobster.jpg +0 -0
  26. data/demo/mint/loremipsum.txt +9 -0
  27. data/demo/mint/tryme.rb +33 -0
  28. data/lib/proutils/icli/abstract_host.rb +71 -0
  29. data/lib/proutils/icli/gforge.rb +668 -0
  30. data/lib/proutils/icli/rubyforge.rb +26 -0
  31. data/lib/proutils/icli/tool.rb +128 -0
  32. data/lib/proutils/icli/uploadutils.rb +410 -0
  33. data/lib/proutils/mint/copier.rb +324 -0
  34. data/lib/proutils/mint/fileutils.rb +47 -0
  35. data/lib/proutils/mint/help.txt +0 -0
  36. data/lib/proutils/rtar/rtar.rb +309 -0
  37. data/lib/proutils/rtar/vendor/archive/tar/minitar/command.rb +814 -0
  38. data/lib/proutils/rtar/vendor/archive/tar/minitar.rb +979 -0
  39. data/lib/proutils/xact/extract.rb +211 -0
  40. data/lib/proutils/xact/save.rb +151 -0
  41. data/meta/MANIFEST +100 -0
  42. data/meta/config.yaml +12 -0
  43. data/meta/icli.yaml +16 -0
  44. data/meta/project.yaml +27 -0
  45. data/meta/proutils.roll +3 -0
  46. data/test/fixture.rb +6 -0
  47. data/test/lib/test_exacto.rb +54 -0
  48. data/work/ANN +14 -0
  49. data/work/icli/icli +223 -0
  50. data/work/icli/rake.rb +82 -0
  51. data/work/icli/utils/consoleutils.rb +67 -0
  52. data/work/icli/utils/emailutils.rb +85 -0
  53. data/work/icli/utils/fileutils.rb +47 -0
  54. data/work/mint/command-old.rb +48 -0
  55. data/work/mint/lazyfile.rb +97 -0
  56. data/work/mint/part.rb +316 -0
  57. data/work/mint/scaffold-old.rb +420 -0
  58. data/work/rtar/index.html +68 -0
  59. data/work/rtar/old-index.html +63 -0
  60. data/work/xact/xact-ginsu +5 -0
  61. data/work/xact/xact-ruby.rb +155 -0
  62. 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