ratch 1.1.0 → 1.2.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 (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
+