linecook 1.2.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{History → History.rdoc} +3 -2
- data/README.rdoc +93 -0
- data/bin/linecook +32 -56
- data/bin/linecook_run +19 -6
- data/bin/linecook_scp +12 -4
- data/doc/vm_setup.rdoc +75 -0
- data/lib/linecook.rb +3 -2
- data/lib/linecook/attributes.rb +33 -8
- data/lib/linecook/command.rb +61 -0
- data/lib/linecook/command_set.rb +85 -0
- data/lib/linecook/command_utils.rb +20 -0
- data/lib/linecook/commands/build.rb +108 -57
- data/lib/linecook/commands/compile.rb +181 -0
- data/lib/linecook/commands/{helper.rb → compile_helper.rb} +123 -94
- data/lib/linecook/commands/run.rb +43 -39
- data/lib/linecook/commands/snapshot.rb +24 -24
- data/lib/linecook/commands/ssh.rb +7 -7
- data/lib/linecook/commands/start.rb +10 -10
- data/lib/linecook/commands/state.rb +7 -7
- data/lib/linecook/commands/stop.rb +3 -3
- data/lib/linecook/commands/{vbox_command.rb → virtual_box_command.rb} +31 -29
- data/lib/linecook/cookbook.rb +149 -131
- data/lib/linecook/executable.rb +28 -0
- data/lib/linecook/package.rb +177 -361
- data/lib/linecook/proxy.rb +4 -10
- data/lib/linecook/recipe.rb +289 -369
- data/lib/linecook/test.rb +114 -98
- data/lib/linecook/utils.rb +31 -41
- data/lib/linecook/version.rb +2 -6
- metadata +120 -68
- data/HowTo/Control Virtual Machines +0 -106
- data/HowTo/Generate Scripts +0 -268
- data/HowTo/Run Scripts +0 -87
- data/HowTo/Setup Virtual Machines +0 -76
- data/README +0 -117
- data/lib/linecook/commands.rb +0 -11
- data/lib/linecook/commands/command.rb +0 -58
- data/lib/linecook/commands/command_error.rb +0 -12
- data/lib/linecook/commands/env.rb +0 -89
- data/lib/linecook/commands/init.rb +0 -86
- data/lib/linecook/commands/package.rb +0 -57
- data/lib/linecook/template.rb +0 -17
- data/lib/linecook/test/command_parser.rb +0 -75
- data/lib/linecook/test/file_test.rb +0 -197
- data/lib/linecook/test/regexp_escape.rb +0 -86
- data/lib/linecook/test/shell_test.rb +0 -177
- data/lib/linecook/test/shim.rb +0 -71
- data/templates/Gemfile +0 -3
- data/templates/Rakefile +0 -146
- data/templates/_gitignore +0 -4
- data/templates/attributes/project_name.rb +0 -3
- data/templates/config/ssh +0 -14
- data/templates/cookbook +0 -10
- data/templates/files/example.txt +0 -1
- data/templates/helpers/project_name/echo.erb +0 -4
- data/templates/packages/abox.yml +0 -2
- data/templates/project_name.gemspec +0 -30
- data/templates/recipes/abox.rb +0 -16
- data/templates/templates/example.erb +0 -1
- data/templates/test/project_name_test.rb +0 -24
- data/templates/test/test_helper.rb +0 -14
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'linecook/command_set'
|
2
|
+
require 'linecook/commands/build'
|
3
|
+
require 'linecook/commands/start'
|
4
|
+
require 'linecook/commands/stop'
|
5
|
+
require 'linecook/commands/state'
|
6
|
+
require 'linecook/commands/snapshot'
|
7
|
+
require 'linecook/commands/ssh'
|
8
|
+
require 'linecook/commands/run'
|
9
|
+
|
10
|
+
module Linecook
|
11
|
+
class Executable < Linecook::CommandSet
|
12
|
+
class << self
|
13
|
+
def commands
|
14
|
+
{
|
15
|
+
'build' => Linecook::Commands::Build,
|
16
|
+
'compile' => Linecook::Commands::Compile,
|
17
|
+
'compile-helper' => Linecook::Commands::CompileHelper,
|
18
|
+
'start' => Linecook::Commands::Start,
|
19
|
+
'stop' => Linecook::Commands::Stop,
|
20
|
+
'state' => Linecook::Commands::State,
|
21
|
+
'snapshot' => Linecook::Commands::Snapshot,
|
22
|
+
'ssh' => Linecook::Commands::Ssh,
|
23
|
+
'run' => Linecook::Commands::Run
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/linecook/package.rb
CHANGED
@@ -1,396 +1,212 @@
|
|
1
|
-
require 'linecook/cookbook'
|
2
|
-
require 'linecook/recipe'
|
3
|
-
require 'linecook/template'
|
4
1
|
require 'tempfile'
|
2
|
+
require 'stringio'
|
5
3
|
|
6
4
|
module Linecook
|
7
5
|
class Package
|
8
|
-
class << self
|
9
|
-
def setup(env, cookbook=nil)
|
10
|
-
unless env.kind_of?(Hash)
|
11
|
-
env = Utils.load_config(env)
|
12
|
-
end
|
13
|
-
|
14
|
-
package = new(env)
|
15
|
-
|
16
|
-
if cookbook
|
17
|
-
manifest = package.manifest
|
18
|
-
manifest.replace cookbook.manifest
|
19
|
-
end
|
20
|
-
|
21
|
-
package
|
22
|
-
end
|
23
|
-
|
24
|
-
def init(package_file=nil, project_dir=nil)
|
25
|
-
cookbook = Cookbook.init(project_dir)
|
26
|
-
package = setup(package_file, cookbook)
|
27
|
-
|
28
|
-
if package_file
|
29
|
-
package.context[PACKAGE_KEY] ||= begin
|
30
|
-
name = File.basename(package_file).chomp(File.extname(package_file))
|
31
|
-
{'recipes' => { 'run' => name }}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
package
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
CONTEXT_KEY = 'linecook'
|
40
|
-
COOKBOOK_KEY = 'cookbook'
|
41
|
-
MANIFEST_KEY = 'manifest'
|
42
|
-
PACKAGE_KEY = 'package'
|
43
|
-
REGISTRY_KEY = 'registry'
|
44
|
-
|
45
|
-
FILES_KEY = 'files'
|
46
|
-
TEMPLATES_KEY = 'templates'
|
47
|
-
RECIPES_KEY = 'recipes'
|
48
|
-
|
49
6
|
# The package environment
|
50
7
|
attr_reader :env
|
51
|
-
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
8
|
+
|
9
|
+
# A registry of (path, source_path) pairs recording what files are
|
10
|
+
# included in the package.
|
11
|
+
attr_reader :registry
|
12
|
+
|
13
|
+
# A hash of (path, Hash) pairs identifing export options for a package
|
14
|
+
# file. See on_export.
|
15
|
+
attr_reader :export_options
|
16
|
+
|
17
|
+
# A hash of default export options.
|
18
|
+
attr_reader :default_export_options
|
19
|
+
|
61
20
|
def initialize(env={})
|
62
21
|
@env = env
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@
|
66
|
-
end
|
67
|
-
|
68
|
-
# Returns the linecook context in env, as keyed by CONTEXT_KEY. Defaults
|
69
|
-
# to an empty hash.
|
70
|
-
def context
|
71
|
-
env[CONTEXT_KEY] ||= {}
|
22
|
+
@registry = {}
|
23
|
+
@export_options = {}
|
24
|
+
@default_export_options = {}
|
72
25
|
end
|
73
|
-
|
74
|
-
#
|
75
|
-
#
|
76
|
-
|
77
|
-
context[MANIFEST_KEY] ||= {}
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns the registry in config, as keyed by REGISTRY_KEY. Defaults to an
|
81
|
-
# empty hash. A hash of (target_name, source_path) pairs identifying
|
82
|
-
# files that should be included in a package
|
83
|
-
def registry
|
84
|
-
context[REGISTRY_KEY] ||= {}
|
85
|
-
end
|
86
|
-
|
87
|
-
# Returns the linecook configs in env, as keyed by CONFIG_KEY. Defaults
|
88
|
-
# to an empty hash.
|
89
|
-
def config
|
90
|
-
context[PACKAGE_KEY] ||= {}
|
91
|
-
end
|
92
|
-
|
93
|
-
# Returns the hash of (source, target) pairs identifying which of the
|
94
|
-
# files will be built into self by build. Files are identified by
|
95
|
-
# FILES_KEY in config, and normalized the same way as recipes.
|
96
|
-
def files
|
97
|
-
config[FILES_KEY] = Utils.hashify(config[FILES_KEY])
|
98
|
-
end
|
99
|
-
|
100
|
-
# Returns the hash of (source, target) pairs identifying which templates
|
101
|
-
# will be built into self by build. Templates are identified by
|
102
|
-
# TEMPLATES_KEY in config, and normalized the same way as recipes.
|
103
|
-
def templates
|
104
|
-
config[TEMPLATES_KEY] = Utils.hashify(config[TEMPLATES_KEY])
|
105
|
-
end
|
106
|
-
|
107
|
-
# Returns the hash of (source, target) pairs identifying which recipes
|
108
|
-
# will be built into self by build. Recipes are identified by RECIPES_KEY
|
109
|
-
# in config.
|
110
|
-
#
|
111
|
-
# Non-hash recipes are normalized by expanding arrays into a redundant
|
112
|
-
# hash, such that each entry has the same source and target (more
|
113
|
-
# concretely, the 'example' recipe is registered as the 'example' script).
|
114
|
-
# Strings are split along colons into an array and then expanded.
|
115
|
-
#
|
116
|
-
# For example:
|
117
|
-
#
|
118
|
-
# package = Package.new('linecook' => {'package' => {'recipes' => 'a:b:c'}})
|
119
|
-
# package.recipes # => {'a' => 'a', 'b' => 'b', 'c' => 'c'}
|
26
|
+
|
27
|
+
# Registers a file into the package with the specified export options. The
|
28
|
+
# source path should be the path to a file or directory to include. To
|
29
|
+
# make an empty file or directory use :file or :dir as the source_path.
|
120
30
|
#
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
# registered.
|
128
|
-
def register(target_name, source_path, mode=0600)
|
129
|
-
source_path = File.expand_path(source_path)
|
130
|
-
|
131
|
-
if registry.has_key?(target_name) && registry[target_name] != [source_path, mode]
|
132
|
-
raise "already registered: #{target_name} (%s, %o)" % registry[target_name]
|
133
|
-
end
|
134
|
-
|
135
|
-
registry[target_name] = [source_path, mode]
|
136
|
-
target_name
|
137
|
-
end
|
138
|
-
|
139
|
-
# Increments target_name until an unregistered name is found and returns
|
140
|
-
# the result.
|
141
|
-
def next_target_name(target_name='file')
|
142
|
-
count = 0
|
143
|
-
registry.each_key do |key|
|
144
|
-
if key.index(target_name) == 0
|
145
|
-
count += 1
|
146
|
-
end
|
31
|
+
# Raises an error if a source is already registered at the path.
|
32
|
+
def register(path, source_path, options={})
|
33
|
+
package_path = path.to_s.strip
|
34
|
+
|
35
|
+
if package_path.empty?
|
36
|
+
raise "invalid package path: #{path.inspect}"
|
147
37
|
end
|
148
|
-
|
149
|
-
if
|
150
|
-
|
38
|
+
|
39
|
+
if registry.has_key?(package_path)
|
40
|
+
raise "already registered: #{path.inspect}"
|
151
41
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
context = context.to_s
|
159
|
-
|
160
|
-
count = counters[context]
|
161
|
-
counters[context] += 1
|
162
|
-
|
163
|
-
"#{context}#{count}"
|
164
|
-
end
|
165
|
-
|
166
|
-
# Returns true if there is a path for the specified resource in manifest.
|
167
|
-
def resource?(type, path)
|
168
|
-
resources = manifest[type]
|
169
|
-
resources && resources.has_key?(path)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Returns the path to the resource in manfiest. Raises an error if there
|
173
|
-
# is no such resource.
|
174
|
-
def resource_path(type, path)
|
175
|
-
resources = manifest[type]
|
176
|
-
resource_path = resources ? resources[path] : nil
|
177
|
-
resource_path or raise "no such resource in manifest: #{type.inspect} #{path.inspect}"
|
178
|
-
end
|
179
|
-
|
180
|
-
# Returns the resource_path the named attributes file (ex 'attributes/name.rb').
|
181
|
-
def attributes_path(attributes_name)
|
182
|
-
resource_path('attributes', attributes_name)
|
183
|
-
end
|
184
|
-
|
185
|
-
# Returns the resource_path the named file (ex 'files/name')
|
186
|
-
def file_path(file_name)
|
187
|
-
resource_path('files', file_name)
|
188
|
-
end
|
189
|
-
|
190
|
-
# Returns the resource_path the named template file (ex 'templates/name.erb').
|
191
|
-
def template_path(template_name)
|
192
|
-
resource_path('templates', template_name)
|
42
|
+
|
43
|
+
source_path = resolve_source_path(source_path)
|
44
|
+
registry[package_path] = source_path
|
45
|
+
on_export(package_path, options)
|
46
|
+
|
47
|
+
source_path
|
193
48
|
end
|
194
|
-
|
195
|
-
#
|
196
|
-
|
197
|
-
|
49
|
+
|
50
|
+
# Removes a file from the package. Returns the source path if one was
|
51
|
+
# registered.
|
52
|
+
def unregister(path)
|
53
|
+
registry.delete(path)
|
54
|
+
export_options.delete(path)
|
198
55
|
end
|
199
|
-
|
200
|
-
#
|
201
|
-
#
|
202
|
-
# extname.
|
56
|
+
|
57
|
+
# Sets export options for the package file. Available options (as
|
58
|
+
# symbols):
|
203
59
|
#
|
204
|
-
#
|
205
|
-
#
|
60
|
+
# move:: When set to true the source will be moved into place
|
61
|
+
# rather than copied (the default)
|
62
|
+
# mode:: Sets the mode of the package file
|
206
63
|
#
|
207
|
-
#
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
64
|
+
# Unless specified, the values in default_export_options will be used.
|
65
|
+
def on_export(path, options={})
|
66
|
+
export_options[path] = default_export_options.merge(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Generates a tempfile and registers it into the package at the specified
|
70
|
+
# path. Returns the open tempfile.
|
71
|
+
def add(path, options={})
|
72
|
+
options = {
|
73
|
+
:move => true
|
74
|
+
}.merge(options)
|
75
|
+
|
76
|
+
# preserve a reference to tempfile in options so that it will not be
|
77
|
+
# unlinked before it can be moved into the package during export
|
78
|
+
tempfile = Tempfile.new File.basename(path)
|
79
|
+
options[:tempfile] = tempfile
|
80
|
+
|
81
|
+
if block_given?
|
82
|
+
begin
|
83
|
+
yield tempfile
|
84
|
+
ensure
|
85
|
+
tempfile.close
|
222
86
|
end
|
223
87
|
end
|
224
|
-
|
225
|
-
|
226
|
-
end
|
227
|
-
|
228
|
-
# Load the template file with the specified name and wraps as a Template.
|
229
|
-
# Returns the new Template object.
|
230
|
-
def load_template(template_name)
|
231
|
-
Template.new template_path(template_name)
|
232
|
-
end
|
233
|
-
|
234
|
-
# Loads and returns the helper constant specified by helper_name. The
|
235
|
-
# helper_name is underscored to determine a require path and camelized to
|
236
|
-
# determine the constant name.
|
237
|
-
def load_helper(helper_name)
|
238
|
-
require Utils.underscore(helper_name)
|
239
|
-
Utils.constantize(helper_name)
|
240
|
-
end
|
241
|
-
|
242
|
-
# Returns a recipe bound to self.
|
243
|
-
def setup_recipe(target_name = next_target_name, mode=0700)
|
244
|
-
Recipe.new(self, target_name, mode)
|
245
|
-
end
|
246
|
-
|
247
|
-
# Generates a tempfile for the target path and registers it with self. As
|
248
|
-
# with register, the target_name will be incremented as needed. Returns
|
249
|
-
# the open tempfile.
|
250
|
-
def setup_tempfile(target_name = next_target_name, mode=0600)
|
251
|
-
tempfile = Tempfile.new File.basename(target_name)
|
252
|
-
|
253
|
-
register(target_name, tempfile.path, mode)
|
254
|
-
tempfiles << tempfile
|
255
|
-
|
88
|
+
|
89
|
+
register path, tempfile.path, options
|
256
90
|
tempfile
|
257
91
|
end
|
258
|
-
|
259
|
-
#
|
260
|
-
def
|
261
|
-
|
92
|
+
|
93
|
+
# Adds an empty dir at path. Returns nil.
|
94
|
+
def add_dir(path, options={})
|
95
|
+
register path, :dir, options
|
262
96
|
end
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
97
|
+
|
98
|
+
alias rm unregister
|
99
|
+
|
100
|
+
# Returns the source path registered at the path, or nil if no source is
|
101
|
+
# registered.
|
102
|
+
def source_path(path)
|
103
|
+
registry[path]
|
269
104
|
end
|
270
|
-
|
271
|
-
#
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
105
|
+
|
106
|
+
# Returns an array of paths that the source path is registered to.
|
107
|
+
def paths(source_path)
|
108
|
+
source = resolve_source_path(source_path)
|
109
|
+
|
110
|
+
paths = []
|
111
|
+
registry.each_pair do |path, current|
|
112
|
+
if current == source
|
113
|
+
paths << path
|
114
|
+
end
|
115
|
+
end
|
116
|
+
paths
|
282
117
|
end
|
283
|
-
|
284
|
-
#
|
285
|
-
#
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
recipe = setup_recipe(target_name, mode)
|
290
|
-
recipe.instance_eval(File.read(path), path)
|
291
|
-
recipe.close
|
292
|
-
|
293
|
-
self
|
118
|
+
|
119
|
+
# Returns the content to be added to the package at the path. Returns nil
|
120
|
+
# if nothing is registered.
|
121
|
+
def content(path, length=nil, offset=nil)
|
122
|
+
source = source_path(path)
|
123
|
+
source ? File.read(source, length, offset) : nil
|
294
124
|
end
|
295
|
-
|
296
|
-
#
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
125
|
+
|
126
|
+
# Increments path until an unregistered path is found and returns the
|
127
|
+
# result in the format "path.count".
|
128
|
+
def next_path(path='file')
|
129
|
+
count = 0
|
130
|
+
registry.each_key do |current|
|
131
|
+
if current.index(path) == 0
|
132
|
+
count += 1
|
133
|
+
end
|
304
134
|
end
|
305
|
-
|
306
|
-
|
307
|
-
|
135
|
+
|
136
|
+
if count > 0
|
137
|
+
path = "#{path}.#{count}"
|
308
138
|
end
|
309
|
-
|
310
|
-
|
311
|
-
end
|
312
|
-
|
313
|
-
# Returns the content of the source_path for target_name, as registered in
|
314
|
-
# self. Returns nil if the target is not registered.
|
315
|
-
def content(target_name, length=nil, offset=nil)
|
316
|
-
path = source_path(target_name)
|
317
|
-
path ? File.read(path, length, offset) : nil
|
318
|
-
end
|
319
|
-
|
320
|
-
# Returns the source_path for target_name, as registered in self. Returns
|
321
|
-
# nil if the target is not registered.
|
322
|
-
def source_path(target_name)
|
323
|
-
entry = registry[target_name]
|
324
|
-
entry ? entry[0] : nil
|
325
|
-
end
|
326
|
-
|
327
|
-
# Returns the mode for target_name, as registered in self. Returns nil if
|
328
|
-
# the target is not registered.
|
329
|
-
def mode(target_name)
|
330
|
-
entry = registry[target_name]
|
331
|
-
entry ? entry[1] : nil
|
139
|
+
|
140
|
+
path
|
332
141
|
end
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
142
|
+
|
143
|
+
def export(dir)
|
144
|
+
registry.keys.sort.each do |path|
|
145
|
+
target_path = File.join(dir, path)
|
146
|
+
source_path = registry[path]
|
147
|
+
options = export_options[path] || default_export_options
|
148
|
+
|
149
|
+
if source_path != target_path
|
150
|
+
if File.exists?(target_path)
|
151
|
+
if block_given?
|
152
|
+
unless yield(source_path, target_path)
|
153
|
+
next
|
154
|
+
end
|
155
|
+
else
|
156
|
+
raise "already exists: #{target_path.inspect}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
target_dir = File.dirname(target_path)
|
161
|
+
FileUtils.mkdir_p(target_dir)
|
162
|
+
|
163
|
+
case source_path
|
164
|
+
when :file
|
165
|
+
FileUtils.touch target_path
|
166
|
+
when :dir
|
167
|
+
FileUtils.mkdir target_path
|
168
|
+
else
|
169
|
+
if File.directory?(source_path)
|
170
|
+
export_dir(source_path, target_path, options)
|
171
|
+
else
|
172
|
+
export_file(source_path, target_path, options)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
if mode = options[:mode]
|
178
|
+
FileUtils.chmod(mode, target_path)
|
179
|
+
end
|
180
|
+
|
181
|
+
registry[path] = target_path
|
338
182
|
end
|
339
|
-
|
183
|
+
|
184
|
+
registry
|
340
185
|
end
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
self
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
def resolve_source_path(source_path) # :nodoc:
|
190
|
+
case source_path
|
191
|
+
when :file, :dir then source_path
|
192
|
+
else File.expand_path(source_path.to_s)
|
193
|
+
end
|
350
194
|
end
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
def export(dir, options={})
|
358
|
-
close
|
359
|
-
|
360
|
-
options = {
|
361
|
-
:allow_move => true
|
362
|
-
}.merge(options)
|
363
|
-
|
364
|
-
allow_move = options[:allow_move]
|
365
|
-
|
366
|
-
if File.exists?(dir)
|
367
|
-
FileUtils.rm_r(dir)
|
195
|
+
|
196
|
+
def export_dir(source_path, target_path, options) # :nodoc:
|
197
|
+
if options[:move]
|
198
|
+
FileUtils.mv(source_path, target_path)
|
199
|
+
else
|
200
|
+
FileUtils.cp_r(source_path, target_path)
|
368
201
|
end
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
source_path,
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
unless File.exists?(export_dir)
|
378
|
-
FileUtils.mkdir_p(export_dir)
|
379
|
-
end
|
380
|
-
|
381
|
-
if allow_move && tempfile?(source_path)
|
382
|
-
FileUtils.mv(source_path, export_path)
|
383
|
-
else
|
384
|
-
FileUtils.cp(source_path, export_path)
|
385
|
-
end
|
386
|
-
|
387
|
-
FileUtils.chmod(mode, export_path)
|
388
|
-
|
389
|
-
registry[target_name] = [export_path, mode]
|
202
|
+
end
|
203
|
+
|
204
|
+
def export_file(source_path, target_path, options) # :nodoc:
|
205
|
+
if options[:move]
|
206
|
+
FileUtils.mv(source_path, target_path)
|
207
|
+
else
|
208
|
+
FileUtils.cp(source_path, target_path)
|
390
209
|
end
|
391
|
-
|
392
|
-
tempfiles.clear
|
393
|
-
registry
|
394
210
|
end
|
395
211
|
end
|
396
212
|
end
|