rbbt-util 5.22.4 → 5.22.5

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.
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