rbbt-util 5.25.7 → 5.25.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/hpc.rb +319 -77
- data/lib/rbbt/util/misc.rb +3 -1
- data/lib/rbbt/workflow/accessor.rb +24 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a8edeae60507177567648ab41bb5566d8707a31
|
4
|
+
data.tar.gz: 9e5188a78754f01da5c96eee01e0448bebb34a1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 593de7cb23b2afd5562bc72cf44efc6d3a9138da692009aa8d15e54996ea31f3dfb9ac75cf0412b0e861c8014be62ff0f2b8ffd6ce74b28c1caa46e0dff53d83
|
7
|
+
data.tar.gz: dd4f867fa4e20a6a8eaf8e53d8cdd8a782f5181e2fb5863004c028f1a8ce8bcf82c2d67b5469e5f8d9c3a437417af4a053a05c80db85f55b0db61a44a58dbd84
|
data/lib/rbbt/hpc.rb
CHANGED
@@ -4,119 +4,361 @@ require 'rbbt/util/cmd'
|
|
4
4
|
module Marenostrum
|
5
5
|
SERVER='mn1'
|
6
6
|
module SLURM
|
7
|
-
TEMPLATE=<<-EOF
|
8
7
|
|
8
|
+
def self.template(args, options = {})
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
dry_run = options.delete :dry_run
|
11
|
+
development = options.delete :drbbt
|
12
|
+
contain = options.delete :contain
|
13
|
+
sync = options.delete :sync
|
14
|
+
contain_and_sync = options.delete :contain_and_sync
|
15
|
+
wipe_container = options.delete :wipe_container
|
16
|
+
copy_image = options.delete :copy_image
|
17
|
+
exclusive = options.delete :exclusive
|
18
|
+
highmem = options.delete :highmem
|
19
|
+
|
20
|
+
if contain_and_sync
|
21
|
+
contain = "/scratch/tmp/rbbt" if contain.nil?
|
22
|
+
sync = "~/.rbbt/var/jobs" if sync.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
contain = File.expand_path(contain) if contain
|
26
|
+
|
27
|
+
singularity = true if contain || ! development
|
28
|
+
|
29
|
+
|
30
|
+
name = options[:name] ||= Misc.obj2digest({:options => options.collect{|k,v| [k,v]}.sort_by{|k,v| k.to_s }, :args => args})
|
31
|
+
workdir = options[:workdir] ||= File.expand_path(File.join('~/rbbt-workdir', name)) if workdir.nil?
|
32
|
+
|
33
|
+
rbbt_cmd = args.reject{|e| e == '--' }.collect{|e| e.include?(" ")? '"' + e + '"' : e } * " "
|
34
|
+
|
35
|
+
queue = options[:queue] || 'bsc_ls'
|
36
|
+
tasks = options[:tasks] || 1
|
37
|
+
time = options[:time] || "0:00:10"
|
38
|
+
|
39
|
+
time = Misc.format_seconds Misc.timespan(time) unless time.include? ":"
|
15
40
|
|
16
|
-
new_options = Misc.add_defaults options, "job-name" => name, "workdir" => workdir,
|
17
|
-
"output" => "log",
|
18
|
-
"error" => "log.err",
|
19
|
-
"ntasks" => "1",
|
20
|
-
"time" => time.to_s,
|
21
|
-
"user" => ENV["USER"],
|
22
|
-
"key_file" => File.join(ENV['HOME'], '.ssh/id_rsa.pub')
|
23
41
|
|
24
|
-
|
25
|
-
IndiferentHash.setup(options)
|
42
|
+
#{{{ PREPARE LOCAL LOGFILES
|
26
43
|
|
27
|
-
|
44
|
+
Open.mkdir workdir
|
28
45
|
|
29
|
-
|
46
|
+
fout = File.join(workdir, 'std.out')
|
47
|
+
ferr = File.join(workdir, 'std.err')
|
48
|
+
fjob = File.join(workdir, 'job.id')
|
49
|
+
fexit = File.join(workdir, 'exit.status')
|
50
|
+
fsync = File.join(workdir, 'sync.log')
|
51
|
+
fcmd = File.join(workdir, 'command.slurm')
|
52
|
+
|
53
|
+
#{{{ GENERATE TEMPLATE
|
54
|
+
|
55
|
+
# HEADER
|
56
|
+
header =<<-EOF
|
30
57
|
#!/bin/bash
|
31
|
-
#{
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
}
|
38
|
-
#{ cmd }
|
58
|
+
#SBATCH --qos="#{queue}"
|
59
|
+
#SBATCH --job-name="#{name}"
|
60
|
+
#SBATCH --workdir="#{Dir.pwd}"
|
61
|
+
#SBATCH --output="#{fout}"
|
62
|
+
#SBATCH --error="#{ferr}"
|
63
|
+
#SBATCH --ntasks="#{tasks}"
|
64
|
+
#SBATCH --time="#{time}"
|
39
65
|
EOF
|
40
66
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
67
|
+
if highmem
|
68
|
+
header +=<<-EOF
|
69
|
+
#SBATCH --constraint=highmem
|
70
|
+
EOF
|
71
|
+
end
|
72
|
+
|
73
|
+
if exclusive
|
74
|
+
header +=<<-EOF
|
75
|
+
#SBATCH --exclusive
|
76
|
+
EOF
|
77
|
+
end
|
78
|
+
|
79
|
+
header +=<<-EOF
|
80
|
+
#CMD: #{rbbt_cmd}
|
81
|
+
EOF
|
82
|
+
|
83
|
+
# ENV
|
84
|
+
env = ""
|
85
|
+
env +=<<-EOF
|
86
|
+
# Prepare env
|
87
|
+
[[ -f ~/config/load.sh ]] && source ~/config/load.sh
|
88
|
+
module load java
|
89
|
+
EOF
|
90
|
+
|
91
|
+
if singularity
|
92
|
+
env +=<<-EOF
|
93
|
+
module load intel/2018.1
|
94
|
+
module load singularity
|
95
|
+
module load samtools
|
96
|
+
SINGULARITY_IMG="$HOME/projects/rbbt.singularity.img"
|
97
|
+
SINGULARITY_RUBY_INLINE="$HOME/.singularity_ruby_inline"
|
98
|
+
mkdir -p "$SINGULARITY_RUBY_INLINE"
|
99
|
+
EOF
|
100
|
+
end
|
101
|
+
|
102
|
+
if contain
|
103
|
+
env +=<<-EOF
|
104
|
+
CONTAINER_DIR="#{contain}"
|
105
|
+
mkdir -p $CONTAINER_DIR/.rbbt/etc/
|
106
|
+
for tmpd in persist_locks produce_locks R_sockets sensiblewrite sensiblewrite_locks step_info_locks tsv_open_locks; do
|
107
|
+
mkdir -p $CONTAINER_DIR/.rbbt/tmp/$tmpd
|
108
|
+
done
|
109
|
+
cp ~/.rbbt/etc/environment $CONTAINER_DIR/.rbbt/etc/
|
110
|
+
echo "rbbt_user: /home/rbbt/.rbbt/{TOPLEVEL}/{SUBPATH}" > $CONTAINER_DIR/.rbbt/etc/search_paths
|
111
|
+
echo "home: $CONTAINER_DIR/home/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
112
|
+
echo "group_projects: $CONTAINER_DIR/projects/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
113
|
+
echo "group_scratch: $CONTAINER_DIR/scratch/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
114
|
+
echo "user_projects: $CONTAINER_DIR/projects/#{ENV['USER']}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
115
|
+
echo "user_scratch: $CONTAINER_DIR/scratch/#{ENV['USER']}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
116
|
+
EOF
|
117
|
+
|
118
|
+
if copy_image
|
119
|
+
env +=<<EOF
|
120
|
+
rsync -avz "$SINGULARITY_IMG" "$CONTAINER_DIR/rbbt.singularity.img"
|
121
|
+
SINGULARITY_IMG="$CONTAINER_DIR/rbbt.singularity.img"
|
122
|
+
EOF
|
52
123
|
end
|
53
124
|
|
54
|
-
|
125
|
+
if wipe_container == "pre" || wipe_container == "both"
|
126
|
+
env +=<<-EOF
|
127
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rm -Rfv .rbbt/var/jobs &>> #{fsync}
|
128
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rbbt system clean -f &>> #{fsync}
|
129
|
+
EOF
|
130
|
+
end
|
55
131
|
end
|
56
|
-
end
|
57
132
|
|
58
|
-
|
59
|
-
|
133
|
+
# RUN
|
134
|
+
run = ""
|
135
|
+
|
136
|
+
if singularity
|
137
|
+
if contain
|
138
|
+
group = File.basename(File.dirname(ENV['HOME']))
|
139
|
+
scratch_group_dir = File.join('/gpfs/scratch/', group)
|
140
|
+
projects_group_dir = File.join('/gpfs/projects/', group)
|
141
|
+
exec_cmd = %(singularity exec -e -C -H "$CONTAINER_DIR" -B "$SINGULARITY_RUBY_INLINE":"$CONTAINER_DIR/.ruby_inline":rw -B ~/git:"$CONTAINER_DIR/git":ro -B #{scratch_group_dir}:"$CONTAINER_DIR/scratch":ro -B ~/.rbbt/software/opt/:"/opt/":ro -B ~/.rbbt:"$CONTAINER_DIR/home/":ro -B #{projects_group_dir}:"$CONTAINER_DIR/projects":ro "$SINGULARITY_IMG" env TMPDIR="$CONTAINER_DIR/.rbbt/tmp" rbbt)
|
142
|
+
else
|
143
|
+
exec_cmd = %(singularity exec -e -B "$SINGULARITY_RUBY_INLINE":"$HOME/.ruby_inline":rw "$SINGULARITY_IMG" rbbt)
|
144
|
+
end
|
145
|
+
|
146
|
+
if development
|
147
|
+
exec_cmd += ' --dev=git'
|
148
|
+
end
|
149
|
+
else
|
150
|
+
exec_cmd = %(~/git/rbbt-util/bin/rbbt --dev=~/git/)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
cmd =<<-EOF
|
155
|
+
#{exec_cmd} \\
|
156
|
+
#{rbbt_cmd}
|
157
|
+
EOF
|
60
158
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
159
|
+
run +=<<-EOF
|
160
|
+
|
161
|
+
# Run command
|
162
|
+
#{cmd}
|
163
|
+
|
164
|
+
# Save exit status
|
165
|
+
echo $? > #{fexit}
|
166
|
+
|
167
|
+
# Clean job.id, since we are done
|
168
|
+
rm #{fjob}
|
169
|
+
EOF
|
170
|
+
|
171
|
+
# CODA
|
172
|
+
coda = ""
|
173
|
+
if sync
|
174
|
+
if singularity
|
175
|
+
coda +=<<-EOF
|
176
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rbbt system clean all -q &>> #{fsync}
|
177
|
+
EOF
|
178
|
+
end
|
179
|
+
|
180
|
+
coda +=<<-EOF
|
181
|
+
rsync -avt "#{File.join(File.expand_path(contain), '.rbbt/var/jobs')}/" "#{File.expand_path(sync)}/" &>> #{fsync}
|
182
|
+
EOF
|
183
|
+
|
184
|
+
if contain && (wipe_container == "post" || wipe_container == "both")
|
185
|
+
coda +=<<-EOF
|
186
|
+
sync_es="$?"
|
187
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rbbt system clean -f &>> #{fsync}
|
188
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rm -v /dev/shm/sem.*.{in,out,process} /dev/shm/sem.Session-PID.*.sem 2> /dev/null >> #{fsync}
|
189
|
+
if [ $sync_es == '0' ]; then
|
190
|
+
singularity exec -e -C -H "$CONTAINER_DIR" "$SINGULARITY_IMG" rm -Rfv .rbbt/var/jobs &>> #{fsync}
|
191
|
+
else
|
192
|
+
echo "WARNING: Results could not sync correctly. Job directory not purged"
|
193
|
+
fi
|
194
|
+
unset sync_es
|
195
|
+
EOF
|
196
|
+
end
|
68
197
|
end
|
69
198
|
|
70
|
-
|
199
|
+
template = [header, env, run, coda] * "\n"
|
200
|
+
|
201
|
+
template
|
71
202
|
end
|
203
|
+
|
204
|
+
def self.issue_template(template, options = {})
|
72
205
|
|
73
|
-
|
74
|
-
|
206
|
+
workdir = options[:workdir]
|
207
|
+
Open.mkdir workdir
|
208
|
+
fout = File.join(workdir, 'std.out')
|
209
|
+
ferr = File.join(workdir, 'std.err')
|
210
|
+
fjob = File.join(workdir, 'job.id')
|
211
|
+
fexit = File.join(workdir, 'exit.status')
|
212
|
+
fsync = File.join(workdir, 'sync.log')
|
213
|
+
fcmd = File.join(workdir, 'command.slurm')
|
214
|
+
|
215
|
+
job = nil
|
216
|
+
if options[:clean_job]
|
217
|
+
[fcmd, fjob, fout, ferr, fsync, fexit].each do |file|
|
218
|
+
Open.rm file if Open.exists? file
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
return if Open.exists?(fexit)
|
223
|
+
|
224
|
+
STDERR.puts Log.color(:magenta, "Issuing SLURM file: #{fcmd}")
|
225
|
+
STDERR.puts template
|
226
|
+
|
227
|
+
Open.write(fcmd, template) unless File.exists? fcmd
|
228
|
+
if File.exists?(fjob)
|
229
|
+
job = Open.read(fjob).to_i
|
230
|
+
else
|
231
|
+
if File.exists?(fout)
|
232
|
+
return
|
233
|
+
else
|
234
|
+
Open.rm fsync
|
235
|
+
Open.rm fexit
|
236
|
+
Open.rm fout
|
237
|
+
Open.rm ferr
|
238
|
+
job = CMD.cmd("sbatch '#{fcmd}'").read.scan(/\d+/).first.to_i
|
239
|
+
Open.write(fjob, job.to_s)
|
240
|
+
end
|
241
|
+
end
|
75
242
|
end
|
76
243
|
|
77
|
-
def self.
|
78
|
-
|
244
|
+
def self.follow_job(workdir, tail = true)
|
245
|
+
fjob = File.join(workdir, 'job.id')
|
246
|
+
fout = File.join(workdir, 'std.out')
|
247
|
+
ferr = File.join(workdir, 'std.err')
|
248
|
+
fstatus = File.join(workdir, 'job.status')
|
249
|
+
|
250
|
+
job = Open.read(fjob) if Open.exists?(fjob)
|
79
251
|
|
80
|
-
|
252
|
+
if job
|
253
|
+
status_txt = CMD.cmd("squeue --job #{job}").read
|
254
|
+
STDERR.puts Log.color(:magenta, "Status [#{job.to_i}]:")
|
255
|
+
STDERR.puts status_txt
|
256
|
+
lines = status_txt.split("\n").length
|
257
|
+
end
|
81
258
|
|
259
|
+
if tail
|
260
|
+
while ! File.exists? fout
|
261
|
+
if job
|
262
|
+
STDERR.puts
|
263
|
+
Log.clear_line(STDERR)
|
264
|
+
STDERR.write Log.color(:magenta, "Waiting for Output")
|
265
|
+
3.times do
|
266
|
+
STDERR.write Log.color(:magenta, ".")
|
267
|
+
sleep 1
|
268
|
+
end
|
269
|
+
status_txt = CMD.cmd("squeue --job #{job}").read
|
270
|
+
lines.times do
|
271
|
+
Log.clear_line(STDERR)
|
272
|
+
end
|
273
|
+
Log.clear_line(STDERR)
|
274
|
+
STDERR.puts Log.color(:magenta, "Status [#{job.to_i}]:")
|
275
|
+
STDERR.puts status_txt
|
276
|
+
lines = status_txt.split("\n").length
|
277
|
+
end
|
278
|
+
end
|
279
|
+
STDERR.puts
|
280
|
+
Log.clear_line(STDERR)
|
281
|
+
STDERR.puts Log.color(:magenta, "Output:")
|
82
282
|
begin
|
83
|
-
cmd
|
84
|
-
|
85
|
-
CMD.cmd(
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
283
|
+
CMD.cmd("squeue --job #{job} > #{fstatus}")
|
284
|
+
out = CMD.cmd("tail -f '#{fout}'", :pipe => true) if File.exists? fout
|
285
|
+
err = CMD.cmd("tail -f '#{ferr}'", :pipe => true) if File.exists? ferr
|
286
|
+
|
287
|
+
Misc.consume_stream(err, true, STDERR) if err
|
288
|
+
Misc.consume_stream(out, true, STDOUT) if out
|
289
|
+
|
290
|
+
sleep 3 while CMD.cmd("squeue --job #{job}").read.include? job.to_s
|
291
|
+
ensure
|
292
|
+
begin
|
293
|
+
err.close if err
|
294
|
+
err.join if err
|
295
|
+
rescue Exception
|
296
|
+
end
|
297
|
+
|
298
|
+
begin
|
299
|
+
out.close if out
|
300
|
+
out.join if out
|
301
|
+
rescue Exception
|
90
302
|
end
|
91
|
-
rescue
|
92
|
-
raise "Could not gather job: #{ id }: " << $!.message
|
93
303
|
end
|
94
304
|
end
|
95
305
|
end
|
96
306
|
|
97
|
-
def self.
|
98
|
-
|
307
|
+
def self.wait_for_job(workdir, time = 1)
|
308
|
+
fexit = File.join(workdir, 'exit.status')
|
309
|
+
fjob = File.join(workdir, 'job.id')
|
310
|
+
job = Open.read(fjob) if Open.exists?(fjob)
|
99
311
|
|
100
|
-
|
312
|
+
status_txt = CMD.cmd("squeue --job #{job}").read
|
313
|
+
STDERR.puts Log.color(:magenta, "Status [#{job.to_i}]:")
|
314
|
+
STDERR.puts status_txt
|
315
|
+
lines = status_txt.split("\n").length
|
101
316
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
317
|
+
while ! Open.exists?(fexit)
|
318
|
+
STDERR.puts
|
319
|
+
Log.clear_line(STDERR)
|
320
|
+
STDERR.write Log.color(:magenta, "Waiting for end")
|
321
|
+
3.times do
|
322
|
+
STDERR.write Log.color(:magenta, ".")
|
323
|
+
sleep 1
|
324
|
+
end
|
325
|
+
status_txt = CMD.cmd("squeue --job #{job}").read
|
326
|
+
lines.times do
|
327
|
+
Log.clear_line(STDERR)
|
328
|
+
end
|
329
|
+
Log.clear_line(STDERR)
|
330
|
+
STDERR.puts Log.color(:magenta, "Status [#{job.to_i}]:")
|
331
|
+
STDERR.puts status_txt
|
332
|
+
lines = status_txt.split("\n").length
|
333
|
+
sleep time
|
106
334
|
end
|
335
|
+
end
|
107
336
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
337
|
+
def self.run_job(job, options = {})
|
338
|
+
workflow = job.workflow
|
339
|
+
task = job.task_name
|
340
|
+
name = job.clean_name
|
341
|
+
TmpFile.with_file(nil, false) do |tmp_directory|
|
342
|
+
workdir = options[:workdir] ||= File.join(tmp_directory, 'workdir')
|
343
|
+
inputs_dir = File.join(tmp_directory, 'inputs_dir')
|
344
|
+
Step.save_job_inputs(job, inputs_dir)
|
345
|
+
cmd = ['workflow', 'task', workflow.to_s, task.to_s, '-pf', '-jn', name, '--load_inputs', inputs_dir, '--log', (options[:log] || Log.severity).to_s]
|
346
|
+
template = self.template(cmd, options)
|
347
|
+
self.issue_template(template, options)
|
348
|
+
self.wait_for_job(workdir)
|
349
|
+
path = Open.read(File.join(workdir, 'std.out'))
|
350
|
+
if job.path != path
|
351
|
+
Log.medium "Path of SLURM job #{path} is different from original job #{job.path}. Stablishing link."
|
352
|
+
Open.ln path, job.path
|
353
|
+
end
|
112
354
|
end
|
113
|
-
|
114
|
-
gather(id, nil, options)
|
115
355
|
end
|
116
356
|
end
|
117
357
|
end
|
118
358
|
|
119
|
-
|
120
|
-
|
359
|
+
if __FILE__ == $0
|
360
|
+
Log.severity = 0
|
361
|
+
iii Marenostrum::SLURM.run('ls', nil, nil, :qos => "debug", :user => 'bsc26892') if __FILE__ == $0
|
362
|
+
end
|
121
363
|
|
122
364
|
|
data/lib/rbbt/util/misc.rb
CHANGED
@@ -71,13 +71,15 @@ module Misc
|
|
71
71
|
def self.timespan(str, default = "s")
|
72
72
|
tokens = {
|
73
73
|
"s" => (1),
|
74
|
+
"sec" => (1),
|
75
|
+
"m" => (60),
|
74
76
|
"min" => (60),
|
75
77
|
"''" => (1),
|
76
78
|
"'" => (60),
|
77
79
|
"h" => (60 * 60),
|
78
80
|
"d" => (60 * 60 * 24),
|
79
81
|
"w" => (60 * 60 * 24 * 7),
|
80
|
-
"
|
82
|
+
"mo" => (60 * 60 * 24 * 30),
|
81
83
|
"y" => (60 * 60 * 24 * 365),
|
82
84
|
}
|
83
85
|
|
@@ -80,6 +80,29 @@ class Step
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
def self.save_job_inputs(job, dir)
|
84
|
+
|
85
|
+
task_name = job.task_name
|
86
|
+
task_info = job.workflow.task_info(task_name)
|
87
|
+
input_types = task_info[:input_types]
|
88
|
+
task_inputs = task_info[:inputs]
|
89
|
+
job.recursive_inputs.zip(job.recursive_inputs.fields).each do |value,name|
|
90
|
+
next unless task_inputs.include? name.to_sym
|
91
|
+
next if value.nil?
|
92
|
+
path = File.join(dir, name.to_s)
|
93
|
+
type = input_types[name]
|
94
|
+
Log.debug "Saving job input #{name} (#{type}) into #{path}"
|
95
|
+
case
|
96
|
+
when Array === value
|
97
|
+
Open.write(path, value * "\n")
|
98
|
+
when IO === value
|
99
|
+
Open.write(path, value)
|
100
|
+
else
|
101
|
+
Open.write(path, value.to_s)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
83
106
|
def name
|
84
107
|
@name ||= path.sub(/.*\/#{Regexp.quote task_name.to_s}\/(.*)/, '\1')
|
85
108
|
end
|
@@ -108,7 +131,7 @@ class Step
|
|
108
131
|
#Lockfile.new path, :refresh => false, :dont_use_lock_id => true
|
109
132
|
Lockfile.new path
|
110
133
|
end if @info_lock.nil?
|
111
|
-
|
134
|
+
@info_lock
|
112
135
|
end
|
113
136
|
|
114
137
|
def status_lock
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.25.
|
4
|
+
version: 5.25.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|