rundoc 3.0.2 → 3.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87495a9fcbdf3fa9a146b633d84f62294bd400b32f806d975db0b372ce6c4f31
4
- data.tar.gz: c50e2b6dbcbb2e313753d1341a17b56208118b10bd20462768348cae56cb3dda
3
+ metadata.gz: d21f4ac48ad2eab762969c03ce386aeb097f99162d38716e4736de44c9bbac83
4
+ data.tar.gz: 79f9be265a84d8474e3ed7d55d90781e9999790b6cf5e578943db89e0fec7ee9
5
5
  SHA512:
6
- metadata.gz: 3e34467cf37d802daf82bb6fd8e81a4ecb4af426bc1645151e7d420dec131e4493b4e5f8ba78de3393bdc84a4de97dbc908434f4e1f06a895fc9002ca72611a5
7
- data.tar.gz: 6971fa4915f79d81d1b6e6dd05f10e45e116f7388ae4c5ffd8b8ad1e9dc28be9c7882b11c6f315934b210281508fc17edb722969497fd951780befcb1d66eef2
6
+ metadata.gz: fcf456c89f09000ddeeaf7aa22654acf419f36294b9e88dec9735f9ec3fcab315085dd6ee97cbd63eb580078e009968219b5240a6fe7a6db4c022d1b878d97cb
7
+ data.tar.gz: 8e2ee0bd6fa26b8b8906ec9b2267a9e98feedc40b54dc53ca457937a7199865c2c6b7663837a067802426321fc93740da3038289ea516139a573a1e5679c8724
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## HEAD
2
2
 
3
+ ## 3.1.1
4
+
5
+ - Fix: Include all code sections in the event of a failure, not just the last one (https://github.com/zombocom/rundoc/pull/71)
6
+
7
+ ## 3.1.0
8
+
9
+ - 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. ()
10
+
11
+ For example if `RUNDOC.md` features many smaller docs:
12
+
13
+ ```
14
+ :::>> rundoc.require "./intro.md"
15
+ :::>> rundoc.require "../shared/install_cli.md"
16
+ :::>> rundoc.require "./clone_app.md"
17
+ ```
18
+
19
+ 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.
20
+
3
21
  ## 3.0.2
4
22
 
5
23
  - Fix: Partial output of the document is now written to disk in a `RUNDOC_FAILED.md` file (https://github.com/zombocom/rundoc/pull/69)
data/README.md CHANGED
@@ -88,6 +88,7 @@ This will generate a project folder with your project in it, and a markdown `REA
88
88
  - [background.stop](#background)
89
89
  - [background.log.read](#background)
90
90
  - [background.log.clear](#background)
91
+ - [background.wait](#background)
91
92
  - Take screenshots
92
93
  - [website.visit](#screenshots)
93
94
  - [website.nav](#screenshots)
@@ -410,6 +411,13 @@ To start a process, pass in the command as the first arg, and give it a name (so
410
411
  :::>> background.start("rails server", name: "server")
411
412
  ```
412
413
 
414
+ - Arguments
415
+ - name: Identifier of the background process, used in later invocations.
416
+ - wait (Optional): A string to wait for before continuing. This is useful to block moving on until an event happend such as a server was booted or web request was received. Also see `background.wait`
417
+ - timeout (Optional): A number of seconds to wait for a given string to be found in the logs.
418
+ - out (Optional): A bash redirect. Defaults to `2>&1` to merge stderr and stdout together.
419
+ - allow_fail (Optional): Set to `true` if the command exiting shouldn't halt doc generation. Poorly named, may be renamed in the future.
420
+
413
421
  You can make the background process wait until it receives a certain string in the logs. For instance to make sure that the server is fully booted:
414
422
 
415
423
  ```
@@ -422,18 +430,38 @@ You can stop the process by referencing the name:
422
430
  :::-- background.stop(name: "server")
423
431
  ```
424
432
 
433
+ - Arguments
434
+ - name
435
+
425
436
  You can also get the log contents:
426
437
 
427
438
  ```
428
439
  :::>> background.log.read(name: "server")
429
440
  ```
430
441
 
442
+ - Arguments
443
+ - name
444
+
431
445
  You can also truncate the logs:
432
446
 
433
447
  ```
434
448
  :::>> background.log.clear(name: "server")
435
449
  ```
436
450
 
451
+ - Arguments
452
+ - name
453
+
454
+ You can also wait for a given string to appear in the logs:
455
+
456
+ ```
457
+ :::>> background.wait(name: "server", wait: "method=GET")
458
+ ```
459
+
460
+ - Arguments
461
+ - name
462
+ - wait: Same as `background.start` a string value to look for before continuing.
463
+ - timeout: Maximum number of seconds to wait
464
+
437
465
  ## Screenshots
438
466
 
439
467
  You'll need selenium and `chromedriver` installed on your system to make screenshots work. On a mac you can run:
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 "## earing on failure directory #{on_failure_dir}"
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(
@@ -191,7 +203,7 @@ module Rundoc
191
203
  to: on_failure_dir
192
204
  )
193
205
 
194
- on_failure_dir.join("RUNDOC_FAILED.md").write(Rundoc::CodeSection.partial_result_to_doc)
206
+ on_failure_dir.join("RUNDOC_FAILED.md").write(Rundoc::Parser.partial_result_to_doc)
195
207
  end
196
208
 
197
209
  private def on_success(output)
@@ -8,7 +8,8 @@ module Rundoc
8
8
  #
9
9
  # Example:
10
10
  #
11
- # cli = CLIArgumentParser.new(argv: ARGV).to_cli
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?
@@ -15,6 +15,7 @@ class Rundoc::CodeCommand::Background
15
15
  log: log,
16
16
  out: out
17
17
  )
18
+ puts "Spawning commmand: `#{@spawn.command}`"
18
19
  ProcessSpawn.add(@name, @spawn)
19
20
  end
20
21
 
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rundoc
4
- # holds code, parses and creates CodeCommand
4
+ # A code secttion respesents a block of fenced code
5
+ #
6
+ # A document can have multiple code sections
5
7
  class CodeSection
6
8
  class ParseError < StandardError
7
9
  def initialize(options = {})
@@ -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/parser.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  module Rundoc
2
+ # This poorly named class is responsible for taking in the raw markdown and running it
3
+ #
4
+ # It works by pulling out the code blocks (CodeSection), and putting them onto a stack.
5
+ # It then executes each in turn and records the results.
2
6
  class Parser
3
7
  DEFAULT_KEYWORD = ":::"
4
8
  INDENT_BLOCK = '(?<before_indent>(^\s*$\n|\A)(^(?:[ ]{4}|\t))(?<indent_contents>.*)(?<after_indent>[^\s].*$\n?(?:(?:^\s*$\n?)*^(?:[ ]{4}|\t).*[^\s].*$\n?)*))'
@@ -7,6 +11,7 @@ module Rundoc
7
11
  COMMAND_REGEX = ->(keyword) {
8
12
  /^#{keyword}(?<tag>(\s|=|-|>)?(=|-|>)?)\s*(?<command>(\S)+)\s+(?<statement>.*)$/
9
13
  }
14
+ PARTIAL_RESULT = []
10
15
 
11
16
  attr_reader :contents, :keyword, :stack, :context
12
17
 
@@ -17,6 +22,7 @@ module Rundoc
17
22
  @keyword = keyword
18
23
  @stack = []
19
24
  partition
25
+ PARTIAL_RESULT.clear
20
26
  end
21
27
 
22
28
  def to_md
@@ -27,13 +33,26 @@ module Rundoc
27
33
  else
28
34
  s
29
35
  end
36
+ PARTIAL_RESULT.replace(result)
30
37
  end
31
- result.join("")
38
+
39
+ self.class.to_doc(result: result)
32
40
  rescue => e
33
41
  File.write("README.md", result.join(""))
34
42
  raise e
35
43
  end
36
44
 
45
+ def self.partial_result_to_doc
46
+ out = to_doc(result: PARTIAL_RESULT)
47
+ unfinished = CodeSection.partial_result_to_doc
48
+ out << unfinished if unfinished
49
+ out
50
+ end
51
+
52
+ def self.to_doc(result:)
53
+ result.join("")
54
+ end
55
+
37
56
  # split into [before_code, code, after_code], process code, and re-run until tail is empty
38
57
  def partition
39
58
  until contents.empty?
@@ -1,3 +1,3 @@
1
1
  module Rundoc
2
- VERSION = "3.0.2"
2
+ VERSION = "3.1.1"
3
3
  end
@@ -1,7 +1,58 @@
1
1
  require "test_helper"
2
2
 
3
3
  class IntegrationFailureTest < Minitest::Test
4
- def test_writes_to_dir_on_failure
4
+ def test_writes_to_dir_on_failure_two_block
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 one
13
+ :::>> $ touch one/rofl.txt
14
+ ```
15
+
16
+ ```
17
+ :::>> $ mkdir two
18
+ :::>> $ touch two/rofl.txt
19
+ :::>> $ touch does/not/exist.txt
20
+ ```
21
+ EOF
22
+
23
+ io = StringIO.new
24
+
25
+ error = nil
26
+ begin
27
+ Rundoc::CLI.new(
28
+ io: io,
29
+ source_path: source_path,
30
+ on_success_dir: dir.join(SUCCESS_DIRNAME)
31
+ ).call
32
+ rescue => e
33
+ error = e
34
+ end
35
+
36
+ assert error
37
+ assert_includes error.message, "exited with non zero status"
38
+
39
+ refute dir.join(SUCCESS_DIRNAME).join("two").exist?
40
+ refute dir.join(SUCCESS_DIRNAME).join("two").join("rofl.txt").exist?
41
+
42
+ assert dir.join(FAILURE_DIRNAME).join("two").exist?
43
+ assert dir.join(FAILURE_DIRNAME).join("two").join("rofl.txt").exist?
44
+
45
+ doc = dir.join(FAILURE_DIRNAME).join("RUNDOC_FAILED.md").read
46
+ assert_includes doc, "$ mkdir one"
47
+ assert_includes doc, "$ touch one/rofl.txt"
48
+
49
+ assert_includes doc, "$ mkdir two"
50
+ assert_includes doc, "$ touch two/rofl.txt"
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_writes_to_dir_on_failure_one_block
5
56
  Dir.mktmpdir do |dir|
6
57
  Dir.chdir(dir) do
7
58
  dir = Pathname(dir)
@@ -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.2
4
+ version: 3.1.1
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-20 00:00:00.000000000 Z
11
+ date: 2024-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -265,6 +265,7 @@ files:
265
265
  - test/integration/print_test.rb
266
266
  - test/integration/require_test.rb
267
267
  - test/integration/website_test.rb
268
+ - test/integration/with_contents_flag_test.rb
268
269
  - test/rundoc/cli_argument_parser_test.rb
269
270
  - test/rundoc/code_commands/append_file_test.rb
270
271
  - test/rundoc/code_commands/background_test.rb