rundoc 4.1.4 → 6.0.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/.github/workflows/ci.yml +3 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +12 -0
- data/README.md +98 -10
- data/lib/rundoc/cli.rb +18 -2
- data/lib/rundoc/code_command/background/log/clear.rb +12 -2
- data/lib/rundoc/code_command/background/log/read.rb +12 -2
- data/lib/rundoc/code_command/background/process_spawn.rb +3 -1
- data/lib/rundoc/code_command/background/start.rb +25 -6
- data/lib/rundoc/code_command/background/stdin_write.rb +21 -8
- data/lib/rundoc/code_command/background/stop.rb +12 -2
- data/lib/rundoc/code_command/background/wait.rb +15 -3
- data/lib/rundoc/code_command/background.rb +2 -0
- data/lib/rundoc/code_command/bash/cd.rb +12 -18
- data/lib/rundoc/code_command/bash.rb +43 -19
- data/lib/rundoc/code_command/comment.rb +33 -0
- data/lib/rundoc/code_command/deferred.rb +66 -0
- data/lib/rundoc/code_command/empty_binding.rb +18 -0
- data/lib/rundoc/code_command/file_command/append.rb +29 -8
- data/lib/rundoc/code_command/file_command/remove.rb +27 -5
- data/lib/rundoc/code_command/no_such_command.rb +8 -3
- data/lib/rundoc/code_command/pipe.rb +36 -16
- data/lib/rundoc/code_command/pre/erb.rb +28 -18
- data/lib/rundoc/code_command/print/erb.rb +27 -16
- data/lib/rundoc/code_command/print/text.rb +27 -8
- data/lib/rundoc/code_command/raw.rb +17 -5
- data/lib/rundoc/code_command/rundoc/ensure_later.rb +59 -0
- data/lib/rundoc/code_command/rundoc/require.rb +25 -17
- data/lib/rundoc/code_command/rundoc_command.rb +26 -9
- data/lib/rundoc/code_command/website/driver.rb +2 -0
- data/lib/rundoc/code_command/website/navigate.rb +18 -12
- data/lib/rundoc/code_command/website/screenshot.rb +17 -11
- data/lib/rundoc/code_command/website/visit.rb +23 -12
- data/lib/rundoc/code_command/website.rb +2 -0
- data/lib/rundoc/code_command/write.rb +37 -9
- data/lib/rundoc/code_command.rb +6 -48
- data/lib/rundoc/context/after_build.rb +2 -0
- data/lib/rundoc/context/execution.rb +2 -0
- data/lib/rundoc/document.rb +6 -2
- data/lib/rundoc/fenced_code_block.rb +10 -7
- data/lib/rundoc/peg_parser.rb +25 -9
- data/lib/rundoc/version.rb +3 -1
- data/lib/rundoc.rb +89 -17
- data/rundoc.gemspec +3 -0
- data/test/integration/ensure_later_test.rb +335 -0
- data/test/integration/print_test.rb +51 -0
- data/test/rundoc/code_commands/append_file_test.rb +35 -10
- data/test/rundoc/code_commands/background_test.rb +24 -22
- data/test/rundoc/code_commands/bash_test.rb +10 -5
- data/test/rundoc/code_commands/comment_test.rb +116 -0
- data/test/rundoc/code_commands/pipe_test.rb +2 -2
- data/test/rundoc/code_commands/print_test.rb +13 -25
- data/test/rundoc/code_commands/remove_contents_test.rb +8 -3
- data/test/rundoc/code_section_test.rb +28 -21
- data/test/rundoc/peg_parser_test.rb +42 -1
- data/test/test_helper.rb +4 -2
- metadata +23 -6
- data/lib/rundoc/code_command/rundoc/depend_on.rb +0 -13
- data/test/fixtures/depend_on/dependency/rundoc.md +0 -5
- data/test/fixtures/depend_on/main/rundoc.md +0 -10
data/lib/rundoc.rb
CHANGED
|
@@ -5,43 +5,78 @@ require "rundoc/version"
|
|
|
5
5
|
module Rundoc
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
|
+
class UnknownCommand < StandardError; end
|
|
9
|
+
|
|
8
10
|
def code_command_from_keyword(keyword, args)
|
|
9
|
-
|
|
10
|
-
original_args = args
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
args_klass = code_command(keyword.to_sym)
|
|
12
|
+
original_args = args&.dup
|
|
13
|
+
|
|
14
|
+
if args_klass
|
|
15
|
+
runner_klass = user_args_runner[keyword]
|
|
16
|
+
|
|
17
|
+
if args.is_a?(Array) && args.last.is_a?(Hash)
|
|
18
|
+
kwargs = args.pop
|
|
19
|
+
user_args = args_klass.new(*args, **kwargs)
|
|
20
|
+
elsif args.is_a?(Hash)
|
|
21
|
+
user_args = args_klass.new(**args)
|
|
22
|
+
else
|
|
23
|
+
user_args = args_klass.new(*args)
|
|
24
|
+
end
|
|
25
|
+
elsif keyword.start_with?("#")
|
|
26
|
+
args_klass = Rundoc::CodeCommand::CommentArgs
|
|
27
|
+
runner_klass = Rundoc::CodeCommand::CommentRunner
|
|
28
|
+
remainder = keyword.to_s.delete_prefix("#")
|
|
29
|
+
comment_text = [remainder, args].compact.join(" ").strip
|
|
30
|
+
user_args = args_klass.new(comment_text.empty? ? nil : comment_text)
|
|
16
31
|
else
|
|
17
|
-
|
|
32
|
+
runner_klass = Rundoc::CodeCommand::NoSuchCommand
|
|
33
|
+
user_args = nil
|
|
18
34
|
end
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
deferred = CodeCommand::Deferred.new(
|
|
37
|
+
args_instance: user_args,
|
|
38
|
+
runner_klass: runner_klass,
|
|
39
|
+
always_hidden: always_hidden_commands[keyword] || keyword.start_with?("#")
|
|
40
|
+
)
|
|
41
|
+
deferred.original_args = original_args
|
|
42
|
+
deferred.keyword = keyword
|
|
43
|
+
deferred
|
|
23
44
|
rescue ArgumentError => e
|
|
24
45
|
raise ArgumentError, "Wrong method signature for #{keyword} with arguments: #{original_args.inspect}, error:\n #{e.message}"
|
|
25
46
|
end
|
|
26
47
|
|
|
48
|
+
def user_code_runner_klass
|
|
49
|
+
@user_code_runner_klass ||= {}
|
|
50
|
+
end
|
|
51
|
+
|
|
27
52
|
def parser_options
|
|
28
53
|
@parser_options ||= {}
|
|
29
54
|
end
|
|
30
55
|
|
|
31
|
-
def
|
|
32
|
-
@
|
|
56
|
+
def user_args_runner
|
|
57
|
+
@user_args_runner ||= {}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def user_args
|
|
61
|
+
@user_args ||= {}
|
|
33
62
|
end
|
|
34
63
|
|
|
35
64
|
def code_command(keyword)
|
|
36
|
-
|
|
65
|
+
user_args[:"#{keyword}"]
|
|
37
66
|
end
|
|
38
67
|
|
|
39
68
|
def known_commands
|
|
40
|
-
|
|
69
|
+
user_args.keys
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def register_code_command(keyword:, args_klass:, runner_klass:, always_hidden: false)
|
|
73
|
+
user_args[keyword] = args_klass
|
|
74
|
+
user_args_runner[keyword] = runner_klass
|
|
75
|
+
always_hidden_commands[keyword] = always_hidden
|
|
41
76
|
end
|
|
42
77
|
|
|
43
|
-
def
|
|
44
|
-
|
|
78
|
+
def always_hidden_commands
|
|
79
|
+
@always_hidden_commands ||= {}
|
|
45
80
|
end
|
|
46
81
|
|
|
47
82
|
def configure(&block)
|
|
@@ -62,6 +97,43 @@ module Rundoc
|
|
|
62
97
|
yield self
|
|
63
98
|
end
|
|
64
99
|
|
|
100
|
+
def ensure_later_blocks
|
|
101
|
+
@ensure_later_blocks ||= []
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def add_ensure_later(dir:, code:, binding:)
|
|
105
|
+
ensure_later_blocks << {dir: dir, code: code, binding: binding}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def run_ensure_later(io:)
|
|
109
|
+
errors = []
|
|
110
|
+
ensure_later_blocks.each do |block|
|
|
111
|
+
io.puts "Running ensure_later block in #{block[:dir]}:\n#{block[:code]}"
|
|
112
|
+
Dir.chdir(block[:dir]) do
|
|
113
|
+
capture_stdout_stderr(io) do
|
|
114
|
+
eval(block[:code], block[:binding]) # rubocop:disable Security/Eval
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
rescue => e
|
|
118
|
+
io.puts "ensure_later block failed in #{block[:dir]}: #{e.message}"
|
|
119
|
+
io.puts e.backtrace.join("\n")
|
|
120
|
+
errors << e
|
|
121
|
+
end
|
|
122
|
+
ensure_later_blocks.clear
|
|
123
|
+
errors
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def capture_stdout_stderr(io)
|
|
127
|
+
old_stdout = $stdout
|
|
128
|
+
old_stderr = $stderr
|
|
129
|
+
$stdout = io
|
|
130
|
+
$stderr = io
|
|
131
|
+
yield
|
|
132
|
+
ensure
|
|
133
|
+
$stdout = old_stdout
|
|
134
|
+
$stderr = old_stderr
|
|
135
|
+
end
|
|
136
|
+
|
|
65
137
|
def filter_sensitive(sensitive)
|
|
66
138
|
raise "Expecting #{sensitive} to be a hash" unless sensitive.is_a?(Hash)
|
|
67
139
|
@sensitive ||= {}
|
data/rundoc.gemspec
CHANGED
|
@@ -16,6 +16,8 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
17
17
|
gem.require_paths = ["lib"]
|
|
18
18
|
|
|
19
|
+
gem.required_ruby_version = ">= 3.2"
|
|
20
|
+
|
|
19
21
|
gem.add_dependency "thor"
|
|
20
22
|
gem.add_dependency "parslet", "~> 2"
|
|
21
23
|
gem.add_dependency "capybara", "~> 3"
|
|
@@ -24,6 +26,7 @@ Gem::Specification.new do |gem|
|
|
|
24
26
|
|
|
25
27
|
gem.add_dependency "aws-sdk-s3", "~> 1"
|
|
26
28
|
gem.add_dependency "dotenv"
|
|
29
|
+
gem.add_dependency "cgi", ">= 0.3.6"
|
|
27
30
|
|
|
28
31
|
gem.add_development_dependency "rake"
|
|
29
32
|
gem.add_development_dependency "mocha"
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class IntegrationEnsureLaterTest < Minitest::Test
|
|
6
|
+
def test_runs_on_success
|
|
7
|
+
Dir.mktmpdir do |dir|
|
|
8
|
+
Dir.chdir(dir) do
|
|
9
|
+
dir = Pathname(dir)
|
|
10
|
+
marker = dir.join("ensure_ran.txt")
|
|
11
|
+
|
|
12
|
+
source_path = dir.join("RUNDOC.md")
|
|
13
|
+
source_path.write <<~EOF
|
|
14
|
+
```
|
|
15
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
16
|
+
File.write("#{marker}", "yes")
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
:::>> $ echo "hello"
|
|
21
|
+
```
|
|
22
|
+
EOF
|
|
23
|
+
|
|
24
|
+
Rundoc::CLI.new(
|
|
25
|
+
io: StringIO.new,
|
|
26
|
+
source_path: source_path,
|
|
27
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
28
|
+
).call
|
|
29
|
+
|
|
30
|
+
assert marker.exist?, "ensure_later block should have run on success"
|
|
31
|
+
assert_equal "yes", marker.read
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_runs_on_failure
|
|
37
|
+
Dir.mktmpdir do |dir|
|
|
38
|
+
Dir.chdir(dir) do
|
|
39
|
+
dir = Pathname(dir)
|
|
40
|
+
marker = dir.join("ensure_ran.txt")
|
|
41
|
+
|
|
42
|
+
source_path = dir.join("RUNDOC.md")
|
|
43
|
+
source_path.write <<~EOF
|
|
44
|
+
```
|
|
45
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
46
|
+
File.write("#{marker}", "cleaned")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
:::>> $ exit 1
|
|
51
|
+
```
|
|
52
|
+
EOF
|
|
53
|
+
|
|
54
|
+
assert_raises do
|
|
55
|
+
Rundoc::CLI.new(
|
|
56
|
+
io: StringIO.new,
|
|
57
|
+
source_path: source_path,
|
|
58
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME),
|
|
59
|
+
on_failure_dir: dir.join(FAILURE_DIRNAME)
|
|
60
|
+
).call
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
assert marker.exist?, "ensure_later block should have run on failure"
|
|
64
|
+
assert_equal "cleaned", marker.read
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_multiple_blocks_run_in_order
|
|
70
|
+
Dir.mktmpdir do |dir|
|
|
71
|
+
Dir.chdir(dir) do
|
|
72
|
+
dir = Pathname(dir)
|
|
73
|
+
marker = dir.join("order.txt")
|
|
74
|
+
|
|
75
|
+
source_path = dir.join("RUNDOC.md")
|
|
76
|
+
source_path.write <<~EOF
|
|
77
|
+
```
|
|
78
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
79
|
+
File.write("#{marker}", "first")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
84
|
+
File.write("#{marker}", File.read("#{marker}") + ",second")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
:::>> $ echo "hello"
|
|
89
|
+
```
|
|
90
|
+
EOF
|
|
91
|
+
|
|
92
|
+
Rundoc::CLI.new(
|
|
93
|
+
io: StringIO.new,
|
|
94
|
+
source_path: source_path,
|
|
95
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
96
|
+
).call
|
|
97
|
+
|
|
98
|
+
assert_equal "first,second", marker.read
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_one_failure_does_not_stop_others
|
|
104
|
+
Dir.mktmpdir do |dir|
|
|
105
|
+
Dir.chdir(dir) do
|
|
106
|
+
dir = Pathname(dir)
|
|
107
|
+
marker = dir.join("second_ran.txt")
|
|
108
|
+
|
|
109
|
+
source_path = dir.join("RUNDOC.md")
|
|
110
|
+
source_path.write <<~EOF
|
|
111
|
+
```
|
|
112
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
113
|
+
raise "intentional failure"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
118
|
+
File.write("#{marker}", "yes")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
:::>> $ echo "hello"
|
|
123
|
+
```
|
|
124
|
+
EOF
|
|
125
|
+
|
|
126
|
+
error = assert_raises(RuntimeError) do
|
|
127
|
+
Rundoc::CLI.new(
|
|
128
|
+
io: StringIO.new,
|
|
129
|
+
source_path: source_path,
|
|
130
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
131
|
+
).call
|
|
132
|
+
end
|
|
133
|
+
assert_match(/intentional failure/, error.message)
|
|
134
|
+
|
|
135
|
+
assert marker.exist?, "second ensure_later should still run after first fails"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_success_plus_ensure_failure_is_overall_failure
|
|
141
|
+
Dir.mktmpdir do |dir|
|
|
142
|
+
Dir.chdir(dir) do
|
|
143
|
+
dir = Pathname(dir)
|
|
144
|
+
|
|
145
|
+
source_path = dir.join("RUNDOC.md")
|
|
146
|
+
source_path.write <<~EOF
|
|
147
|
+
```
|
|
148
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
149
|
+
raise "cleanup failed"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
:::>> $ echo "hello"
|
|
154
|
+
```
|
|
155
|
+
EOF
|
|
156
|
+
|
|
157
|
+
error = assert_raises(RuntimeError) do
|
|
158
|
+
Rundoc::CLI.new(
|
|
159
|
+
io: StringIO.new,
|
|
160
|
+
source_path: source_path,
|
|
161
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
162
|
+
).call
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
assert_match(/cleanup failed/, error.message)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_dir_rundoc_root
|
|
171
|
+
Dir.mktmpdir do |dir|
|
|
172
|
+
Dir.chdir(dir) do
|
|
173
|
+
dir = Pathname(dir)
|
|
174
|
+
marker = dir.join("root_marker.txt")
|
|
175
|
+
|
|
176
|
+
source_path = dir.join("RUNDOC.md")
|
|
177
|
+
source_path.write <<~EOF
|
|
178
|
+
```
|
|
179
|
+
:::>> $ mkdir subdir
|
|
180
|
+
:::>> $ cd subdir
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
:::-- rundoc.ensure_later(dir: :rundoc_root)
|
|
185
|
+
File.write("#{marker}", Dir.pwd)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
:::>> $ echo "hello"
|
|
190
|
+
```
|
|
191
|
+
EOF
|
|
192
|
+
|
|
193
|
+
cli = Rundoc::CLI.new(
|
|
194
|
+
io: StringIO.new,
|
|
195
|
+
source_path: source_path,
|
|
196
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
197
|
+
)
|
|
198
|
+
output_dir = cli.execution_context.output_dir.realpath.to_s
|
|
199
|
+
|
|
200
|
+
cli.call
|
|
201
|
+
|
|
202
|
+
assert marker.exist?, "ensure_later with dir: :rundoc_root should run"
|
|
203
|
+
assert_equal output_dir, marker.read
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def test_output_not_in_document
|
|
209
|
+
Dir.mktmpdir do |dir|
|
|
210
|
+
Dir.chdir(dir) do
|
|
211
|
+
dir = Pathname(dir)
|
|
212
|
+
|
|
213
|
+
source_path = dir.join("RUNDOC.md")
|
|
214
|
+
source_path.write <<~EOF
|
|
215
|
+
```
|
|
216
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
217
|
+
puts "THIS SHOULD NOT APPEAR"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
:::>> $ echo "visible"
|
|
222
|
+
```
|
|
223
|
+
EOF
|
|
224
|
+
|
|
225
|
+
Rundoc::CLI.new(
|
|
226
|
+
io: StringIO.new,
|
|
227
|
+
source_path: source_path,
|
|
228
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
229
|
+
).call
|
|
230
|
+
|
|
231
|
+
readme = dir.join(SUCCESS_DIRNAME).join("README.md").read
|
|
232
|
+
refute_match(/THIS SHOULD NOT APPEAR/, readme)
|
|
233
|
+
assert_match(/visible/, readme)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_invalid_dir_raises
|
|
239
|
+
Dir.mktmpdir do |dir|
|
|
240
|
+
Dir.chdir(dir) do
|
|
241
|
+
dir = Pathname(dir)
|
|
242
|
+
|
|
243
|
+
source_path = dir.join("RUNDOC.md")
|
|
244
|
+
source_path.write <<~EOF
|
|
245
|
+
```
|
|
246
|
+
:::-- rundoc.ensure_later(dir: :invalid)
|
|
247
|
+
puts "should not run"
|
|
248
|
+
```
|
|
249
|
+
EOF
|
|
250
|
+
|
|
251
|
+
assert_raises(ArgumentError) do
|
|
252
|
+
Rundoc::CLI.new(
|
|
253
|
+
io: StringIO.new,
|
|
254
|
+
source_path: source_path,
|
|
255
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
256
|
+
).call
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def test_shared_binding_with_rundoc
|
|
263
|
+
Dir.mktmpdir do |dir|
|
|
264
|
+
Dir.chdir(dir) do
|
|
265
|
+
dir = Pathname(dir)
|
|
266
|
+
marker = dir.join("binding_test.txt")
|
|
267
|
+
|
|
268
|
+
source_path = dir.join("RUNDOC.md")
|
|
269
|
+
source_path.write <<~EOF
|
|
270
|
+
```
|
|
271
|
+
:::-- rundoc
|
|
272
|
+
def my_helper
|
|
273
|
+
"from_rundoc"
|
|
274
|
+
end
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
279
|
+
File.write("#{marker}", my_helper)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
:::>> $ echo "hello"
|
|
284
|
+
```
|
|
285
|
+
EOF
|
|
286
|
+
|
|
287
|
+
Rundoc::CLI.new(
|
|
288
|
+
io: StringIO.new,
|
|
289
|
+
source_path: source_path,
|
|
290
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME)
|
|
291
|
+
).call
|
|
292
|
+
|
|
293
|
+
assert_equal "from_rundoc", marker.read
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def test_runs_on_failure_from_subdirectory
|
|
299
|
+
Dir.mktmpdir do |dir|
|
|
300
|
+
Dir.chdir(dir) do
|
|
301
|
+
dir = Pathname(dir)
|
|
302
|
+
marker = dir.join("ensure_ran.txt")
|
|
303
|
+
|
|
304
|
+
source_path = dir.join("RUNDOC.md")
|
|
305
|
+
source_path.write <<~EOF
|
|
306
|
+
```
|
|
307
|
+
:::>> $ mkdir myapp
|
|
308
|
+
:::>> $ cd myapp
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
:::-- rundoc.ensure_later(dir: :cwd)
|
|
313
|
+
File.write("#{marker}", "cleaned")
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
:::>> $ exit 1
|
|
318
|
+
```
|
|
319
|
+
EOF
|
|
320
|
+
|
|
321
|
+
assert_raises do
|
|
322
|
+
Rundoc::CLI.new(
|
|
323
|
+
io: StringIO.new,
|
|
324
|
+
source_path: source_path,
|
|
325
|
+
on_success_dir: dir.join(SUCCESS_DIRNAME),
|
|
326
|
+
on_failure_dir: dir.join(FAILURE_DIRNAME)
|
|
327
|
+
).call
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
assert marker.exist?, "ensure_later from subdirectory should run even on failure"
|
|
331
|
+
assert_equal "cleaned", marker.read
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
end
|
|
@@ -50,6 +50,57 @@ class IntegrationPrintTest < Minitest::Test
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
def test_rundoc_configure_defines_variable_accessible_from_erb
|
|
54
|
+
key = SecureRandom.hex
|
|
55
|
+
contents = <<~RUBY
|
|
56
|
+
```
|
|
57
|
+
:::-- rundoc.configure
|
|
58
|
+
@shared_value = "#{key}"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
:::-> print.erb
|
|
63
|
+
<%= @shared_value %>
|
|
64
|
+
```
|
|
65
|
+
RUBY
|
|
66
|
+
|
|
67
|
+
Dir.mktmpdir do |dir|
|
|
68
|
+
Dir.chdir(dir) do
|
|
69
|
+
parsed = parse_contents(contents)
|
|
70
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
|
71
|
+
assert_includes actual, key
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_erb_defines_variable_accessible_from_rundoc_configure
|
|
77
|
+
key = SecureRandom.hex
|
|
78
|
+
contents = <<~RUBY
|
|
79
|
+
```
|
|
80
|
+
:::-> print.erb
|
|
81
|
+
<% @from_erb = "#{key}" %>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
:::-- rundoc.configure
|
|
86
|
+
@roundtripped = @from_erb + "_via_configure"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
:::-> print.erb
|
|
91
|
+
<%= @roundtripped %>
|
|
92
|
+
```
|
|
93
|
+
RUBY
|
|
94
|
+
|
|
95
|
+
Dir.mktmpdir do |dir|
|
|
96
|
+
Dir.chdir(dir) do
|
|
97
|
+
parsed = parse_contents(contents)
|
|
98
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
|
99
|
+
assert_includes actual, "#{key}_via_configure"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
53
104
|
def test_erb_in_block
|
|
54
105
|
contents = <<~RUBY
|
|
55
106
|
```
|
|
@@ -7,8 +7,13 @@ class AppendFileTest < Minitest::Test
|
|
|
7
7
|
file = "foo.rb"
|
|
8
8
|
`echo 'foo' >> #{file}`
|
|
9
9
|
|
|
10
|
-
cc = Rundoc::CodeCommand::FileCommand::
|
|
11
|
-
|
|
10
|
+
cc = Rundoc::CodeCommand::FileCommand::AppendRunner.new(
|
|
11
|
+
render_command: false,
|
|
12
|
+
render_result: false,
|
|
13
|
+
io: StringIO.new,
|
|
14
|
+
user_args: Rundoc::CodeCommand::FileCommand::AppendArgs.new(file),
|
|
15
|
+
contents: "bar"
|
|
16
|
+
)
|
|
12
17
|
cc.call
|
|
13
18
|
|
|
14
19
|
result = File.read(file)
|
|
@@ -16,8 +21,13 @@ class AppendFileTest < Minitest::Test
|
|
|
16
21
|
assert_match(/foo/, result)
|
|
17
22
|
assert_match(/bar/, result)
|
|
18
23
|
|
|
19
|
-
cc = Rundoc::CodeCommand::FileCommand::
|
|
20
|
-
|
|
24
|
+
cc = Rundoc::CodeCommand::FileCommand::AppendRunner.new(
|
|
25
|
+
render_command: false,
|
|
26
|
+
render_result: false,
|
|
27
|
+
io: StringIO.new,
|
|
28
|
+
user_args: Rundoc::CodeCommand::FileCommand::AppendArgs.new(file),
|
|
29
|
+
contents: "baz"
|
|
30
|
+
)
|
|
21
31
|
cc.call
|
|
22
32
|
|
|
23
33
|
actual = File.read(file)
|
|
@@ -39,8 +49,13 @@ class AppendFileTest < Minitest::Test
|
|
|
39
49
|
line = 2
|
|
40
50
|
`echo '#{contents}' >> #{file}`
|
|
41
51
|
|
|
42
|
-
cc = Rundoc::CodeCommand::FileCommand::
|
|
43
|
-
|
|
52
|
+
cc = Rundoc::CodeCommand::FileCommand::AppendRunner.new(
|
|
53
|
+
render_command: false,
|
|
54
|
+
render_result: false,
|
|
55
|
+
io: StringIO.new,
|
|
56
|
+
user_args: Rundoc::CodeCommand::FileCommand::AppendArgs.new("#{file}##{line}"),
|
|
57
|
+
contents: "gem 'pg'"
|
|
58
|
+
)
|
|
44
59
|
cc.call
|
|
45
60
|
|
|
46
61
|
expected = "source https://rubygems.org\ngem 'pg'\ngem rails, 4.0.0\n\n"
|
|
@@ -54,8 +69,13 @@ class AppendFileTest < Minitest::Test
|
|
|
54
69
|
Dir.chdir(dir) do
|
|
55
70
|
filename = "file-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}.txt"
|
|
56
71
|
FileUtils.touch(filename)
|
|
57
|
-
cc = Rundoc::CodeCommand::FileCommand::
|
|
58
|
-
|
|
72
|
+
cc = Rundoc::CodeCommand::FileCommand::AppendRunner.new(
|
|
73
|
+
render_command: false,
|
|
74
|
+
render_result: false,
|
|
75
|
+
io: StringIO.new,
|
|
76
|
+
user_args: Rundoc::CodeCommand::FileCommand::AppendArgs.new("file-*.txt"),
|
|
77
|
+
contents: "some text"
|
|
78
|
+
)
|
|
59
79
|
cc.call
|
|
60
80
|
|
|
61
81
|
assert_equal "\nsome text\n", File.read(filename)
|
|
@@ -69,8 +89,13 @@ class AppendFileTest < Minitest::Test
|
|
|
69
89
|
FileUtils.touch("file-1234.txt")
|
|
70
90
|
FileUtils.touch("file-5678.txt")
|
|
71
91
|
assert_raises do
|
|
72
|
-
cc = Rundoc::CodeCommand::FileCommand::
|
|
73
|
-
|
|
92
|
+
cc = Rundoc::CodeCommand::FileCommand::AppendRunner.new(
|
|
93
|
+
render_command: false,
|
|
94
|
+
render_result: false,
|
|
95
|
+
io: StringIO.new,
|
|
96
|
+
user_args: Rundoc::CodeCommand::FileCommand::AppendArgs.new("file-*.txt"),
|
|
97
|
+
contents: "some text"
|
|
98
|
+
)
|
|
74
99
|
cc.call
|
|
75
100
|
end
|
|
76
101
|
end
|