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,39 @@
1
+ module Ratch
2
+
3
+ # The XDG utility module provides access ot the XDG library functions.
4
+ # This module requires the `xdg` gem.
5
+ #
6
+ # This module simply maps the #xdg method to the XDG function module.
7
+ #
8
+ # NOTE: This module is non-essential since one can just use
9
+ # the XDG module directly, however we want to encourage the
10
+ # use XDG, so it's been provided to encourage that in the context
11
+ # of a Ratch script.
12
+ #
13
+ module XDGUtils
14
+
15
+ def self.included(base)
16
+ begin
17
+ require 'xdg'
18
+ rescue
19
+ $stderr << "The `xdg` gem is needed to use the XDGUtils module."
20
+ exit -1
21
+ end
22
+ end
23
+
24
+ def self.extended(base)
25
+ included(base)
26
+ end
27
+
28
+ # Simple access to XDG function module.
29
+ #
30
+ # xdg.config.home #=> "~/.config"
31
+ #
32
+ def xdg
33
+ XDG
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,54 @@
1
+ module Ratch
2
+
3
+ #
4
+ module ZlibUtils
5
+
6
+ #
7
+ def self.included(base)
8
+ require 'zlib'
9
+ end
10
+
11
+ def self.extended(base)
12
+ included(base)
13
+ end
14
+
15
+ # Create a gzip file.
16
+ def gzip(file, tofile=nil, options={})
17
+ noop, verbose = *util_options(options)
18
+
19
+ tofile ||= File.basename(file) + '.gz'
20
+
21
+ puts "gzip #{file}" if verbose
22
+
23
+ file = localize(file)
24
+ tofile = localize(tofile)
25
+
26
+ Zlib::GzipWriter.open(tofile) do |gz|
27
+ gz.write(File.read(file))
28
+ end unless noop
29
+
30
+ return tofile
31
+ end
32
+
33
+ # Unpack a gzip file.
34
+ def ungzip(file, options={})
35
+ noop, verbose = *util_options(options)
36
+
37
+ fname = File.basename(file).chomp(File.extname(file))
38
+
39
+ puts "ungzip #{file}" if verbose
40
+
41
+ fname = localize(fname)
42
+ file = localize(file)
43
+
44
+ Zlib::GzipReader.open(file) do |gz|
45
+ File.open(fname, 'wb'){ |f| f << gz.read }
46
+ end unless noop
47
+
48
+ return fname
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,198 @@
1
+ = Ratch::Shell
2
+
3
+ The Shell class mimics a basic shell command line prompt.
4
+
5
+ require 'ratch/shell'
6
+
7
+ The demonstration sets up sample directory consisting of the following
8
+ entires in the tmp/qed directory:
9
+
10
+ foo.txt
11
+ zoo/
12
+ zoo/bar.txt
13
+
14
+ == Initial Path
15
+
16
+ When no path argument is provided to the initializer, the present working path
17
+ is used. The path is stored as a Pathname object.
18
+
19
+ shell = Ratch::Shell.new
20
+ shell.work.assert = Pathname.new(Dir.pwd).expand_path
21
+
22
+ Otherwise the path given is used.
23
+
24
+ shell = Ratch::Shell.new('.')
25
+ shell.work.assert = Pathname.new('.').expand_path
26
+
27
+ shell = Ratch::Shell.new('..')
28
+ shell.work.assert = Pathname.new('..').expand_path
29
+
30
+ An error is raise if the path does not exist.
31
+
32
+ expect Ratch::FileNotFound do
33
+ Ratch::Shell.new('not_a_path')
34
+ end
35
+
36
+ == Processing Options
37
+
38
+ The +initialize+ method accepts a few options. The +quiet+ option supresses
39
+ all output to stdout.
40
+
41
+ shell = Ratch::Shell.new(:quiet=>true)
42
+ shell.assert.quiet?
43
+
44
+ The +noop+ option prevents any actual writing to disk --the process will
45
+ simply pretend that it has done so.
46
+
47
+ shell = Ratch::Shell.new(:noop=>true)
48
+ shell.assert.noop?
49
+
50
+ The +trace+ option provides step by step feedback on what is taking place.
51
+
52
+ shell = Ratch::Shell.new(:trace=>true)
53
+ shell.assert.trace?
54
+
55
+ The +dryrun+ option is simply a compbination of +noop+ and +trace+.
56
+
57
+ shell = Ratch::Shell.new(:dryrun=>true)
58
+ shell.assert.noop?
59
+ shell.assert.trace?
60
+ shell.assert.dryrun?
61
+
62
+ == Equality
63
+
64
+ For two Shell objects to be considered equal, via #==, they must both
65
+ be instances of Ratch::Shell (or subclass) and have the same working
66
+ path.
67
+
68
+ shell1 = Ratch::Shell.new('.')
69
+ shell2 = Ratch::Shell.new('.')
70
+ shell1.assert = shell2
71
+
72
+ shell1 = Ratch::Shell.new('.')
73
+ shell2 = Ratch::Shell.new('..')
74
+ shell1.refute = shell2
75
+
76
+ The more strict #eql? method also ensures that the +noop+ option is the same.
77
+
78
+ shell1 = Ratch::Shell.new('.', :noop=>true)
79
+ shell2 = Ratch::Shell.new('.', :noop=>true)
80
+ shell1.assert.eql? shell2
81
+
82
+ shell1 = Ratch::Shell.new('.', :noop=>true)
83
+ shell2 = Ratch::Shell.new('.', :noop=>false)
84
+ shell1.refute.eql? shell2
85
+
86
+ == File System Locations
87
+
88
+ The Shell class provides a few convenient methods for accessing common
89
+ locations in the file system, namely #work, #home, #parent and #root.
90
+
91
+ shell = Ratch::Shell.new
92
+
93
+ shell.work.assert == Pathname.new('.').expand_path
94
+ shell.parent.assert == Pathname.new('..').expand_path
95
+
96
+ The current user's home directoryis accessible via the #home method.
97
+
98
+ shell.home.assert == Pathname.new('~').expand_path
99
+
100
+ The system's root folder can be accessed via #root method.
101
+
102
+ shell.root.assert == Pathname.new('/').expand_path
103
+
104
+ In addition the Shell class provides methods for accessing pathnames
105
+ relative to the current shell directory. The #path (or #pathname) method
106
+ returns a Pathname object with the given path.
107
+
108
+ shell.path('foo')
109
+
110
+ This will work regardless if the path actually exists or not. On the other hand,
111
+ the #file and #dir methods will do the same, but will raise an error if the path
112
+ given is not an existing file or a directory, respectively.
113
+
114
+ shell.file('foo.txt')
115
+
116
+ expect Ratch::FileNotFound do
117
+ shell.file('not.txt')
118
+ end
119
+
120
+ shell.dir('zoo')
121
+
122
+ expect Ratch::FileNotFound do
123
+ shell.dir('not')
124
+ end
125
+
126
+ == Entries
127
+
128
+ Shell#entries works just like Dir.entries except that each path is returned
129
+ as a Pathname object.
130
+
131
+ shell = Ratch::Shell.new
132
+
133
+ shell.entries.assert == ['foo.txt', '.', '..', 'zoo'].map{|f| Pathname.new(f)}
134
+
135
+ The #file_entries method limits the list to files only.
136
+
137
+ shell.file_entries.assert == ['foo.txt'].map{|f| Pathname.new(f)}
138
+
139
+ Whereas #directory_entries (or #dir_entries) limits the list to directories.
140
+
141
+ shell.directory_entries.assert == ['.', '..', 'zoo'].map{|f| Pathname.new(f)}
142
+
143
+ Of course, having to deal with the '.' and '..' is annoying most of the time
144
+ so Shell provides more convenient methods. Like #entries, #pathnames
145
+ provides a list of entries less the dot paths.
146
+
147
+ shell.pathnames.assert == ['foo.txt', 'zoo'].map{|f| Pathname.new(f)}
148
+
149
+ The #directories (also #folders) method limits this list to directories only.
150
+
151
+ shell.directories.assert == ['zoo'].map{|f| Pathname.new(f)}
152
+
153
+ And #files works out to be the same as #file_entires.
154
+
155
+ shell.files.assert == ['foo.txt'].map{|f| Pathname.new(f)}
156
+
157
+ == Globbing
158
+
159
+ shell = Ratch::Shell.new
160
+
161
+ shell.glob('*').assert == ['foo.txt', 'zoo']
162
+
163
+ == File Testing
164
+
165
+ Shell provides an interface to most of FileTest's functions.
166
+
167
+ shell.assert.exist?('foo.txt')
168
+ shell.assert.file?('foo.txt')
169
+ shell.refute.directory?('foo.txt')
170
+ shell.assert.directory?('zoo')
171
+
172
+ == File IO
173
+
174
+ Shell can be used to easily read the contents of a file.
175
+
176
+ shell = Ratch::Shell.new
177
+
178
+ shell.read('foo.txt').assert == 'SAMPLE FOO.TXT'
179
+
180
+ As well as write a new file.
181
+
182
+ shell.write('baz.txt', 'BAZ TEXT')
183
+ shell.read('baz.txt').assert == 'BAZ TEXT'
184
+
185
+ Or append to an existing file.
186
+
187
+ shell.append('baz.txt', ' 2')
188
+ shell.read('baz.txt').assert == 'BAZ TEXT 2'
189
+
190
+ The shell command supports many file methods, including #rm.
191
+
192
+ shell.rm('baz.txt')
193
+
194
+ == System Calls
195
+
196
+ The Shell class can also call out to system commands. This is handled
197
+ by the Ratch::System class. See the system.rdoc file for details.
198
+
@@ -0,0 +1,34 @@
1
+ = Ratch::Script
2
+
3
+ The Ratch::Script class is the context used for evaluating Ratch-based
4
+ batch files, aka shell scripts.
5
+
6
+ require 'ratch/script'
7
+
8
+ In most every respect the Script class behaves like Ratch::Shell, except that
9
+ its initializer takes a file name to be evaluated.
10
+
11
+ Let's say we have a Ratch script called 'foo.ratch':
12
+
13
+ #!/usr/bin/env ratch
14
+
15
+ @test_message = "Hello World!"
16
+
17
+ We can load the script via Ratch::Script.new.
18
+
19
+ script = Ratch::Script.new('foo.ratch')
20
+
21
+ The file name can be accessed from the script using #script_file.
22
+
23
+ script.script_file.assert == 'foo.ratch'
24
+
25
+ To execute a script, use the `#execute!` method, or it's alias `#run!`.
26
+
27
+ script.execute!
28
+
29
+ We can see that the script did indeed execute by plubming for the instance
30
+ variable it set.
31
+
32
+ msg = script.instance_variable_get('@test_message')
33
+ msg.assert == "Hello World!"
34
+
@@ -0,0 +1,71 @@
1
+ = Ratch::Batch
2
+
3
+ The Batch class makes makes it possible to work with multiple files
4
+ at once as easily as one would work with a single file.
5
+
6
+ require 'ratch/batch'
7
+
8
+ The demonstration sets up a sample directory consisting of the following
9
+ entires in the temporary working directory:
10
+
11
+ foo.txt
12
+ bar.txt
13
+ zoo/
14
+ zoo/one.txt
15
+ zoo/two.txt
16
+
17
+ To create a new Batch instance, pass the the base directory and any
18
+ inclusion patterns to the initializer.
19
+
20
+ batch = Ratch::Batch.new('.', '*.txt')
21
+
22
+ In this example we will get every `.txt` file at the toplevel of the base
23
+ directory.
24
+
25
+ batch.to_a.assert = ['foo.txt', 'bar.txt'].to_pathnames
26
+
27
+ To get a list of files relative to the base directory, use #entries.
28
+
29
+ batch.entries.assert = ['foo.txt', 'bar.txt'].to_pathnames
30
+
31
+ Internally a Batch instance tracks the files selected via a Ratch::FileList
32
+ object. This can be directly accessed via the #list method.
33
+
34
+ batch.file_list.assert.is_a?(Ratch::FileList)
35
+
36
+ batch.file_list.to_a.assert = ['foo.txt', 'bar.txt']
37
+
38
+ As with the delegated FileTest methods of the Shell class, Batch can test
39
+ the set of files in agregate. For example, to ensure all the entries
40
+ are files we can use the #file? method.
41
+
42
+ batch.assert.file?
43
+
44
+ Likewise to enusre none the entires are directories we can use the #directory?
45
+ method.
46
+
47
+ batch.refute.directory?
48
+
49
+ The Batch list can be reduced to just files or just directories via the #file!
50
+ and #directory! methods.
51
+
52
+ batch = Ratch::Batch.new('.', '*')
53
+ batch.file!
54
+ batch.list.assert = ['foo.txt', 'bar.txt']
55
+
56
+ batch = Ratch::Batch.new('.', '*')
57
+ batch.directory!
58
+ batch.list.assert = ['zoo']
59
+
60
+ The Batch class is enumerable, both #each and #size are defined.
61
+
62
+ batch = Ratch::Batch.new('.', '*.txt')
63
+
64
+ batch.each do |pathname|
65
+ pathname.assert.is_a?(Pathname)
66
+ end
67
+
68
+ batch.size.assert = 2
69
+
70
+ Any enumerable method is likewise applicable.
71
+
@@ -0,0 +1,3 @@
1
+ = Ratch::System
2
+
3
+
@@ -0,0 +1,8 @@
1
+ class ::Array
2
+
3
+ # Helper extension for comparison tests.
4
+ def to_pathnames
5
+ map{ |f| Pathname.new(f) }
6
+ end
7
+
8
+ end
@@ -0,0 +1,20 @@
1
+ require 'fileutils'
2
+
3
+ Before :demo do
4
+ clear_working_directory!
5
+ end
6
+
7
+ When "consisting of the following entires" do |text|
8
+ text.split(/\s+/).each do |file|
9
+ if /\/$/ =~ file
10
+ FileUtils.mkdir_p(file) unless File.directory?(file)
11
+ else
12
+ File.open(file, 'w+'){ |f| f << "SAMPLE #{file}".upcase }
13
+ end
14
+ end
15
+ end
16
+
17
+ When "Let's say we have a Ratch script called '(((.*?)))'" do |file, text|
18
+ File.open(file, 'w'){ |f| f << text }
19
+ end
20
+
@@ -0,0 +1,63 @@
1
+ require 'ratch/batch'
2
+
3
+ KO.case Ratch::Batch do
4
+
5
+ def initialize
6
+ stage_clear
7
+ stage_fake %w{a.txt b.txt d/x.txt d/y.txt}
8
+
9
+ @batch1 = Ratch::Batch.new('.')
10
+ @batch2 = Ratch::Batch.new('.', '*')
11
+ @batch3 = Ratch::Batch.new('.', '**/*')
12
+ end
13
+
14
+ test :local do
15
+ @batch1.local == Pathname.new('.')
16
+ end
17
+
18
+ test :list do
19
+ @batch1.list.is_a?(Array)
20
+ end
21
+
22
+ test :file_list do
23
+ @batch1.file_list.is_a?(Ratch::FileList)
24
+ end
25
+
26
+ test :each do
27
+ r = []
28
+ @batch2.each{ |pn| r << pn }
29
+ r.map(&:to_s).sort == %w{a.txt b.txt d}
30
+ end
31
+
32
+ test "passes #each thru to Enumerable methods" do
33
+ @batch2.all?{ |pn| pn.is_a? Pathname }
34
+ end
35
+
36
+ test :size do
37
+ batch = Ratch::Batch.new('.', '*')
38
+ batch.size == 3
39
+ end
40
+
41
+ test :directory? do
42
+ batch = Ratch::Batch.new('.', '*')
43
+ not batch.directory?
44
+ end
45
+
46
+ test :file? do
47
+ not @batch2.file?
48
+ end
49
+
50
+ test :directory! do
51
+ batch = Ratch::Batch.new('.', '*')
52
+ batch.directory!
53
+ batch.filenames == %w{d}
54
+ end
55
+
56
+ test :file! do
57
+ batch = Ratch::Batch.new('.', '*')
58
+ batch.file!
59
+ batch.filenames.sort == %w{a.txt b.txt}
60
+ end
61
+
62
+ end
63
+