ratch 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/.ruby +99 -0
  2. data/COPYING +203 -21
  3. data/History.rdoc +35 -0
  4. data/License.txt +204 -0
  5. data/README.rdoc +113 -0
  6. data/Version +1 -0
  7. data/bin/ludo +16 -0
  8. data/bin/ratch +1 -8
  9. data/lib/ratch.rb +28 -0
  10. data/lib/ratch.yml +99 -0
  11. data/lib/ratch/batch.rb +500 -0
  12. data/lib/ratch/console.rb +199 -0
  13. data/lib/ratch/core_ext.rb +1 -4
  14. data/lib/ratch/core_ext/facets.rb +15 -1
  15. data/lib/ratch/core_ext/filetest.rb +29 -0
  16. data/lib/ratch/core_ext/{string.rb → to_actual_filename.rb} +0 -23
  17. data/lib/ratch/core_ext/to_console.rb +30 -12
  18. data/lib/ratch/core_ext/{object.rb → to_yamlfrag.rb} +1 -0
  19. data/lib/ratch/core_ext/unfold_paragraphs.rb +27 -0
  20. data/lib/ratch/file_list.rb +411 -0
  21. data/lib/ratch/script.rb +99 -5
  22. data/lib/ratch/script/help.rb +84 -0
  23. data/lib/ratch/shell.rb +783 -0
  24. data/lib/ratch/system.rb +15 -0
  25. data/lib/ratch/utils/cli.rb +49 -0
  26. data/lib/ratch/utils/config.rb +52 -0
  27. data/lib/ratch/{emailer.rb → utils/email.rb} +43 -6
  28. data/lib/ratch/utils/ftp.rb +134 -0
  29. data/lib/ratch/utils/pom.rb +22 -0
  30. data/lib/ratch/utils/rdoc.rb +48 -0
  31. data/lib/ratch/utils/tar.rb +88 -0
  32. data/lib/ratch/utils/xdg.rb +39 -0
  33. data/lib/ratch/utils/zlib.rb +54 -0
  34. data/spec/01_shell.rdoc +198 -0
  35. data/spec/02_script.rdoc +34 -0
  36. data/spec/03_batch.rdoc +71 -0
  37. data/spec/04_system.rdoc +3 -0
  38. data/spec/applique/array.rb +8 -0
  39. data/spec/applique/setup.rb +20 -0
  40. data/test/case_batch.rb +63 -0
  41. data/test/case_shell.rb +46 -0
  42. data/test/core_ext/case_pathname.rb +361 -0
  43. data/test/helper.rb +4 -0
  44. data/test/utils/case_cli.rb +6 -0
  45. data/test/utils/case_config.rb +12 -0
  46. data/test/utils/case_email.rb +10 -0
  47. data/test/utils/case_ftp.rb +6 -0
  48. data/test/utils/case_pom.rb +17 -0
  49. data/test/utils/case_rdoc.rb +23 -0
  50. data/test/utils/case_tar.rb +6 -0
  51. data/test/utils/case_zlib.rb +11 -0
  52. data/test/utils/fixtures/pom_sample/Profile +4 -0
  53. data/test/utils/fixtures/rdoc_sample/README.rdoc +4 -0
  54. data/test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb +9 -0
  55. metadata +139 -82
  56. data/HISTORY +0 -6
  57. data/MANIFEST +0 -53
  58. data/NEWS +0 -12
  59. data/README +0 -87
  60. data/VERSION +0 -1
  61. data/demo/tryme-task.ratch +0 -12
  62. data/demo/tryme1.ratch +0 -6
  63. data/doc/log/basic_stats/index.html +0 -39
  64. data/doc/log/notes.xml +0 -18
  65. data/doc/log/stats.log +0 -14
  66. data/doc/log/syntax.log +0 -0
  67. data/doc/log/testunit.log +0 -156
  68. data/lib/ratch/commandline.rb +0 -16
  69. data/lib/ratch/core_ext/pathname.rb +0 -38
  70. data/lib/ratch/dsl.rb +0 -420
  71. data/lib/ratch/index.rb +0 -4
  72. data/lib/ratch/io.rb +0 -116
  73. data/lib/ratch/plugin.rb +0 -65
  74. data/lib/ratch/service.rb +0 -33
  75. data/lib/ratch/task.rb +0 -249
  76. data/lib/ratch/task2.rb +0 -298
  77. data/meta/abstract +0 -4
  78. data/meta/author +0 -1
  79. data/meta/contact +0 -1
  80. data/meta/homepage +0 -1
  81. data/meta/name +0 -1
  82. data/meta/requires +0 -4
  83. data/meta/summary +0 -1
  84. data/test/README +0 -1
  85. data/test/test_helper.rb +0 -4
  86. data/test/test_task.rb +0 -46
@@ -0,0 +1,15 @@
1
+ module Ratch
2
+
3
+ # TODO: Build it!
4
+ #
5
+ # The System class provides a robust interface for interacting with
6
+ # system commands. It is essenatially a wrapper around popen3 or popen4.
7
+ #
8
+ # Having a separate class rather integrating this into Shell (as
9
+ # Ruby's standard Shell class does) provides a better SOC.
10
+ #
11
+ class System
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,49 @@
1
+ module Ratch
2
+
3
+ # TODO: How best to support CLI interface?
4
+ module CLI
5
+
6
+ #
7
+ def self.included(base)
8
+ require 'facets/argvector'
9
+ end
10
+
11
+ #
12
+ def self.extended(base)
13
+ require 'facets/argvector'
14
+ end
15
+
16
+ #
17
+ def initialize(*args)
18
+ argv = ArgVector.new(ARGV)
19
+
20
+ @arguments, parameters = *argv.parameters
21
+
22
+ args << {} unless Hash === args.last
23
+
24
+ opts = args.last
25
+
26
+ opts.merge!(parameters)
27
+
28
+ super(*args)
29
+ end
30
+
31
+ #
32
+ def arguments
33
+ @arguments
34
+ end
35
+
36
+ # DEPRECATE!
37
+ #alias_method :commandline, :cli
38
+
39
+ # DEPRECATE!
40
+ #alias_method :command, :cli
41
+
42
+ #
43
+ #def commandline
44
+ # #@commandline ||= ArgVector.new(ARGV)
45
+ # @commandline
46
+ #end
47
+ end
48
+
49
+ end
@@ -0,0 +1,52 @@
1
+ module Ratch
2
+
3
+ # Utility extensions for working with configuration files.
4
+ #--
5
+ # TODO: Perhaps utilize confectionary gem in future?
6
+ #++
7
+ module ConfigUtils
8
+
9
+ #
10
+ def self.included(base)
11
+ require 'yaml'
12
+ end
13
+
14
+ def self.extended(base)
15
+ included(base)
16
+ end
17
+
18
+ # Load configuration data from a file. Results are cached and an empty
19
+ # Hash is returned if the file is not found.
20
+ #
21
+ # Since they are YAML files, they can optionally end with '.yaml' or '.yml'.
22
+ def configuration(file)
23
+ @configuration ||= {}
24
+ @configuration[file] ||= (
25
+ begin
26
+ configuration!(file)
27
+ rescue LoadError
28
+ Hash.new{ |h,k| h[k] = {} }
29
+ end
30
+ )
31
+ end
32
+
33
+ # Load configuration data from a file. The "bang" version will raise an error
34
+ # if file is not found. It also does not cache the results.
35
+ #
36
+ # Since they are YAML files, they can optionally end with '.yaml' or '.yml'.
37
+ def configuration!(file)
38
+ @configuration ||= {}
39
+ patt = file + "{.yml,.yaml,}"
40
+ path = Dir.glob(patt, File::FNM_CASEFOLD).find{ |f| File.file?(f) }
41
+ if path
42
+ # The || {} is in case the file is empty.
43
+ data = YAML::load(File.open(path)) || {}
44
+ @configuration[file] = data
45
+ else
46
+ raise LoadError, "Missing file -- #{path}"
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -1,11 +1,37 @@
1
- begin
2
- require 'facets/net/smtp_tls'
3
- rescue LoadError
4
- require 'net/smtp'
5
- end
1
+ module Ratch
6
2
 
3
+ # The Mail utility module provides an easy to use +email+ method.
4
+ module EmailUtils
7
5
 
8
- module Ratch
6
+ # Email function to easily send out an email.
7
+ #
8
+ # Settings:
9
+ #
10
+ # subject Subject of email message.
11
+ # from Message FROM address [email].
12
+ # to Email address to send announcemnt.
13
+ # server Email server to route message.
14
+ # port Email server's port.
15
+ # domain Email server's domain name.
16
+ # account Email account name if needed.
17
+ # password Password for login..
18
+ # login Login type: plain, cram_md5 or login [plain].
19
+ # secure Uses TLS security, true or false? [false]
20
+ # message Mesage to send -or-
21
+ # file File that contains message.
22
+ #
23
+ def email(options)
24
+ options[:file] = localize(options[:file]) if options[:file]
25
+ emailer = Emailer.new(options.rekey)
26
+ success = emailer.email
27
+ if Exception === success
28
+ puts "Email failed: #{success.message}."
29
+ else
30
+ puts "Email sent successfully to #{success.join(';')}."
31
+ end
32
+ end
33
+
34
+ end
9
35
 
10
36
  # Emailer class makes it easy send out an email.
11
37
  #
@@ -67,6 +93,8 @@ module Ratch
67
93
 
68
94
  #
69
95
  def initialize(options={})
96
+ require_smtp
97
+
70
98
  options = options.rekey
71
99
 
72
100
  if not options[:server]
@@ -171,6 +199,15 @@ module Ratch
171
199
  return inp
172
200
  end
173
201
 
202
+ #
203
+ def require_smtp
204
+ begin
205
+ require 'facets/net/smtp_tls'
206
+ rescue LoadError
207
+ require 'net/smtp'
208
+ end
209
+ end
210
+
174
211
  end
175
212
 
176
213
  end
@@ -0,0 +1,134 @@
1
+ module Ratch
2
+
3
+ # FIXME: This module needs major work. Methods #ftp_files and
4
+ # ftp_stage_transfer need to either be generalized and moved to
5
+ # Shell or Script, or removed.
6
+ #
7
+ module FTPUtils
8
+
9
+ def self.included(base)
10
+ require 'net/ftp'
11
+ require 'net/sftp'
12
+ end
13
+
14
+ def self.extended(base)
15
+ included(base)
16
+ end
17
+
18
+ # Use ftp to upload files.
19
+ #
20
+ def ftp(keys)
21
+ keys = upload_parameters(keys)
22
+
23
+ # set transfer rules
24
+ if keys.stage
25
+ trans = ftp_stage_transfer(keys.stage)
26
+ else
27
+ ftp_files(keys.dir, keys.copy).each do |from|
28
+ trans << [from,from]
29
+ end
30
+ end
31
+
32
+ # append location of publication dir to from
33
+ dir = keys.dir
34
+ trans.collect!{ |from,to| [File.join(dir,from), to] }
35
+
36
+ if keys.dryrun
37
+ puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
38
+ keys.trans.each do |f, t|
39
+ puts "ftp put #{f} #{t}"
40
+ end
41
+ else
42
+ Net::FTP.open(keys.host) do |ftp|
43
+ ftp.login(keys.user) #password?
44
+ ftp.chdir(keys.root)
45
+ keys.trans.each do |f, t|
46
+ puts "ftp #{f} #{t}" unless keys.quiet
47
+ ftp.putbinaryfile( f, t, 1024 )
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ # Use sftp to upload files.
54
+ #
55
+ def sftp( keys )
56
+ keys = upload_parameters(keys)
57
+
58
+ # set transfer rules
59
+ if keys.stage
60
+ trans = ftp_stage_transfer(keys.stage)
61
+ else
62
+ ftp_files(keys.dir, keys.copy).each do |from|
63
+ trans << [from,from]
64
+ end
65
+ end
66
+
67
+ # append location of publication dir to from
68
+ dir = keys.dir
69
+ trans.collect!{ |from,to| [File.join(dir,from), to] }
70
+
71
+ if keys.dryrun
72
+ puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
73
+ keys.trans.each do |f,t|
74
+ puts "sftp put #{f} #{t}"
75
+ end
76
+ else
77
+ Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
78
+ #sftp.login( user )
79
+ sftp.chdir(keys.root)
80
+ keys.trans.each do |f,t|
81
+ puts "sftp #{f} #{t}" unless keys.quiet
82
+ sftp.put_file(f,t) #, 1024 )
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ # Put together the list of files to copy.
89
+ def ftp_files( dir, copy )
90
+ Dir.chdir(dir) do
91
+ del, add = copy.partition{ |f| /^[-]/ =~ f }
92
+
93
+ # remove - and + prefixes
94
+ del.collect!{ |f| f.sub(/^[-]/,'') }
95
+ add.collect!{ |f| f.sub(/^[+]/,'') }
96
+
97
+ #del.concat(must_exclude)
98
+
99
+ ftp_files = []
100
+ add.each{ |g| files += Dir.glob(g) }
101
+ del.each{ |g| files -= Dir.glob(g) }
102
+
103
+ files.collect!{ |f| f.sub(/^\//,'') }
104
+
105
+ return files
106
+ end
107
+ end
108
+
109
+ # Combine three part stage list into a two part from->to list.
110
+ #
111
+ # Using the stage list of three space separated fields.
112
+ #
113
+ # fromdir file todir
114
+ #
115
+ # This is used to generate a from -> to list of the form:
116
+ #
117
+ # fromdir/file todir/file
118
+ #
119
+ def ftp_stage_transfer( list )
120
+ trans = []
121
+ list.each do |line|
122
+ trans << Shellwords.shellwords(line)
123
+ end
124
+
125
+ trans.collect! do |from, base, to|
126
+ file = File.join(from,base)
127
+ to = File.join(to,base)
128
+ [from, to]
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,22 @@
1
+ module Ratch
2
+
3
+ # Methods for utilizing Ruby POM.
4
+ module POMUtils
5
+
6
+ def self.included(base)
7
+ require 'pom'
8
+ end
9
+
10
+ def self.extended(base)
11
+ included(base)
12
+ end
13
+
14
+ #
15
+ def project
16
+ @project ||= ::POM::Project.new
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
@@ -0,0 +1,48 @@
1
+ module Ratch
2
+
3
+ # Provides a pure-Ruby method for generating RDocs.
4
+ module RDocUtils
5
+
6
+ DEFAULT_RDOC_OPTIONS = {
7
+ :quiet => true
8
+ }
9
+
10
+ # RDoc command.
11
+ #
12
+ # :call-seq:
13
+ # rdoc(file1, file2, ..., :opt1 => val1, ...)
14
+ #
15
+ def rdoc(*files)
16
+ require 'rdoc/rdoc'
17
+
18
+ options = Hash===files.last ? files.pop : {}
19
+ options.rekey!(&:to_s)
20
+
21
+ options['title'] ||= options.delete('T')
22
+
23
+ options['debug'] = options['debug'] #|| debug?
24
+ options['quiet'] = options['quiet'] #|| quiet?
25
+ options['verbose'] = options['verbose'] #|| verbose?
26
+
27
+ # apply pom (todo?)
28
+ #options['title'] ||= metadata.title
29
+
30
+ options = DEFAULT_RDOC_OPTIONS.merge(options)
31
+
32
+ locally do
33
+ rdoc = RDoc::RDoc.new
34
+ opts = options.to_argv + files
35
+ $stderr.puts("rdoc " + opts.join(' ')) if ($VERBOSE || $DEBUG)
36
+ disable_warnings do
37
+ rdoc.document(options.to_argv + files)
38
+ end
39
+ end
40
+ end
41
+
42
+ #
43
+ # TODO: Implement ri doc generator.
44
+
45
+ end
46
+
47
+ end
48
+
@@ -0,0 +1,88 @@
1
+ require 'ratch/utils/zlib'
2
+
3
+ module Ratch
4
+
5
+ # Utility methods for working with tarballs archives.
6
+ #--
7
+ # TODO: Add compress support ?
8
+ # TODO: Add bzip support ?
9
+ #++
10
+ module TarUtils
11
+
12
+ # When included include GZipUtils too.
13
+ def self.included(base)
14
+ #require 'zlib'
15
+ include ZLibUtils
16
+ require 'archive/tar/minitar'
17
+ end
18
+
19
+ #
20
+ def self.extended(base)
21
+ included(base)
22
+ end
23
+
24
+ # Tar
25
+ def tar(folder, file=nil, options={})
26
+ noop, verbose = *util_options(options)
27
+ file ||= File.basename(File.expand_path(folder)) + '.tar'
28
+ cmd = "tar -cf #{file} #{folder}"
29
+ puts cmd if verbose
30
+ unless noop
31
+ locally do
32
+ gzIO = File.open(file, 'wb')
33
+ Archive::Tar::Minitar.pack(folder, gzIO)
34
+ end
35
+ end
36
+ path(file)
37
+ end
38
+
39
+ # Untar
40
+ def untar(file, options={})
41
+ noop, verbose = *util_options(options)
42
+ #file ||= File.basename(File.expand_path(folder)) + '.tar'
43
+ cmd = "untar #{file}"
44
+ puts cmd if verbose
45
+ unless noop
46
+ locally do
47
+ gzIO = File.open(file, 'wb')
48
+ Archive::Tar::Minitar.unpack(gzIO)
49
+ end
50
+ end
51
+ path(file)
52
+ end
53
+
54
+ # Tar Gzip
55
+ def tar_gzip(folder, file=nil, options={})
56
+ noop, verbose = *util_options(options)
57
+ file ||= File.basename(File.expand_path(folder)) + '.tar.gz' # '.tgz' which ?
58
+ cmd = "tar --gzip -czf #{file} #{folder}"
59
+ puts cmd if verbose
60
+ unless noop
61
+ locally do #folder, file = localize(folder), localize(file)
62
+ gzIO = Zlib::GzipWriter.new(File.open(file, 'wb'))
63
+ Archive::Tar::Minitar.pack(folder, gzIO)
64
+ end
65
+ end
66
+ path(file)
67
+ end
68
+
69
+ alias_method :tar_z, :tar_gzip
70
+
71
+ # Untar Gzip
72
+ #
73
+ # FIXME: Write unified untar_gzip function.
74
+ def untar_gzip(file, options={})
75
+ untar(ungzip(file, options), options)
76
+ end
77
+
78
+ alias_method :untar_z, :untar_gzip
79
+
80
+ #def tgz(folder, file=nil, options={})
81
+ # file ||= File.basename(File.expand_path(folder)) + '.tgz'
82
+ # tar_gzip(folder, file, options)
83
+ #end
84
+
85
+ end
86
+
87
+ end
88
+