linecook 1.2.1 → 2.0.0
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/{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
|