rundoc 2.0.0 → 3.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -7
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +25 -0
  5. data/README.md +35 -48
  6. data/Rakefile +5 -1
  7. data/bin/rundoc +4 -17
  8. data/lib/rundoc/cli.rb +207 -49
  9. data/lib/rundoc/cli_argument_parser.rb +140 -0
  10. data/lib/rundoc/code_command/bash.rb +8 -1
  11. data/lib/rundoc/code_command/rundoc/depend_on.rb +1 -24
  12. data/lib/rundoc/code_command/rundoc/require.rb +13 -7
  13. data/lib/rundoc/code_command/website/driver.rb +7 -5
  14. data/lib/rundoc/code_command/website/navigate.rb +1 -1
  15. data/lib/rundoc/code_command/website/screenshot.rb +7 -2
  16. data/lib/rundoc/code_command/website/visit.rb +1 -1
  17. data/lib/rundoc/code_section.rb +4 -6
  18. data/lib/rundoc/context/after_build.rb +14 -0
  19. data/lib/rundoc/context/execution.rb +22 -0
  20. data/lib/rundoc/parser.rb +9 -5
  21. data/lib/rundoc/version.rb +1 -1
  22. data/lib/rundoc.rb +13 -5
  23. data/rundoc.gemspec +1 -0
  24. data/test/fixtures/cnb/ruby/download.md +22 -0
  25. data/test/fixtures/cnb/ruby/image_structure.md +34 -0
  26. data/test/fixtures/cnb/ruby/intro.md +5 -0
  27. data/test/fixtures/cnb/ruby/multiple_langs.md +43 -0
  28. data/test/fixtures/cnb/ruby/rundoc.md +48 -0
  29. data/test/fixtures/cnb/ruby/what_is_pack_build.md +18 -0
  30. data/test/fixtures/cnb/shared/call_to_action.md +11 -0
  31. data/test/fixtures/cnb/shared/configure_builder.md +23 -0
  32. data/test/fixtures/cnb/shared/install_pack.md +14 -0
  33. data/test/fixtures/cnb/shared/pack_build.md +20 -0
  34. data/test/fixtures/cnb/shared/procfile.md +13 -0
  35. data/test/fixtures/cnb/shared/use_the_image.md +52 -0
  36. data/test/fixtures/cnb/shared/what_is_a_builder.md +18 -0
  37. data/test/fixtures/rails_4/rundoc.md +5 -7
  38. data/test/fixtures/rails_5/rundoc.md +1 -1
  39. data/test/fixtures/rails_6/rundoc.md +2 -2
  40. data/test/fixtures/rails_7/rundoc.md +2 -3
  41. data/test/fixtures/simple_git/rundoc.md +13 -0
  42. data/test/integration/after_build_test.rb +62 -0
  43. data/test/integration/print_test.rb +9 -9
  44. data/test/integration/require_test.rb +63 -0
  45. data/test/integration/website_test.rb +35 -0
  46. data/test/rundoc/cli_argument_parser_test.rb +118 -0
  47. data/test/rundoc/code_section_test.rb +40 -8
  48. data/test/rundoc/parser_test.rb +3 -3
  49. data/test/rundoc/peg_parser_test.rb +6 -6
  50. data/test/rundoc/regex_test.rb +22 -0
  51. data/test/system/exe_cli_test.rb +231 -0
  52. data/test/test_helper.rb +74 -1
  53. metadata +40 -3
@@ -16,7 +16,7 @@ class ParserTest < Minitest::Test
16
16
  Dir.mktmpdir do |dir|
17
17
  Dir.chdir(dir) do
18
18
  expected = "sup\n\n```\n$ mkdir foo\n$ ls\nfoo\n```\n\nyo\n"
19
- parsed = Rundoc::Parser.new(contents)
19
+ parsed = parse_contents(contents)
20
20
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
21
21
  assert_equal expected, actual
22
22
  end
@@ -38,7 +38,7 @@ class ParserTest < Minitest::Test
38
38
  Dir.mktmpdir do |dir|
39
39
  Dir.chdir(dir) do
40
40
  expected = "sup\n\nIn file `foo/code.rb` write:\n\n```\na = 1 + 1\nb = a * 2\n```\nyo\n"
41
- parsed = Rundoc::Parser.new(contents)
41
+ parsed = parse_contents(contents)
42
42
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
43
43
  assert_equal expected, actual
44
44
  end
@@ -56,7 +56,7 @@ class ParserTest < Minitest::Test
56
56
  Dir.mktmpdir do |dir|
57
57
  Dir.chdir(dir) do
58
58
  expected = "\nIn file `foo/newb.rb` write:\n\n```\nputs 'hello world'\n$ cat foo/newb.rb\nputs 'hello world'\n```\n"
59
- parsed = Rundoc::Parser.new(contents)
59
+ parsed = parse_contents(contents)
60
60
  actual = parsed.to_md.gsub(Rundoc::CodeSection::AUTOGEN_WARNING, "")
61
61
  assert_equal expected, actual
62
62
  end
@@ -270,36 +270,36 @@ class PegParserTest < Minitest::Test
270
270
 
271
271
  def test_rundoc_sub_commands_no_quotes
272
272
  input = +""
273
- input << %(:::-- rundoc.depend_on ../foo/bar.md\n)
273
+ input << %(:::-- rundoc.require ../foo/bar.md\n)
274
274
 
275
275
  parser = Rundoc::PegParser.new.command_with_stdin
276
276
  tree = parser.parse_with_debug(input)
277
277
 
278
278
  actual = @transformer.apply(tree)
279
- assert_equal :"rundoc.depend_on", actual.keyword
279
+ assert_equal :"rundoc.require", actual.keyword
280
280
  end
281
281
 
282
282
  def test_seattle_style_method_call
283
283
  input = +""
284
- input << %(rundoc.depend_on '../foo/bar.md')
284
+ input << %(rundoc.require '../foo/bar.md')
285
285
  parser = Rundoc::PegParser.new.method_call
286
286
  tree = parser.parse_with_debug(input)
287
287
 
288
288
  actual = @transformer.apply(tree)
289
289
 
290
- assert_equal :"rundoc.depend_on", actual.keyword
290
+ assert_equal :"rundoc.require", actual.keyword
291
291
  end
292
292
 
293
293
  def test_rundoc_seattle_sub_command
294
294
  input = +""
295
- input << %(:::>> rundoc.depend_on '../foo/bar.md'\n)
295
+ input << %(:::>> rundoc.require '../foo/bar.md'\n)
296
296
 
297
297
  parser = Rundoc::PegParser.new.command
298
298
  tree = parser.parse_with_debug(input)
299
299
 
300
300
  actual = @transformer.apply(tree)
301
301
 
302
- assert_equal :"rundoc.depend_on", actual.keyword
302
+ assert_equal :"rundoc.require", actual.keyword
303
303
  end
304
304
 
305
305
  def test_positional_args
@@ -190,4 +190,26 @@ class RegexTest < Minitest::Test
190
190
 
191
191
  assert_equal contents.strip, match.to_s.strip
192
192
  end
193
+
194
+ def test_codeblock_optional_newline_regex
195
+ code_block_with_newline = <<~MD
196
+ hi
197
+ ```
198
+ :::>> $ echo "hello"
199
+ ```
200
+ MD
201
+ code_block_without_newline = code_block_with_newline.strip
202
+
203
+ expected = <<~MD.strip
204
+ ```
205
+ :::>> $ echo "hello"
206
+ ```
207
+ MD
208
+ regex = Rundoc::Parser::CODEBLOCK_REGEX
209
+ match = code_block_with_newline.match(regex)
210
+ assert_equal expected, match.to_s.strip
211
+
212
+ match = code_block_without_newline.match(regex)
213
+ assert_equal expected, match.to_s.strip
214
+ end
193
215
  end
@@ -0,0 +1,231 @@
1
+ require "test_helper"
2
+
3
+ class SystemsCliTest < Minitest::Test
4
+ def exe_path
5
+ root_dir.join("bin").join("rundoc")
6
+ end
7
+
8
+ def test_git
9
+ Dir.mktmpdir do |dir|
10
+ dir = Pathname(dir)
11
+ contents = fixture_path("simple_git").join("rundoc.md").read
12
+
13
+ dir.join("rundoc.md").write(contents)
14
+ run!("#{exe_path} #{dir.join("rundoc.md")}")
15
+
16
+ output_dir = dir.join(SUCCESS_DIRNAME)
17
+ .tap { |p| assert p.exist? }
18
+
19
+ assert output_dir.join(".git").exist?
20
+
21
+ readme = output_dir
22
+ .join("README.md")
23
+ .tap { |p| assert p.exist? }
24
+
25
+ assert readme.exist?
26
+
27
+ actual = strip_autogen_warning(readme.read)
28
+ assert actual.include?("$ echo \"hello world\"")
29
+ end
30
+ end
31
+
32
+ def test_help
33
+ output = run!("#{exe_path} --help")
34
+ assert output.include?("Usage:")
35
+ end
36
+
37
+ def test_force_fail_dir_protection
38
+ Dir.mktmpdir do |dir|
39
+ dir = Pathname(dir)
40
+ rundoc = dir.join("RUNDOC.md")
41
+ rundoc.write "Done"
42
+
43
+ not_empty = dir.join(FAILURE_DIRNAME).tap(&:mkpath).join("not_empty.txt")
44
+ not_empty.write("Not empty")
45
+
46
+ run!("#{exe_path} #{rundoc}", raise_on_nonzero_exit: false)
47
+ assert !$?.success?
48
+
49
+ assert not_empty.exist?
50
+
51
+ run!("#{exe_path} #{rundoc} --force", raise_on_nonzero_exit: false)
52
+ assert $?.success?
53
+ assert !not_empty.exist?
54
+ end
55
+ end
56
+
57
+ def test_force_success_dir_protection
58
+ Dir.mktmpdir do |dir|
59
+ dir = Pathname(dir)
60
+
61
+ rundoc = dir.join("RUNDOC.md")
62
+ rundoc.write "Done"
63
+
64
+ not_empty = dir.join(SUCCESS_DIRNAME).tap(&:mkpath).join("not_empty.txt")
65
+ not_empty.write("Not empty")
66
+
67
+ run!("#{exe_path} #{rundoc}", raise_on_nonzero_exit: false)
68
+ assert !$?.success?
69
+
70
+ assert not_empty.exist?
71
+
72
+ run!("#{exe_path} #{rundoc} --force", raise_on_nonzero_exit: false)
73
+ assert $?.success?
74
+ assert !not_empty.exist?
75
+ end
76
+ end
77
+
78
+ def test_dotenv
79
+ Dir.mktmpdir do |dir|
80
+ key = SecureRandom.hex
81
+ dir = Pathname(dir)
82
+ dotenv = dir.join("another").join("directory").tap(&:mkpath).join(".env")
83
+
84
+ dotenv.write <<~EOF
85
+ FLORP="#{key}"
86
+ EOF
87
+
88
+ rundoc = dir.join("RUNDOC.md")
89
+ rundoc.write <<~EOF
90
+ ```
91
+ :::>> $ echo $FLORP
92
+ ```
93
+ EOF
94
+
95
+ run!("#{exe_path} #{rundoc} --dotenv-path #{dotenv}")
96
+
97
+ readme = dir.join(SUCCESS_DIRNAME)
98
+ .tap { |p| assert p.exist? }
99
+ .join("README.md")
100
+ .tap { |p| assert p.exist? }
101
+
102
+ actual = strip_autogen_warning(readme.read)
103
+ expected = <<~EOF
104
+ ```
105
+ $ echo $FLORP
106
+ #{key}
107
+ ```
108
+ EOF
109
+ assert_equal expected.strip, actual.strip
110
+ end
111
+ end
112
+
113
+ def test_screenshots_dir
114
+ Dir.mktmpdir do |dir|
115
+ dir = Pathname(dir)
116
+ rundoc = dir.join("RUNDOC.md")
117
+ screenshots_dirname = "lol_screenshots"
118
+ rundoc.write <<~EOF
119
+ ```
120
+ :::>> website.visit(name: "example", url: "http://example.com")
121
+ :::>> website.screenshot(name: "example")
122
+ ```
123
+ EOF
124
+
125
+ run!("#{exe_path} #{rundoc} --screenshots-dir #{screenshots_dirname}")
126
+
127
+ dir.join(SUCCESS_DIRNAME)
128
+ .tap { |p| assert p.exist? }
129
+ .join(screenshots_dirname)
130
+ .tap { |p| assert p.exist? }
131
+
132
+ readme = dir.join(SUCCESS_DIRNAME).join("README.md").read
133
+ actual = strip_autogen_warning(readme)
134
+
135
+ expected = "![Screenshot of http://example.com/](#{screenshots_dirname}/screenshot_1.png)"
136
+ assert_equal expected, actual.strip
137
+ end
138
+ end
139
+
140
+ def test_output_filename
141
+ Dir.mktmpdir do |dir|
142
+ dir = Pathname(dir)
143
+ rundoc = dir.join("RUNDOC.md")
144
+ failure_dir = dir.join("lol")
145
+ rundoc.write "Done"
146
+
147
+ assert !failure_dir.exist?
148
+
149
+ run!("#{exe_path} #{rundoc} --output-filename tutorial.md")
150
+
151
+ tutorial_md = dir.join(SUCCESS_DIRNAME)
152
+ .tap { |p| assert p.exist? }
153
+ .join("tutorial.md")
154
+ .tap { |p| assert p.exist? }
155
+
156
+ actual = strip_autogen_warning(tutorial_md.read)
157
+ expected = "Done"
158
+
159
+ assert_equal expected.strip, actual.strip
160
+ end
161
+ end
162
+
163
+ def test_on_failure_dir
164
+ Dir.mktmpdir do |dir|
165
+ dir = Pathname(dir)
166
+ rundoc = dir.join("RUNDOC.md")
167
+ failure_dir = dir.join("lol")
168
+ rundoc.write <<~EOF
169
+ ```
170
+ :::>> $ touch lol.txt
171
+ :::>> $ echo "hello world" && exit 1
172
+ ```
173
+ EOF
174
+
175
+ assert !failure_dir.exist?
176
+
177
+ run!("#{exe_path} #{rundoc} --on-failure-dir #{failure_dir}", raise_on_nonzero_exit: false)
178
+ assert !$?.success?
179
+
180
+ assert failure_dir.exist?
181
+ assert !Dir.exist?(dir.join(FAILURE_DIRNAME))
182
+ assert failure_dir.join("lol.txt").exist?
183
+ end
184
+ end
185
+
186
+ def test_on_success_dir
187
+ Dir.mktmpdir do |dir|
188
+ dir = Pathname(dir)
189
+ rundoc = dir.join("RUNDOC.md")
190
+ success_dir = dir.join("lol")
191
+ rundoc.write "Done"
192
+
193
+ assert !success_dir.exist?
194
+ run!("#{exe_path} #{rundoc} --on-success-dir #{success_dir}")
195
+
196
+ assert success_dir.exist?
197
+ assert !Dir.exist?(dir.join(SUCCESS_DIRNAME))
198
+
199
+ readme = success_dir.join("README.md")
200
+ actual = strip_autogen_warning(readme.read)
201
+ expected = "Done"
202
+
203
+ assert_equal expected.strip, actual.strip
204
+ end
205
+ end
206
+
207
+ def test_simple_file
208
+ Dir.mktmpdir do |dir|
209
+ dir = Pathname(dir)
210
+ rundoc = dir.join("RUNDOC.md")
211
+ rundoc.write <<~EOF
212
+ ```
213
+ :::>> $ echo "hello world"
214
+ ```
215
+ EOF
216
+
217
+ run!("#{exe_path} #{rundoc}")
218
+
219
+ readme = dir.join(SUCCESS_DIRNAME).join("README.md")
220
+ actual = strip_autogen_warning(readme.read)
221
+ expected = <<~EOF
222
+ ```
223
+ $ echo "hello world"
224
+ hello world
225
+ ```
226
+ EOF
227
+
228
+ assert_equal expected.strip, actual.strip
229
+ end
230
+ end
231
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "simplecov"
2
+ SimpleCov.start
3
+
1
4
  require "bundler"
2
5
 
3
6
  Bundler.require
@@ -7,5 +10,75 @@ require "minitest/autorun"
7
10
  require "mocha/minitest"
8
11
  require "tmpdir"
9
12
 
10
- def assert_tests_run
13
+ class Minitest::Test
14
+ SUCCESS_DIRNAME = Rundoc::CLI::DEFAULTS::ON_SUCCESS_DIR
15
+ FAILURE_DIRNAME = Rundoc::CLI::DEFAULTS::ON_FAILURE_DIR
16
+
17
+ def default_context(
18
+ output_dir: nil,
19
+ source_path: nil,
20
+ screenshots_dirname: nil
21
+ )
22
+
23
+ Rundoc::Context::Execution.new(
24
+ output_dir: output_dir || Pathname("/dev/null"),
25
+ source_path: source_path || Pathname("/dev/null"),
26
+ screenshots_dirname: screenshots_dirname || Pathname("/dev/null")
27
+ )
28
+ end
29
+
30
+ def parse_contents(
31
+ contents,
32
+ output_dir: nil,
33
+ source_path: nil,
34
+ screenshots_dirname: nil
35
+ )
36
+ context = default_context(
37
+ output_dir: output_dir,
38
+ source_path: source_path,
39
+ screenshots_dirname: screenshots_dirname
40
+ )
41
+ Rundoc::Parser.new(
42
+ contents,
43
+ context: context
44
+ )
45
+ end
46
+
47
+ def root_dir
48
+ Pathname(__dir__).join("..").expand_path
49
+ end
50
+
51
+ def fixture_path(dir = "")
52
+ root_dir.join("test").join("fixtures").join(dir)
53
+ end
54
+
55
+ def run!(cmd, raise_on_nonzero_exit: true)
56
+ out = `#{cmd} 2>&1`
57
+ raise "Command: #{cmd} failed: #{out}" if !$?.success? && raise_on_nonzero_exit
58
+ out
59
+ end
60
+
61
+ def strip_autogen_warning(string)
62
+ string.gsub!(Rundoc::CodeSection::AUTOGEN_WARNING, "")
63
+ string.gsub!(/<!-- STOP.*STOP -->/m, "")
64
+ string
65
+ end
66
+
67
+ class FakeExit
68
+ def initialize
69
+ @called = false
70
+ @value = nil
71
+ end
72
+
73
+ def exit(value = nil)
74
+ @called = true
75
+ @value = value
76
+ end
77
+
78
+ def called?
79
+ @called
80
+ end
81
+
82
+ attr_reader :value
83
+ end
11
84
  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: 2.0.0
4
+ version: 3.0.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-05-09 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: RunDOC turns docs to runable code
168
182
  email:
169
183
  - richard.schneeman+rubygems@gmail.com
@@ -177,6 +191,7 @@ files:
177
191
  - ".gitignore"
178
192
  - ".standard.yml"
179
193
  - CHANGELOG.md
194
+ - CONTRIBUTING.md
180
195
  - Dockerfile
181
196
  - Gemfile
182
197
  - README.md
@@ -184,6 +199,7 @@ files:
184
199
  - bin/rundoc
185
200
  - lib/rundoc.rb
186
201
  - lib/rundoc/cli.rb
202
+ - lib/rundoc/cli_argument_parser.rb
187
203
  - lib/rundoc/code_command.rb
188
204
  - lib/rundoc/code_command/background.rb
189
205
  - lib/rundoc/code_command/background/log/clear.rb
@@ -211,11 +227,26 @@ files:
211
227
  - lib/rundoc/code_command/website/visit.rb
212
228
  - lib/rundoc/code_command/write.rb
213
229
  - lib/rundoc/code_section.rb
230
+ - lib/rundoc/context/after_build.rb
231
+ - lib/rundoc/context/execution.rb
214
232
  - lib/rundoc/parser.rb
215
233
  - lib/rundoc/peg_parser.rb
216
234
  - lib/rundoc/version.rb
217
235
  - rundoc.gemspec
218
236
  - test/fixtures/build_logs/rundoc.md
237
+ - test/fixtures/cnb/ruby/download.md
238
+ - test/fixtures/cnb/ruby/image_structure.md
239
+ - test/fixtures/cnb/ruby/intro.md
240
+ - test/fixtures/cnb/ruby/multiple_langs.md
241
+ - test/fixtures/cnb/ruby/rundoc.md
242
+ - test/fixtures/cnb/ruby/what_is_pack_build.md
243
+ - test/fixtures/cnb/shared/call_to_action.md
244
+ - test/fixtures/cnb/shared/configure_builder.md
245
+ - test/fixtures/cnb/shared/install_pack.md
246
+ - test/fixtures/cnb/shared/pack_build.md
247
+ - test/fixtures/cnb/shared/procfile.md
248
+ - test/fixtures/cnb/shared/use_the_image.md
249
+ - test/fixtures/cnb/shared/what_is_a_builder.md
219
250
  - test/fixtures/depend_on/dependency/rundoc.md
220
251
  - test/fixtures/depend_on/main/rundoc.md
221
252
  - test/fixtures/java/rundoc.md
@@ -227,7 +258,12 @@ files:
227
258
  - test/fixtures/require/dependency/rundoc.md
228
259
  - test/fixtures/require/main/rundoc.md
229
260
  - test/fixtures/screenshot/rundoc.md
261
+ - test/fixtures/simple_git/rundoc.md
262
+ - test/integration/after_build_test.rb
230
263
  - test/integration/print_test.rb
264
+ - test/integration/require_test.rb
265
+ - test/integration/website_test.rb
266
+ - test/rundoc/cli_argument_parser_test.rb
231
267
  - test/rundoc/code_commands/append_file_test.rb
232
268
  - test/rundoc/code_commands/background_test.rb
233
269
  - test/rundoc/code_commands/bash_test.rb
@@ -239,6 +275,7 @@ files:
239
275
  - test/rundoc/peg_parser_test.rb
240
276
  - test/rundoc/regex_test.rb
241
277
  - test/rundoc/test_parse_java.rb
278
+ - test/system/exe_cli_test.rb
242
279
  - test/test_helper.rb
243
280
  homepage: https://github.com/schneems/rundoc
244
281
  licenses:
@@ -259,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
296
  - !ruby/object:Gem::Version
260
297
  version: '0'
261
298
  requirements: []
262
- rubygems_version: 3.5.3
299
+ rubygems_version: 3.5.9
263
300
  signing_key:
264
301
  specification_version: 4
265
302
  summary: RunDOC generates runable code from docs