ratch 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +99 -0
- data/COPYING +203 -21
- data/History.rdoc +35 -0
- data/License.txt +204 -0
- data/README.rdoc +113 -0
- data/Version +1 -0
- data/bin/ludo +16 -0
- data/bin/ratch +1 -8
- data/lib/ratch.rb +28 -0
- data/lib/ratch.yml +99 -0
- data/lib/ratch/batch.rb +500 -0
- data/lib/ratch/console.rb +199 -0
- data/lib/ratch/core_ext.rb +1 -4
- data/lib/ratch/core_ext/facets.rb +15 -1
- data/lib/ratch/core_ext/filetest.rb +29 -0
- data/lib/ratch/core_ext/{string.rb → to_actual_filename.rb} +0 -23
- data/lib/ratch/core_ext/to_console.rb +30 -12
- data/lib/ratch/core_ext/{object.rb → to_yamlfrag.rb} +1 -0
- data/lib/ratch/core_ext/unfold_paragraphs.rb +27 -0
- data/lib/ratch/file_list.rb +411 -0
- data/lib/ratch/script.rb +99 -5
- data/lib/ratch/script/help.rb +84 -0
- data/lib/ratch/shell.rb +783 -0
- data/lib/ratch/system.rb +15 -0
- data/lib/ratch/utils/cli.rb +49 -0
- data/lib/ratch/utils/config.rb +52 -0
- data/lib/ratch/{emailer.rb → utils/email.rb} +43 -6
- data/lib/ratch/utils/ftp.rb +134 -0
- data/lib/ratch/utils/pom.rb +22 -0
- data/lib/ratch/utils/rdoc.rb +48 -0
- data/lib/ratch/utils/tar.rb +88 -0
- data/lib/ratch/utils/xdg.rb +39 -0
- data/lib/ratch/utils/zlib.rb +54 -0
- data/spec/01_shell.rdoc +198 -0
- data/spec/02_script.rdoc +34 -0
- data/spec/03_batch.rdoc +71 -0
- data/spec/04_system.rdoc +3 -0
- data/spec/applique/array.rb +8 -0
- data/spec/applique/setup.rb +20 -0
- data/test/case_batch.rb +63 -0
- data/test/case_shell.rb +46 -0
- data/test/core_ext/case_pathname.rb +361 -0
- data/test/helper.rb +4 -0
- data/test/utils/case_cli.rb +6 -0
- data/test/utils/case_config.rb +12 -0
- data/test/utils/case_email.rb +10 -0
- data/test/utils/case_ftp.rb +6 -0
- data/test/utils/case_pom.rb +17 -0
- data/test/utils/case_rdoc.rb +23 -0
- data/test/utils/case_tar.rb +6 -0
- data/test/utils/case_zlib.rb +11 -0
- data/test/utils/fixtures/pom_sample/Profile +4 -0
- data/test/utils/fixtures/rdoc_sample/README.rdoc +4 -0
- data/test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb +9 -0
- metadata +139 -82
- data/HISTORY +0 -6
- data/MANIFEST +0 -53
- data/NEWS +0 -12
- data/README +0 -87
- data/VERSION +0 -1
- data/demo/tryme-task.ratch +0 -12
- data/demo/tryme1.ratch +0 -6
- data/doc/log/basic_stats/index.html +0 -39
- data/doc/log/notes.xml +0 -18
- data/doc/log/stats.log +0 -14
- data/doc/log/syntax.log +0 -0
- data/doc/log/testunit.log +0 -156
- data/lib/ratch/commandline.rb +0 -16
- data/lib/ratch/core_ext/pathname.rb +0 -38
- data/lib/ratch/dsl.rb +0 -420
- data/lib/ratch/index.rb +0 -4
- data/lib/ratch/io.rb +0 -116
- data/lib/ratch/plugin.rb +0 -65
- data/lib/ratch/service.rb +0 -33
- data/lib/ratch/task.rb +0 -249
- data/lib/ratch/task2.rb +0 -298
- data/meta/abstract +0 -4
- data/meta/author +0 -1
- data/meta/contact +0 -1
- data/meta/homepage +0 -1
- data/meta/name +0 -1
- data/meta/requires +0 -4
- data/meta/summary +0 -1
- data/test/README +0 -1
- data/test/test_helper.rb +0 -4
- data/test/test_task.rb +0 -46
data/README.rdoc
ADDED
@@ -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
|
data/bin/ludo
ADDED
@@ -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
data/lib/ratch.rb
ADDED
@@ -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
|
+
|
data/lib/ratch.yml
ADDED
@@ -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
|
data/lib/ratch/batch.rb
ADDED
@@ -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
|
+
|