nanoc 4.8.10 → 4.8.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/NEWS.md +7 -0
- data/lib/nanoc.rb +11 -6
- data/lib/nanoc/base.rb +1 -0
- data/lib/nanoc/base/changes_stream.rb +53 -0
- data/lib/nanoc/base/contracts_support.rb +0 -2
- data/lib/nanoc/base/feature.rb +3 -0
- data/lib/nanoc/base/memoization.rb +0 -2
- data/lib/nanoc/base/repos/aggregate_data_source.rb +8 -0
- data/lib/nanoc/base/repos/data_source.rb +12 -0
- data/lib/nanoc/base/repos/in_mem_data_source.rb +10 -1
- data/lib/nanoc/base/repos/prefixed_data_source.rb +8 -0
- data/lib/nanoc/base/repos/site_loader.rb +11 -7
- data/lib/nanoc/base/services/compiler.rb +2 -3
- data/lib/nanoc/base/services/compiler/stages/postprocess.rb +2 -3
- data/lib/nanoc/base/services/compiler/stages/preprocess.rb +1 -1
- data/lib/nanoc/base/services/pruner.rb +0 -2
- data/lib/nanoc/base/services/temp_filename_factory.rb +0 -2
- data/lib/nanoc/checking/checks/external_links.rb +0 -5
- data/lib/nanoc/checking/checks/internal_links.rb +0 -2
- data/lib/nanoc/checking/checks/stale.rb +0 -2
- data/lib/nanoc/cli.rb +7 -1
- data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +0 -3
- data/lib/nanoc/cli/commands/live.rb +30 -0
- data/lib/nanoc/cli/commands/view.rb +4 -5
- data/lib/nanoc/cli/error_handler.rb +52 -36
- data/lib/nanoc/cli/logger.rb +0 -2
- data/lib/nanoc/cli/stack_trace_writer.rb +50 -0
- data/lib/nanoc/data_sources/filesystem.rb +25 -0
- data/lib/nanoc/extra.rb +1 -0
- data/lib/nanoc/extra/jruby_nokogiri_warner.rb +0 -2
- data/lib/nanoc/extra/link_collector.rb +0 -2
- data/lib/nanoc/extra/live_recompiler.rb +131 -0
- data/lib/nanoc/extra/parallel_collection.rb +0 -2
- data/lib/nanoc/extra/piper.rb +0 -2
- data/lib/nanoc/filters/relativize_paths.rb +8 -7
- data/lib/nanoc/helpers/link_to.rb +0 -2
- data/lib/nanoc/rule_dsl/action_provider.rb +2 -2
- data/lib/nanoc/version.rb +1 -1
- data/nanoc.gemspec +15 -4
- data/nanoc.manifest +545 -0
- data/spec/manifest_spec.rb +22 -0
- data/spec/nanoc/base/changes_stream_spec.rb +45 -0
- data/spec/nanoc/base/checksummer_spec.rb +0 -2
- data/spec/nanoc/base/directed_graph_spec.rb +66 -0
- data/spec/nanoc/base/entities/code_snippet_spec.rb +9 -0
- data/spec/nanoc/base/entities/context_spec.rb +26 -0
- data/spec/nanoc/base/entities/identifiable_collection_spec.rb +53 -0
- data/spec/nanoc/base/repos/aggregate_data_source_spec.rb +87 -0
- data/spec/nanoc/base/repos/data_source_spec.rb +95 -0
- data/spec/nanoc/base/repos/in_mem_data_source_spec.rb +39 -0
- data/spec/nanoc/base/repos/prefixed_data_source_spec.rb +39 -0
- data/spec/nanoc/cli/error_handler_spec.rb +43 -0
- data/spec/nanoc/cli/stack_trace_writer_spec.rb +156 -0
- data/spec/nanoc/data_sources/filesystem_spec.rb +46 -0
- data/spec/nanoc/extra/live_recompiler_spec.rb +129 -0
- data/spec/nanoc/helpers/blogging_spec.rb +1 -1
- data/spec/spec_helper.rb +60 -0
- data/test/base/test_compiler.rb +11 -11
- data/test/cli/test_cli.rb +0 -1
- data/test/cli/test_error_handler.rb +4 -5
- data/test/filters/test_relativize_paths.rb +30 -0
- data/test/filters/test_sass.rb +3 -3
- data/test/rule_dsl/test_compiler_dsl.rb +2 -2
- metadata +39 -43
- data/.github/CONTRIBUTING.md +0 -17
- data/.github/ISSUE_TEMPLATE.md +0 -23
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -18
- data/.gitignore +0 -10
- data/.travis.yml +0 -27
- data/Gemfile +0 -73
- data/Guardfile +0 -5
- data/scripts/release +0 -95
- data/test/base/test_code_snippet.rb +0 -17
- data/test/base/test_context.rb +0 -35
- data/test/base/test_data_source.rb +0 -60
- data/test/base/test_directed_graph.rb +0 -56
- data/test/base/test_item_array.rb +0 -37
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Nanoc::Int::InMemDataSource, stdio: true do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new(Nanoc::DataSource) do
|
6
|
+
def item_changes
|
7
|
+
%i[one_foo one_bar]
|
8
|
+
end
|
9
|
+
|
10
|
+
def layout_changes
|
11
|
+
%i[one_foo one_bar]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:original_data_source) do
|
17
|
+
klass.new({}, nil, nil, {})
|
18
|
+
end
|
19
|
+
|
20
|
+
subject(:data_source) do
|
21
|
+
described_class.new([], [], original_data_source)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#item_changes' do
|
25
|
+
subject { data_source.item_changes }
|
26
|
+
|
27
|
+
it 'yields changes from the original' do
|
28
|
+
expect(subject).to eq(original_data_source.item_changes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#layout_changes' do
|
33
|
+
subject { data_source.layout_changes }
|
34
|
+
|
35
|
+
it 'yields changes from the original' do
|
36
|
+
expect(subject).to eq(original_data_source.layout_changes)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Nanoc::Int::PrefixedDataSource, stdio: true do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new(Nanoc::DataSource) do
|
6
|
+
def item_changes
|
7
|
+
%i[one_foo one_bar]
|
8
|
+
end
|
9
|
+
|
10
|
+
def layout_changes
|
11
|
+
%i[one_foo one_bar]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:original_data_source) do
|
17
|
+
klass.new({}, nil, nil, {})
|
18
|
+
end
|
19
|
+
|
20
|
+
subject(:data_source) do
|
21
|
+
described_class.new(original_data_source, '/itemz', '/layoutz')
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#item_changes' do
|
25
|
+
subject { data_source.item_changes }
|
26
|
+
|
27
|
+
it 'yields changes from the original' do
|
28
|
+
expect(subject).to eq(original_data_source.item_changes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#layout_changes' do
|
33
|
+
subject { data_source.layout_changes }
|
34
|
+
|
35
|
+
it 'yields changes from the original' do
|
36
|
+
expect(subject).to eq(original_data_source.layout_changes)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Nanoc::CLI::ErrorHandler do
|
4
|
+
subject(:error_handler) { described_class.new }
|
5
|
+
|
6
|
+
describe '#forwards_stack_trace?' do
|
7
|
+
subject { error_handler.forwards_stack_trace? }
|
8
|
+
|
9
|
+
context 'feature enabled' do
|
10
|
+
around do |ex|
|
11
|
+
Nanoc::Feature.enable(Nanoc::Feature::SENSIBLE_STACK_TRACES) do
|
12
|
+
ex.run
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'Ruby 2.4' do
|
17
|
+
it { is_expected.to be(true) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'Ruby 2.5' do
|
21
|
+
it { is_expected.to be(true) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'feature not enabled' do
|
26
|
+
context 'Ruby 2.4' do
|
27
|
+
before do
|
28
|
+
expect(error_handler).to receive(:ruby_version).and_return('2.4.2')
|
29
|
+
end
|
30
|
+
|
31
|
+
it { is_expected.to be(false) }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'Ruby 2.5' do
|
35
|
+
before do
|
36
|
+
expect(error_handler).to receive(:ruby_version).and_return('2.5.0')
|
37
|
+
end
|
38
|
+
|
39
|
+
it { is_expected.to be(true) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Nanoc::CLI::StackTraceWriter do
|
4
|
+
subject(:writer) do
|
5
|
+
described_class.new(io, forwards: forwards)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:io) { StringIO.new }
|
9
|
+
let(:forwards) { true }
|
10
|
+
|
11
|
+
describe '#write' do
|
12
|
+
let(:exception) do
|
13
|
+
backtrace_generator = lambda do |af|
|
14
|
+
if af.zero?
|
15
|
+
raise 'finally!'
|
16
|
+
else
|
17
|
+
backtrace_generator.call(af - 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
backtrace_generator.call(3)
|
23
|
+
rescue => e
|
24
|
+
return e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
subject { writer.write(exception, verbose: verbose) }
|
29
|
+
|
30
|
+
let(:verbose) { false }
|
31
|
+
|
32
|
+
context 'backwards' do
|
33
|
+
let(:forwards) { false }
|
34
|
+
|
35
|
+
context 'verbose' do
|
36
|
+
let(:verbose) { true }
|
37
|
+
|
38
|
+
it 'starts with zero' do
|
39
|
+
expect { subject }
|
40
|
+
.to change { io.string }
|
41
|
+
.from('')
|
42
|
+
.to(start_with(' 0. '))
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has more recent stack frames at the top' do
|
46
|
+
expect { subject }
|
47
|
+
.to change { io.string }
|
48
|
+
.from('')
|
49
|
+
.to(match(%r{^ 0\. /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m))
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'has more than 10 stack frames' do
|
53
|
+
expect { subject }
|
54
|
+
.to change { io.string }
|
55
|
+
.from('')
|
56
|
+
.to(match(%r{^ 11\. }))
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'does not contain a see-more explanation' do
|
60
|
+
subject
|
61
|
+
expect(io.string).not_to match(/crash\.log/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'not verbose' do
|
66
|
+
let(:verbose) { false }
|
67
|
+
|
68
|
+
it 'starts with zero' do
|
69
|
+
expect { subject }
|
70
|
+
.to change { io.string }
|
71
|
+
.from('')
|
72
|
+
.to(start_with(' 0. '))
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'has more recent stack frames at the top' do
|
76
|
+
expect { subject }
|
77
|
+
.to change { io.string }
|
78
|
+
.from('')
|
79
|
+
.to(match(%r{^ 0\. /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m))
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has not more than 10 stack frames' do
|
83
|
+
subject
|
84
|
+
expect(io.string).not_to match(/^ 11\. /)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'does not contain a see-more explanation' do
|
88
|
+
subject
|
89
|
+
expect(io.string).to include(" lines omitted (see crash.log for details)\n")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'forwards' do
|
95
|
+
let(:forwards) { true }
|
96
|
+
|
97
|
+
context 'verbose' do
|
98
|
+
let(:verbose) { true }
|
99
|
+
|
100
|
+
it 'ends with most recent line' do
|
101
|
+
expect { subject }
|
102
|
+
.to change { io.string }
|
103
|
+
.from('')
|
104
|
+
.to(match(%r{^ 1\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n /.+/spec/nanoc/cli}m))
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'has more recent stack frames at the bottom' do
|
108
|
+
expect { subject }
|
109
|
+
.to change { io.string }
|
110
|
+
.from('')
|
111
|
+
.to(match(%r{^ 2\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m))
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'has more than 10 stack frames' do
|
115
|
+
expect { subject }
|
116
|
+
.to change { io.string }
|
117
|
+
.from('')
|
118
|
+
.to(match(%r{^ 11\. from }))
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'does not contain a see-more explanation' do
|
122
|
+
subject
|
123
|
+
expect(io.string).not_to match(/crash\.log/)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'not verbose' do
|
128
|
+
let(:verbose) { false }
|
129
|
+
|
130
|
+
it 'ends with most recent line' do
|
131
|
+
expect { subject }
|
132
|
+
.to change { io.string }
|
133
|
+
.from('')
|
134
|
+
.to(match(%r{^ 1\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n /.+/spec/nanoc/cli}m))
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'has more recent stack frames at the top' do
|
138
|
+
expect { subject }
|
139
|
+
.to change { io.string }
|
140
|
+
.from('')
|
141
|
+
.to(match(%r{^ 2\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d+.*$\n 1\. from /.+/spec/nanoc/cli/stack_trace_writer_spec\.rb:\d}m))
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'has not more than 10 stack frames' do
|
145
|
+
subject
|
146
|
+
expect(io.string).not_to match(/^ 11\. from /)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'does not contain a see-more explanation' do
|
150
|
+
subject
|
151
|
+
expect(io.string).to include(" lines omitted (see crash.log for details)\n")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -79,4 +79,50 @@ describe Nanoc::DataSources::Filesystem do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
describe '#item_changes' do
|
84
|
+
subject { data_source.item_changes }
|
85
|
+
|
86
|
+
it 'returns a stream' do
|
87
|
+
expect(subject).to be_a(Nanoc::ChangesStream)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'contains one element after changing' do
|
91
|
+
FileUtils.mkdir_p('content')
|
92
|
+
|
93
|
+
enum = DDBuffer.new(1).call(subject.to_enum)
|
94
|
+
q = SizedQueue.new(1)
|
95
|
+
Thread.new { q << enum.take(1).first }
|
96
|
+
|
97
|
+
# FIXME: sleep is ugly
|
98
|
+
sleep 0.3
|
99
|
+
File.write('content/wat.md', 'stuff')
|
100
|
+
|
101
|
+
expect(q.pop).to eq(:unknown)
|
102
|
+
subject.stop
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#layout_changes' do
|
107
|
+
subject { data_source.layout_changes }
|
108
|
+
|
109
|
+
it 'returns a stream' do
|
110
|
+
expect(subject).to be_a(Nanoc::ChangesStream)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'contains one element after changing' do
|
114
|
+
FileUtils.mkdir_p('layouts')
|
115
|
+
|
116
|
+
enum = DDBuffer.new(1).call(subject.to_enum)
|
117
|
+
q = SizedQueue.new(1)
|
118
|
+
Thread.new { q << enum.take(1).first }
|
119
|
+
|
120
|
+
# FIXME: sleep is ugly
|
121
|
+
sleep 0.3
|
122
|
+
File.write('layouts/wat.md', 'stuff')
|
123
|
+
|
124
|
+
expect(q.pop).to eq(:unknown)
|
125
|
+
subject.stop
|
126
|
+
end
|
127
|
+
end
|
82
128
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Nanoc::Extra::LiveRecompiler, site: true, stdio: true do
|
4
|
+
it 'detects content changes' do
|
5
|
+
command = nil
|
6
|
+
command_runner = Nanoc::CLI::CommandRunner.new({}, [], command)
|
7
|
+
live_recompiler = described_class.new(command_runner: command_runner)
|
8
|
+
|
9
|
+
pid = fork do
|
10
|
+
trap(:INT) { exit(0) }
|
11
|
+
live_recompiler.run
|
12
|
+
end
|
13
|
+
|
14
|
+
# FIXME: wait is ugly
|
15
|
+
sleep 0.5
|
16
|
+
|
17
|
+
File.write('content/lol.html', 'hej')
|
18
|
+
sleep 0.1 until File.file?('output/lol.html')
|
19
|
+
expect(File.read('output/lol.html')).to eq('hej')
|
20
|
+
|
21
|
+
sleep 1.0 # HFS+ mtime resolution is 1s
|
22
|
+
File.write('content/lol.html', 'bye')
|
23
|
+
sleep 0.1 until File.read('output/lol.html') == 'bye'
|
24
|
+
|
25
|
+
# Stop
|
26
|
+
Process.kill('INT', pid)
|
27
|
+
Process.waitpid(pid)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'detects rules changes' do
|
31
|
+
command = nil
|
32
|
+
command_runner = Nanoc::CLI::CommandRunner.new({}, [], command)
|
33
|
+
live_recompiler = described_class.new(command_runner: command_runner)
|
34
|
+
|
35
|
+
pid = fork do
|
36
|
+
trap(:INT) { exit(0) }
|
37
|
+
live_recompiler.run
|
38
|
+
end
|
39
|
+
|
40
|
+
# FIXME: wait is ugly
|
41
|
+
sleep 0.5
|
42
|
+
|
43
|
+
File.write('content/lol.html', '<%= "hej" %>')
|
44
|
+
sleep 0.1 until File.file?('output/lol.html')
|
45
|
+
expect(File.read('output/lol.html')).to eq('<%= "hej" %>')
|
46
|
+
|
47
|
+
sleep 1.0 # HFS+ mtime resolution is 1s
|
48
|
+
File.write('Rules', <<~RULES)
|
49
|
+
compile '/**/*' do
|
50
|
+
filter :erb
|
51
|
+
write item.identifier
|
52
|
+
end
|
53
|
+
RULES
|
54
|
+
sleep 0.1 until File.read('output/lol.html') == 'hej'
|
55
|
+
|
56
|
+
# Stop
|
57
|
+
Process.kill('INT', pid)
|
58
|
+
Process.waitpid(pid)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'detects config changes' do
|
62
|
+
command = nil
|
63
|
+
command_runner = Nanoc::CLI::CommandRunner.new({}, [], command)
|
64
|
+
live_recompiler = described_class.new(command_runner: command_runner)
|
65
|
+
|
66
|
+
File.write('nanoc.yaml', 'site_name: Oldz')
|
67
|
+
File.write('content/lol.html', '<%= @config[:site_name] %>')
|
68
|
+
File.write('Rules', <<~RULES)
|
69
|
+
compile '/**/*' do
|
70
|
+
filter :erb
|
71
|
+
write item.identifier
|
72
|
+
end
|
73
|
+
RULES
|
74
|
+
|
75
|
+
pid = fork do
|
76
|
+
trap(:INT) { exit(0) }
|
77
|
+
live_recompiler.run
|
78
|
+
end
|
79
|
+
|
80
|
+
# FIXME: wait is ugly
|
81
|
+
sleep 0.5
|
82
|
+
|
83
|
+
sleep 0.1 until File.file?('output/lol.html')
|
84
|
+
expect(File.read('output/lol.html')).to eq('Oldz')
|
85
|
+
|
86
|
+
sleep 1.0 # HFS+ mtime resolution is 1s
|
87
|
+
File.write('nanoc.yaml', 'site_name: Newz')
|
88
|
+
sleep 0.1 until File.read('output/lol.html') == 'Newz'
|
89
|
+
|
90
|
+
# Stop
|
91
|
+
Process.kill('INT', pid)
|
92
|
+
Process.waitpid(pid)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'detects config changes' do
|
96
|
+
command = nil
|
97
|
+
command_runner = Nanoc::CLI::CommandRunner.new({}, [], command)
|
98
|
+
live_recompiler = described_class.new(command_runner: command_runner)
|
99
|
+
|
100
|
+
FileUtils.mkdir_p('lib')
|
101
|
+
File.write('lib/lol.rb', 'def greeting; "hi"; end')
|
102
|
+
File.write('content/lol.html', '<%= greeting %>')
|
103
|
+
File.write('Rules', <<~RULES)
|
104
|
+
compile '/**/*' do
|
105
|
+
filter :erb
|
106
|
+
write item.identifier
|
107
|
+
end
|
108
|
+
RULES
|
109
|
+
|
110
|
+
pid = fork do
|
111
|
+
trap(:INT) { exit(0) }
|
112
|
+
live_recompiler.run
|
113
|
+
end
|
114
|
+
|
115
|
+
# FIXME: wait is ugly
|
116
|
+
sleep 0.5
|
117
|
+
|
118
|
+
sleep 0.1 until File.file?('output/lol.html')
|
119
|
+
expect(File.read('output/lol.html')).to eq('hi')
|
120
|
+
|
121
|
+
sleep 1.0 # HFS+ mtime resolution is 1s
|
122
|
+
File.write('lib/lol.rb', 'def greeting; "yo"; end')
|
123
|
+
sleep 0.1 until File.read('output/lol.html') == 'yo'
|
124
|
+
|
125
|
+
# Stop
|
126
|
+
Process.kill('INT', pid)
|
127
|
+
Process.waitpid(pid)
|
128
|
+
end
|
129
|
+
end
|