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,113 @@
1
+ = Ratch
2
+
3
+ Ruby-based Batch Scripts
4
+
5
+
6
+ == Introduction
7
+
8
+ Ratch is Ruby-based DSL for building batch scripts. It's intent
9
+ is to ease the burden of batch script writers by supplementing
10
+ the standard ruby environment to be more conducive to the needs
11
+ of batch scripting.
12
+
13
+ In addition to using Ratch to write stand-alone batch scripts,
14
+ it makes a very powerful library for other applications that
15
+ require batch-like functionality. In general any program that
16
+ access the file system extensively could benefit from it's use.
17
+
18
+
19
+ == Resources
20
+
21
+ * home: http://rubyworks.github.com/ratch
22
+ * code: http://github.com/rubyworks/ratch
23
+ * talk: http://googlegroups.com/
24
+
25
+ == Usage
26
+
27
+ === Batch Scripting
28
+
29
+ To use for your own scripts, simply add a bang line.
30
+
31
+ #!/usr/bin/env ratch
32
+
33
+ On Windows, of course, you will want to associate the .ratch extension
34
+ name to the ratch executable instead.
35
+
36
+ === As a Library
37
+
38
+ To use Ratch as a library, require 'ratch' and create an instance of
39
+ Ratch::Shell.
40
+
41
+ If you wish to extend Ratch::Shell for your application, it is recommend
42
+ that you either subclass Ratch::Shell, e.g.
43
+
44
+ require 'ratch'
45
+
46
+ class MyClass < Ratch::Shell
47
+
48
+
49
+ end
50
+
51
+ Or delegate to a Ratch::Shell instance, e.g.
52
+
53
+ require 'ratch'
54
+
55
+ class MyClass
56
+
57
+ def initialize(path)
58
+ @shell = Ratch::Shell.new(path)
59
+ end
60
+
61
+ end
62
+
63
+ For details on all the functionality Ratch provides, please refer to
64
+ the API documentation.
65
+
66
+
67
+ == Bonus Feature
68
+
69
+ Ratch also includes the `ludo` command, which stands for "lookup and do".
70
+ It will ascend up the directory tree searching for a matching executable
71
+ script. If it finds one it will execute the script relative the currently
72
+ ascended directory.
73
+
74
+
75
+ == Installation
76
+
77
+ Standard installation procedure apply.
78
+
79
+ $ gem install ratch
80
+
81
+ or manually using Setup.rb
82
+
83
+ $ tar -xzf ratch-1.0.0.tgz
84
+ $ cd ratch-1.0.0
85
+ $ setup.rb
86
+
87
+
88
+ == Development
89
+
90
+ Ratch is hosted on GitHub.
91
+
92
+ To pull the 'ratch' repository anonymously, use:
93
+
94
+ git clone git://github.com/rubyworks/ratch.git
95
+
96
+
97
+ == Copying
98
+
99
+ Copyright (c) 2008 Thomas Sawyer
100
+
101
+ Licensed under the Apache License, Version 2.0 (the "License");
102
+ you may not use this program except in compliance with the License.
103
+ You may obtain a copy of the License at
104
+
105
+ http://www.apache.org/licenses/LICENSE-2.0
106
+
107
+ Unless required by applicable law or agreed to in writing, software
108
+ distributed under the License is distributed on an "AS IS" BASIS,
109
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
110
+ See the License for the specific language governing permissions and
111
+ limitations under the License.
112
+
113
+
data/Version ADDED
@@ -0,0 +1 @@
1
+ 1.2.0
@@ -0,0 +1,16 @@
1
+ #! /usr/bin/ruby1.8
2
+
3
+ # for FileTest.root?
4
+ require 'facets/filetest'
5
+
6
+ name = ARGV[0]
7
+
8
+ if name
9
+ Dir.chdir '..' until FileTest.executable?(name) or FileTest.root?(Dir.pwd)
10
+ if FileTest.executable?( name )
11
+ system name
12
+ end
13
+ else
14
+ puts "Script #{name} not found."
15
+ end
16
+
data/bin/ratch CHANGED
@@ -1,10 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- $0 = ARGV.shift
4
-
5
2
  require 'ratch/script'
6
-
7
- script = Ratch::Script.new
8
-
9
- script.instance_eval(File.read($0))
10
-
3
+ Ratch::Script.execute(ARGV.shift)
@@ -0,0 +1,28 @@
1
+ module Ratch
2
+ # Access to project metadata.
3
+ def self.metadata
4
+ @metadata ||= (
5
+ require 'yaml'
6
+ YAML.load(File.dirname(__FILE__) + '/ratch.yml')
7
+ )
8
+ end
9
+
10
+ # Access to project metadata via constants.
11
+ def self.const_missing(name)
12
+ metadata[name.to_s.downcase] || super(name)
13
+ end
14
+
15
+ # TODO: Only here b/c of issue with Ruby 1.8.x.
16
+ VERSION = metadata['version']
17
+ end
18
+
19
+ require 'ratch/script'
20
+
21
+ # Load utility extension modules.
22
+ require 'ratch/utils/cli'
23
+ require 'ratch/utils/pom'
24
+ require 'ratch/utils/rdoc'
25
+ #require 'ratch/utils/email'
26
+ #require 'ratch/utils/tar'
27
+ #require 'ratch/utils/zlib'
28
+
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: ratch
3
+ spec_version: 1.0.0
4
+ repositories:
5
+ public: git://github.com/rubyworks/ratch.git
6
+ title: Ratch
7
+ contact: trans <transfire@gmail.com>
8
+ requires:
9
+ - group: []
10
+
11
+ name: facets
12
+ version: 2.9.1+
13
+ - group: []
14
+
15
+ name: minitar
16
+ version: 0.5.3+
17
+ - group:
18
+ - test
19
+ name: ko
20
+ version: 1.2.0~
21
+ - group:
22
+ - test
23
+ name: qed
24
+ version: 0+
25
+ - group:
26
+ - build
27
+ name: syckle
28
+ version: 0+
29
+ resources:
30
+ code: http://github.org/rubyworks/ratch
31
+ mail: http://groups.gooogle.com/group/rubyworks-mailinglist
32
+ home: http://rubyworks.github.org/ratch
33
+ manifest:
34
+ - .ruby
35
+ - bin/ludo
36
+ - bin/ratch
37
+ - lib/ratch/batch.rb
38
+ - lib/ratch/console.rb
39
+ - lib/ratch/core_ext/facets.rb
40
+ - lib/ratch/core_ext/filetest.rb
41
+ - lib/ratch/core_ext/to_actual_filename.rb
42
+ - lib/ratch/core_ext/to_console.rb
43
+ - lib/ratch/core_ext/to_list.rb
44
+ - lib/ratch/core_ext/to_yamlfrag.rb
45
+ - lib/ratch/core_ext/unfold_paragraphs.rb
46
+ - lib/ratch/core_ext.rb
47
+ - lib/ratch/file_list.rb
48
+ - lib/ratch/script/help.rb
49
+ - lib/ratch/script.rb
50
+ - lib/ratch/shell.rb
51
+ - lib/ratch/system.rb
52
+ - lib/ratch/utils/cli.rb
53
+ - lib/ratch/utils/config.rb
54
+ - lib/ratch/utils/email.rb
55
+ - lib/ratch/utils/ftp.rb
56
+ - lib/ratch/utils/pom.rb
57
+ - lib/ratch/utils/rdoc.rb
58
+ - lib/ratch/utils/tar.rb
59
+ - lib/ratch/utils/xdg.rb
60
+ - lib/ratch/utils/zlib.rb
61
+ - lib/ratch.rb
62
+ - lib/ratch.yml
63
+ - man/ratch.1
64
+ - spec/01_shell.rdoc
65
+ - spec/02_script.rdoc
66
+ - spec/03_batch.rdoc
67
+ - spec/04_system.rdoc
68
+ - spec/applique/array.rb
69
+ - spec/applique/setup.rb
70
+ - test/case_batch.rb
71
+ - test/case_shell.rb
72
+ - test/core_ext/case_pathname.rb
73
+ - test/helper.rb
74
+ - test/utils/case_cli.rb
75
+ - test/utils/case_config.rb
76
+ - test/utils/case_email.rb
77
+ - test/utils/case_ftp.rb
78
+ - test/utils/case_pom.rb
79
+ - test/utils/case_rdoc.rb
80
+ - test/utils/case_tar.rb
81
+ - test/utils/case_zlib.rb
82
+ - test/utils/fixtures/pom_sample/Profile
83
+ - test/utils/fixtures/rdoc_sample/README.rdoc
84
+ - test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb
85
+ - README.rdoc
86
+ - History.rdoc
87
+ - Version
88
+ - License.txt
89
+ - COPYING
90
+ version: 1.2.0
91
+ licenses:
92
+ - Apache 2.0
93
+ copyright: Copyright (c) 2009 Thomas Sawyer
94
+ description: Ratch is a Ruby-based batch scripting language. It's a DSL over regular Ruby to make the life of the batch script writter easier.
95
+ summary: Ruby-based Batch Scripting
96
+ organization: RubyWorks
97
+ authors:
98
+ - Trans <transfire@gmail.com>
99
+ created: 2009-09-22
@@ -0,0 +1,500 @@
1
+ require 'ratch/core_ext'
2
+ require 'ratch/file_list'
3
+
4
+ module Ratch
5
+
6
+ # Proccess a list of files in batch.
7
+ #
8
+ # The Batch interface mimics the Shell class in most respects.
9
+ #
10
+ # TODO: Should FileList use Pathname, or only in Batch?
11
+ class Batch
12
+ include Enumerable
13
+
14
+ #
15
+ def self.[](*patterns)
16
+ new('.', *patterns)
17
+ end
18
+
19
+ #
20
+ def initialize(local, *patterns)
21
+ @local = Pathname.new(local)
22
+ @options = (Hash === patterns.last ? patterns.pop : {}).rekey(&:to_sym)
23
+
24
+ @file_list = FileList.all
25
+
26
+ patterns.each do |pattern|
27
+ if @local == Pathname.new('.')
28
+ @file_list.add(pattern)
29
+ else
30
+ @file_list.add(File.join(local,pattern))
31
+ end
32
+ end
33
+ end
34
+
35
+ #
36
+ attr :local
37
+
38
+ # Returns the the underlying FileList object.
39
+ def file_list
40
+ @file_list
41
+ end
42
+
43
+ # Iterate over pathnames.
44
+ def each(&block)
45
+ @file_list.each{ |file| block.call(Pathname.new(file)) }
46
+ end
47
+
48
+ # Returns the Integer size of the list of files.
49
+ def size
50
+ @file_list.size
51
+ end
52
+
53
+ # Return the list of files as Pathname objects.
54
+ def to_a
55
+ @file_list.map{ |file| Pathname.new(file) }
56
+ end
57
+
58
+ # Return the list of files as Pathname objects.
59
+ alias_method :pathnames, :to_a
60
+
61
+ # Returns the list of files as Strings, rather than Pathname objects.
62
+ def list
63
+ @file_list.to_a
64
+ end
65
+ alias_method :filenames, :list
66
+
67
+ # Returns an Array of file paths relative to +local+.
68
+ def entries
69
+ map{ |entry| entry.sub(local.to_s+'/','') }
70
+ end
71
+
72
+ # Limit list to files.
73
+ def file!
74
+ @file_list = @file_list.select{ |f| File.file?(f) }
75
+ end
76
+
77
+ # Limit list to directories.
78
+ def directory!
79
+ @file_list = @file_list.select{ |f| File.directory?(f) }
80
+ end
81
+
82
+ # Limit list to selection block.
83
+ def select!(&block)
84
+ #@file_list = FileList.all(*to_a.select{ |f| block.call(f) })
85
+ @file_list = @file_list.select{ |f| block.call(f) }
86
+ end
87
+
88
+ #############
89
+ # FileTest #
90
+ #############
91
+
92
+ # This is called #size in FileTest but must be renamed to
93
+ # avoid the clash with the Enumerable mixin.
94
+ def byte_size
95
+ inject(0){ |sum, path| sum + FileTest.size(path) }
96
+ end
97
+
98
+ # An alias for #byte_size.
99
+ alias_method :size?, :byte_size
100
+
101
+ def directory? ; all?{ |path| FileTest.directory?(path) } ; end
102
+ def symlink? ; all?{ |path| FileTest.symlink?(path) } ; end
103
+ def readable? ; all?{ |path| FileTest.readable?(path) } ; end
104
+ def chardev? ; all?{ |path| FileTest.chardev?(path) } ; end
105
+ def exist? ; all?{ |path| FileTest.exist?(path) } ; end
106
+ def exists? ; all?{ |path| FileTest.exists?(path) } ; end
107
+ def zero? ; all?{ |path| FileTest.zero?(path) } ; end
108
+ def pipe? ; all?{ |path| FileTest.pipe?(path) } ; end
109
+ def file? ; all?{ |path| FileTest.file?(path) } ; end
110
+ def sticky? ; all?{ |path| FileTest.sticky?(path) } ; end
111
+ def blockdev? ; all?{ |path| FileTest.blockdev?(path) } ; end
112
+ def grpowned? ; all?{ |path| FileTest.grpowned?(path) } ; end
113
+ def setgid? ; all?{ |path| FileTest.setgid?(path) } ; end
114
+ def setuid? ; all?{ |path| FileTest.setuid?(path) } ; end
115
+ def socket? ; all?{ |path| FileTest.socket?(path) } ; end
116
+ def owned? ; all?{ |path| FileTest.owned?(path) } ; end
117
+ def writable? ; all?{ |path| FileTest.writable?(path) } ; end
118
+ def executable? ; all?{ |path| FileTest.executable?(path) } ; end
119
+ def safe? ; all?{ |path| FileTest.safe?(path) } ; end
120
+
121
+ # TODO: Will this work since all paths are localized?
122
+ def relative? ; all?{ |path| FileTest.relative?(path) } ; end
123
+ def absolute? ; all?{ |path| FileTest.absolute?(path) } ; end
124
+
125
+ def writable_real? ; all?{ |path| FileTest.writable_real?(path) } ; end
126
+ def executable_real? ; all?{ |path| FileTest.executable_real?(path) } ; end
127
+ def readable_real? ; all?{ |path| FileTest.readable_real?(path) } ; end
128
+
129
+ alias_method :dir?, :directory?
130
+
131
+ def identical?(other)
132
+ all?{ |path| FileTest.identical?(path, other) }
133
+ end
134
+
135
+ # TODO: Really?
136
+ alias_method :compare_file, :identical?
137
+ alias_method :cmp, :identical?
138
+
139
+
140
+ #############
141
+ # FileUtils #
142
+ #############
143
+
144
+ # Low-level Methods Omitted
145
+ # -------------------------
146
+ # getwd -> pwd
147
+ # compare_file -> cmp
148
+ # remove_file -> rm
149
+ # copy_file -> cp
150
+ # remove_dir -> rmdir
151
+ # safe_unlink -> rm_f
152
+ # makedirs -> mkdir_p
153
+ # rmtree -> rm_rf
154
+ # copy_stream
155
+ # remove_entry
156
+ # copy_entry
157
+ # remove_entry_secure
158
+ # compare_stream
159
+
160
+ # Present working directory.
161
+ # TODO: Does this make sense?
162
+ def pwd
163
+ @local
164
+ end
165
+
166
+ # Make a directory for every entry.
167
+ def mkdir(options={})
168
+ list.each do |dir|
169
+ if File.exist?(dir)
170
+ raise Errno::EEXIST, "File exists - #{dir}"
171
+ end
172
+ end
173
+ list.map{ |dir| fileutils.mkdir(dir, options) }
174
+ end
175
+
176
+ # Make a directory for every entry.
177
+ def mkdir_p(options={})
178
+ list.each do |dir|
179
+ if File.exist?(dir) && !File.directory?(dir)
180
+ raise Errno::EEXIST, "File exists - #{dir}"
181
+ end
182
+ end
183
+ list.map{ |dir| fileutils.mkdir_p(dir, options) }
184
+ end
185
+ alias_method :mkpath, :mkdir_p
186
+
187
+ # Remove every directory.
188
+ def rmdir(options={})
189
+ list.map{ |dir| fileutils.rmdir(dir, options) }
190
+ end
191
+
192
+ # ln(list, destdir, options={})
193
+ def ln(dir, options={})
194
+ #src = list.to_a
195
+ #new = localize(new)
196
+ fileutils.ln(list, dir, options)
197
+ end
198
+ alias_method :link, :ln
199
+
200
+ # ln_s(list, destdir, options={})
201
+ def ln_s(dir, options={})
202
+ #src = list.to_a
203
+ #new = localize(new)
204
+ fileutils.ln_s(list, dir, options)
205
+ end
206
+ alias_method :symlink, :ln_s
207
+
208
+ def ln_sf(dir, options={})
209
+ #src = list.to_a
210
+ #new = localize(new)
211
+ fileutils.ln_sf(list, dir, options)
212
+ end
213
+
214
+ # cp(list, dir, options={})
215
+ def cp(dir, options={})
216
+ #src = list.to_a
217
+ #dest = localize(dest)
218
+ fileutils.cp(list, dir, options)
219
+ end
220
+ alias_method :copy, :cp
221
+
222
+ # cp_r(list, dir, options={})
223
+ def cp_r(dir, options={})
224
+ #src = list.to_a
225
+ #dest = localize(dest)
226
+ fileutils.cp_r(list, dir, options)
227
+ end
228
+
229
+ # mv(list, dir, options={})
230
+ def mv(dir, options={})
231
+ #src = list.to_a
232
+ #dest = localize(dest)
233
+ fileutils.mv(list, dir, options)
234
+ end
235
+ alias_method :move, :mv
236
+
237
+ #
238
+ def rm(options={})
239
+ list = list.to_a
240
+ fileutils.rm(list, options)
241
+ end
242
+
243
+ # Alias for #rm.
244
+ alias_method :remove, :rm
245
+
246
+ # Remove, recursively removing the contents of directories.
247
+ def rm_r(options={})
248
+ #list = list.to_a
249
+ fileutils.rm_r(list, options)
250
+ end
251
+
252
+ # Remove, with force option.
253
+ def rm_f(options={})
254
+ #list = list.to_a
255
+ fileutils.rm_f(list, options)
256
+ end
257
+
258
+ # Remove with force option, recursively removing the contents of directories.
259
+ def rm_rf(options={})
260
+ #list = list.to_a
261
+ fileutils.rm_rf(list, options)
262
+ end
263
+
264
+ # Install files to a directory with given mode. Unlike #cp, this will
265
+ # not copy the file if an up-to-date copy already exists.
266
+ def install(dir, mode, options={})
267
+ #src = list.to_a
268
+ #dest = localize(dest)
269
+ fileutils.install(list, dir, mode, options)
270
+ end
271
+
272
+ # Change mode of files.
273
+ def chmod(mode, options={})
274
+ #list = list.to_a
275
+ fileutils.chmod(mode, list, options)
276
+ end
277
+
278
+ # Change mode of files, following directories recursively.
279
+ def chmod_r(mode, options={})
280
+ #list = list.to_a
281
+ fileutils.chmod_r(mode, list, options)
282
+ end
283
+ #alias_method :chmod_R, :chmod_r
284
+
285
+ # Change owner of files.
286
+ def chown(user, group, options={})
287
+ #list = list.to_a
288
+ fileutils.chown(user, group, list, options)
289
+ end
290
+
291
+ # Change owner of files, following directories recursively.
292
+ def chown_r(user, group, options={})
293
+ #list = list.to_a
294
+ fileutils.chown_r(user, group, list, options)
295
+ end
296
+ #alias_method :chown_R, :chown_r
297
+
298
+ # Touch each file.
299
+ def touch(options={})
300
+ #list = list.to_a
301
+ fileutils.touch(list, options)
302
+ end
303
+
304
+ # Stage files. This is like #install but uses hardlinks.
305
+ def stage(dir)
306
+ #dir = localize(directory)
307
+ #files = localize(files)
308
+ #list = list.to_a
309
+ fileutils.stage(dir, local, list)
310
+ end
311
+
312
+ # Convenient alias for #map_mv.
313
+ def rename(options={}, &block)
314
+ map_mv(options, &block)
315
+ end
316
+
317
+ # Rename the list of files in batch, using a block to determine the new
318
+ # names. If the block returns nil, the file will not be renamed.
319
+ #
320
+ # This is similar to #mv, but allows for detailed control over the renaming.
321
+ #
322
+ # Unlike the other `map_*` methods, this changes the Batch list in-place,
323
+ # since the files renamed no loner exist.
324
+ #
325
+ # Returns the changed FileList instance.
326
+ def map_mv(options={}, &block)
327
+ @file_list = map_send(:mv, options={}, &block)
328
+ end
329
+
330
+ # Hard link the list of files in batch, using a block to determine the new
331
+ # names. If the block returns nil, the file will not be linked.
332
+ #
333
+ # This is similar to #ln, but allows for detailed control over the link names.
334
+ def map_ln(options={}, &block)
335
+ map_send(:ln, options={}, &block)
336
+ end
337
+
338
+ # Soft link the list of files in batch, using a block to determine the new
339
+ # names. If the block returns nil, the file will not be linked.
340
+ #
341
+ # This is similar to #ln_s, but allows for detailed control over the link names.
342
+ def map_ln_s(options={}, &block)
343
+ map_send(:ln_s, options={}, &block)
344
+ end
345
+
346
+ # Force soft linking of the list of files in batch, using a block to
347
+ # determine the new names. If the block returns nil, the file will not
348
+ # be linked.
349
+ #
350
+ # This is similar to #ln_sf, but allows for detailed control over the
351
+ # link names.
352
+ def map_ln_sf(options={}, &block)
353
+ map_send(:ln_sf, options={}, &block)
354
+ end
355
+
356
+ # Copy the list of files in batch, using a block to determine the new
357
+ # file names. If the block returns nil, the file will not be copied.
358
+ #
359
+ # This is similar to #cp, but allows for detailed control over the new
360
+ # file names.
361
+ def map_cp(options={}, &block)
362
+ map_send(:cp, options={}, &block)
363
+ end
364
+
365
+ # Copy the list of files recursively in batch, using a block to determine
366
+ # the new file names. If the block returns nil, the file will not be copied.
367
+ #
368
+ # This is similar to #cp_r, but allows for detailed control over the new
369
+ # file names.
370
+ def map_cp_r(options={}, &block)
371
+ map_send(:cp_r, options={}, &block)
372
+ end
373
+
374
+ # # Force copy the list of files recursively in batch, using a block to
375
+ # # determine the new file names. If the block returns nil, the file will not
376
+ # # be copied.
377
+ # #
378
+ # # This is similar to #cp_rf, but allows for detailed control over the new
379
+ # # file names.
380
+ # def map_cp_rf(options={}, &block)
381
+ # map_send(:cp_rf, options={}, &block)
382
+ # end
383
+
384
+ private
385
+
386
+ SAFE_METHODS = [:ln]
387
+
388
+ # Generic name mapping procedure which can be used for any
389
+ # FileUtils method that has a `src, dest` interface.
390
+ #--
391
+ # TODO: Make public?
392
+ #++
393
+ def map_send(method, options={}, &block)
394
+
395
+ map = {}
396
+ list.each do |file|
397
+ if dest = block.call(file)
398
+ map[file] = dest
399
+ end
400
+ end
401
+
402
+ if options[:safe] or !options[:force] or SAFE_METHODS.include?(method)
403
+ ensure_safe(map)
404
+ end
405
+
406
+ map.each do |src, dest|
407
+ fileutils.__send__(method, src, dest, options)
408
+ end
409
+ FileList.all(*map.values)
410
+ end
411
+
412
+ # Given a map of source to destination, this method ensures
413
+ # a FileUtils operation can is "safe" --that the destination does not
414
+ # yet and exist and/or the source and destination are compatible.
415
+ # If nota file rrror is raised.
416
+ def ensure_safe(map)
417
+ map.each do |src, dest|
418
+ raise unless File.exist?(src)
419
+ if File.directory?(src)
420
+ if File.directory?(dest)
421
+ new_map = {}
422
+ Dir.entries(src).each do |e|
423
+ next if e == '.' or e == '..'
424
+ new_map[File.join(src, e)] = File.join(dest, e)
425
+ end
426
+ ensure_safe_destination(new_map)
427
+ else
428
+ raise Errno::EISDIR, "Is a directory - #{src}"
429
+ end
430
+ else
431
+ if File.directory?(dest)
432
+ check = File.join(dest, src)
433
+ if File.exist?(check)
434
+ raise Errno::EEXIST, "File exists - #{check}"
435
+ end
436
+ else
437
+ raise Errno::EEXIST, "File exists - #{dest}" if File.exist?(dest)
438
+ end
439
+ end
440
+ end
441
+ end
442
+
443
+ public
444
+
445
+ # An intergrated glob like method that takes a set of include globs,
446
+ # exclude globs and ignore globs to produce a collection of paths.
447
+ #
448
+ # Ignore_globs differ from exclude_globs in that they match by
449
+ # the basename of the path rather than the whole pathname.
450
+ #
451
+ #def amass(include_globs, exclude_globs=[], ignore_globs=[])
452
+ # locally do
453
+ # fileutils.amass(include_globs, exclude_globs, ignore_globs)
454
+ # end
455
+ #end
456
+
457
+ # Is +path+ out-of-date in comparsion to all files in batch.
458
+ def outofdate?(path)
459
+ fileutils.outofdate?(path, to_a)
460
+ end
461
+
462
+ # Is +path+ up-to-date in comparsion to all files in batch.
463
+ def uptodate?(path)
464
+ fileutils.uptodate?(path, to_a)
465
+ end
466
+
467
+ #
468
+ def noop?
469
+ @options[:noop] or @options[:dryrun]
470
+ end
471
+
472
+ #
473
+ def verbose?
474
+ @options[:verbose] or @options[:dryrun]
475
+ end
476
+
477
+ #
478
+ def dryrun?
479
+ noop? && verbose?
480
+ end
481
+
482
+ private
483
+
484
+ # Returns FileUtils module based on mode.
485
+ def fileutils
486
+ if dryrun?
487
+ ::FileUtils::DryRun
488
+ elsif noop?
489
+ ::FileUtils::Noop
490
+ elsif verbose?
491
+ ::FileUtils::Verbose
492
+ else
493
+ ::FileUtils
494
+ end
495
+ end
496
+
497
+ end
498
+
499
+ end
500
+