scout-gear 2.0.0 → 5.2.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.
- checksums.yaml +4 -4
- data/.vimproject +65 -2
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/scout +233 -24
- data/lib/scout/cmd.rb +344 -0
- data/lib/scout/concurrent_stream.rb +259 -0
- data/lib/scout/exceptions.rb +15 -8
- data/lib/scout/indiferent_hash/options.rb +8 -26
- data/lib/scout/log/color.rb +2 -2
- data/lib/scout/log/fingerprint.rb +11 -1
- data/lib/scout/log/progress/report.rb +0 -1
- data/lib/scout/log/progress/util.rb +1 -1
- data/lib/scout/log/progress.rb +4 -4
- data/lib/scout/log.rb +10 -2
- data/lib/scout/meta_extension.rb +19 -3
- data/lib/scout/misc/digest.rb +56 -0
- data/lib/scout/misc/filesystem.rb +26 -0
- data/lib/scout/misc/format.rb +17 -6
- data/lib/scout/misc/insist.rb +56 -0
- data/lib/scout/misc/monitor.rb +23 -0
- data/lib/scout/misc.rb +5 -11
- data/lib/scout/open/lock.rb +61 -0
- data/lib/scout/open/remote.rb +120 -0
- data/lib/scout/open/stream.rb +373 -0
- data/lib/scout/open/util.rb +225 -0
- data/lib/scout/open.rb +169 -0
- data/lib/scout/path/find.rb +68 -21
- data/lib/scout/path/tmpfile.rb +8 -0
- data/lib/scout/path/util.rb +14 -1
- data/lib/scout/path.rb +6 -30
- data/lib/scout/persist/open.rb +17 -0
- data/lib/scout/persist/path.rb +15 -0
- data/lib/scout/persist/serialize.rb +151 -0
- data/lib/scout/persist.rb +54 -0
- data/lib/scout/resource/path.rb +20 -0
- data/lib/scout/resource/produce/rake.rb +69 -0
- data/lib/scout/resource/produce.rb +246 -0
- data/lib/scout/resource/scout.rb +3 -0
- data/lib/scout/resource/util.rb +48 -0
- data/lib/scout/resource.rb +39 -0
- data/lib/scout/simple_opt/accessor.rb +1 -1
- data/lib/scout/simple_opt/doc.rb +29 -23
- data/lib/scout/simple_opt/parse.rb +4 -3
- data/lib/scout/tmpfile.rb +39 -1
- data/lib/scout/workflow/definition.rb +78 -0
- data/lib/scout/workflow/documentation.rb +83 -0
- data/lib/scout/workflow/step/info.rb +77 -0
- data/lib/scout/workflow/step/load.rb +18 -0
- data/lib/scout/workflow/step.rb +132 -0
- data/lib/scout/workflow/task/inputs.rb +114 -0
- data/lib/scout/workflow/task.rb +155 -0
- data/lib/scout/workflow/usage.rb +314 -0
- data/lib/scout/workflow/util.rb +11 -0
- data/lib/scout/workflow.rb +40 -0
- data/lib/scout-gear.rb +4 -0
- data/lib/scout.rb +1 -0
- data/lib/workflow-scout.rb +2 -0
- data/scout-gear.gemspec +77 -5
- data/scout_commands/alias +48 -0
- data/scout_commands/find +83 -0
- data/scout_commands/glob +0 -0
- data/scout_commands/rbbt +23 -0
- data/scout_commands/workflow/info +29 -0
- data/scout_commands/workflow/list +27 -0
- data/scout_commands/workflow/task +58 -0
- data/scout_commands/workflow/task_old +706 -0
- data/test/scout/indiferent_hash/test_options.rb +11 -1
- data/test/scout/misc/test_digest.rb +30 -0
- data/test/scout/misc/test_filesystem.rb +30 -0
- data/test/scout/misc/test_insist.rb +13 -0
- data/test/scout/open/test_lock.rb +52 -0
- data/test/scout/open/test_remote.rb +25 -0
- data/test/scout/open/test_stream.rb +515 -0
- data/test/scout/open/test_util.rb +73 -0
- data/test/scout/path/test_find.rb +28 -0
- data/test/scout/persist/test_open.rb +37 -0
- data/test/scout/persist/test_path.rb +37 -0
- data/test/scout/persist/test_serialize.rb +114 -0
- data/test/scout/resource/test_path.rb +40 -0
- data/test/scout/resource/test_produce.rb +62 -0
- data/test/scout/resource/test_util.rb +27 -0
- data/test/scout/simple_opt/test_doc.rb +16 -0
- data/test/scout/test_cmd.rb +85 -0
- data/test/scout/test_concurrent_stream.rb +29 -0
- data/test/scout/test_meta_extension.rb +9 -0
- data/test/scout/test_misc.rb +0 -7
- data/test/scout/test_open.rb +146 -0
- data/test/scout/test_path.rb +3 -1
- data/test/scout/test_persist.rb +83 -0
- data/test/scout/test_resource.rb +26 -0
- data/test/scout/test_workflow.rb +87 -0
- data/test/scout/workflow/step/test_info.rb +30 -0
- data/test/scout/workflow/step/test_load.rb +65 -0
- data/test/scout/workflow/task/test_inputs.rb +182 -0
- data/test/scout/workflow/test_definition.rb +0 -0
- data/test/scout/workflow/test_documentation.rb +30 -0
- data/test/scout/workflow/test_step.rb +36 -0
- data/test/scout/workflow/test_task.rb +179 -0
- data/test/scout/workflow/test_usage.rb +35 -0
- data/test/scout/workflow/test_util.rb +17 -0
- data/test/test_helper.rb +17 -0
- data/test/test_scout-gear.rb +0 -0
- metadata +75 -3
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative '../../misc'
|
2
|
+
require_relative '../../path'
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
class Rake::FileTask
|
6
|
+
class << self
|
7
|
+
alias_method :old_define_task, :define_task
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.define_task(file, *args, &block)
|
11
|
+
@@files ||= []
|
12
|
+
@@files << file
|
13
|
+
old_define_task(file, *args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.files
|
17
|
+
@@files
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.clear_files
|
21
|
+
@@files = []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ScoutRake
|
26
|
+
class TaskNotFound < StandardError; end
|
27
|
+
def self.run(rakefile, dir, task, &block)
|
28
|
+
old_pwd = FileUtils.pwd
|
29
|
+
|
30
|
+
Rake::Task.clear
|
31
|
+
Rake::FileTask.clear_files
|
32
|
+
|
33
|
+
t = nil
|
34
|
+
pid = Process.fork{
|
35
|
+
if block_given?
|
36
|
+
TOPLEVEL_BINDING.receiver.instance_exec &block
|
37
|
+
else
|
38
|
+
if Path.is_filename? rakefile
|
39
|
+
rakefile = rakefile.produce.find
|
40
|
+
load rakefile
|
41
|
+
else
|
42
|
+
TmpFile.with_file(rakefile) do |tmpfile|
|
43
|
+
load tmpfile
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
raise TaskNotFound if Rake::Task[task].nil?
|
49
|
+
|
50
|
+
#Misc.pre_fork
|
51
|
+
begin
|
52
|
+
Misc.in_dir(dir) do
|
53
|
+
Rake::Task[task].invoke
|
54
|
+
|
55
|
+
Rake::Task.clear
|
56
|
+
Rake::FileTask.clear_files
|
57
|
+
end
|
58
|
+
rescue Exception
|
59
|
+
Log.error "Error in rake: #{$!.message}"
|
60
|
+
Log.exception $!
|
61
|
+
Kernel.exit! -1
|
62
|
+
end
|
63
|
+
Kernel.exit! 0
|
64
|
+
}
|
65
|
+
Process.waitpid(pid)
|
66
|
+
raise "Rake failed" unless $?.success?
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require_relative '../open'
|
2
|
+
require_relative '../tmpfile'
|
3
|
+
require_relative 'produce/rake'
|
4
|
+
|
5
|
+
module Resource
|
6
|
+
def claim(path, type, content = nil, &block)
|
7
|
+
if type == :rake
|
8
|
+
@rake_dirs ||= {}
|
9
|
+
@rake_dirs[path] = content || block
|
10
|
+
else
|
11
|
+
@resources ||= {}
|
12
|
+
@resources[path] = [type, content || block]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def rake_for(path)
|
17
|
+
@rake_dirs ||= {}
|
18
|
+
@rake_dirs.select{|dir, content|
|
19
|
+
Misc.path_relative_to(dir, path)
|
20
|
+
}.sort_by{|dir, content|
|
21
|
+
dir.length
|
22
|
+
}.last
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_rake(path)
|
26
|
+
!! rake_for(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_rake(path, rakefile, rake_dir)
|
30
|
+
task = Misc.path_relative_to rake_dir, path
|
31
|
+
rakefile = rakefile.produce if rakefile.respond_to? :produce
|
32
|
+
rakefile = rakefile.find if rakefile.respond_to? :find
|
33
|
+
|
34
|
+
rake_dir = rake_dir.find(:user) if rake_dir.respond_to? :find
|
35
|
+
|
36
|
+
begin
|
37
|
+
if Proc === rakefile
|
38
|
+
ScoutRake.run(nil, rake_dir, task, &rakefile)
|
39
|
+
else
|
40
|
+
ScoutRake.run(rakefile, rake_dir, task)
|
41
|
+
end
|
42
|
+
rescue Rake::TaskNotFound
|
43
|
+
if rake_dir.nil? or rake_dir.empty? or rake_dir == "/" or rake_dir == "./"
|
44
|
+
raise $!
|
45
|
+
end
|
46
|
+
task = File.join(File.basename(rake_dir), task)
|
47
|
+
rake_dir = File.dirname(rake_dir)
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def produce(path, force = false)
|
53
|
+
case
|
54
|
+
when @resources.include?(path)
|
55
|
+
type, content = @resources[path]
|
56
|
+
when (Path === path && @resources.include?(path.original))
|
57
|
+
type, content = @resources[path.original]
|
58
|
+
when has_rake(path)
|
59
|
+
type = :rake
|
60
|
+
rake_dir, content = rake_for(path)
|
61
|
+
rake_dir = Path.setup(rake_dir.dup, self.pkgdir, self)
|
62
|
+
else
|
63
|
+
if path !~ /\.(gz|bgz)$/
|
64
|
+
begin
|
65
|
+
produce(path.annotate(path + '.gz'), force)
|
66
|
+
rescue ResourceNotFound
|
67
|
+
begin
|
68
|
+
produce(path.annotate(path + '.bgz'), force)
|
69
|
+
rescue ResourceNotFound
|
70
|
+
raise ResourceNotFound, "Resource is missing and does not seem to be claimed: #{ self } -- #{ path } "
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
raise ResourceNotFound, "Resource is missing and does not seem to be claimed: #{ self } -- #{ path } "
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
if path.respond_to?(:find)
|
79
|
+
final_path = force ? path.find(:default) : path.find
|
80
|
+
else
|
81
|
+
final_path = path
|
82
|
+
end
|
83
|
+
|
84
|
+
if type and not File.exist?(final_path) or force
|
85
|
+
Log.medium "Producing: (#{self.to_s}) #{ final_path }"
|
86
|
+
lock_filename = TmpFile.tmp_for_file(final_path, :dir => lock_dir)
|
87
|
+
|
88
|
+
Open.lock lock_filename do
|
89
|
+
FileUtils.rm_rf final_path if force and File.exist? final_path
|
90
|
+
|
91
|
+
if ! File.exist?(final_path) || force
|
92
|
+
|
93
|
+
begin
|
94
|
+
case type
|
95
|
+
when :string
|
96
|
+
Open.sensible_write(final_path, content)
|
97
|
+
when :csv
|
98
|
+
raise "TSV/CSV Not implemented yet"
|
99
|
+
#require 'rbbt/tsv/csv'
|
100
|
+
#tsv = TSV.csv Open.open(content)
|
101
|
+
#Open.sensible_write(final_path, tsv.to_s)
|
102
|
+
when :url
|
103
|
+
options = {}
|
104
|
+
options[:noz] = true if Open.gzip?(final_path) || Open.bgzip?(final_path) || Open.zip?(final_path)
|
105
|
+
Open.sensible_write(final_path, Open.open(content, options))
|
106
|
+
when :proc
|
107
|
+
data = case content.arity
|
108
|
+
when 0
|
109
|
+
content.call
|
110
|
+
when 1
|
111
|
+
content.call final_path
|
112
|
+
end
|
113
|
+
case data
|
114
|
+
when String, IO, StringIO
|
115
|
+
Open.sensible_write(final_path, data)
|
116
|
+
when Array
|
117
|
+
Open.sensible_write(final_path, data * "\n")
|
118
|
+
when TSV
|
119
|
+
Open.sensible_write(final_path, data.dumper_stream)
|
120
|
+
when TSV::Dumper
|
121
|
+
Open.sensible_write(final_path, data.stream)
|
122
|
+
when nil
|
123
|
+
else
|
124
|
+
raise "Unkown object produced: #{Log.fingerprint data}"
|
125
|
+
end
|
126
|
+
when :rake
|
127
|
+
run_rake(path, content, rake_dir)
|
128
|
+
when :install
|
129
|
+
Log.debug "Installing software: #{path}"
|
130
|
+
|
131
|
+
$set_software_env = false unless File.exist? path
|
132
|
+
|
133
|
+
software_dir = path.resource.root.software.find :user
|
134
|
+
helper_file = File.expand_path(Rbbt.share.install.software.lib.install_helpers.find(:lib, caller_lib_dir(__FILE__)))
|
135
|
+
#helper_file = File.expand_path(Rbbt.share.install.software.lib.install_helpers.find)
|
136
|
+
|
137
|
+
preamble = <<-EOF
|
138
|
+
#!/bin/bash
|
139
|
+
|
140
|
+
RBBT_SOFTWARE_DIR="#{software_dir}"
|
141
|
+
|
142
|
+
INSTALL_HELPER_FILE="#{helper_file}"
|
143
|
+
source "$INSTALL_HELPER_FILE"
|
144
|
+
EOF
|
145
|
+
|
146
|
+
content = content.call if Proc === content
|
147
|
+
|
148
|
+
content = if content =~ /git:|\.git$/
|
149
|
+
{:git => content}
|
150
|
+
else
|
151
|
+
{:src => content}
|
152
|
+
end if String === content and Open.remote?(content)
|
153
|
+
|
154
|
+
script_text = case content
|
155
|
+
when nil
|
156
|
+
raise "No way to install #{path}"
|
157
|
+
when Path
|
158
|
+
Open.read(content)
|
159
|
+
when String
|
160
|
+
if Path.is_filename?(content) and Open.exists?(content)
|
161
|
+
Open.read(content)
|
162
|
+
else
|
163
|
+
content
|
164
|
+
end
|
165
|
+
when Hash
|
166
|
+
name = content[:name] || File.basename(path)
|
167
|
+
git = content[:git]
|
168
|
+
src = content[:src]
|
169
|
+
url = content[:url]
|
170
|
+
jar = content[:jar]
|
171
|
+
extra = content[:extra]
|
172
|
+
commands = content[:commands]
|
173
|
+
if git
|
174
|
+
<<-EOF
|
175
|
+
|
176
|
+
name='#{name}'
|
177
|
+
url='#{git}'
|
178
|
+
|
179
|
+
install_git "$name" "$url" #{extra}
|
180
|
+
|
181
|
+
#{commands}
|
182
|
+
EOF
|
183
|
+
elsif src
|
184
|
+
<<-EOF
|
185
|
+
|
186
|
+
name='#{name}'
|
187
|
+
url='#{src}'
|
188
|
+
|
189
|
+
install_src "$name" "$url" #{extra}
|
190
|
+
|
191
|
+
#{commands}
|
192
|
+
EOF
|
193
|
+
elsif jar
|
194
|
+
<<-EOF
|
195
|
+
|
196
|
+
name='#{name}'
|
197
|
+
url='#{jar}'
|
198
|
+
|
199
|
+
install_jar "$name" "$url" #{extra}
|
200
|
+
|
201
|
+
#{commands}
|
202
|
+
EOF
|
203
|
+
else
|
204
|
+
<<-EOF
|
205
|
+
|
206
|
+
name='#{name}'
|
207
|
+
url='#{url}'
|
208
|
+
|
209
|
+
#{commands}
|
210
|
+
EOF
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
script = preamble + "\n" + script_text
|
215
|
+
Log.debug "Installing software with script:\n" << script
|
216
|
+
CMD.cmd_log('bash', :in => script)
|
217
|
+
|
218
|
+
set_software_env(software_dir) unless $set_software_env
|
219
|
+
$set_software_env = true
|
220
|
+
else
|
221
|
+
raise "Could not produce #{ resource }. (#{ type }, #{ content })"
|
222
|
+
end
|
223
|
+
rescue
|
224
|
+
FileUtils.rm_rf final_path if File.exist? final_path
|
225
|
+
raise $!
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# After producing a file, make sure we recheck all locations, the file
|
232
|
+
# might have appeared with '.gz' extension for instance
|
233
|
+
path.instance_variable_set("@path", {})
|
234
|
+
|
235
|
+
path
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
module Path
|
241
|
+
def produce(force = false)
|
242
|
+
return self if ! force && Open.exist?(self)
|
243
|
+
self.pkgdir.produce self if Resource === self.pkgdir
|
244
|
+
return self
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Resource
|
2
|
+
def identify(path)
|
3
|
+
return path unless path.start_with?("/")
|
4
|
+
path_maps = path.path_maps || self.path_maps || Path.path_maps
|
5
|
+
path = File.expand_path(path)
|
6
|
+
path += "/" if File.directory?(path)
|
7
|
+
|
8
|
+
map_order ||= (path_maps.keys & Path.basic_map_order) + (path_maps.keys - Path.basic_map_order)
|
9
|
+
map_order -= [:current, "current"]
|
10
|
+
map_order << :current
|
11
|
+
|
12
|
+
choices = []
|
13
|
+
map_order.uniq.each do |name|
|
14
|
+
pattern = path_maps[name]
|
15
|
+
pattern = path_maps[pattern] while Symbol === pattern
|
16
|
+
next if pattern.nil?
|
17
|
+
|
18
|
+
pattern = pattern.sub('{PWD}', Dir.pwd)
|
19
|
+
if String === pattern and pattern.include?('{')
|
20
|
+
regexp = "^" + pattern
|
21
|
+
.gsub(/{(TOPLEVEL)}/,'(?<\1>[^/]+)')
|
22
|
+
.gsub(/{([^}]+)}/,'(?<\1>[^/]+)?') +
|
23
|
+
"(?:/(?<REST>.*))?/?$"
|
24
|
+
if m = path.match(regexp)
|
25
|
+
if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] == self.pkgdir
|
26
|
+
unlocated = %w(TOPLEVEL SUBPATH PATH REST).collect{|c|
|
27
|
+
m.named_captures.include?(c) ? m[c] : nil
|
28
|
+
}.compact * "/"
|
29
|
+
unlocated.gsub!(/\/+/,'/')
|
30
|
+
unlocated[self.subdir] = "" if self.subdir
|
31
|
+
choices << self.annotate(unlocated)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Path.setup(choices.sort_by{|s| s.length }.first, self, nil, path_maps)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.relocate(path)
|
41
|
+
return path if Open.exists?(path)
|
42
|
+
resource = path.pkgdir if Path === path
|
43
|
+
resource = Scout unless Resource === resource
|
44
|
+
unlocated = resource.identify path
|
45
|
+
unlocated.find
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'log'
|
2
|
+
require_relative 'path'
|
3
|
+
require_relative 'resource/produce'
|
4
|
+
require_relative 'resource/path'
|
5
|
+
require_relative 'resource/util'
|
6
|
+
|
7
|
+
module Resource
|
8
|
+
extend MetaExtension
|
9
|
+
extension_attr :pkgdir, :libdir, :subdir, :resources, :rake_dirs, :path_maps, :lock_dir
|
10
|
+
|
11
|
+
def self.default_lock_dir
|
12
|
+
Path.setup('tmp/produce_locks').find
|
13
|
+
end
|
14
|
+
|
15
|
+
def subdir
|
16
|
+
@subdir ||= ""
|
17
|
+
end
|
18
|
+
|
19
|
+
def lock_dir
|
20
|
+
@lock_dir ||= Resource.default_lock_dir
|
21
|
+
end
|
22
|
+
|
23
|
+
def pkgdir
|
24
|
+
@pkgdir ||= Path.default_pkgdir
|
25
|
+
end
|
26
|
+
|
27
|
+
def root
|
28
|
+
Path.setup(subdir, self, self.libdir, @path_maps)
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(name, prev = nil, *args)
|
32
|
+
if prev.nil?
|
33
|
+
root.send(name, *args)
|
34
|
+
else
|
35
|
+
root.send(name, prev, *args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/scout/simple_opt/doc.rb
CHANGED
@@ -2,7 +2,7 @@ require_relative '../log'
|
|
2
2
|
module SOPT
|
3
3
|
|
4
4
|
class << self
|
5
|
-
|
5
|
+
attr_writer :command, :summary, :synopsys, :description
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.command
|
@@ -42,10 +42,33 @@ module SOPT
|
|
42
42
|
"=<#{ type }>"
|
43
43
|
end
|
44
44
|
#extra << " (default: #{Array === default ? (default.length > 3 ? default[0..2]*", " + ', ...' : default*", " ): default})" if default != nil
|
45
|
-
extra << " (default: #{
|
45
|
+
extra << " (default: #{Log.fingerprint(default)})" if default != nil
|
46
46
|
input_str << Log.color(:green, extra)
|
47
47
|
end
|
48
48
|
|
49
|
+
def self.input_array_doc(input_array)
|
50
|
+
input_array.collect do |name,type,description,default,options|
|
51
|
+
type = :string if type.nil?
|
52
|
+
|
53
|
+
name = name.to_s
|
54
|
+
shortcut, options = options, nil if String === options || Symbol === options
|
55
|
+
|
56
|
+
case options && options[:shortcut]
|
57
|
+
when FalseClass
|
58
|
+
shortcut = nil
|
59
|
+
when TrueClass, nil
|
60
|
+
shortcut = fix_shortcut(name[0], name)
|
61
|
+
else
|
62
|
+
shortcut = options[:shortcut]
|
63
|
+
end unless shortcut
|
64
|
+
|
65
|
+
shortcut = fix_shortcut(shortcut, name)
|
66
|
+
register(shortcut, name, type, description) unless self.inputs.include? name
|
67
|
+
name = SOPT.input_format(name, type.to_sym, default, shortcut )
|
68
|
+
Misc.format_definition_list_item(name, description)
|
69
|
+
end * "\n"
|
70
|
+
end
|
71
|
+
|
49
72
|
def self.input_doc(inputs, input_types = nil, input_descriptions = nil, input_defaults = nil, input_shortcuts = nil)
|
50
73
|
type = description = default = nil
|
51
74
|
shortcut = ""
|
@@ -73,32 +96,13 @@ module SOPT
|
|
73
96
|
register(shortcut, name, type, description) unless self.inputs.include? name
|
74
97
|
|
75
98
|
name = SOPT.input_format(name, type.to_sym, default, shortcut)
|
76
|
-
description
|
77
|
-
Misc.format_definition_list_item(name, description, 80, 31, nil)
|
99
|
+
Misc.format_definition_list_item(name, description)
|
78
100
|
end * "\n"
|
79
101
|
end
|
80
102
|
|
81
|
-
def self.doc
|
82
|
-
doc = <<-EOF
|
83
|
-
#{Log.color :magenta}#{command}(1) -- #{summary}
|
84
|
-
#{"=" * (command.length + summary.length + 7)}#{Log.color :reset}
|
85
|
-
|
86
|
-
#{ Log.color :magenta, "## SYNOPSYS"}
|
87
|
-
|
88
|
-
#{Log.color :blue, synopsys}
|
89
|
-
|
90
|
-
#{ Log.color :magenta, "## DESCRIPTION"}
|
91
|
-
|
92
|
-
#{Misc.format_paragraph description}
|
93
|
-
|
94
|
-
#{ Log.color :magenta, "## OPTIONS"}
|
95
|
-
|
96
|
-
#{input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)}
|
97
|
-
EOF
|
98
|
-
end
|
99
103
|
|
100
104
|
def self.doc
|
101
|
-
doc
|
105
|
+
doc =<<-EOF
|
102
106
|
#{Log.color :magenta}#{command}(1) -- #{summary}
|
103
107
|
#{"=" * (command.length + summary.length + 7)}#{Log.color :reset}
|
104
108
|
|
@@ -116,5 +120,7 @@ module SOPT
|
|
116
120
|
|
117
121
|
doc << Log.color(:magenta, "## OPTIONS") << "\n\n"
|
118
122
|
doc << input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)
|
123
|
+
|
124
|
+
doc
|
119
125
|
end
|
120
126
|
end
|
@@ -44,23 +44,24 @@ module SOPT
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.parse(opt_str)
|
47
|
-
info = {}
|
48
|
-
|
49
47
|
inputs = []
|
48
|
+
|
50
49
|
if opt_str.include? "\n"
|
51
50
|
re = /\n+/
|
52
51
|
else
|
53
52
|
re = /:/
|
54
53
|
end
|
54
|
+
|
55
55
|
opt_str.split(re).each do |entry|
|
56
56
|
entry.strip!
|
57
57
|
next if entry.empty?
|
58
|
-
names, _sep, description = entry.partition
|
58
|
+
names, _sep, description = entry.partition(/\s+/)
|
59
59
|
short, long, asterisk = names.match(/\s*(?:-(.+))?(?:--(.+?))([*])?$/).values_at 1,2,3
|
60
60
|
|
61
61
|
inputs << long
|
62
62
|
register short, long, asterisk, description
|
63
63
|
end
|
64
|
+
|
64
65
|
inputs
|
65
66
|
end
|
66
67
|
end
|
data/lib/scout/tmpfile.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
require 'fileutils'
|
2
1
|
require_relative 'misc'
|
2
|
+
require_relative 'log'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module TmpFile
|
6
|
+
MAX_FILE_LENGTH = 150
|
7
|
+
|
5
8
|
def self.user_tmp(subdir = nil)
|
6
9
|
if subdir
|
7
10
|
File.join(ENV["HOME"],"/tmp/scout", subdir)
|
@@ -89,4 +92,39 @@ module TmpFile
|
|
89
92
|
end
|
90
93
|
end
|
91
94
|
end
|
95
|
+
|
96
|
+
def self.tmp_for_file(file, tmp_options = {}, other_options = {})
|
97
|
+
tmp_for_file = IndiferentHash.process_options tmp_options, :file
|
98
|
+
return tmp_for_file unless tmp_for_file.nil?
|
99
|
+
|
100
|
+
prefix = IndiferentHash.process_options tmp_options, :prefix
|
101
|
+
|
102
|
+
if prefix.nil?
|
103
|
+
perfile = file.to_s.gsub(/\//, '>')
|
104
|
+
else
|
105
|
+
perfile = prefix.to_s + ":" + file.to_s.gsub(/\//, '>')
|
106
|
+
end
|
107
|
+
|
108
|
+
perfile.sub!(/\.b?gz$/,'')
|
109
|
+
|
110
|
+
if other_options.include? :filters
|
111
|
+
other_options[:filters].each do |match,value|
|
112
|
+
perfile = perfile + "&F[#{match}=#{Misc.digest(value)}]"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
persistence_dir = IndiferentHash.process_options(tmp_options, :dir) || TmpFile.tmpdir
|
117
|
+
Path.setup(persistence_dir) unless Path === persistence_dir
|
118
|
+
|
119
|
+
filename = perfile.gsub(/\s/,'_').gsub(/\//,'>')
|
120
|
+
clean_options = other_options.dup
|
121
|
+
clean_options.delete :unnamed
|
122
|
+
clean_options.delete "unnamed"
|
123
|
+
|
124
|
+
filename = filename[0..MAX_FILE_LENGTH] << Misc.digest(filename[MAX_FILE_LENGTH+1..-1]) if filename.length > MAX_FILE_LENGTH + 10
|
125
|
+
|
126
|
+
filename += ":" << Misc.digest(clean_options) unless clean_options.empty?
|
127
|
+
|
128
|
+
persistence_dir[filename]
|
129
|
+
end
|
92
130
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative '../meta_extension'
|
2
|
+
|
3
|
+
module Workflow
|
4
|
+
extend MetaExtension
|
5
|
+
extension_attr :name, :tasks
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :directory
|
9
|
+
|
10
|
+
def directory
|
11
|
+
@directory ||= Path.setup('var/jobs')
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
@name ||= self.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :directory
|
21
|
+
def directory
|
22
|
+
@directory ||= Workflow.directory[name]
|
23
|
+
end
|
24
|
+
|
25
|
+
def directory=(directory)
|
26
|
+
@directory = directory
|
27
|
+
@tasks.each{|name,d| d.directory = directory[name] } if @tasks
|
28
|
+
end
|
29
|
+
|
30
|
+
def annotate_next_task(type, obj)
|
31
|
+
@annotate_next_task ||= {}
|
32
|
+
@annotate_next_task[type] ||= []
|
33
|
+
@annotate_next_task[type] << obj
|
34
|
+
end
|
35
|
+
|
36
|
+
def annotate_next_task_single(type, obj)
|
37
|
+
@annotate_next_task ||= {}
|
38
|
+
@annotate_next_task[type] = obj
|
39
|
+
end
|
40
|
+
|
41
|
+
def dep(*args, &block)
|
42
|
+
case args.length
|
43
|
+
when 3
|
44
|
+
workflow, task, options = args
|
45
|
+
when 2
|
46
|
+
if Hash === args.last
|
47
|
+
task, options = args
|
48
|
+
else
|
49
|
+
workflow, task = args
|
50
|
+
end
|
51
|
+
when 1
|
52
|
+
task = args.first
|
53
|
+
end
|
54
|
+
workflow = self if workflow.nil?
|
55
|
+
options = {} if options.nil?
|
56
|
+
annotate_next_task :deps, [workflow, task, options, block, args]
|
57
|
+
end
|
58
|
+
|
59
|
+
def input(*args)
|
60
|
+
annotate_next_task(:inputs, args)
|
61
|
+
end
|
62
|
+
|
63
|
+
def task(name_and_type, &block)
|
64
|
+
name, type = name_and_type.collect.first
|
65
|
+
@tasks ||= IndiferentHash.setup({})
|
66
|
+
begin
|
67
|
+
@annotate_next_task ||= {}
|
68
|
+
task = Task.setup(block, @annotate_next_task.merge(name: name, type: type, directory: directory[name]))
|
69
|
+
@tasks[name] = task
|
70
|
+
ensure
|
71
|
+
@annotate_next_task = {}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def desc(description)
|
76
|
+
annotate_next_task_single(:description, description)
|
77
|
+
end
|
78
|
+
end
|