rundoc 1.1.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/check_changelog.yml +16 -7
- data/.github/workflows/ci.yml +48 -0
- data/.standard.yml +6 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -1
- data/README.md +98 -5
- data/Rakefile +9 -10
- data/lib/rundoc/cli.rb +15 -17
- data/lib/rundoc/code_command/background/log/clear.rb +1 -1
- data/lib/rundoc/code_command/background/log/read.rb +1 -1
- data/lib/rundoc/code_command/background/process_spawn.rb +8 -9
- data/lib/rundoc/code_command/background/start.rb +7 -7
- data/lib/rundoc/code_command/background/stop.rb +1 -1
- data/lib/rundoc/code_command/background/wait.rb +2 -2
- data/lib/rundoc/code_command/background.rb +6 -6
- data/lib/rundoc/code_command/bash/cd.rb +6 -7
- data/lib/rundoc/code_command/bash.rb +12 -13
- data/lib/rundoc/code_command/file_command/append.rb +12 -16
- data/lib/rundoc/code_command/file_command/remove.rb +6 -9
- data/lib/rundoc/code_command/no_such_command.rb +0 -1
- data/lib/rundoc/code_command/pipe.rb +2 -5
- data/lib/rundoc/code_command/print/erb.rb +48 -0
- data/lib/rundoc/code_command/print/text.rb +33 -0
- data/lib/rundoc/code_command/raw.rb +1 -1
- data/lib/rundoc/code_command/rundoc/depend_on.rb +0 -1
- data/lib/rundoc/code_command/rundoc/require.rb +2 -3
- data/lib/rundoc/code_command/rundoc_command.rb +3 -4
- data/lib/rundoc/code_command/website/driver.rb +17 -17
- data/lib/rundoc/code_command/website/navigate.rb +2 -2
- data/lib/rundoc/code_command/website/screenshot.rb +1 -1
- data/lib/rundoc/code_command/website/visit.rb +4 -5
- data/lib/rundoc/code_command/website.rb +4 -4
- data/lib/rundoc/code_command/write.rb +10 -11
- data/lib/rundoc/code_command.rb +28 -17
- data/lib/rundoc/code_section.rb +42 -25
- data/lib/rundoc/parser.rb +17 -19
- data/lib/rundoc/peg_parser.rb +57 -59
- data/lib/rundoc/version.rb +1 -1
- data/lib/rundoc.rb +10 -14
- data/rundoc.gemspec +19 -21
- data/test/fixtures/rails_4/rundoc.md +100 -33
- data/test/fixtures/rails_5/rundoc.md +77 -14
- data/test/fixtures/rails_6/rundoc.md +231 -167
- data/test/fixtures/rails_7/rundoc.md +477 -0
- data/test/integration/print_test.rb +194 -0
- data/test/rundoc/code_commands/append_file_test.rb +5 -8
- data/test/rundoc/code_commands/background_test.rb +3 -6
- data/test/rundoc/code_commands/bash_test.rb +12 -7
- data/test/rundoc/code_commands/pipe_test.rb +9 -9
- data/test/rundoc/code_commands/print_test.rb +94 -0
- data/test/rundoc/code_commands/remove_contents_test.rb +4 -5
- data/test/rundoc/code_section_test.rb +50 -56
- data/test/rundoc/parser_test.rb +28 -61
- data/test/rundoc/peg_parser_test.rb +49 -53
- data/test/rundoc/regex_test.rb +120 -127
- data/test/rundoc/test_parse_java.rb +1 -3
- data/test/test_helper.rb +4 -6
- metadata +39 -42
- data/.travis.yml +0 -8
- data/lib/rundoc/code_command/repl.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45657dd48e87b08e841e90a828d026a9248b0c52667824b77eb799c5d2afc6f5
|
4
|
+
data.tar.gz: 03b6a8b17ba747ae9952398772edf2cbff4b2ac0710a8a52e20055b46aafd657
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c717ac8241f4d4b4028c0ecb2e5391705112e00001abee2385af7ece74bcef546064fc09377eec41d0e4aab1323d3c5856cbbac772ca78237681110d9e82d472
|
7
|
+
data.tar.gz: c7736d871a79f584f7bb6ed9bfa50447ced0a6dd1a923578a0f5d8df28e8b1d36350715f38435959f7de2770112080005b79f7a4cbfdd27a8c87a6b906fe02b2
|
@@ -1,13 +1,22 @@
|
|
1
1
|
name: Check Changelog
|
2
2
|
|
3
3
|
on:
|
4
|
-
|
5
|
-
|
4
|
+
pull_request:
|
5
|
+
types: [opened, reopened, edited, labeled, unlabeled, synchronize]
|
6
|
+
|
6
7
|
jobs:
|
7
|
-
|
8
|
+
check-changelog:
|
8
9
|
runs-on: ubuntu-latest
|
10
|
+
if: |
|
11
|
+
!contains(github.event.pull_request.body, '[skip changelog]') &&
|
12
|
+
!contains(github.event.pull_request.body, '[changelog skip]') &&
|
13
|
+
!contains(github.event.pull_request.body, '[skip ci]') &&
|
14
|
+
!contains(github.event.pull_request.labels.*.name, 'skip changelog') &&
|
15
|
+
!contains(github.event.pull_request.labels.*.name, 'dependencies') &&
|
16
|
+
!contains(github.event.pull_request.labels.*.name, 'automation')
|
9
17
|
steps:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
- uses: actions/checkout@v3
|
19
|
+
- name: Check that CHANGELOG is touched
|
20
|
+
run: |
|
21
|
+
git fetch origin ${{ github.base_ref }} --depth 1 && \
|
22
|
+
git diff remotes/origin/${{ github.base_ref }} --name-only | grep CHANGELOG.md
|
@@ -0,0 +1,48 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
- pull_request
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
test:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby:
|
14
|
+
- 3.1
|
15
|
+
- 3.2
|
16
|
+
- 3.3
|
17
|
+
- head
|
18
|
+
steps:
|
19
|
+
- name: Checkout code
|
20
|
+
uses: actions/checkout@v3
|
21
|
+
- name: Set up Ruby
|
22
|
+
uses: ruby/setup-ruby@v1
|
23
|
+
with:
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
25
|
+
bundler-cache: true
|
26
|
+
- name: test
|
27
|
+
run: bundle exec rake test
|
28
|
+
continue-on-error: ${{ matrix.ruby == 'head' }}
|
29
|
+
|
30
|
+
lint:
|
31
|
+
runs-on: ubuntu-latest
|
32
|
+
strategy:
|
33
|
+
fail-fast: false
|
34
|
+
matrix:
|
35
|
+
ruby:
|
36
|
+
- 3.3
|
37
|
+
- head
|
38
|
+
steps:
|
39
|
+
- name: Checkout code
|
40
|
+
uses: actions/checkout@v3
|
41
|
+
- name: Set up Ruby
|
42
|
+
uses: ruby/setup-ruby@v1
|
43
|
+
with:
|
44
|
+
ruby-version: ${{ matrix.ruby }}
|
45
|
+
bundler-cache: true
|
46
|
+
- name: lint
|
47
|
+
run: bundle exec standardrb --no-fix
|
48
|
+
continue-on-error: ${{ matrix.ruby == 'head' }}
|
data/.standard.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
## HEAD
|
2
2
|
|
3
|
+
## 2.0.0
|
4
|
+
|
5
|
+
- Change: Ruby 2.7 and 3.0 are no longer supported
|
6
|
+
- Add: `print.text` and `print.erb` see README for usage details
|
7
|
+
- Add: Output documents include more frequent warnings that the document was autogenerated and should not be modified
|
8
|
+
- Breaking: Remove repl_runner support.
|
9
|
+
- Fix `file.write` do not prepend "In file x ..." when the command is hidden i.e. `:::-> file.write`
|
10
|
+
|
11
|
+
## 1.1.3
|
12
|
+
|
13
|
+
- Bugfix: Bash commands that output to stderr and use `||` are now captured (https://github.com/schneems/rundoc/pull/29)
|
14
|
+
|
3
15
|
## 1.1.2
|
4
16
|
|
5
17
|
- Fix pipe support (https://github.com/schneems/rundoc/pull/28)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -47,7 +47,7 @@ gem 'rundoc'
|
|
47
47
|
Run the `rundoc build` command on any markdown file
|
48
48
|
|
49
49
|
```sh
|
50
|
-
$ rundoc build --path
|
50
|
+
$ bin/rundoc build --path <test/fixtures/rails_7/rundoc.md>
|
51
51
|
```
|
52
52
|
|
53
53
|
> Note: This command will create and manipulate directories in the working directory of your source markdown file. Best practice is to have your source markdown file in its own empty directory.
|
@@ -65,6 +65,9 @@ This will generate a project folder with your project in it, and a markdown READ
|
|
65
65
|
- Execute Bash Commands
|
66
66
|
- [$](#shell-commands)
|
67
67
|
- [fail.$](#shell-commands)
|
68
|
+
- Printing
|
69
|
+
- [print.text](#print)
|
70
|
+
- [print.erb](#print)
|
68
71
|
- Chain commands
|
69
72
|
- [pipe](#pipe)
|
70
73
|
- [|](#pipe)
|
@@ -146,7 +149,7 @@ Would output:
|
|
146
149
|
bahz
|
147
150
|
```
|
148
151
|
|
149
|
-
This STDIN feature could be useful if you are running an interactive command such as `play new` which requires user input.
|
152
|
+
This STDIN feature could be useful if you are running an interactive command such as `play new` which requires user input.
|
150
153
|
|
151
154
|
Different commands will do different things with this input. For example the `rundoc` command executes Ruby configuration code:
|
152
155
|
|
@@ -181,7 +184,7 @@ RunDOC only cares about things that come after a `:::` section. If you have a "r
|
|
181
184
|
You can mix non-command code and commands, as long as the things that aren't rendering come first. This can be used to "fake" a command, for example:
|
182
185
|
|
183
186
|
```
|
184
|
-
$ rails new myapp # Not a command since it's missing the ":::>>"
|
187
|
+
$ rails new myapp # Not a command since it's missing the ":::>>"
|
185
188
|
:::-> $ rails new myapp --skip-test --skip-yarn --skip-sprockets
|
186
189
|
:::>> | $ head -n 5
|
187
190
|
```
|
@@ -197,13 +200,12 @@ $ rails new myapp # Not a command since it's missing the ":::>>""
|
|
197
200
|
create config.ru
|
198
201
|
```
|
199
202
|
|
200
|
-
|
203
|
+
In this example it looks like the command was run without any flags, but in reality `rails new myapp --skip-test --skip-yarn --skip-sprockets | head -n 5` was executed. Though it's more explicit to use a `print.text` block, see [#print.text](#print) for more info.
|
201
204
|
|
202
205
|
## Rendering Cheat Sheet
|
203
206
|
|
204
207
|
An arrow `>` is shorthand for "render this" and a dash `-` is shorthand for skip this section. The two positions are **command** first and **result** second.
|
205
208
|
|
206
|
-
|
207
209
|
- `:::>-` (YES command output, not result output)
|
208
210
|
- `:::>>` (YES command output, YES result output)
|
209
211
|
- `:::--` (not command output, not result output)
|
@@ -250,6 +252,64 @@ These custom commands are kept to a minimum, and for the most part behave as you
|
|
250
252
|
|
251
253
|
Running shell commands like this can be very powerful, you'll likely want more control of how you manipulate files in your project. To do this you can use the `file.` namespace:
|
252
254
|
|
255
|
+
## Print
|
256
|
+
|
257
|
+
Current commands:
|
258
|
+
|
259
|
+
- `print.text`
|
260
|
+
- `print.erb`
|
261
|
+
|
262
|
+
Behaves slightly differently than other commands. The "command" portion of the control character i.e. `:::>` controls whether the contents will be rendered inside the block or before the block (versus usually this is used to control if the command such as `$ cd` is shown).
|
263
|
+
|
264
|
+
- `:::>>` Print inside the code block
|
265
|
+
- `:::->` Print BEFORE the code block, if multiple calls are made, they will be displayed in order.
|
266
|
+
- `:::--` Nothing will be rendered, can be used to pass data to another rundoc command via the pipe operator.
|
267
|
+
- `:::>-` Same behavior as `:::--`.
|
268
|
+
|
269
|
+
This functionality is present to allow body text to be generated (versus only allowing generated text in code blocks).
|
270
|
+
|
271
|
+
Use the `print.text` keyword followed by what you want to print:
|
272
|
+
|
273
|
+
```
|
274
|
+
:::-> print.text
|
275
|
+
I will render BEFORE the code block, use :::>> to render in it.
|
276
|
+
|
277
|
+
It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness,
|
278
|
+
it was the epoch of belief, it was the epoch ...
|
279
|
+
```
|
280
|
+
|
281
|
+
Specifying `:::->` with `print.text` will render text without a code block (or before the code block if there are other rundoc commands). If you want to render text with a code block you can do it via `:::>>`.
|
282
|
+
|
283
|
+
To dynamically change the contents of the thing you're printing you can use `print.erb`:
|
284
|
+
|
285
|
+
```
|
286
|
+
:::-> print.erb
|
287
|
+
I will render BEFORE the code block, use :::>> to render in it.
|
288
|
+
|
289
|
+
What a week!
|
290
|
+
Captain it's only <%= Time.now.strftime("%A") %>!
|
291
|
+
```
|
292
|
+
|
293
|
+
This will evaluate the context of ERB and write it to the file. Like `print.text` use `:::->` to write the contents without a code block (or before the code block if there are other rundoc commands). If you want to render text with a code block you can do it via `:::>>`.
|
294
|
+
|
295
|
+
ERB commands share a default context. That means you can set a value in one `print.erb` section and view it from another. If you want to isolate your erb blocks you can provide a custom name via the `binding:` keyword:
|
296
|
+
|
297
|
+
```
|
298
|
+
:::>> print.erb(binding: "mc_hammer")
|
299
|
+
I will render IN a code block, use `:::->` to render before.
|
300
|
+
|
301
|
+
<%= @stop = true %>
|
302
|
+
|
303
|
+
:::>> print.erb(binding: "different")
|
304
|
+
<% if @stop %>
|
305
|
+
Hammer time
|
306
|
+
<% else %>
|
307
|
+
Can't touch this
|
308
|
+
<% end %>
|
309
|
+
```
|
310
|
+
|
311
|
+
In this example setting `@stop` in one `print.erb` will have no effect on the other.
|
312
|
+
|
253
313
|
## File Commands
|
254
314
|
|
255
315
|
Current Commands:
|
@@ -504,6 +564,39 @@ Sometimes sensitive info like usernames, email addresses, or passwords may be in
|
|
504
564
|
|
505
565
|
This command `filter_sensitive` can be called multiple times with different values. Since the config is in Ruby you could iterate over an array of sensitive data
|
506
566
|
|
567
|
+
## Writing a new command
|
568
|
+
|
569
|
+
Rundoc does not have a stable internal command interface. You can define your own commands, but unless it is committed in this repo, it may break on a minor version change.
|
570
|
+
|
571
|
+
To add a new command it needs to be parsed and called. Examples of commands being implemented are seen in `lib/rundoc/code_command`.
|
572
|
+
|
573
|
+
A new command needs to be registered:
|
574
|
+
|
575
|
+
```
|
576
|
+
Rundoc.register_code_command(:lol, Rundoc::CodeCommand::Lol)
|
577
|
+
```
|
578
|
+
|
579
|
+
They should inherit from Rundoc::CodeCommand:
|
580
|
+
|
581
|
+
```
|
582
|
+
class Rundoc::CodeCommand::Lol < Rundoc::CodeCommand
|
583
|
+
def initialize(line)
|
584
|
+
end
|
585
|
+
end
|
586
|
+
```
|
587
|
+
|
588
|
+
The initialize method is called with input from the document. The command is rendered (`:::>-`) by the output of the `def call` method. The contents produced by the command (`:::->`) are rendered by the `def to_md` method.
|
589
|
+
|
590
|
+
The syntax for commands is ruby-ish but it is a custom grammar implemented in `lib/peg_parser.rb` for more info on manipulating the grammar see this tutorial on how I added keword-like/hash-like syntax https://github.com/schneems/implement_ruby_hash_syntax_with_parslet_example.
|
591
|
+
|
592
|
+
Command initialize methods natively support:
|
593
|
+
|
594
|
+
- Barewords as a single string input
|
595
|
+
- Keyword arguments
|
596
|
+
- A combination of the two
|
597
|
+
|
598
|
+
Anything that is passed to the command via "stdin" is available via a method `self.contents`. The interplay between the input and `self.contents` is not strongly defined.
|
599
|
+
|
507
600
|
## Copyright
|
508
601
|
|
509
602
|
All content Copyright Richard Schneeman © 2020
|
data/Rakefile
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
|
2
|
-
require 'bundler/gem_tasks'
|
1
|
+
require "bundler/gem_tasks"
|
3
2
|
|
4
|
-
require
|
3
|
+
require "rundoc"
|
5
4
|
|
6
|
-
require
|
7
|
-
require
|
5
|
+
require "rake"
|
6
|
+
require "rake/testtask"
|
8
7
|
|
9
|
-
task :
|
8
|
+
task default: [:test]
|
10
9
|
|
11
|
-
|
12
|
-
t.libs <<
|
13
|
-
t.libs <<
|
14
|
-
t.pattern =
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << "lib"
|
12
|
+
t.libs << "test"
|
13
|
+
t.pattern = "test/rundoc/**/*_test.rb"
|
15
14
|
t.verbose = false
|
16
15
|
end
|
data/lib/rundoc/cli.rb
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
module Rundoc
|
2
2
|
class CLI
|
3
|
-
def build(path:
|
3
|
+
def build(path:)
|
4
4
|
@path = Pathname.new(path).expand_path
|
5
5
|
raise "#{@path} does not exist" unless File.exist?(@path)
|
6
6
|
raise "Expecting #{@path} to be a rundoc markdown file" unless File.file?(@path)
|
7
|
-
@working_dir
|
8
|
-
|
7
|
+
@working_dir = Pathname.new(File.expand_path("../", @path))
|
9
8
|
|
10
9
|
dot_env_path = File.expand_path("../.env", @path)
|
11
10
|
if File.exist?(dot_env_path)
|
12
|
-
require
|
11
|
+
require "dotenv"
|
13
12
|
Dotenv.load(dot_env_path)
|
14
|
-
ENV[
|
15
|
-
ENV[
|
16
|
-
ENV[
|
17
|
-
ENV[
|
13
|
+
ENV["AWS_ACCESS_KEY_ID"] ||= ENV["BUCKETEER_AWS_ACCESS_KEY_ID"]
|
14
|
+
ENV["AWS_REGION"] ||= ENV["BUCKETEER_AWS_REGION"]
|
15
|
+
ENV["AWS_SECRET_ACCESS_KEY"] ||= ENV["BUCKETEER_AWS_SECRET_ACCESS_KEY"]
|
16
|
+
ENV["AWS_BUCKET_NAME"] ||= ENV["BUCKETEER_BUCKET_NAME"]
|
18
17
|
end
|
19
18
|
|
20
19
|
source_contents = File.read(@path)
|
21
|
-
tmp_dir
|
20
|
+
tmp_dir = @working_dir.join("tmp")
|
22
21
|
|
23
22
|
FileUtils.remove_entry_secure(tmp_dir) if tmp_dir.exist?
|
24
23
|
tmp_dir.mkdir
|
@@ -28,7 +27,7 @@ module Rundoc
|
|
28
27
|
|
29
28
|
Instead modify the rundoc script and re-run it.
|
30
29
|
|
31
|
-
Command: #{
|
30
|
+
Command: #{$0} #{$*.join(" ")}
|
32
31
|
STOP -->
|
33
32
|
HEREDOC
|
34
33
|
|
@@ -41,12 +40,12 @@ module Rundoc
|
|
41
40
|
|
42
41
|
puts "== Done, run was successful"
|
43
42
|
project_name = if Rundoc.project_root
|
44
|
-
Rundoc.project_root.split(
|
43
|
+
Rundoc.project_root.split("/").last
|
45
44
|
else
|
46
|
-
|
45
|
+
"project"
|
47
46
|
end
|
48
47
|
|
49
|
-
project_dir
|
48
|
+
project_dir = @working_dir.join(project_name)
|
50
49
|
|
51
50
|
FileUtils.remove_entry_secure(project_dir) if project_dir.exist?
|
52
51
|
|
@@ -62,16 +61,15 @@ module Rundoc
|
|
62
61
|
|
63
62
|
source_path = project_dir.join("README.md")
|
64
63
|
puts "== Done, writing original source to #{source_path}"
|
65
|
-
File.
|
64
|
+
File.write(source_path, @output)
|
66
65
|
|
67
66
|
puts "== Copying source"
|
68
|
-
source_path = project_dir.join("
|
69
|
-
File.
|
67
|
+
source_path = project_dir.join("copied-#{@path.to_s.split("/").last}")
|
68
|
+
File.write(source_path, source_contents)
|
70
69
|
|
71
70
|
Dir.chdir(project_dir) do
|
72
71
|
Rundoc.run_after_build
|
73
72
|
end
|
74
|
-
|
75
73
|
ensure
|
76
74
|
Rundoc::CodeCommand::Background::ProcessSpawn.tasks.each do |name, task|
|
77
75
|
next unless task.alive?
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "shellwords"
|
2
|
+
require "timeout"
|
3
|
+
require "fileutils"
|
4
4
|
|
5
5
|
class Rundoc::CodeCommand::Background
|
6
6
|
# This class is responsible for running processes in the background
|
@@ -28,8 +28,8 @@ class Rundoc::CodeCommand::Background
|
|
28
28
|
# ProcessSpawn.find("muh_server") # => <# ProcessSpawn instance >
|
29
29
|
# ProcessSpawn.find("foo") # => RuntimeError "Could not find task with name 'foo', ..."
|
30
30
|
class ProcessSpawn
|
31
|
-
|
32
|
-
|
31
|
+
class << self
|
32
|
+
attr_reader :tasks
|
33
33
|
end
|
34
34
|
|
35
35
|
@tasks = {}
|
@@ -45,7 +45,7 @@ class Rundoc::CodeCommand::Background
|
|
45
45
|
|
46
46
|
attr_reader :log, :pid
|
47
47
|
|
48
|
-
def initialize(command
|
48
|
+
def initialize(command, timeout: 5, log: Tempfile.new("log"), out: "2>&1")
|
49
49
|
@command = command
|
50
50
|
@timeout_value = timeout
|
51
51
|
@log_reference = log # https://twitter.com/schneems/status/1285289971083907075
|
@@ -68,8 +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 #{
|
72
|
-
false
|
71
|
+
raise "Timeout waiting for #{@command.inspect} to find a match using #{wait_value.inspect} in \n'#{log.read}'"
|
73
72
|
end
|
74
73
|
|
75
74
|
def alive?
|
@@ -81,7 +80,7 @@ class Rundoc::CodeCommand::Background
|
|
81
80
|
|
82
81
|
def stop
|
83
82
|
return unless alive?
|
84
|
-
Process.kill(
|
83
|
+
Process.kill("TERM", -Process.getpgid(@pid))
|
85
84
|
Process.wait(@pid)
|
86
85
|
end
|
87
86
|
|
@@ -1,25 +1,25 @@
|
|
1
|
-
require
|
1
|
+
require "tempfile"
|
2
2
|
|
3
3
|
class Rundoc::CodeCommand::Background
|
4
4
|
class Start < Rundoc::CodeCommand
|
5
|
-
def initialize(command, name
|
5
|
+
def initialize(command, name:, wait: nil, timeout: 5, log: Tempfile.new("log"), out: "2>&1", allow_fail: false)
|
6
6
|
@command = command
|
7
|
-
@name
|
8
|
-
@wait
|
7
|
+
@name = name
|
8
|
+
@wait = wait
|
9
9
|
@allow_fail = allow_fail
|
10
10
|
FileUtils.touch(log)
|
11
11
|
|
12
12
|
@spawn = ProcessSpawn.new(
|
13
13
|
@command,
|
14
14
|
timeout: timeout,
|
15
|
-
log:
|
16
|
-
out:
|
15
|
+
log: log,
|
16
|
+
out: out
|
17
17
|
)
|
18
18
|
ProcessSpawn.add(@name, @spawn)
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_md(env = {})
|
22
|
-
|
22
|
+
"$ #{@command}"
|
23
23
|
end
|
24
24
|
|
25
25
|
def call(env = {})
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class Rundoc::CodeCommand::Background
|
2
2
|
class Wait < Rundoc::CodeCommand
|
3
|
-
def initialize(name
|
3
|
+
def initialize(name:, wait:, timeout: 5)
|
4
4
|
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
|
5
|
-
@wait
|
5
|
+
@wait = wait
|
6
6
|
@timeout_value = Integer(timeout)
|
7
7
|
end
|
8
8
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Rundoc::CodeCommand::Background
|
2
2
|
end
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
4
|
+
require "rundoc/code_command/background/process_spawn"
|
5
|
+
require "rundoc/code_command/background/start"
|
6
|
+
require "rundoc/code_command/background/stop"
|
7
|
+
require "rundoc/code_command/background/wait"
|
8
|
+
require "rundoc/code_command/background/log/clear"
|
9
|
+
require "rundoc/code_command/background/log/read"
|
@@ -3,34 +3,33 @@ class Rundoc::CodeCommand::Bash
|
|
3
3
|
# we change the directory of the parent program (rundoc) rather than
|
4
4
|
# changing the directory of a spawned child (via exec, ``, system, etc.)
|
5
5
|
class Cd < Rundoc::CodeCommand::Bash
|
6
|
-
|
7
6
|
def initialize(line)
|
8
7
|
@line = line
|
9
8
|
end
|
10
9
|
|
11
10
|
# Ignore duplicate chdir warnings "warning: conflicting chdir during another chdir block"
|
12
11
|
def supress_chdir_warning
|
13
|
-
old_stderr
|
12
|
+
old_stderr = $stderr
|
14
13
|
capture_stderr = StringIO.new
|
15
|
-
$stderr
|
16
|
-
|
14
|
+
$stderr = capture_stderr
|
15
|
+
yield
|
17
16
|
ensure
|
18
17
|
if old_stderr
|
19
18
|
$stderr = old_stderr
|
20
19
|
capture_string = capture_stderr.string
|
21
|
-
|
20
|
+
warn capture_string if capture_string.each_line.count > 1 || !capture_string.include?("conflicting chdir")
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
24
|
def call(env)
|
26
|
-
line = @line.sub(
|
25
|
+
line = @line.sub("cd", "").strip
|
27
26
|
puts "running $ cd #{line}"
|
28
27
|
|
29
28
|
supress_chdir_warning do
|
30
29
|
Dir.chdir(line)
|
31
30
|
end
|
32
31
|
|
33
|
-
|
32
|
+
nil
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
class Rundoc::CodeCommand::Bash < Rundoc::CodeCommand
|
2
|
-
|
3
2
|
# line = "cd ..""
|
4
3
|
# line = "pwd"
|
5
4
|
# line = "ls"
|
6
5
|
def initialize(line)
|
7
|
-
@line
|
6
|
+
@line = line
|
8
7
|
@contents = ""
|
9
|
-
@delegate = case @line.split(
|
10
|
-
when
|
8
|
+
@delegate = case @line.split(" ").first.downcase
|
9
|
+
when "cd"
|
11
10
|
Cd.new(@line)
|
12
11
|
else
|
13
12
|
false
|
@@ -28,16 +27,17 @@ class Rundoc::CodeCommand::Bash < Rundoc::CodeCommand
|
|
28
27
|
|
29
28
|
# markdown doesn't understand bash color codes
|
30
29
|
def sanitize_escape_chars(input)
|
31
|
-
input.gsub(/\e\[(\d+)m/,
|
30
|
+
input.gsub(/\e\[(\d+)m/, "")
|
32
31
|
end
|
33
32
|
|
34
33
|
def shell(cmd, stdin = nil)
|
35
|
-
|
36
|
-
msg
|
34
|
+
cmd = "(#{cmd}) 2>&1"
|
35
|
+
msg = "Running: $ '#{cmd}'"
|
36
|
+
msg << " with stdin: '#{stdin.inspect}'" if stdin && !stdin.empty?
|
37
37
|
puts msg
|
38
38
|
|
39
39
|
result = ""
|
40
|
-
IO.popen(
|
40
|
+
IO.popen(cmd, "w+") do |io|
|
41
41
|
io << stdin if stdin
|
42
42
|
io.close_write
|
43
43
|
result = sanitize_escape_chars io.read
|
@@ -45,13 +45,12 @@ class Rundoc::CodeCommand::Bash < Rundoc::CodeCommand
|
|
45
45
|
unless $?.success?
|
46
46
|
raise "Command `#{@line}` exited with non zero status: #{result}" unless keyword.to_s.include?("fail")
|
47
47
|
end
|
48
|
-
|
48
|
+
result
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
52
|
Rundoc.register_code_command(:bash, Rundoc::CodeCommand::Bash)
|
54
|
-
Rundoc.register_code_command(:
|
55
|
-
Rundoc.register_code_command(:
|
53
|
+
Rundoc.register_code_command(:"$", Rundoc::CodeCommand::Bash)
|
54
|
+
Rundoc.register_code_command(:"fail.$", Rundoc::CodeCommand::Bash)
|
56
55
|
|
57
|
-
require
|
56
|
+
require "rundoc/code_command/bash/cd"
|