ratch 0.1
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.
- data/LICENSE.txt +344 -0
- data/README.txt +10 -0
- data/bin/lt +4 -0
- data/bin/ludo +4 -0
- data/bin/ratch +8 -0
- data/data/mint/ratch/announce +224 -0
- data/data/mint/ratch/install +49 -0
- data/data/mint/ratch/notes +183 -0
- data/data/mint/ratch/publish +44 -0
- data/data/mint/ratch/rdoc +40 -0
- data/data/mint/ratch/setup +1616 -0
- data/data/mint/ratch/stats +138 -0
- data/demo/README +8 -0
- data/demo/doc/rdoc/created.rid +1 -0
- data/demo/doc/rdoc/files/README.html +112 -0
- data/demo/doc/rdoc/files/lib/foo/foo_rb.html +145 -0
- data/demo/doc/rdoc/fr_class_index.html +26 -0
- data/demo/doc/rdoc/fr_file_index.html +28 -0
- data/demo/doc/rdoc/fr_method_index.html +27 -0
- data/demo/doc/rdoc/index.html +24 -0
- data/demo/doc/rdoc/rdoc-style.css +208 -0
- data/demo/lib/foo/foo.rb +7 -0
- data/demo/util/conf/rdoc +4 -0
- data/demo/util/one +6 -0
- data/demo/util/rdoc +39 -0
- data/demo/util/tryme +10 -0
- data/dev/taskable-simple.rb +42 -0
- data/dev/taskable.rb +573 -0
- data/lib/ratch/batch.rb +43 -0
- data/lib/ratch/cli/lt.rb +56 -0
- data/lib/ratch/cli/ludo.rb +14 -0
- data/lib/ratch/cli/ratch.rb +47 -0
- data/lib/ratch/configutils.rb +100 -0
- data/lib/ratch/consoleutils.rb +88 -0
- data/lib/ratch/emailutils.rb +88 -0
- data/lib/ratch/fileutils.rb +173 -0
- data/lib/ratch/options.rb +57 -0
- data/lib/ratch/runnable.rb +117 -0
- data/lib/ratch/taskable.rb +105 -0
- data/lib/ratch/taskutils.rb +44 -0
- data/lib/ratch/uploadutils.rb +413 -0
- data/meta/manifest.txt +70 -0
- data/meta/project.yaml +24 -0
- data/misc/original.rb +308 -0
- data/task/setup +1616 -0
- data/task/stats +138 -0
- metadata +114 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
module Ratch
|
3
|
+
|
4
|
+
# General Options
|
5
|
+
|
6
|
+
module GeneralOptions
|
7
|
+
|
8
|
+
#
|
9
|
+
|
10
|
+
def argv
|
11
|
+
@argv ||= ARGV.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convert command line argv to args.
|
15
|
+
#
|
16
|
+
# TODO Is this implmented as expected?
|
17
|
+
|
18
|
+
def command_parameters
|
19
|
+
argv.to_params
|
20
|
+
end
|
21
|
+
|
22
|
+
# Debug mode.
|
23
|
+
|
24
|
+
def debug?
|
25
|
+
@debug
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
|
30
|
+
def trace?
|
31
|
+
@trace ||= %w{--trace}.any?{|a| argv.delete(a)}
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
|
36
|
+
def trace!
|
37
|
+
@trace = true
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
|
42
|
+
def noharm?
|
43
|
+
@noharm ||= %w{--dryrun --dry-run --noharm}.any?{|a| argv.delete(a)}
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :dryrun?, :noharm? ; module_function :dryrun?
|
47
|
+
|
48
|
+
#
|
49
|
+
|
50
|
+
def noharm!
|
51
|
+
@noharm = true
|
52
|
+
end
|
53
|
+
alias_method :dryrun!, :noharm! ; module_function :dryrun!
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
#
|
4
|
+
|
5
|
+
module Runnable
|
6
|
+
|
7
|
+
# TODO How to handle arguments?
|
8
|
+
|
9
|
+
def run(batchfile, arguments=nil)
|
10
|
+
BatchFile.new(batchfile).call
|
11
|
+
# # TODO probably should raise error instead
|
12
|
+
# abort "missing batch file -- #{batchfile}" unless File.file?(batchfile)
|
13
|
+
# script = File.read($0 = batchfile)
|
14
|
+
# #instance_eval(script)
|
15
|
+
# eval(script, binding, $0)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Batch run, ie. run and cache.
|
19
|
+
# Usually this can be take care of by method_missing.
|
20
|
+
# But, in some cases, built in method names block task
|
21
|
+
# calls, so you have to use #batch to invoke those.
|
22
|
+
|
23
|
+
def batch(batchfile, arguments=nil)
|
24
|
+
task_cache[task] ||= run(batchfile, arguments)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Task cache, which prevents batch runs from re-executing.
|
28
|
+
|
29
|
+
def task_cache
|
30
|
+
@@task_cache ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Is a task complete or in the process of being completed?
|
34
|
+
|
35
|
+
def done?(task)
|
36
|
+
task == $0 or task_cache.key?(task)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Shell runner.
|
40
|
+
|
41
|
+
def sh(cmd)
|
42
|
+
if noharm?
|
43
|
+
puts cmd
|
44
|
+
true
|
45
|
+
else
|
46
|
+
puts "--> system call: #{cmd}" if trace?
|
47
|
+
system(cmd)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Abort running.
|
52
|
+
|
53
|
+
def abort(msg=nil)
|
54
|
+
puts msg if msg
|
55
|
+
exit 0
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
module OpenRunnable
|
62
|
+
|
63
|
+
# If method is missing try to run an external task
|
64
|
+
# or binary by that name. If it is a binary, arguments
|
65
|
+
# translate into commandline parameters. For example:
|
66
|
+
#
|
67
|
+
# tar 'foo/', :x=>true, :v=>true, :z=>true, :f=>'foo.tar.gz'
|
68
|
+
#
|
69
|
+
# or
|
70
|
+
#
|
71
|
+
# tar '-xvzf', "foo.tar.gz", "foo/"
|
72
|
+
#
|
73
|
+
# becomes
|
74
|
+
#
|
75
|
+
# tar -x -v -z -f foo.tar.gz foo/
|
76
|
+
#
|
77
|
+
# If it is a task, it will be cached. Tasks only ever run once.
|
78
|
+
# To run them more than once you can manually execute them with #run.
|
79
|
+
# Likewise you can manually run and cache by calling #batch.
|
80
|
+
# This is good to know, b/c in some cases built in method names
|
81
|
+
# block task calls, so you have to #batch to invoke them.
|
82
|
+
|
83
|
+
def method_missing(sym,*args)
|
84
|
+
puts "method_missing: #{sym}" if debug?
|
85
|
+
|
86
|
+
name = sym.to_s
|
87
|
+
|
88
|
+
task = task?(name)
|
89
|
+
done = task && done?(task)
|
90
|
+
cache = task && !done && name[1,-1] != '!'
|
91
|
+
bin = bin?(name) if (!task || done)
|
92
|
+
none = task && done && !bin
|
93
|
+
#task = name if bin
|
94
|
+
|
95
|
+
return super unless task || bin
|
96
|
+
|
97
|
+
return if none # nothing to do
|
98
|
+
|
99
|
+
params = args.to_params
|
100
|
+
|
101
|
+
if bin
|
102
|
+
cmd = "#{File.basename(bin)} #{params}"
|
103
|
+
res = sh(cmd)
|
104
|
+
elsif task
|
105
|
+
cmd = "./#{task} #{params}"
|
106
|
+
puts "--> #{cache ? '' : 'not-'}cached execution: #{cmd}" if trace?
|
107
|
+
res = run(task, args)
|
108
|
+
if cache
|
109
|
+
#@task_cache[task] ||= (system(cmd); true)
|
110
|
+
task_cache[task] ||= res
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
return res
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
module Taskable
|
4
|
+
|
5
|
+
#def main
|
6
|
+
# @main
|
7
|
+
#end
|
8
|
+
|
9
|
+
def tasks
|
10
|
+
@tasks ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Define a main task.
|
14
|
+
|
15
|
+
def main(name, &block)
|
16
|
+
@main = Task.register(name, &block)
|
17
|
+
tasks[@main.name] = @main
|
18
|
+
end
|
19
|
+
|
20
|
+
# Define a task.
|
21
|
+
|
22
|
+
def task(name, &block)
|
23
|
+
tsk = Task.register(name, &block)
|
24
|
+
tasks[tsk.name] = tsk
|
25
|
+
end
|
26
|
+
|
27
|
+
# Define a file target.
|
28
|
+
|
29
|
+
def file(name, &block)
|
30
|
+
tasks[name.to_s] = FileTask.register(name, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
#
|
37
|
+
#
|
38
|
+
|
39
|
+
class Task
|
40
|
+
|
41
|
+
def self.tasks
|
42
|
+
@@tasks ||= {}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.register(name_deps, &block)
|
46
|
+
if Hash===name_deps
|
47
|
+
name = name_deps.keys[0]
|
48
|
+
deps = name_deps.values[0]
|
49
|
+
else
|
50
|
+
name = name_deps
|
51
|
+
deps = []
|
52
|
+
end
|
53
|
+
tasks[name.to_s] = new(name, *deps, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
attr :name
|
57
|
+
attr :preqs
|
58
|
+
attr :action
|
59
|
+
|
60
|
+
#
|
61
|
+
|
62
|
+
def initialize(name, *preqs, &action)
|
63
|
+
@name = name.to_s
|
64
|
+
@preqs = preqs
|
65
|
+
@action = action
|
66
|
+
end
|
67
|
+
|
68
|
+
def call
|
69
|
+
#p plan
|
70
|
+
plan.each{ |name| @@tasks[name].action_call }
|
71
|
+
#action_call
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
|
76
|
+
def action_call
|
77
|
+
@action.call if @action
|
78
|
+
end
|
79
|
+
|
80
|
+
# TODO Check for circular dependencies.
|
81
|
+
|
82
|
+
def plan(list=[])
|
83
|
+
if list.include?(name)
|
84
|
+
raise "Circular dependency #{name}."
|
85
|
+
end
|
86
|
+
|
87
|
+
@preqs.each do |need|
|
88
|
+
need = need.to_s
|
89
|
+
next if list.include?(need)
|
90
|
+
@@tasks[need].plan(list)
|
91
|
+
end
|
92
|
+
list << name
|
93
|
+
return list
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
#
|
100
|
+
#
|
101
|
+
|
102
|
+
class FileTask < Task
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# TITLE:
|
2
|
+
#
|
3
|
+
# TaskUtils
|
4
|
+
#
|
5
|
+
# SUMMARY:
|
6
|
+
#
|
7
|
+
# All the task methods used by BatchRunner.
|
8
|
+
#
|
9
|
+
# COPYRIGHT:
|
10
|
+
#
|
11
|
+
# Copyright (c) 2007 7rans
|
12
|
+
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
#require 'facets/hash/merge' # for reverse_merge
|
16
|
+
|
17
|
+
require 'ratch/options'
|
18
|
+
require 'ratch/consoleutils'
|
19
|
+
require 'ratch/configutils'
|
20
|
+
require 'ratch/emailutils'
|
21
|
+
require 'ratch/fileutils'
|
22
|
+
require 'ratch/taskable'
|
23
|
+
require 'ratch/runnable'
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
module Ratch
|
28
|
+
|
29
|
+
# = TaskUtils
|
30
|
+
|
31
|
+
module TaskUtils
|
32
|
+
include GeneralOptions
|
33
|
+
|
34
|
+
include ConsoleUtils
|
35
|
+
include FileUtils
|
36
|
+
include ConfigUtils
|
37
|
+
include EmailUtils
|
38
|
+
|
39
|
+
include Taskable
|
40
|
+
include Runnable
|
41
|
+
include OpenRunnable
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,413 @@
|
|
1
|
+
# = uploadutils.rb
|
2
|
+
#
|
3
|
+
# CREDIT Thomas Sawyer
|
4
|
+
#
|
5
|
+
# TODO Incorporate password into scp and ftp ?
|
6
|
+
# TODO rsync needs --delete option
|
7
|
+
|
8
|
+
require 'openssl'
|
9
|
+
require 'shellwords'
|
10
|
+
require 'tmpdir'
|
11
|
+
|
12
|
+
require 'facets/openobject'
|
13
|
+
|
14
|
+
module Ratch
|
15
|
+
|
16
|
+
# Upload files to host. These means of uploading are current
|
17
|
+
# supported: ftp, sftp, scp and rsync.
|
18
|
+
#
|
19
|
+
# user Username for host.
|
20
|
+
# host Host server's domain name.
|
21
|
+
# root Document root path on host.
|
22
|
+
# copy Directory of files to publish, or
|
23
|
+
# Files to publish using from and to.
|
24
|
+
#
|
25
|
+
# dryrun If true only pretend to upload.
|
26
|
+
# quiet Supress all output.
|
27
|
+
# verbose Provide extra details.
|
28
|
+
#
|
29
|
+
# The copy parameter allows you to simply specify a file
|
30
|
+
# or directory which will be published to host's document
|
31
|
+
# root location.
|
32
|
+
#
|
33
|
+
# If you need more control over which files to publish
|
34
|
+
# where, you can use the copy parameter instead. Provide
|
35
|
+
# an array of pattern strings in the form of "{from} {to}".
|
36
|
+
# If the desitination is the host's document root you do
|
37
|
+
# not need to specify the {to} part. For example:
|
38
|
+
#
|
39
|
+
# copy = [ 'web/*', 'doc/api/* doc/api' ]
|
40
|
+
#
|
41
|
+
# The first copies the files under your project's web directory
|
42
|
+
# to the host's document root. The second copies your projects
|
43
|
+
# doc/api files to the doc/api location on the host.
|
44
|
+
#
|
45
|
+
# The internal template used for the outbound destination
|
46
|
+
# is 'username@host:root/'.
|
47
|
+
|
48
|
+
module UploadUtils
|
49
|
+
|
50
|
+
module_function
|
51
|
+
|
52
|
+
#
|
53
|
+
# Upload via given protocol.
|
54
|
+
#
|
55
|
+
|
56
|
+
def upload( protocol, opts )
|
57
|
+
send(protocol.to_s.downcase,opts)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Use ftp to upload files.
|
62
|
+
#
|
63
|
+
|
64
|
+
def ftp( keys )
|
65
|
+
keys = upload_parameters(keys)
|
66
|
+
|
67
|
+
# set transfer rules
|
68
|
+
if keys.stage
|
69
|
+
trans = stage_transfer(keys.stage)
|
70
|
+
else
|
71
|
+
files(keys.dir, keys.copy).each do |from|
|
72
|
+
trans << [from,from]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# append location of publication dir to from
|
77
|
+
dir = keys.dir
|
78
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
79
|
+
|
80
|
+
if keys.dryrun
|
81
|
+
puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
82
|
+
keys.trans.each do |f, t|
|
83
|
+
puts "ftp put #{f} #{t}"
|
84
|
+
end
|
85
|
+
else
|
86
|
+
require 'net/ftp'
|
87
|
+
Net::FTP.open(keys.host) do |ftp|
|
88
|
+
ftp.login(keys.user) #password?
|
89
|
+
ftp.chdir(keys.root)
|
90
|
+
keys.trans.each do |f, t|
|
91
|
+
puts "ftp #{f} #{t}" unless keys.quiet
|
92
|
+
ftp.putbinaryfile( f, t, 1024 )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# Use sftp to upload files.
|
100
|
+
#
|
101
|
+
|
102
|
+
def sftp( keys )
|
103
|
+
keys = upload_parameters(keys)
|
104
|
+
|
105
|
+
# set transfer rules
|
106
|
+
if keys.stage
|
107
|
+
trans = stage_transfer(keys.stage)
|
108
|
+
else
|
109
|
+
files(keys.dir, keys.copy).each do |from|
|
110
|
+
trans << [from,from]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# append location of publication dir to from
|
115
|
+
dir = keys.dir
|
116
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
117
|
+
|
118
|
+
if keys.dryrun
|
119
|
+
puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
120
|
+
keys.trans.each do |f,t|
|
121
|
+
puts "sftp put #{f} #{t}"
|
122
|
+
end
|
123
|
+
else
|
124
|
+
require 'net/sftp'
|
125
|
+
Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
|
126
|
+
#sftp.login( user )
|
127
|
+
sftp.chdir(keys.root)
|
128
|
+
keys.trans.each do |f,t|
|
129
|
+
puts "sftp #{f} #{t}" unless keys.quiet
|
130
|
+
sftp.put_file(f,t) #, 1024 )
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Use rsync to upload files.
|
138
|
+
#
|
139
|
+
|
140
|
+
def rsync( keys )
|
141
|
+
keys = upload_parameters(keys)
|
142
|
+
|
143
|
+
flags = []
|
144
|
+
flags << "-n" if keys.dryrun
|
145
|
+
flags << "-q" if keys.quiet
|
146
|
+
flags << "-v" if keys.verbose
|
147
|
+
flags << "--progress" unless keys.quiet
|
148
|
+
flags = flags.join(' ').strip
|
149
|
+
flags = ' ' + flags unless flags.empty?
|
150
|
+
|
151
|
+
manfile = 'Publish.txt'
|
152
|
+
|
153
|
+
if keys.stage
|
154
|
+
dir = stage_linkdir(keys.dir, keys.stage)
|
155
|
+
Dir.chdir(dir) do
|
156
|
+
cpy = files(keys.copy)
|
157
|
+
end
|
158
|
+
manifest = File.join(dir,manfile)
|
159
|
+
cmd = %{rsync#{flags} -L -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
|
160
|
+
else
|
161
|
+
dir = keys.dir
|
162
|
+
cpy = files(dir, keys.copy)
|
163
|
+
manifest = File.join(dir,manfile)
|
164
|
+
cmd = %{rsync#{flags} -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
|
165
|
+
end
|
166
|
+
|
167
|
+
#Dir.chdir(keys.dir) do
|
168
|
+
begin
|
169
|
+
File.open(manifest, 'w'){ |f| f << cpy.join("\n") }
|
170
|
+
ENV['RSYNC_PASSWORD'] = keys.pass if keys.pass
|
171
|
+
puts cmd unless keys.quiet
|
172
|
+
system cmd
|
173
|
+
ensure
|
174
|
+
ENV.delete('RSYNC_PASSWORD') if keys.pass
|
175
|
+
end
|
176
|
+
#end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
# private (can't do b/c of module_function)
|
181
|
+
|
182
|
+
# parse publishing options.
|
183
|
+
|
184
|
+
def upload_parameters( keys )
|
185
|
+
keys = OpenObject.new(keys)
|
186
|
+
|
187
|
+
keys.copy = keys.copy || '**/*'
|
188
|
+
keys.host = keys.host || keys.domain
|
189
|
+
keys.user = keys.user || keys.username
|
190
|
+
keys.root = keys.root || '/'
|
191
|
+
#keys.pass = keys.pass || keys.password
|
192
|
+
|
193
|
+
# validate
|
194
|
+
raise ArgumentError, "missing publish parameter -- dir" unless keys.dir
|
195
|
+
raise ArgumentError, "missing publish parameter -- host" unless keys.host
|
196
|
+
raise ArgumentError, "missing publish parameter -- user" unless keys.user
|
197
|
+
#raise ArgumentError, "missing publish parameter -- copy" unless keys.copy
|
198
|
+
#raise ArgumentError, "missing publish parameter -- root" unless keys.root
|
199
|
+
|
200
|
+
keys.root = '' if keys.root.nil?
|
201
|
+
keys.root.sub!(/^\//,'')
|
202
|
+
|
203
|
+
if String===keys.copy and File.directory?(keys.copy)
|
204
|
+
copy = File.join(keys.copy, '*')
|
205
|
+
end
|
206
|
+
keys.copy = [keys.copy].flatten.compact
|
207
|
+
|
208
|
+
# trans = []
|
209
|
+
# keys.copy.each do |from|
|
210
|
+
# #from, to = *Shellwords.shellwords(c)
|
211
|
+
# #to = from if to.nil?
|
212
|
+
# #to = to[1..-1] if to[0,1] == '/'
|
213
|
+
# from.sub('*','**/*') unless from =~ /\*\*/
|
214
|
+
# files = Dir.glob(from)
|
215
|
+
# files.each do |f|
|
216
|
+
# #t = File.join(to,File.basename(f))
|
217
|
+
# #t = t[1..-1] if t[0,1] == '/'
|
218
|
+
# trans << [f,f]
|
219
|
+
# end
|
220
|
+
# end
|
221
|
+
# keys.trans = trans
|
222
|
+
|
223
|
+
return keys
|
224
|
+
end
|
225
|
+
|
226
|
+
# Put together the list of files to copy.
|
227
|
+
|
228
|
+
def files( dir, copy )
|
229
|
+
Dir.chdir(dir) do
|
230
|
+
del, add = copy.partition{ |f| /^[-]/ =~ f }
|
231
|
+
|
232
|
+
# remove - and + prefixes
|
233
|
+
del.collect!{ |f| f.sub(/^[-]/,'') }
|
234
|
+
add.collect!{ |f| f.sub(/^[+]/,'') }
|
235
|
+
|
236
|
+
#del.concat(must_exclude)
|
237
|
+
|
238
|
+
files = []
|
239
|
+
add.each{ |g| files += Dir.multiglob(g) }
|
240
|
+
del.each{ |g| files -= Dir.multiglob(g) }
|
241
|
+
|
242
|
+
files.collect!{ |f| f.sub(/^\//,'') }
|
243
|
+
|
244
|
+
return files
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Combine three part stage list into a two part from->to list.
|
249
|
+
#
|
250
|
+
# Using the stage list of three space separated fields.
|
251
|
+
#
|
252
|
+
# fromdir file todir
|
253
|
+
#
|
254
|
+
# This is used to generate a from -> to list of the form:
|
255
|
+
#
|
256
|
+
# fromdir/file todir/file
|
257
|
+
#
|
258
|
+
|
259
|
+
def stage_transfer( list )
|
260
|
+
trans = []
|
261
|
+
list.each do |line|
|
262
|
+
trans << Shellwords.shellwords(line)
|
263
|
+
end
|
264
|
+
|
265
|
+
trans.collect! do |from, base, to|
|
266
|
+
file = File.join(from,base)
|
267
|
+
to = File.join(to,base)
|
268
|
+
[from, to]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# When using stage options this will create temporary linked location.
|
273
|
+
|
274
|
+
def stage_linkdir( dir, list )
|
275
|
+
folder = File.join(Dir.tmpdir, 'ratchets', 'project', object_id.abs.to_s)
|
276
|
+
FileUtils.mkdir_p(folder)
|
277
|
+
|
278
|
+
Dir.chdir(dir) do
|
279
|
+
stage_transfer(list).each do |file, to|
|
280
|
+
link = File.join(folder,to)
|
281
|
+
FileUtils.ln_s(link,file)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
return folder
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
=begin
|
294
|
+
|
295
|
+
|
296
|
+
#--
|
297
|
+
# SHELLS OUT! Need net/scp library to fix.
|
298
|
+
#++
|
299
|
+
|
300
|
+
# Use scp to upload files.
|
301
|
+
|
302
|
+
def scp( keys )
|
303
|
+
keys = upload_parameters(keys)
|
304
|
+
|
305
|
+
flags = []
|
306
|
+
flags << "-v" if keys.verbose
|
307
|
+
flags << "-q" if keys.quiet
|
308
|
+
flags = flags.join(' ').strip
|
309
|
+
flags = ' ' + flags unless flags.empty?
|
310
|
+
|
311
|
+
upload_stage(keys) do #|tmpdir|
|
312
|
+
cmd = "scp -r#{flags} * #{keys.user}@#{keys.host}:/#{keys.root}"
|
313
|
+
puts cmd unless keys.quiet
|
314
|
+
system cmd unless keys.dryrun
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# Use rsync to upload files.
|
319
|
+
|
320
|
+
def rsync( keys )
|
321
|
+
keys = upload_parameters(keys)
|
322
|
+
|
323
|
+
flags = []
|
324
|
+
flags << "-n" if keys.dryrun
|
325
|
+
flags << "-v" if keys.verbose
|
326
|
+
flags << "-q" if keys.quiet
|
327
|
+
flags = flags.join(' ').strip
|
328
|
+
flags = ' ' + flags unless flags.empty?
|
329
|
+
|
330
|
+
upload_stage(keys) do #|tmpdir|
|
331
|
+
begin
|
332
|
+
ENV['RSYNC_PASSWORD'] = keys.pass if keys.pass
|
333
|
+
cmd = "rsync -R#{flags} -arz * #{keys.user}@#{keys.host} /#{keys.root}"
|
334
|
+
ensure
|
335
|
+
ENV.delete('RSYNC_PASSWORD') if keys.pass
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Use ftp to upload files.
|
341
|
+
|
342
|
+
def ftp( keys )
|
343
|
+
keys = upload_parameters(keys)
|
344
|
+
|
345
|
+
if keys.dryrun
|
346
|
+
puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
347
|
+
keys.trans.each do |f, t|
|
348
|
+
puts "ftp put #{f} #{t}"
|
349
|
+
end
|
350
|
+
else
|
351
|
+
require 'net/ftp'
|
352
|
+
Net::FTP.open(keys.host) do |ftp|
|
353
|
+
ftp.login(keys.user) #password?
|
354
|
+
ftp.chdir(keys.root)
|
355
|
+
keys.trans.each do |f, t|
|
356
|
+
puts "ftp #{f} #{t}" unless keys.quiet
|
357
|
+
ftp.putbinaryfile( f, t, 1024 )
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
# Use sftp to upload files.
|
364
|
+
|
365
|
+
def sftp( keys )
|
366
|
+
keys = upload_parameters(keys)
|
367
|
+
|
368
|
+
if keys.dryrun
|
369
|
+
puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
370
|
+
keys.trans.each do |f,t|
|
371
|
+
puts "sftp put #{f} #{t}"
|
372
|
+
end
|
373
|
+
else
|
374
|
+
require 'net/sftp'
|
375
|
+
Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
|
376
|
+
#sftp.login( user )
|
377
|
+
sftp.chdir(keys.root)
|
378
|
+
keys.trans.each do |f,t|
|
379
|
+
puts "sftp #{f} #{t}" unless keys.quiet
|
380
|
+
sftp.put_file(f,t) #, 1024 )
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
|
387
|
+
# Creates a stage from which the whole directory can be uploaded.
|
388
|
+
# This is needed for scp and rsync which have to shelled out,
|
389
|
+
# and can't conveniently copy one file at a time.
|
390
|
+
|
391
|
+
def upload_stage(keys) #:yield:
|
392
|
+
tmp = "scp_#{object_id.abs}_#{ Time.now.strftime("%Y%m%d%H%M%S")}"
|
393
|
+
tmpdir = File.join(Dir.tmpdir,tmp)
|
394
|
+
|
395
|
+
puts "mkdir -p #{tmpdir}" unless keys.quiet
|
396
|
+
FileUtils.mkdir_p(tmpdir) # go ahead and do this even if dryrun
|
397
|
+
|
398
|
+
fu = keys.dryrun ? FileUtils::DryRun : FileUtils
|
399
|
+
keys.trans.each do |f, t|
|
400
|
+
to = File.join(tmpdir, t)
|
401
|
+
fu.mv(f,to)
|
402
|
+
end
|
403
|
+
|
404
|
+
puts "cd #{tmpdir}" unless keys.quiet
|
405
|
+
Dir.chdir(tmpdir) do
|
406
|
+
yield #(tmpdir)
|
407
|
+
end
|
408
|
+
|
409
|
+
puts "rm -r #{tmpdir}" unless keys.quiet
|
410
|
+
FileUtils.rm_r(tmpdir) # now remove the temp dir
|
411
|
+
end
|
412
|
+
|
413
|
+
=end
|