rbbt-util 5.22.4 → 5.22.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 694be20134e0bd77c1d240c04fe52f547cd4b431
4
- data.tar.gz: f96f17c3f62ec9f5d781036966c022f275e8b879
3
+ metadata.gz: 1c617d4a4ffaed12ddf8a5cdf44a4ff5113e47d0
4
+ data.tar.gz: 74125cd2876fff8d7c097d89eee4adb47f61a26c
5
5
  SHA512:
6
- metadata.gz: 6d725866e6cbf97a5a627ca5e575d202e348e2688bf37aff4032d8c752b7fd6e747e1df85c00cf69de6258b7112812da43356db552f65940f22ef86101107afb
7
- data.tar.gz: 98dfdd3a29d277cb2c2c52f76e6ffbae1c7f1d033f823a36637235b7b47bb61e0ae43652c14f626a9341df41f370fa0fa7ed55b2a625a63896ffce82c4d9d37a
6
+ metadata.gz: 81bf1cb9b56203f6ab747ef961fc920146e07b78e2a220fdf2e9174adfd0effbf01974e4560ff6759c2e180d4ce03ea6c2db4fc2a047e07162c342a265735b8f
7
+ data.tar.gz: c4ef6e26f7683f2365f9ca15cfc045cf69a04a174d2f59a0dce0a22ede010b22f962d17d9bc03f73469338c1c47c2c6cf33a6d65173e387e6f71c633462fabfc
@@ -160,7 +160,7 @@ module Annotated
160
160
  object
161
161
  when Array
162
162
  object.respond_to?(:clean_annotations) ?
163
- object.clean_annotations :
163
+ object.clean_annotations(true) :
164
164
  object.inject([]){|acc,e| acc << Annotated.purge(e); acc}
165
165
  when Hash
166
166
  new = {}
@@ -146,12 +146,13 @@ module Rbbt
146
146
  task = File.basename(taskdir)
147
147
  next if tasks and not tasks.include? task
148
148
 
149
- cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/*.files\" -prune \\) -not -name '*.pid' -not -name '*.notify' -not -name '\\.*' -not -type d 2>/dev/null"
149
+ #cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.notify' -not -name '\\.*' 2>/dev/null"
150
+ cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.notify' -not -name '\\.*' \\( -not -type d -o -name '*.files' \\) 2>/dev/null"
150
151
 
151
152
  files = CMD.cmd(cmd, :pipe => true)
152
153
  TSV.traverse files, :type => :array, :into => jobs, :_bar => "Finding jobs in #{ taskdir }" do |file|
153
154
  _files << file
154
- if m = file.match(/(.*).(info|pid)$/)
155
+ if m = file.match(/(.*)\.(info|pid|files)$/)
155
156
  file = m[1]
156
157
  end
157
158
  next if seen.include? file
@@ -194,10 +194,7 @@ source "$INSTALL_HELPER_FILE"
194
194
  EOF
195
195
 
196
196
  script = preamble + "\n" + Open.read(content)
197
- install_io = CMD.cmd('bash', :in => script, :log => true, :pipe => true, :stderr => true)
198
- while line = install_io.gets
199
- Log.debug line
200
- end
197
+ CMD.cmd_log('bash', :in => script)
201
198
 
202
199
  set_software_env(software_dir)
203
200
  else
@@ -141,7 +141,7 @@ module Path
141
141
  if self.match(/(.*?)\/(.*)/)
142
142
  toplevel, subpath = self.match(/(.*?)\/(.*)/).values_at 1, 2
143
143
  else
144
- toplevel, subpath = self, ""
144
+ toplevel, subpath = "{REMOVE}", self
145
145
  end
146
146
 
147
147
  path = nil
@@ -199,7 +199,9 @@ module Path
199
199
  sub('{SUBPATH}', subpath).
200
200
  sub('{BASENAME}', File.basename(self)).
201
201
  sub('{PATH}', self).
202
- sub('{LIBDIR}', libdir) #, @pkgdir, @resource, @search_paths
202
+ sub('{LIBDIR}', libdir).
203
+ sub('{REMOVE}/', '').
204
+ sub('{REMOVE}', '')
203
205
 
204
206
  path = path + '.gz' if File.exist? path + '.gz'
205
207
  path = path + '.bgz' if File.exist? path + '.bgz'
@@ -94,6 +94,7 @@ class RbbtProcessQueue
94
94
  Log.debug "Closing up process queue #{Process.pid}"
95
95
  @count = 0
96
96
  Thread.new do
97
+ Log.debug "Pushing closed stream #{Process.pid}"
97
98
  while true
98
99
  @queue.push ClosedStream.new unless @queue.cleaned
99
100
  end unless @processes.empty?
@@ -127,7 +128,7 @@ class RbbtProcessQueue
127
128
  rescue TryAgain
128
129
  retry
129
130
  rescue Aborted
130
- Log.low "Closing manager thread"
131
+ Log.low "Aborting manager thread #{Process.pid}"
131
132
  raise Aborted
132
133
  rescue Exception
133
134
  Log.exception $!
@@ -32,7 +32,7 @@ module Docker
32
32
  Open.write(directory[name], obj)
33
33
  end
34
34
  end
35
- end
35
+ end if job_inputs
36
36
  else
37
37
  TmpFile.with_file do |tmpfile|
38
38
  Path.setup(tmpfile)
@@ -55,12 +55,16 @@ module Docker
55
55
  Open.write(tmpfile[name], obj)
56
56
  end
57
57
  end
58
- end
58
+ end if job_inputs
59
59
  pipe = false
60
60
  end
61
61
 
62
62
  end
63
63
  cmd = "docker run #{mount_cmd} #{image_cmd} #{cmd}"
64
- CMD.cmd(cmd, :log => true, :pipe => pipe)
64
+ if pipe
65
+ CMD.cmd(cmd, :log => true, :pipe => true)
66
+ else
67
+ CMD.cmd_log(cmd, :log => true)
68
+ end
65
69
  end
66
70
  end
@@ -67,6 +67,26 @@ module Misc
67
67
  def self.tokenize(str)
68
68
  str.scan(/"[^"]*"|'[^']*'|[^"'\s]+/)
69
69
  end
70
+
71
+ def self.timespan(str, default = "s")
72
+ tokens = {
73
+ "s" => (1),
74
+ "m" => (60),
75
+ "h" => (60 * 60),
76
+ "d" => (60 * 60 * 24),
77
+ "w" => (60 * 60 * 24 * 7),
78
+ }
79
+
80
+ tokens[nil] = tokens[default]
81
+ tokens[""] = tokens[default]
82
+ time = 0
83
+ str.scan(/(\d+)(\w?)/).each do |amount, measure|
84
+ time += amount.to_i * tokens[measure]
85
+ end
86
+ time
87
+ end
88
+
89
+
70
90
  end
71
91
 
72
92
  module PDF2Text
@@ -236,7 +236,52 @@ module Open
236
236
  end
237
237
  end
238
238
 
239
- def self.mv(source, target, options)
239
+ def self.ln_s(source, target, options = {})
240
+ source = source.find if Path === source
241
+ target = target.find if Path === target
242
+
243
+ FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
244
+ FileUtils.rm target if File.exists?(target)
245
+ FileUtils.ln_s source, target
246
+ end
247
+
248
+ def self.ln(source, target, options = {})
249
+ source = source.find if Path === source
250
+ target = target.find if Path === target
251
+
252
+ FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
253
+ FileUtils.rm target if File.exists?(target)
254
+ FileUtils.ln source, target
255
+ end
256
+
257
+ def self.ln_h(source, target, options = {})
258
+ source = source.find if Path === source
259
+ target = target.find if Path === target
260
+
261
+ FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
262
+ FileUtils.rm target if File.exists?(target)
263
+ begin
264
+ CMD.cmd("ln -L '#{ source }' '#{ target }'")
265
+ rescue ProcessFailed
266
+ if $!.message.include? "Invalid cross-device link"
267
+ Log.debug "Could not hard link #{source} and #{target}: cross-device link"
268
+ CMD.cmd("cp -L '#{ source }' '#{ target }'")
269
+ else
270
+ raise $!
271
+ end
272
+ end
273
+ end
274
+
275
+ def self.cp(source, target, options = {})
276
+ source = source.find if Path === source
277
+ target = target.find if Path === target
278
+
279
+ FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
280
+ FileUtils.rm target if File.exists?(target)
281
+ FileUtils.cp source, target
282
+ end
283
+
284
+ def self.mv(source, target, options = {})
240
285
  dir_sub_path_source = find_repo_dir(source)
241
286
  dir_sub_path_target = find_repo_dir(target)
242
287
 
@@ -276,7 +321,7 @@ module Open
276
321
  exists_in_repo(*dir_sub_path)
277
322
  else
278
323
  file = file.find if Path === file
279
- File.exist? file
324
+ File.exist?(file) || File.symlink?(file)
280
325
  end
281
326
  end
282
327
 
@@ -310,7 +310,8 @@ module Workflow
310
310
 
311
311
  task_info = task_info(taskname)
312
312
  task_inputs = task_info[:inputs]
313
- defaults = IndiferentHash.setup(task_info[:input_defaults]).merge(task.input_defaults)
313
+ #defaults = IndiferentHash.setup(task_info[:input_defaults]).merge(task.input_defaults)
314
+ defaults = IndiferentHash.setup(task.input_defaults)
314
315
 
315
316
  missing_inputs = []
316
317
  task.required_inputs.each do |input|
@@ -328,7 +329,6 @@ module Workflow
328
329
  dependencies = real_dependencies(task, jobname, defaults.merge(inputs), task_dependencies[taskname] || [])
329
330
 
330
331
  real_inputs = {}
331
- recursive_inputs = rec_inputs(taskname)
332
332
 
333
333
  inputs.each do |k,v|
334
334
  default = defaults[k]
@@ -339,7 +339,9 @@ module Workflow
339
339
  real_inputs[k] = v
340
340
  end
341
341
 
342
- if real_inputs.empty? and not Workflow::TAG == :inputs
342
+ overriden = dependencies.select{|dep| dep.overriden }.any?
343
+
344
+ if real_inputs.empty? and not Workflow::TAG == :inputs and not overriden
343
345
  step_path = step_path taskname, jobname, [], [], task.extension
344
346
  input_values = task.take_input_values(inputs)
345
347
  else
@@ -350,6 +352,7 @@ module Workflow
350
352
  job = get_job_step step_path, task, input_values, dependencies
351
353
  job.workflow = self
352
354
  job.clean_name = jobname
355
+ job.overriden = overriden
353
356
  job
354
357
  end
355
358
 
@@ -378,6 +378,7 @@ class Step
378
378
  canfail_paths = self.canfail_paths
379
379
  dirty_files = rec_dependencies.reject{|dep|
380
380
  (defined?(WorkflowRESTClient) && WorkflowRESTClient::RemoteStep === dep) ||
381
+ ! Open.exists?(dep.info_file) ||
381
382
  (dep.path && (Open.exists?(dep.path) || Open.remote?(dep.path))) ||
382
383
  ((dep.error? || dep.aborted?) && (! dep.recoverable_error? || canfail_paths.include?(dep.path)))
383
384
  }
@@ -392,6 +393,7 @@ class Step
392
393
  if done? and not (status == :done or status == :ending or status == :producing) and not status == :noinfo
393
394
  return true
394
395
  end
396
+
395
397
  if status == :done and not done?
396
398
  return true
397
399
  end
@@ -561,6 +563,18 @@ class Step
561
563
 
562
564
  value || default
563
565
  end
566
+
567
+ def access
568
+ CMD.cmd("touch -c -h -a #{self.path} #{self.info_file}")
569
+ end
570
+
571
+ def rec_access
572
+ access
573
+ rec_dependencies.each do |dep|
574
+ dep.access
575
+ end
576
+ end
577
+
564
578
  end
565
579
 
566
580
  module Workflow
@@ -832,6 +846,18 @@ module Workflow
832
846
  def real_dependencies(task, orig_jobname, inputs, dependencies)
833
847
  real_dependencies = []
834
848
  path_deps = {}
849
+
850
+ override_dependencies = IndiferentHash.setup({})
851
+
852
+ inputs.each do |key,value|
853
+ if String === key && m = key.match(/(.*)#(.*)/)
854
+ workflow, task = m.values_at 1, 2
855
+ workflow = self.to_s if workflow.empty?
856
+ override_dependencies[workflow] ||= IndiferentHash.setup({})
857
+ override_dependencies[workflow][task] = value
858
+ end
859
+ end
860
+
835
861
  dependencies.each do |dependency|
836
862
  _inputs = IndiferentHash.setup(inputs.dup)
837
863
  jobname = orig_jobname
@@ -841,20 +867,37 @@ module Workflow
841
867
  when Array
842
868
  workflow, dep_task, options = dependency
843
869
 
844
- compute = options[:compute] if options
870
+ if override_dependencies[workflow.to_s] && value = override_dependencies[workflow.to_s][dep_task]
871
+ d_ = Step === value ? value : Workflow.load_step(value)
872
+ d_.task = workflow.tasks[dep_task]
873
+ d_.workflow = workflow
874
+ d_.overriden = true
875
+ d_
876
+ else
877
+
878
+ compute = options[:compute] if options
845
879
 
846
- all_d = (real_dependencies + real_dependencies.flatten.collect{|d| d.rec_dependencies} ).flatten.compact.uniq
847
-
848
- _inputs = assign_dep_inputs(_inputs, options, all_d, workflow.task_info(dep_task))
849
- jobname = _inputs[:jobname] if _inputs.include? :jobname
880
+ all_d = (real_dependencies + real_dependencies.flatten.collect{|d| d.rec_dependencies} ).flatten.compact.uniq
850
881
 
851
- job = workflow.job(dep_task, jobname, _inputs)
852
- ComputeDependency.setup(job, compute) if compute
853
- job
882
+ _inputs = assign_dep_inputs(_inputs, options, all_d, workflow.task_info(dep_task))
883
+ jobname = _inputs[:jobname] if _inputs.include? :jobname
884
+
885
+ job = workflow.job(dep_task, jobname, _inputs)
886
+ ComputeDependency.setup(job, compute) if compute
887
+ job
888
+ end
854
889
  when Step
855
890
  dependency
856
891
  when Symbol
857
- job(dependency, jobname, _inputs)
892
+ if override_dependencies[self.to_s] && value = override_dependencies[self.to_s][dependency]
893
+ d_ = Step === value ? value : Workflow.load_step(value)
894
+ d_.task = self.tasks[dependency]
895
+ d_.workflow = self
896
+ d_.overriden = true
897
+ d_
898
+ else
899
+ job(dependency, jobname, _inputs)
900
+ end
858
901
  when Proc
859
902
  if DependencyBlock === dependency
860
903
  orig_dep = dependency.dependency
@@ -874,10 +917,18 @@ module Workflow
874
917
  if Hash === d
875
918
  d[:workflow] ||= wf
876
919
  d[:task] ||= task_name
877
- task_info = d[:workflow].task_info(d[:task])
878
-
879
- inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
880
- d = d[:workflow].job(d[:task], d[:jobname], inputs)
920
+ if override_dependencies[d[:workflow].to_s] && value = override_dependencies[d[:workflow].to_s][d[:task]]
921
+ d = (Step === value ? value : Workflow.load_step(value))
922
+ d.task = d[:workflow].tasks[d[:task]]
923
+ d.workflow = self
924
+ d.overriden = true
925
+ d
926
+ else
927
+ task_info = d[:workflow].task_info(d[:task])
928
+
929
+ inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
930
+ d = d[:workflow].job(d[:task], d[:jobname], inputs)
931
+ end
881
932
  end
882
933
  ComputeDependency.setup(d, compute) if compute
883
934
  new_ << d
@@ -888,9 +939,16 @@ module Workflow
888
939
  dep = dependency.call jobname, _inputs, real_dependencies
889
940
  if Hash === dep
890
941
  dep[:workflow] ||= wf || self
891
- task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
892
- inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
893
- dep = dep[:workflow].job(dep[:task], dep[:jobname], inputs)
942
+ if override_dependencies[d[:workflow].to_s] && value = override_dependencies[d[:workflow].to_s][d[:task]]
943
+ dep = (Step === value ? value : Workflow.load_step(value))
944
+ dep.task = d[:workflow].tasks[d[:task]]
945
+ dep.workflow = self
946
+ dep.overriden = true
947
+ else
948
+ task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
949
+ inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
950
+ dep = dep[:workflow].job(dep[:task], dep[:jobname], inputs)
951
+ end
894
952
  end
895
953
  end
896
954
 
@@ -915,7 +973,7 @@ module Workflow
915
973
  key_obj = {:inputs => clean_inputs, :dependencies => dependencies}
916
974
  key_str = Misc.obj2str(key_obj)
917
975
  hash_str = Misc.digest(key_str)
918
- Log.debug "Hash for '#{[taskname, jobname] * "/"}' #{hash_str} for #{key_str}"
976
+ #Log.debug "Hash for '#{[taskname, jobname] * "/"}' #{hash_str} for #{key_str}"
919
977
  jobname + '_' << hash_str
920
978
  when :inputs
921
979
  all_inputs = {}
@@ -6,6 +6,7 @@ require 'rbbt/workflow/accessor'
6
6
 
7
7
  class Step
8
8
  attr_accessor :clean_name, :path, :task, :workflow, :inputs, :dependencies, :bindings
9
+ attr_accessor :task_name, :overriden
9
10
  attr_accessor :pid
10
11
  attr_accessor :exec
11
12
  attr_accessor :result, :mutex, :seen
@@ -28,6 +29,14 @@ class Step
28
29
  end
29
30
  end
30
31
 
32
+ def overriden
33
+ if @overriden.nil?
34
+ dependencies.select{|dep| dep.overriden }.any?
35
+ else
36
+ @overriden
37
+ end
38
+ end
39
+
31
40
  def initialize(path, task = nil, inputs = nil, dependencies = nil, bindings = nil, clean_name = nil)
32
41
  path = Path.setup(Misc.sanitize_filename(path)) if String === path
33
42
  path = path.call if Proc === path
@@ -100,8 +109,13 @@ class Step
100
109
  end
101
110
 
102
111
  def task_name
103
- return @path.split("/")[-2] if @task.nil?
104
- @task.name
112
+ @task_name ||= begin
113
+ if @task.nil?
114
+ @path.split("/")[-2]
115
+ else
116
+ @task.name
117
+ end
118
+ end
105
119
  end
106
120
 
107
121
  def path
@@ -259,7 +273,7 @@ class Step
259
273
  pid_file = Step.pid_file path
260
274
  files_dir = Step.files_dir path
261
275
 
262
- if Open.exists?(path) or Open.exists?(pid_file) or Open.exists?(info_file)
276
+ if Open.exists?(path) or Open.exists?(pid_file) or Open.exists?(info_file) or Open.exists?(files_dir)
263
277
 
264
278
  @result = nil
265
279
  @pid = nil
@@ -291,7 +305,7 @@ class Step
291
305
  self
292
306
  end
293
307
 
294
- def rec_dependencies
308
+ def rec_dependencies(need_run = false)
295
309
 
296
310
  # A step result with no info_file means that it was manually
297
311
  # placed. In that case, do not consider its dependencies
@@ -301,7 +315,9 @@ class Step
301
315
 
302
316
  new_dependencies = []
303
317
  dependencies.each{|step|
304
- r = step.rec_dependencies
318
+ next if self.done? && need_run && Open.exists?(step.info_file)
319
+
320
+ r = step.rec_dependencies(need_run)
305
321
  new_dependencies.concat r
306
322
  new_dependencies << step
307
323
  }
@@ -290,7 +290,7 @@ class Step
290
290
  def run_dependencies
291
291
  dep_step = {}
292
292
 
293
- rec_dependencies = self.rec_dependencies
293
+ rec_dependencies = self.rec_dependencies(true)
294
294
 
295
295
  return if rec_dependencies.empty?
296
296
 
@@ -108,6 +108,7 @@ class Step
108
108
  rec_dependencies.
109
109
  select{|dependency| ! (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === dependency) }.
110
110
  select{|dependency| ! Open.remote?(dependency.path) }.
111
+ select{|dependency| Open.exists?(dependency.info_file) }.
111
112
  select{|dependency| ! dependency.error? }
112
113
  end
113
114
 
@@ -126,9 +127,15 @@ class Step
126
127
  outdated_dep = []
127
128
  canfail_paths = self.canfail_paths
128
129
  checks.each do |dep|
129
- if dep.done? && self.done? && (File.mtime(dep.path) > File.mtime(self.path))
130
- outdated_time << dep
130
+ next unless Open.exists?(dep.info_file)
131
+
132
+ begin
133
+ if dep.done? && self.done? && Open.exists?(dep.path) && Open.exists?(self.path) && (File.mtime(dep.path) > File.mtime(self.path))
134
+ outdated_time << dep
135
+ end
136
+ rescue
131
137
  end
138
+
132
139
  if (! dep.done? && ! canfail_paths.include?(dep.path)) || ! dep.updated?
133
140
  outdated_dep << dep
134
141
  end
@@ -32,7 +32,12 @@ module Task
32
32
  seen = []
33
33
  task_inputs = dep_inputs deps, workflow
34
34
  task_inputs.each do |task,new_inputs|
35
- task.inputs.zip(task.input_types.values_at(*task.inputs)).select{|i,t| t.to_sym == :select and task.input_options[i][:select_options] }.each{|i,t| selects << [i, task.input_options[i][:select_options]] }
35
+ new_inputs.zip(task.input_types.values_at(*new_inputs)).select do |i,t|
36
+ t.to_sym == :select and task.input_options[i][:select_options]
37
+ end.each do |i,t|
38
+ selects << [i, task.input_options[i][:select_options]]
39
+ end
40
+
36
41
  if task.workflow and task.workflow != workflow
37
42
  puts " #{Log.color :yellow, ["[#{task.workflow.to_s}]", task.name.to_s] *" "}:"
38
43
  else
@@ -93,10 +93,13 @@ get_git(){
93
93
  cd $OPT_SCM_DIR
94
94
  if [ -d "$name" ]; then
95
95
  cd "$name"
96
- git stash
97
- git pull origin master
98
- git rebase master
99
- git stash apply
96
+
97
+ if [ ! "$NOWEB" == "true" ]; then
98
+ git stash
99
+ git pull origin master
100
+ git rebase master
101
+ git stash apply
102
+ fi
100
103
  else
101
104
  git clone "$url" "$name"
102
105
  fi
@@ -211,11 +214,23 @@ setup(){
211
214
  local old_pwd="`expand_path $(pwd)`"
212
215
  cd "$OPT_DIR/bin"
213
216
 
214
- for exe in `ls "$pkg_dir/bin/"`;do
217
+ for exe in ` find "$pkg_dir/bin/" -maxdepth 1 -type f -executable`; do
218
+ exe=$(basename $exe)
215
219
  rm -f ./$exe
216
220
  ln -s "$pkg_dir/bin/$exe" . 2>/dev/null
217
221
  done
218
222
 
223
+ cd "$old_pwd"
224
+ else
225
+ local old_pwd="`expand_path $(pwd)`"
226
+ cd "$OPT_DIR/bin"
227
+
228
+ for exe in ` find "$pkg_dir/" -maxdepth 1 -type f -executable`; do
229
+ exe=$(basename $exe)
230
+ rm -f ./$exe
231
+ ln -s "$pkg_dir/$exe" . 2>/dev/null
232
+ done
233
+
219
234
  cd "$old_pwd"
220
235
  fi
221
236
 
@@ -236,6 +251,27 @@ install_src(){
236
251
  build "$name" "$extra"
237
252
  }
238
253
 
254
+ custom_build(){
255
+ local name="$1"
256
+ shift;
257
+ local cmd="$@"
258
+
259
+ echo "Building $name"
260
+
261
+ local old_pwd="`expand_path $(pwd)`"
262
+ cd "`build_dir`"
263
+ echo `pwd`
264
+ ls
265
+
266
+ eval $cmd
267
+
268
+ move_opt "$name"
269
+ setup "$name"
270
+ clean_build
271
+
272
+ cd "$old_pwd"
273
+ }
274
+
239
275
  install_git(){
240
276
  local name="$1"
241
277
  local url="$2"
@@ -14,6 +14,7 @@ Clean orphaned files
14
14
  $ rbbt system clean <workflow> <task>
15
15
 
16
16
  -a--all Apply to all jobs, not only uncompleted
17
+ -o--older* Clean jobs not access in some time
17
18
  -f--force Remove locks and files regardless of been active
18
19
  -q--quick Quick check
19
20
  -d--dirty Clean dirty jobs
@@ -29,6 +30,9 @@ task = task.split "," if task
29
30
  all = options.delete :all
30
31
  force = options.delete :force
31
32
  dirty = options.delete :dirty
33
+ time = options.delete :older
34
+
35
+ time = Misc.timespan time, 'd' if time
32
36
 
33
37
  puts Log.color(:magenta, "# System clean")
34
38
 
@@ -103,8 +107,17 @@ TSV.traverse jobs, :_bar => "Checking job status" do |file,i|
103
107
  status = status.to_s
104
108
  end
105
109
 
106
- next unless (force and status !~ /done/) or status == 'dirty' or status =~ /\bnopid/ or status =~ /\berror$/ or status =~ /\bmissing$/ or status =~ /\baborted$/ or status =~ /\bdead$/ or status =~ /\bsync$/ or status == ""
107
- puts " Removing #{ file } - #{status}"
108
- Step.clean(file)
110
+ if time and File.exists?(file)
111
+ old = Time.now - File.atime(file)
112
+ status = 'old'
113
+ end
114
+
115
+ if (force and status !~ /done/) or
116
+ status =~ /\b(old|dirty|nopid|error|missing|aborted|dead|sync)$/ or
117
+ status == ""
118
+
119
+ puts " Removing #{ file } - #{status}"
120
+ Step.clean(file)
121
+ end
109
122
  end
110
123
 
@@ -52,8 +52,10 @@ def status_msg(status)
52
52
  :red
53
53
  when :streaming, :started
54
54
  :cyan
55
- when :done, :noinfo
55
+ when :done
56
56
  :green
57
+ when :noinfo
58
+ :blue
57
59
  when :dependencies, :waiting, :setyp
58
60
  :yellow
59
61
  else
@@ -17,6 +17,7 @@ Use - to read from STDIN
17
17
  -k--key_field* Use this field as key
18
18
  -h--help Print this help
19
19
  -l--lines Separate in lines
20
+ -t--type* Type of tsv
20
21
  EOF
21
22
 
22
23
  rbbt_usage and exit 0 if options[:help]
@@ -44,11 +45,13 @@ fields = options[:fields]
44
45
  key_field = options[:key_field]
45
46
  fields = fields.split(/[,|]/, -1) unless fields.nil?
46
47
 
47
- parser = TSV::Parser.new tsv, :key_field => key_field, :fields => fields
48
+ parser = TSV::Parser.new tsv, :key_field => key_field, :fields => fields, :type => options[:type]
48
49
  fields ||= parser.fields
49
50
 
50
51
  TSV.traverse(parser) do |k,v|
51
52
  next unless k.include? key
53
+ k = k.first if Array === k
54
+ puts Log.color(:blue, "Key: #{ k }")
52
55
  if fields.length == 1
53
56
  if options[:lines]
54
57
  puts (Array === v ? v.flatten*"\n" : v.to_s )
@@ -37,8 +37,10 @@ def status_msg(status)
37
37
  :red
38
38
  when :streaming, :started
39
39
  :cyan
40
- when :done, :noinfo
40
+ when :done
41
41
  :green
42
+ when :noinfo
43
+ :blue
42
44
  when :dependencies, :waiting, :setyp
43
45
  :yellow
44
46
  else
@@ -45,8 +45,10 @@ def status_msg(status)
45
45
  :red
46
46
  when :streaming, :started
47
47
  :cyan
48
- when :done, :noinfo
48
+ when :done
49
49
  :green
50
+ when :noinfo
51
+ :blue
50
52
  when :dependencies, :waiting, :setyp
51
53
  :yellow
52
54
  else
@@ -60,16 +62,18 @@ def status_msg(status)
60
62
  end
61
63
 
62
64
  def report_msg(status, name, path, info = nil)
63
-
64
65
  parts = path.sub(/\{.*/,'').sub(/#{Regexp.quote(name)}$/,'').split "/"
65
66
 
66
67
  task = Log.color(:yellow, parts.pop)
67
68
  workflow = Log.color(:magenta, parts.pop)
69
+ if status.to_s == 'noinfo' and parts.last != 'jobs'
70
+ task, status, workflow = Log.color(:yellow, info[:task_name]), Log.color(:blue, "file"), Log.color(:magenta, "-")
71
+ end
68
72
 
69
73
  str = if not Open.remote?(path) and (File.exists?(path) and $main_mtime and ($main_mtime - File.mtime(path)) < 0)
70
- status_msg(status.to_s) << " " << [workflow, task, path] * " " << " (#{Log.color(:red, "Mtime out of sync") })"
74
+ status_msg(status.to_s) << " " << [workflow, task, path].compact * " " << " (#{Log.color(:red, "Mtime out of sync") })"
71
75
  else
72
- status_msg(status.to_s) << " " << [workflow, task, path] * " "
76
+ status_msg(status.to_s) << " " << [workflow, task, path].compact * " "
73
77
  end
74
78
 
75
79
  if $inputs and $inputs.any?
@@ -97,8 +101,9 @@ def report_msg(status, name, path, info = nil)
97
101
  str << "\n"
98
102
  end
99
103
 
100
- def report(step, offset = 0)
101
- info = step.info || {}
104
+ def report(step, offset = 0, task = nil)
105
+ info = step.info || {}
106
+ info[:task_name] = task
102
107
  path = step.path
103
108
  status = info[:status] || :missing
104
109
  status = "remote" if Open.remote?(path)
@@ -110,9 +115,9 @@ def report(step, offset = 0)
110
115
  new = ! $seen.include?(path)
111
116
  dep = get_step path
112
117
  if new
113
- str << report(dep, offset + 1)
118
+ str << report(dep, offset + 1, task)
114
119
  else
115
- str << Log.color(:blue, Log.uncolor(report(dep, offset+1)))
120
+ str << Log.color(:blue, Log.uncolor(report(dep, offset+1, task)))
116
121
  end
117
122
  end if info[:dependencies]
118
123
  str
@@ -202,6 +202,7 @@ the job dependencies recursively.
202
202
  -W--workflows* Load a list of workflows
203
203
  -R--requires* Require a list of files
204
204
  -rwt--remote_workflow_tasks* Load a yaml file describing remote workflow tasks
205
+ -od--override_deps* Override deps using 'Workflow#task=<path>' array_separated
205
206
  EOF
206
207
 
207
208
  workflow = ARGV.shift
@@ -216,6 +217,7 @@ detach = !!options.delete(:detach)
216
217
  do_exec = !!options.delete(:exec)
217
218
  clean = !!options.delete(:clean)
218
219
  clean_task = options.delete(:clean_task)
220
+ override_deps = options.delete(:override_deps)
219
221
  recursive_clean = !!options.delete(:recursive_clean)
220
222
  out = options.include?(:output) ? File.open(options[:output], 'wb') : STDOUT
221
223
 
@@ -294,6 +296,13 @@ saved_job_options = job_options
294
296
 
295
297
  workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir))) if options[:workdir]
296
298
 
299
+ if override_deps
300
+ override_deps.split($array_separator).each do |part|
301
+ t_, value = part.split("=")
302
+ job_options.merge!( t_ => value)
303
+ end
304
+ end
305
+
297
306
  #- get job
298
307
 
299
308
  job = workflow.job(task.name, name, job_options)
@@ -306,7 +315,9 @@ end
306
315
 
307
316
  if clean_task
308
317
  job.rec_dependencies.each do |dep|
309
- dep.clean if dep.task_name.to_s == clean_task.to_s
318
+ next unless dep.task_name.to_s == clean_task.to_s
319
+ dep.clean
320
+ dep.set_info :status, :cleaned
310
321
  end
311
322
  end
312
323
 
@@ -17,6 +17,16 @@ class TestTSV < Test::Unit::TestCase
17
17
  end
18
18
  end
19
19
 
20
+ def test_find_current
21
+ TmpFile.with_file do |dir|
22
+ Misc.in_dir dir do
23
+ CMD.cmd('touch foo')
24
+ p = Path.setup('foo')
25
+ assert_equal File.join(dir, 'foo'), p.find(:current)
26
+ end
27
+ end
28
+ end
29
+
20
30
  def test_prev
21
31
  path = Path.setup "/tmp"
22
32
  assert_equal "/tmp/bar/foo", path.foo("bar")
@@ -31,9 +41,9 @@ class TestTSV < Test::Unit::TestCase
31
41
  assert_equal path.find, path.doc_file.find(:lib).source_for_doc_file
32
42
  assert_equal path.find, path.doc_file.source_for_doc_file.find
33
43
 
34
- assert_equal "doc/lib/rbbt/resource.doc", path.doc_file.set_extension('doc')
35
- assert_equal "lib/rbbt/resource.rb", path.doc_file.set_extension('doc').source_for_doc_file
44
+ assert_equal "doc/lib/rbbt/resource.rb.doc", path.doc_file.set_extension('doc')
45
+ #assert_equal "lib/rbbt/resource.rb", path.doc_file.set_extension('doc').source_for_doc_file
36
46
 
37
- assert_equal "doc/lib/rbbt/resource.doc", path.doc_file.set_extension('doc')
47
+ assert_equal "doc/lib/rbbt/resource.rb.doc", path.doc_file.set_extension('doc')
38
48
  end
39
49
  end
@@ -33,7 +33,8 @@ class TestTSV < Test::Unit::TestCase
33
33
  assert TSV === TestResource.tmp.test.test_tsv.tsv
34
34
  end
35
35
 
36
- def test_rake
36
+ def __test_rake
37
+ iii TestResource.tmp.test.work.footest.foo.find
37
38
  TestResource.tmp.test.work.footest.foo.read == "TEST"
38
39
  assert TestResource.tmp.test.work.footest.foo.read == "TEST"
39
40
  end
@@ -98,7 +98,7 @@ row2 A B Id3
98
98
  end
99
99
  end
100
100
 
101
- def test_tsv_field_selection
101
+ def test_tsv_field_selection2
102
102
  content =<<-EOF
103
103
  #Id ValueA ValueB OtherID
104
104
  row1 a|aa|aaa b Id1|Id2
@@ -107,6 +107,23 @@ for this dependency
107
107
  task :send_input_dep_to_reverse => :text do
108
108
  TSV.get_stream step(:reverse_input_text)
109
109
  end
110
+
111
+ input :i, :string, "Input", "A"
112
+ task :t1 => :string do |i|
113
+ i
114
+ end
115
+
116
+ input :i, :string, "Input", "B"
117
+ task :t2 => :string do |i|
118
+ i
119
+ end
120
+
121
+ dep :t1, :i => "C"
122
+ dep :t2
123
+ task :t3 => :string do |i|
124
+ step(:t1).load + step(:t2).load
125
+ end
126
+
110
127
  end
111
128
 
112
129
  TestWF.workdir = Rbbt.tmp.test.workflow
@@ -198,6 +215,12 @@ class TestWorkflow < Test::Unit::TestCase
198
215
  assert_equal "V:AA", job.run
199
216
  end
200
217
 
218
+ def test_override_dep
219
+ TmpFile.with_file("OTHER") do |file|
220
+ assert TestWF.job(:repeat2, nil, :number => 3, "TestWF#str" => file).run.include? "OTHER"
221
+ end
222
+ end
223
+
201
224
  def __test_stream
202
225
  io = TestWF.job(:stream).run(:stream)
203
226
  Misc.consume_stream(TSV.get_stream(io), false, STDOUT)
@@ -228,4 +251,9 @@ class TestWorkflow < Test::Unit::TestCase
228
251
  assert TestWF.rec_input_use(:double_dep)[:times][TestWF].include?(:repeat)
229
252
  end
230
253
 
254
+ def test_shared_inputs
255
+ assert_equal "CB", TestWF.job(:t3).run
256
+ assert_equal "CB", TestWF.job(:t3).run
257
+ end
258
+
231
259
  end
@@ -602,4 +602,12 @@ EOF
602
602
  assert_equal 1, hash[:A]
603
603
  assert_equal 3, hash[:C]
604
604
  end
605
+
606
+ def test_time_stamp
607
+ assert_equal 10, Misc.timespan('10')
608
+ assert_equal 10, Misc.timespan('10s')
609
+ assert_equal 60, Misc.timespan('1m')
610
+ assert_equal 60*60*24, Misc.timespan('1d')
611
+ assert_equal 60*60*24, Misc.timespan('1d')
612
+ end
605
613
  end
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.22.4
4
+ version: 5.22.5
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-07-05 00:00:00.000000000 Z
11
+ date: 2018-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake