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,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
+