rundoc 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/rundoc/cli.rb +16 -2
- data/lib/rundoc/cli_argument_parser.rb +6 -1
- data/lib/rundoc/code_command/background/process_spawn.rb +2 -2
- data/lib/rundoc/code_command/background/start.rb +1 -0
- data/lib/rundoc/code_section.rb +16 -0
- data/lib/rundoc/context/execution.rb +5 -2
- data/lib/rundoc/version.rb +1 -1
- data/test/integration/failure_test.rb +46 -0
- data/test/integration/with_contents_flag_test.rb +35 -0
- data/test/test_helper.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e89c8353e4727ae39613f24c38bf3a69f027c6d1e533e64e281a588405ff57f
|
4
|
+
data.tar.gz: 34df7f620c446901596deec889b9c8f785bd10e0441a54e1904b799ae9b8f0cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb56a43157798ba53c4e63d715fd75892bc6d2b93bd0b8d379168c4dcc8807af3c31a5b8ac1a8af6215fa738bad6f8b4e2df525bae1c6590ef8bf7d3e94b29d
|
7
|
+
data.tar.gz: 8f6555c197fc600cc5cbf60af7d558213f50ec2a01b3d72f57e09eec628ba3169a512230b9ae106071afb2b536a6b7a314b3a8a832eb64e158565d977ab28e06
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
## HEAD
|
2
2
|
|
3
|
+
## 3.1.0
|
4
|
+
|
5
|
+
- Add: `--with-contents` flag that accepts a directory. The **contents** of the directory (and not the directory itself) will be copied into the working dir before execution. This is useful for debugging a single rundoc step. ()
|
6
|
+
|
7
|
+
For example if `RUNDOC.md` features many smaller docs:
|
8
|
+
|
9
|
+
```
|
10
|
+
:::>> rundoc.require "./intro.md"
|
11
|
+
:::>> rundoc.require "../shared/install_cli.md"
|
12
|
+
:::>> rundoc.require "./clone_app.md"
|
13
|
+
```
|
14
|
+
|
15
|
+
If the command fails on `clone_app.md` then you can rapidly iterate by calling `$ rundoc ./clone_app.md --with-contents failed/my-app` but be careful to not use the same failure directory etc or it will be replaced.
|
16
|
+
|
17
|
+
## 3.0.2
|
18
|
+
|
19
|
+
- Fix: Partial output of the document is now written to disk in a `RUNDOC_FAILED.md` file (https://github.com/zombocom/rundoc/pull/69)
|
20
|
+
|
3
21
|
## 3.0.1
|
4
22
|
|
5
23
|
- Fix: Save in-progress work in the "failure" directory when the rundoc command is interrupted via a signal such as `SIGTERM` (https://github.com/zombocom/rundoc/pull/67)
|
data/lib/rundoc/cli.rb
CHANGED
@@ -24,6 +24,7 @@ module Rundoc
|
|
24
24
|
on_success_dir: nil,
|
25
25
|
on_failure_dir: nil,
|
26
26
|
output_filename: nil,
|
27
|
+
with_contents_dir: nil,
|
27
28
|
screenshots_dirname: nil
|
28
29
|
)
|
29
30
|
@io = io
|
@@ -37,6 +38,7 @@ module Rundoc
|
|
37
38
|
@execution_context = Rundoc::Context::Execution.new(
|
38
39
|
output_dir: Dir.mktmpdir,
|
39
40
|
source_path: source_path,
|
41
|
+
with_contents_dir: with_contents_dir,
|
40
42
|
screenshots_dirname: screenshots_dirname
|
41
43
|
)
|
42
44
|
|
@@ -136,13 +138,23 @@ module Rundoc
|
|
136
138
|
|
137
139
|
source_contents = execution_context.source_path.read
|
138
140
|
if on_failure_dir.exist? && !Dir.empty?(on_failure_dir)
|
139
|
-
io.puts "##
|
141
|
+
io.puts "## erring on failure directory #{on_failure_dir}"
|
140
142
|
clean_dir(
|
141
143
|
dir: on_failure_dir,
|
142
144
|
description: "on failure directory"
|
143
145
|
)
|
144
146
|
end
|
145
147
|
|
148
|
+
if execution_context.with_contents_dir
|
149
|
+
io.puts "## Copying contents from #{execution_context.with_contents_dir} to tmp working dir"
|
150
|
+
Dir.chdir(execution_context.with_contents_dir) do
|
151
|
+
FileUtils.cp_r(
|
152
|
+
".",
|
153
|
+
execution_context.output_dir
|
154
|
+
)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
146
158
|
io.puts "## Working dir is #{execution_context.output_dir}"
|
147
159
|
Dir.chdir(execution_context.output_dir) do
|
148
160
|
parser = Rundoc::Parser.new(
|
@@ -152,7 +164,7 @@ module Rundoc
|
|
152
164
|
output = begin
|
153
165
|
parser.to_md
|
154
166
|
rescue StandardError, SignalException => e
|
155
|
-
|
167
|
+
io.puts "Received exception: #{e.inspect}, cleaning up before re-raise"
|
156
168
|
on_fail
|
157
169
|
raise e
|
158
170
|
end
|
@@ -190,6 +202,8 @@ module Rundoc
|
|
190
202
|
from: execution_context.output_dir,
|
191
203
|
to: on_failure_dir
|
192
204
|
)
|
205
|
+
|
206
|
+
on_failure_dir.join("RUNDOC_FAILED.md").write(Rundoc::CodeSection.partial_result_to_doc)
|
193
207
|
end
|
194
208
|
|
195
209
|
private def on_success(output)
|
@@ -8,7 +8,8 @@ module Rundoc
|
|
8
8
|
#
|
9
9
|
# Example:
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# options = Rundoc::CLIArgumentParser.new(argv: ARGV).call.options
|
12
|
+
# cli = Rundoc::CLI.new(**options)
|
12
13
|
# cli.call
|
13
14
|
#
|
14
15
|
class CLIArgumentParser
|
@@ -109,6 +110,10 @@ module Rundoc
|
|
109
110
|
@exit_obj.exit(0)
|
110
111
|
end
|
111
112
|
|
113
|
+
opts.on("--with-contents <dir>", "Copies contents of directory into the tmp working dir") do |v|
|
114
|
+
options[:with_contents_dir] = v
|
115
|
+
end
|
116
|
+
|
112
117
|
opts.on("--on-success-dir <dir>", "Success dir, relative to CWD. i.e. `<rundoc.md/dir>/#{CLI::DEFAULTS::ON_SUCCESS_DIR}/`.") do |v|
|
113
118
|
options[:on_success_dir] = v
|
114
119
|
end
|
@@ -43,7 +43,7 @@ class Rundoc::CodeCommand::Background
|
|
43
43
|
@tasks[name]
|
44
44
|
end
|
45
45
|
|
46
|
-
attr_reader :log, :pid
|
46
|
+
attr_reader :log, :pid, :command
|
47
47
|
|
48
48
|
def initialize(command, timeout: 5, log: Tempfile.new("log"), out: "2>&1")
|
49
49
|
@command = command
|
@@ -68,7 +68,7 @@ class Rundoc::CodeCommand::Background
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
rescue Timeout::Error
|
71
|
-
raise "Timeout waiting for #{@command.inspect} to find a match using #{wait_value.inspect} in \n'#{log.read}'"
|
71
|
+
raise "Timeout (#{timeout_value}s) waiting for #{@command.inspect} to find a match using #{wait_value.inspect} in \n'#{log.read}'"
|
72
72
|
end
|
73
73
|
|
74
74
|
def alive?
|
data/lib/rundoc/code_section.rb
CHANGED
@@ -30,6 +30,9 @@ module Rundoc
|
|
30
30
|
AUTOGEN_WARNING = "\n<!-- STOP. This document is autogenerated. Do not manually modify. See the top of the doc for more details. -->"
|
31
31
|
attr_accessor :original, :fence, :lang, :code, :commands, :keyword
|
32
32
|
|
33
|
+
PARTIAL_RESULT = []
|
34
|
+
PARTIAL_ENV = {}
|
35
|
+
|
33
36
|
def initialize(match, keyword:, context:)
|
34
37
|
@original = match.to_s
|
35
38
|
@commands = []
|
@@ -40,6 +43,8 @@ module Rundoc
|
|
40
43
|
@lang = match[:lang]
|
41
44
|
@code = match[:contents]
|
42
45
|
parse_code_command
|
46
|
+
PARTIAL_RESULT.clear
|
47
|
+
PARTIAL_ENV.clear
|
43
48
|
end
|
44
49
|
|
45
50
|
def render
|
@@ -69,10 +74,21 @@ module Rundoc
|
|
69
74
|
tmp_result << code_output if code_command.render_result?
|
70
75
|
|
71
76
|
result << tmp_result unless code_command.hidden?
|
77
|
+
|
78
|
+
PARTIAL_RESULT.replace(result)
|
79
|
+
PARTIAL_ENV.replace(env)
|
72
80
|
end
|
73
81
|
|
74
82
|
return "" if hidden?
|
75
83
|
|
84
|
+
self.class.to_doc(result: result, env: env)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.partial_result_to_doc
|
88
|
+
to_doc(result: PARTIAL_RESULT, env: PARTIAL_ENV)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.to_doc(result:, env:)
|
76
92
|
array = [env[:before]]
|
77
93
|
|
78
94
|
result.flatten!
|
@@ -9,13 +9,16 @@ module Rundoc
|
|
9
9
|
# The directory we are actively manipulating
|
10
10
|
:output_dir,
|
11
11
|
# Directory to store screenshots, relative to output_dir
|
12
|
-
:screenshots_dir
|
12
|
+
:screenshots_dir,
|
13
|
+
# Directory we are copying from, i.e. a directory to source from could be nil
|
14
|
+
:with_contents_dir
|
13
15
|
|
14
|
-
def initialize(source_path:, output_dir:, screenshots_dirname:)
|
16
|
+
def initialize(source_path:, output_dir:, screenshots_dirname:, with_contents_dir:)
|
15
17
|
@source_path = Pathname(source_path).expand_path
|
16
18
|
@source_dir = @source_path.parent
|
17
19
|
@output_dir = Pathname(output_dir).expand_path
|
18
20
|
@screenshots_dir = @output_dir.join(screenshots_dirname).expand_path
|
21
|
+
@with_contents_dir = with_contents_dir
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
data/lib/rundoc/version.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class IntegrationFailureTest < Minitest::Test
|
4
|
+
def test_writes_to_dir_on_failure
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
Dir.chdir(dir) do
|
7
|
+
dir = Pathname(dir)
|
8
|
+
|
9
|
+
source_path = dir.join("RUNDOC.md")
|
10
|
+
source_path.write <<~EOF
|
11
|
+
```
|
12
|
+
:::>> $ mkdir lol
|
13
|
+
:::>> $ touch lol/rofl.txt
|
14
|
+
:::>> $ touch does/not/exist.txt
|
15
|
+
```
|
16
|
+
EOF
|
17
|
+
|
18
|
+
io = StringIO.new
|
19
|
+
|
20
|
+
error = nil
|
21
|
+
begin
|
22
|
+
Rundoc::CLI.new(
|
23
|
+
io: io,
|
24
|
+
source_path: source_path,
|
25
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
26
|
+
).call
|
27
|
+
rescue => e
|
28
|
+
error = e
|
29
|
+
end
|
30
|
+
|
31
|
+
assert error
|
32
|
+
assert_includes error.message, "exited with non zero status"
|
33
|
+
|
34
|
+
refute dir.join(SUCCESS_DIRNAME).join("lol").exist?
|
35
|
+
refute dir.join(SUCCESS_DIRNAME).join("lol").join("rofl.txt").exist?
|
36
|
+
|
37
|
+
assert dir.join(FAILURE_DIRNAME).join("lol").exist?
|
38
|
+
assert dir.join(FAILURE_DIRNAME).join("lol").join("rofl.txt").exist?
|
39
|
+
|
40
|
+
doc = dir.join(FAILURE_DIRNAME).join("RUNDOC_FAILED.md").read
|
41
|
+
assert_includes doc, "$ mkdir lol"
|
42
|
+
assert_includes doc, "$ touch lol/rofl.txt"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class WithContentsFlagTest < Minitest::Test
|
4
|
+
def test_with_contents_flag
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
Dir.chdir(dir) do
|
7
|
+
dir = Pathname(dir)
|
8
|
+
|
9
|
+
contents_dir = dir.join("contents").tap { |p| p.mkpath }
|
10
|
+
FileUtils.touch(contents_dir.join("file1.txt"))
|
11
|
+
|
12
|
+
source_path = dir.join("RUNDOC.md")
|
13
|
+
source_path.write <<~EOF
|
14
|
+
```
|
15
|
+
:::>> $ ls
|
16
|
+
```
|
17
|
+
EOF
|
18
|
+
|
19
|
+
refute dir.join(SUCCESS_DIRNAME).join("file1.txt").exist?
|
20
|
+
|
21
|
+
io = StringIO.new
|
22
|
+
Rundoc::CLI.new(
|
23
|
+
io: io,
|
24
|
+
source_path: source_path,
|
25
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME),
|
26
|
+
with_contents_dir: contents_dir
|
27
|
+
).call
|
28
|
+
|
29
|
+
doc = dir.join(SUCCESS_DIRNAME).join("README.md").read
|
30
|
+
assert_includes doc, "$ ls"
|
31
|
+
assert_includes doc, "file1.txt"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -23,6 +23,7 @@ class Minitest::Test
|
|
23
23
|
Rundoc::Context::Execution.new(
|
24
24
|
output_dir: output_dir || Pathname("/dev/null"),
|
25
25
|
source_path: source_path || Pathname("/dev/null"),
|
26
|
+
with_contents_dir: nil,
|
26
27
|
screenshots_dirname: screenshots_dirname || Pathname("/dev/null")
|
27
28
|
)
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rundoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Schneeman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -261,9 +261,11 @@ files:
|
|
261
261
|
- test/fixtures/screenshot/rundoc.md
|
262
262
|
- test/fixtures/simple_git/rundoc.md
|
263
263
|
- test/integration/after_build_test.rb
|
264
|
+
- test/integration/failure_test.rb
|
264
265
|
- test/integration/print_test.rb
|
265
266
|
- test/integration/require_test.rb
|
266
267
|
- test/integration/website_test.rb
|
268
|
+
- test/integration/with_contents_flag_test.rb
|
267
269
|
- test/rundoc/cli_argument_parser_test.rb
|
268
270
|
- test/rundoc/code_commands/append_file_test.rb
|
269
271
|
- test/rundoc/code_commands/background_test.rb
|