scout-essentials 1.8.6 → 1.8.7
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 +1 -136
- data/VERSION +1 -1
- data/doc/CMD.md +161 -1
- data/lib/scout/cmd.rb +3 -1
- data/lib/scout/concurrent_stream.rb +1 -1
- data/lib/scout/log/fingerprint.rb +1 -0
- data/lib/scout/log/progress/report.rb +1 -1
- data/lib/scout/log/progress/util.rb +1 -1
- data/lib/scout/misc/format.rb +1 -1
- data/lib/scout/misc/hook.rb +6 -0
- data/lib/scout/open/util.rb +12 -8
- data/lib/scout/open.rb +3 -3
- data/lib/scout/path/find.rb +3 -3
- data/lib/scout/resource/path.rb +21 -1
- data/lib/scout/resource/produce/rake.rb +2 -1
- data/scout-essentials.gemspec +3 -3
- data/test/scout/open/test_remote.rb +10 -0
- data/test/scout/path/test_util.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3193beb1b7024505d5a238bb6d9caa280ddab034b23431652138697ebc9ac7f0
|
|
4
|
+
data.tar.gz: 29ef13d1a7862228eabc8f153f602ba728eda98cf4907b23770a8fb65cb36b98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c074200ead16664e4ecdcd262315f389500cd59391b533bcdd1f4a84bdf9ab3fcf96152698f643393d198d9cc1d552707144fd4fbc9c962badbb33d57c79d364
|
|
7
|
+
data.tar.gz: 57663384b0258537a626eb867e8dd209c9e84bc477dbc462c6096af539f54b176936b1cd4ace7cd47525b5e791a6b13ac41a000fdf2709a9add3a830eb1a33ab
|
data/.vimproject
CHANGED
|
@@ -1,146 +1,11 @@
|
|
|
1
1
|
scout-essentials=/$PWD filter="*.rb *.txt *.md *.conf *.yaml" {
|
|
2
2
|
LICENSE.txt
|
|
3
3
|
chats=chats filter="*"{
|
|
4
|
+
improve_doc
|
|
4
5
|
intro
|
|
5
6
|
|
|
6
7
|
review
|
|
7
8
|
document.rb
|
|
8
|
-
docs=docs{
|
|
9
|
-
Analyze Annotation tests
|
|
10
|
-
Analyze CMD and related tests
|
|
11
|
-
Analyze CMD tests
|
|
12
|
-
Analyze log tests
|
|
13
|
-
Analyze Open tests
|
|
14
|
-
Analyze Path tests
|
|
15
|
-
Analyze Persist tests
|
|
16
|
-
Analyze Resource tests
|
|
17
|
-
Analyze selected tests
|
|
18
|
-
simple_opt, log, open, persist, cmd, tmpfile
|
|
19
|
-
|
|
20
|
-
Analyze SimpleOpt tests
|
|
21
|
-
Analyze simple_opt tests
|
|
22
|
-
Analyze tests: simple_opt, log, open, persist, cmd, tmpfile
|
|
23
|
-
Analyze tmpfile tests
|
|
24
|
-
Analyze Utilities tests
|
|
25
|
-
Assemble Annotation docs
|
|
26
|
-
Assemble CMD docs
|
|
27
|
-
Assemble CMD docs
|
|
28
|
-
update
|
|
29
|
-
|
|
30
|
-
Assemble Open docs
|
|
31
|
-
Assemble Open docs
|
|
32
|
-
update
|
|
33
|
-
|
|
34
|
-
Assemble Path docs
|
|
35
|
-
Assemble Persist docs
|
|
36
|
-
Assemble Persist docs
|
|
37
|
-
update
|
|
38
|
-
|
|
39
|
-
Assemble Resource docs
|
|
40
|
-
Assemble Resource docs
|
|
41
|
-
update
|
|
42
|
-
|
|
43
|
-
Assemble Top-level README
|
|
44
|
-
Assemble Top-level README
|
|
45
|
-
update
|
|
46
|
-
|
|
47
|
-
Assemble Top-level README draft
|
|
48
|
-
Assemble Utilities docs
|
|
49
|
-
Assemble Utilities docs
|
|
50
|
-
update
|
|
51
|
-
|
|
52
|
-
Confirm·Explore Utilities dirs
|
|
53
|
-
Explore Annotation dirs
|
|
54
|
-
Explore CMD dirs
|
|
55
|
-
Explore Log dir
|
|
56
|
-
Explore Log lib dir
|
|
57
|
-
Explore Log lib dir
|
|
58
|
-
refresh
|
|
59
|
-
|
|
60
|
-
Explore Log test dir
|
|
61
|
-
Explore Log test dir
|
|
62
|
-
refresh
|
|
63
|
-
|
|
64
|
-
Explore Open dirs
|
|
65
|
-
Explore Path dirs
|
|
66
|
-
Explore Persist dirs
|
|
67
|
-
Explore Resource dirs
|
|
68
|
-
Explore Utilities dirs
|
|
69
|
-
Finalize README step
|
|
70
|
-
refresh
|
|
71
|
-
|
|
72
|
-
Finalize README.md into memory key
|
|
73
|
-
.md
|
|
74
|
-
|
|
75
|
-
conditional
|
|
76
|
-
|
|
77
|
-
NEXT_STEPS
|
|
78
|
-
QA Annotation docs
|
|
79
|
-
QA CMD docs
|
|
80
|
-
QA Integrated README
|
|
81
|
-
QA Integrated README
|
|
82
|
-
post-update
|
|
83
|
-
|
|
84
|
-
QA Integrated README
|
|
85
|
-
post-update
|
|
86
|
-
|
|
87
|
-
refresh
|
|
88
|
-
|
|
89
|
-
QA Open docs
|
|
90
|
-
QA Path docs
|
|
91
|
-
QA Persist docs
|
|
92
|
-
QA Resource docs
|
|
93
|
-
QA Utilities docs
|
|
94
|
-
Read Annotation source files
|
|
95
|
-
Read CMD source files
|
|
96
|
-
Read CMD source files
|
|
97
|
-
refresh
|
|
98
|
-
|
|
99
|
-
Read Log source files
|
|
100
|
-
Read Log source files
|
|
101
|
-
iterate
|
|
102
|
-
|
|
103
|
-
Read Log source files
|
|
104
|
-
refresh
|
|
105
|
-
|
|
106
|
-
Read Log source files
|
|
107
|
-
use explorer output
|
|
108
|
-
|
|
109
|
-
Read Open source files
|
|
110
|
-
Read Open stream and lockfile
|
|
111
|
-
Read Path source files
|
|
112
|
-
Read Persist serialize and open
|
|
113
|
-
Read Persist source files
|
|
114
|
-
Read Resource scout.rb
|
|
115
|
-
Read Resource source files
|
|
116
|
-
Read SimpleOpt source files
|
|
117
|
-
Read TmpFile and IndiferentHash source files
|
|
118
|
-
Read Utilities source files
|
|
119
|
-
Run QA Integrator on assembled docs
|
|
120
|
-
Update CMD docs
|
|
121
|
-
assemble
|
|
122
|
-
|
|
123
|
-
Update Open docs
|
|
124
|
-
assemble
|
|
125
|
-
|
|
126
|
-
Update Persist docs
|
|
127
|
-
assemble
|
|
128
|
-
|
|
129
|
-
Update Resource docs
|
|
130
|
-
assemble
|
|
131
|
-
|
|
132
|
-
Update Utilities docs
|
|
133
|
-
assemble
|
|
134
|
-
|
|
135
|
-
final=final{
|
|
136
|
-
annotation.md
|
|
137
|
-
cmd.md
|
|
138
|
-
open.md
|
|
139
|
-
path.md
|
|
140
|
-
persist.md
|
|
141
|
-
resource.md
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
9
|
}
|
|
145
10
|
doc=doc{
|
|
146
11
|
Annotation.md
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.8.
|
|
1
|
+
1.8.7
|
data/doc/CMD.md
CHANGED
|
@@ -32,12 +32,72 @@ puts stream.read # streaming consumption
|
|
|
32
32
|
stream.join # wait for producers and check exit status
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
## Common gotchas
|
|
36
|
+
|
|
37
|
+
These are the most common sources of confusion when using `CMD.cmd`:
|
|
38
|
+
|
|
39
|
+
- **String vs Symbol as the first argument**:
|
|
40
|
+
- `CMD.cmd('mytool ...')` runs exactly that shell command.
|
|
41
|
+
- `CMD.cmd(:mytool, ...)` goes through `CMD.get_tool(:mytool)` first (tool registry / bootstrap). This is useful when you want
|
|
42
|
+
tool discovery/installation behavior.
|
|
43
|
+
- If you do *not* rely on the tool registry, prefer passing the command as a String.
|
|
44
|
+
|
|
45
|
+
- **Pipe mode needs a `join` (for correct error detection)**:
|
|
46
|
+
- With `:pipe => true`, you typically do `io = CMD.cmd(..., pipe: true)` and then `io.read`.
|
|
47
|
+
- To reliably detect failures (non-zero exit), call `io.join` (unless you deliberately set `no_fail: true`).
|
|
48
|
+
|
|
49
|
+
- **Non-pipe mode returns a `StringIO`**:
|
|
50
|
+
- With `:pipe => false` (default), CMD collects stdout and returns a `StringIO` *after* the process completes.
|
|
51
|
+
- This is convenient, but can be memory-heavy for large outputs.
|
|
52
|
+
|
|
53
|
+
- **`save_stderr` vs logging**:
|
|
54
|
+
- `log: true` (default in many contexts) logs stderr lines as they arrive.
|
|
55
|
+
- `save_stderr: true` additionally accumulates stderr into `io.std_err` (useful for raising helpful exceptions).
|
|
56
|
+
|
|
57
|
+
- **`no_fail` suppresses exceptions**:
|
|
58
|
+
- If you pass `no_fail: true`, CMD will not raise `ProcessFailed` / `ConcurrentStreamProcessFailed` on non-zero exits.
|
|
59
|
+
- This is useful for "try it" probes, but make sure you explicitly check `io.exit_status` (or parse output) when you need correctness.
|
|
60
|
+
|
|
61
|
+
- **`{opt}` placeholder**:
|
|
62
|
+
- If the command string contains the exact substring `'{opt}'`, CMD replaces it with the processed options string.
|
|
63
|
+
- Otherwise, options are appended to the end of the command.
|
|
64
|
+
|
|
65
|
+
- **Second argument ambiguity**:
|
|
66
|
+
- `CMD.cmd(tool, {...})` means the second argument is treated as options and `cmd_fragment_or_options` becomes nil.
|
|
67
|
+
- If you intended to pass a command fragment, pass it as a String, e.g. `CMD.cmd('cut', "-f 2", in: "a b")`.
|
|
68
|
+
|
|
35
69
|
---
|
|
36
70
|
|
|
37
71
|
## Important options
|
|
38
72
|
|
|
39
73
|
All options are passed as an options Hash (converted with IndiferentHash), and many are special keys:
|
|
40
74
|
|
|
75
|
+
### Understanding `CMD.cmd` arguments
|
|
76
|
+
|
|
77
|
+
`CMD.cmd` has a flexible signature:
|
|
78
|
+
|
|
79
|
+
- `CMD.cmd(tool_or_cmd, cmd_fragment_or_options = nil, options = {})`
|
|
80
|
+
|
|
81
|
+
Common calling styles:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
# 1) Single string command
|
|
85
|
+
io = CMD.cmd("echo hello")
|
|
86
|
+
|
|
87
|
+
# 2) Tool + command fragment
|
|
88
|
+
io = CMD.cmd("cut", "-f 2 -d ' '", in: "a b")
|
|
89
|
+
|
|
90
|
+
# 3) Tool + options hash (options are converted to CLI flags)
|
|
91
|
+
io = CMD.cmd("cut", {"-f" => 2, "-d" => " "}, in: "a b")
|
|
92
|
+
|
|
93
|
+
# 4) Tool registry symbol (uses CMD.get_tool first)
|
|
94
|
+
io = CMD.cmd(:python, "--version")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Notes:
|
|
98
|
+
- If the *second* argument is a Hash, it is treated as option flags and `cmd_fragment_or_options` becomes nil.
|
|
99
|
+
- Options are shell-quoted; values containing single quotes are escaped.
|
|
100
|
+
|
|
41
101
|
- :pipe (boolean) — if true, return a stream you can read from; otherwise CMD returns a StringIO after the process completes.
|
|
42
102
|
- :in — input to feed to the command:
|
|
43
103
|
- String will be wrapped by StringIO and streamed to process stdin.
|
|
@@ -177,6 +237,39 @@ CMD.cmd('grep . NONEXISTINGFILE', :pipe => true).join
|
|
|
177
237
|
|
|
178
238
|
## Recommendations & patterns
|
|
179
239
|
|
|
240
|
+
### Robust error-handling pattern
|
|
241
|
+
|
|
242
|
+
A common robust pattern is:
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
io = CMD.cmd("SomeTool", "--flag value", log: true, save_stderr: true, no_fail: true)
|
|
246
|
+
|
|
247
|
+
# Decide how to handle failure
|
|
248
|
+
if io.exit_status != 0
|
|
249
|
+
raise ScoutException, io.read + "
|
|
250
|
+
" + io.std_err.to_s
|
|
251
|
+
end
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- `no_fail: true` prevents immediate exceptions (useful so you can include stderr in your own error message).
|
|
255
|
+
- If you want CMD to raise automatically, omit `no_fail` and rely on `ProcessFailed` / `ConcurrentStreamProcessFailed`.
|
|
256
|
+
|
|
257
|
+
### Large outputs
|
|
258
|
+
|
|
259
|
+
- Prefer `:pipe => true` when you want to stream and transform output without buffering everything in memory.
|
|
260
|
+
- If you need to keep the full output, write it to a file as you consume it, and return/keep only a small summary in memory.
|
|
261
|
+
|
|
262
|
+
### Pipelines
|
|
263
|
+
|
|
264
|
+
When composing multiple commands, use pipe mode and pass the upstream stream as `:in`:
|
|
265
|
+
|
|
266
|
+
```ruby
|
|
267
|
+
io1 = CMD.cmd("tool1", "--emit", pipe: true)
|
|
268
|
+
io2 = CMD.cmd("tool2", "--filter", in: io1, pipe: true)
|
|
269
|
+
out = io2.read
|
|
270
|
+
io2.join
|
|
271
|
+
```
|
|
272
|
+
|
|
180
273
|
- Prefer `:pipe => true` + ConcurrentStream when you want streaming processing without waiting for full output in memory.
|
|
181
274
|
- Provide `:in` as an IO to stream large inputs into a subprocess.
|
|
182
275
|
- Use `:autojoin => true` to automatically join producers on EOF/close (useful for simple consumers).
|
|
@@ -200,4 +293,71 @@ CMD.cmd('grep . NONEXISTINGFILE', :pipe => true).join
|
|
|
200
293
|
|
|
201
294
|
---
|
|
202
295
|
|
|
203
|
-
CMD centralizes robust process execution patterns needed throughout the framework: streaming, joining, logging, error detection and tool bootstrap. Use its options to control behavior for production-grade command invocation.
|
|
296
|
+
CMD centralizes robust process execution patterns needed throughout the framework: streaming, joining, logging, error detection and tool bootstrap. Use its options to control behavior for production-grade command invocation.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Designing command wrappers for workflows and agents
|
|
301
|
+
|
|
302
|
+
When you wrap external CLI tools inside workflow tasks (or expose them to agents), use a pattern that maximizes reproducibility and keeps outputs small for downstream consumers:
|
|
303
|
+
|
|
304
|
+
- Backend task (tool runner)
|
|
305
|
+
- Run the binary, write all full outputs to `step.files_dir` (use `file('name')` helpers).
|
|
306
|
+
- Return a compact JSON summary with:
|
|
307
|
+
- `files`: list of important output file paths (full paths inside `.files/`).
|
|
308
|
+
- `params`: what parameters were used (seeds, time, sample_count, fixed clamps, etc.).
|
|
309
|
+
- optional small parsed snippets (e.g. final probabilities) if tiny.
|
|
310
|
+
- Use `CMD.cmd('Binary', ...)` (string) unless the tool is registered; include `save_stderr: true` so errors are captured.
|
|
311
|
+
|
|
312
|
+
- Analysis task (summary)
|
|
313
|
+
- `dep` on the backend task and parse only the necessary outputs into a compact summary suitable for the interactive/LLM context (JSON, small tables, phenotype probs).
|
|
314
|
+
- Echo the backend `params` in the returned result so cached runs are auditable.
|
|
315
|
+
|
|
316
|
+
Benefits:
|
|
317
|
+
- Clear cache boundaries: the backend is the expensive, cacheable step; the analysis is cheap and reproducible given the backend outputs.
|
|
318
|
+
- Agents never have to load entire trace files; they get a compact summary.
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
## Quick checklist when using CMD in workflows
|
|
322
|
+
|
|
323
|
+
- Prefer `CMD.cmd('Binary', ...)` string invocation unless you intentionally want the tool registry/install behavior via symbol form.
|
|
324
|
+
- For long-running streaming tasks use `:pipe => true` and **always** `join` the returned stream (or rely on `autojoin`) to detect failures.
|
|
325
|
+
- If you must ignore process failures for probing, use `no_fail: true` but explicitly check exit code or outputs later.
|
|
326
|
+
- Use `save_stderr: true` when you will raise on error: include `io.std_err` in exception messages.
|
|
327
|
+
- Avoid returning raw `StringIO` of huge outputs from tasks — write to `step.files_dir` instead and return a small summary.
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Minimal patterns/examples
|
|
331
|
+
|
|
332
|
+
Read-only capture (small output):
|
|
333
|
+
```ruby
|
|
334
|
+
out = CMD.cmd("echo hello").read # synchronous, small stdout
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Streaming safe consumption:
|
|
338
|
+
```ruby
|
|
339
|
+
stream = CMD.cmd("tail -f /some/log", pipe: true)
|
|
340
|
+
begin
|
|
341
|
+
data = stream.read
|
|
342
|
+
ensure
|
|
343
|
+
stream.join # ensure you detect non-zero exit and collect stderr
|
|
344
|
+
end
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Pass an IO to stdin safely:
|
|
348
|
+
```ruby
|
|
349
|
+
f = Open.open('input.txt')
|
|
350
|
+
io = CMD.cmd('someprog', :in => f, pipe: true)
|
|
351
|
+
puts io.read
|
|
352
|
+
io.join
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Tool registry vs direct call:
|
|
356
|
+
```ruby
|
|
357
|
+
# use tool registry (only if the tool is registered in CMD.tool)
|
|
358
|
+
CMD.cmd(:my_registered_tool, '--version')
|
|
359
|
+
# prefer direct call when portability is desired
|
|
360
|
+
CMD.cmd('my_tool --version')
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
For more advanced patterns and examples see the `CMD` implementation and tests in the codebase.
|
data/lib/scout/cmd.rb
CHANGED
|
@@ -212,8 +212,10 @@ module CMD
|
|
|
212
212
|
in_content.close unless in_content.closed?
|
|
213
213
|
in_content.join if in_content.respond_to? :join
|
|
214
214
|
end
|
|
215
|
-
rescue
|
|
215
|
+
rescue Exception
|
|
216
216
|
Log.error "Error in CMD [#{pid}] #{cmd}: #{$!.message}" unless no_fail
|
|
217
|
+
sin.close unless sin.closed?
|
|
218
|
+
sin.join if sin.respond_to? :join
|
|
217
219
|
raise $!
|
|
218
220
|
end
|
|
219
221
|
end
|
data/lib/scout/misc/format.rb
CHANGED
|
@@ -45,7 +45,7 @@ module Misc
|
|
|
45
45
|
|
|
46
46
|
i = 0
|
|
47
47
|
#size = size + offset + indent
|
|
48
|
-
re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*))|(?:\n
|
|
48
|
+
re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*))|(?:\n```)|(?:\n\s*[-\*])|(?:\n\s\s+))/
|
|
49
49
|
text.split(re).collect do |paragraph|
|
|
50
50
|
i += 1
|
|
51
51
|
str = if i % 2 == 1
|
data/lib/scout/misc/hook.rb
CHANGED
data/lib/scout/open/util.rb
CHANGED
|
@@ -35,21 +35,25 @@ module Open
|
|
|
35
35
|
Bgzf.setup stream
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def self.gunzip(stream)
|
|
39
|
-
|
|
38
|
+
def self.gunzip(stream, options = {})
|
|
39
|
+
options = IndiferentHash.add_defaults options, :pipe => true, :no_fail => false, :no_wait => true, in: stream
|
|
40
|
+
CMD.cmd('zcat', options)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
|
-
def self.gzip(stream)
|
|
43
|
-
|
|
43
|
+
def self.gzip(stream, options = {})
|
|
44
|
+
options = IndiferentHash.add_defaults options, :pipe => true, :no_fail => false, :no_wait => true, in: stream
|
|
45
|
+
CMD.cmd('gzip', options)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
def self.bgzip(stream)
|
|
47
|
-
|
|
48
|
+
def self.bgzip(stream, options = {})
|
|
49
|
+
options = IndiferentHash.add_defaults options, :pipe => true, :no_fail => false, :no_wait => true, in: stream
|
|
50
|
+
CMD.cmd('bgzip', options)
|
|
48
51
|
end
|
|
49
52
|
|
|
50
|
-
def self.unzip(stream)
|
|
53
|
+
def self.unzip(stream, options = {})
|
|
54
|
+
options = IndiferentHash.add_defaults options, :pipe => true, :no_fail => false, :no_wait => true, in: stream
|
|
51
55
|
TmpFile.with_file(stream.read) do |filename|
|
|
52
|
-
StringIO.new(CMD.cmd("unzip '{opt}' #{filename}",
|
|
56
|
+
StringIO.new(CMD.cmd("unzip '{opt}' #{filename}", options))
|
|
53
57
|
end
|
|
54
58
|
end
|
|
55
59
|
|
data/lib/scout/open.rb
CHANGED
|
@@ -52,9 +52,9 @@ module Open
|
|
|
52
52
|
|
|
53
53
|
io = file_open(file, grep, mode, invert_grep, fixed_grep, options)
|
|
54
54
|
|
|
55
|
-
io = unzip(io) if ((String === file and zip?(file)) and not options[:noz]) or options[:zip]
|
|
56
|
-
io = gunzip(io) if ((String === file and gzip?(file)) and not options[:noz]) or options[:gzip]
|
|
57
|
-
io = bgunzip(io) if ((String === file and bgzip?(file)) and not options[:noz]) or options[:bgzip]
|
|
55
|
+
io = unzip(io, options) if ((String === file and zip?(file)) and not options[:noz]) or options[:zip]
|
|
56
|
+
io = gunzip(io, options) if ((String === file and gzip?(file)) and not options[:noz]) or options[:gzip]
|
|
57
|
+
io = bgunzip(io, options) if ((String === file and bgzip?(file)) and not options[:noz]) or options[:bgzip]
|
|
58
58
|
|
|
59
59
|
io.extend NamedStream
|
|
60
60
|
io.filename = file
|
data/lib/scout/path/find.rb
CHANGED
|
@@ -288,15 +288,15 @@ module Path
|
|
|
288
288
|
|
|
289
289
|
def find_with_extension(extension, *args, produce: true)
|
|
290
290
|
found = self.find(*args)
|
|
291
|
-
return found if found.exists?
|
|
291
|
+
return found if found.exists? && ! found.directory?
|
|
292
292
|
if Array === extension
|
|
293
293
|
extension.each do |ext|
|
|
294
294
|
found_with_extension = self.set_extension(ext).find
|
|
295
|
-
return found_with_extension if found_with_extension.exists?
|
|
295
|
+
return found_with_extension if found_with_extension.exists?
|
|
296
296
|
end
|
|
297
297
|
else
|
|
298
298
|
found_with_extension = self.set_extension(extension).find
|
|
299
|
-
return found_with_extension if found_with_extension.exists?
|
|
299
|
+
return found_with_extension if found_with_extension.exists?
|
|
300
300
|
end
|
|
301
301
|
return found
|
|
302
302
|
end
|
data/lib/scout/resource/path.rb
CHANGED
|
@@ -76,6 +76,26 @@ module Path
|
|
|
76
76
|
|
|
77
77
|
def exists?(produce: true)
|
|
78
78
|
return true if Open.exists?(self.find)
|
|
79
|
-
|
|
79
|
+
if produce
|
|
80
|
+
self.produce
|
|
81
|
+
Open.exists?(self.find)
|
|
82
|
+
else
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def find_with_extension(extension, *args, produce: true)
|
|
88
|
+
found = self.find(*args)
|
|
89
|
+
return found if found.exists?(produce: produce) && ! found.directory?
|
|
90
|
+
if Array === extension
|
|
91
|
+
extension.each do |ext|
|
|
92
|
+
found_with_extension = self.set_extension(ext).find
|
|
93
|
+
return found_with_extension if found_with_extension.exists?(produce: produce)
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
found_with_extension = self.set_extension(extension).find
|
|
97
|
+
return found_with_extension if found_with_extension.exists?(produce: produce)
|
|
98
|
+
end
|
|
99
|
+
return found
|
|
80
100
|
end
|
|
81
101
|
end
|
|
@@ -56,12 +56,13 @@ module ScoutRake
|
|
|
56
56
|
Rake::FileTask.clear_files
|
|
57
57
|
end
|
|
58
58
|
rescue Exception
|
|
59
|
+
Log.exception $!
|
|
59
60
|
Log.error "Error in rake: #{$!.message}"
|
|
60
61
|
Kernel.exit! -1
|
|
61
62
|
end
|
|
62
63
|
Kernel.exit! 0
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
Misc.wait_child(pid)
|
|
65
66
|
raise "Rake failed" unless $?.success?
|
|
66
67
|
|
|
67
68
|
end
|
data/scout-essentials.gemspec
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: scout-essentials 1.8.
|
|
5
|
+
# stub: scout-essentials 1.8.7 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "scout-essentials".freeze
|
|
9
|
-
s.version = "1.8.
|
|
9
|
+
s.version = "1.8.7".freeze
|
|
10
10
|
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
12
12
|
s.require_paths = ["lib".freeze]
|
|
@@ -159,7 +159,7 @@ Gem::Specification.new do |s|
|
|
|
159
159
|
]
|
|
160
160
|
s.homepage = "http://github.com/mikisvaz/scout-essentials".freeze
|
|
161
161
|
s.licenses = ["MIT".freeze]
|
|
162
|
-
s.rubygems_version = "3.7.
|
|
162
|
+
s.rubygems_version = "3.7.0.dev".freeze
|
|
163
163
|
s.summary = "Scout essential tools".freeze
|
|
164
164
|
|
|
165
165
|
s.specification_version = 4
|
|
@@ -21,5 +21,15 @@ class TestOpenRemote < Test::Unit::TestCase
|
|
|
21
21
|
end
|
|
22
22
|
end if false
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
def test_error
|
|
26
|
+
teardown
|
|
27
|
+
sss 0
|
|
28
|
+
assert_raises ConcurrentStreamProcessFailed do
|
|
29
|
+
stream = Open.open("ftp://ftp.ncbi.nlm.nih.gov/pub/geo/DATA/SOFT/GDS/GDS3148.soft.gz", nocache: true)
|
|
30
|
+
stream.read
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
24
34
|
end
|
|
25
35
|
|
|
@@ -58,5 +58,14 @@ class TestPathUtil < Test::Unit::TestCase
|
|
|
58
58
|
CMD.cmd("chmod +w #{dir.find}")
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
def test_find_exists
|
|
63
|
+
TmpFile.with_path do |dir|
|
|
64
|
+
Open.write dir.f1.set_extension("rb"), 'test1'
|
|
65
|
+
|
|
66
|
+
assert dir.f1.find_with_extension("rb").exists?
|
|
67
|
+
refute dir.f1.find_with_extension("rp").exists?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
61
70
|
end
|
|
62
71
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scout-essentials
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.8.
|
|
4
|
+
version: 1.8.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Vazquez
|
|
@@ -298,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
298
298
|
- !ruby/object:Gem::Version
|
|
299
299
|
version: '0'
|
|
300
300
|
requirements: []
|
|
301
|
-
rubygems_version: 3.7.
|
|
301
|
+
rubygems_version: 3.7.0.dev
|
|
302
302
|
specification_version: 4
|
|
303
303
|
summary: Scout essential tools
|
|
304
304
|
test_files: []
|