howzit 2.1.28 → 2.1.29

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.
@@ -0,0 +1,296 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Howzit::ConditionalContent do
6
+ describe '.process' do
7
+ context 'with simple @if blocks' do
8
+ it 'includes content when condition is true' do
9
+ content = <<~CONTENT
10
+ @if "test" == "test"
11
+ This should be included
12
+ @end
13
+ CONTENT
14
+
15
+ result = described_class.process(content, {})
16
+ expect(result).to include('This should be included')
17
+ expect(result).not_to include('@if')
18
+ expect(result).not_to include('@end')
19
+ end
20
+
21
+ it 'excludes content when condition is false' do
22
+ content = <<~CONTENT
23
+ @if "test" == "other"
24
+ This should NOT be included
25
+ @end
26
+ CONTENT
27
+
28
+ result = described_class.process(content, {})
29
+ expect(result).not_to include('This should NOT be included')
30
+ end
31
+ end
32
+
33
+ context 'with @unless blocks' do
34
+ it 'includes content when condition is false' do
35
+ content = <<~CONTENT
36
+ @unless "test" == "other"
37
+ This should be included
38
+ @end
39
+ CONTENT
40
+
41
+ result = described_class.process(content, {})
42
+ expect(result).to include('This should be included')
43
+ end
44
+
45
+ it 'excludes content when condition is true' do
46
+ content = <<~CONTENT
47
+ @unless "test" == "test"
48
+ This should NOT be included
49
+ @end
50
+ CONTENT
51
+
52
+ result = described_class.process(content, {})
53
+ expect(result).not_to include('This should NOT be included')
54
+ end
55
+ end
56
+
57
+ context 'with nested blocks' do
58
+ it 'handles nested @if blocks correctly' do
59
+ content = <<~CONTENT
60
+ @if "outer" == "outer"
61
+ Outer content
62
+ @if "inner" == "inner"
63
+ Inner content
64
+ @end
65
+ More outer content
66
+ @end
67
+ CONTENT
68
+
69
+ result = described_class.process(content, {})
70
+ expect(result).to include('Outer content')
71
+ expect(result).to include('Inner content')
72
+ expect(result).to include('More outer content')
73
+ end
74
+
75
+ it 'excludes nested content when outer condition is false' do
76
+ content = <<~CONTENT
77
+ @if "outer" == "other"
78
+ Outer content
79
+ @if "inner" == "inner"
80
+ Inner content
81
+ @end
82
+ More outer content
83
+ @end
84
+ CONTENT
85
+
86
+ result = described_class.process(content, {})
87
+ expect(result).not_to include('Outer content')
88
+ expect(result).not_to include('Inner content')
89
+ expect(result).not_to include('More outer content')
90
+ end
91
+
92
+ it 'excludes nested content when inner condition is false' do
93
+ content = <<~CONTENT
94
+ @if "outer" == "outer"
95
+ Outer content
96
+ @if "inner" == "other"
97
+ Inner content
98
+ @end
99
+ More outer content
100
+ @end
101
+ CONTENT
102
+
103
+ result = described_class.process(content, {})
104
+ expect(result).to include('Outer content')
105
+ expect(result).not_to include('Inner content')
106
+ expect(result).to include('More outer content')
107
+ end
108
+ end
109
+
110
+ context 'with @run directives inside blocks' do
111
+ it 'includes @run when condition is true' do
112
+ content = <<~CONTENT
113
+ @if 1 == 1
114
+ @run(echo "test")
115
+ @end
116
+ CONTENT
117
+
118
+ result = described_class.process(content, {})
119
+ expect(result).to include('@run(echo "test")')
120
+ end
121
+
122
+ it 'excludes @run when condition is false' do
123
+ content = <<~CONTENT
124
+ @if 1 == 2
125
+ @run(echo "test")
126
+ @end
127
+ CONTENT
128
+
129
+ result = described_class.process(content, {})
130
+ expect(result).not_to include('@run(echo "test")')
131
+ end
132
+ end
133
+
134
+ context 'with code blocks inside conditional blocks' do
135
+ it 'includes code blocks when condition is true' do
136
+ content = <<~CONTENT
137
+ @if "test" == "test"
138
+ ```run
139
+ echo "hello"
140
+ ```
141
+ @end
142
+ CONTENT
143
+
144
+ result = described_class.process(content, {})
145
+ expect(result).to include('```run')
146
+ expect(result).to include('echo "hello"')
147
+ end
148
+
149
+ it 'excludes code blocks when condition is false' do
150
+ content = <<~CONTENT
151
+ @if "test" == "other"
152
+ ```run
153
+ echo "hello"
154
+ ```
155
+ @end
156
+ CONTENT
157
+
158
+ result = described_class.process(content, {})
159
+ expect(result).not_to include('```run')
160
+ expect(result).not_to include('echo "hello"')
161
+ end
162
+ end
163
+
164
+ context 'with metadata in conditions' do
165
+ it 'uses metadata from context' do
166
+ content = <<~CONTENT
167
+ @if env == "production"
168
+ Production content
169
+ @end
170
+ CONTENT
171
+
172
+ context = { metadata: { 'env' => 'production' } }
173
+ result = described_class.process(content, context)
174
+ expect(result).to include('Production content')
175
+ end
176
+ end
177
+
178
+ context 'with multiple sequential blocks' do
179
+ it 'handles multiple independent blocks' do
180
+ content = <<~CONTENT
181
+ @if 1 == 1
182
+ First block
183
+ @end
184
+ @if 2 == 2
185
+ Second block
186
+ @end
187
+ CONTENT
188
+
189
+ result = described_class.process(content, {})
190
+ expect(result).to include('First block')
191
+ expect(result).to include('Second block')
192
+ end
193
+ end
194
+
195
+ context 'with @elsif blocks' do
196
+ it 'includes first branch when @if condition is true' do
197
+ content = <<~CONTENT
198
+ @if 1 == 1
199
+ First branch
200
+ @elsif 2 == 2
201
+ Second branch
202
+ @else
203
+ Third branch
204
+ @end
205
+ CONTENT
206
+
207
+ result = described_class.process(content, {})
208
+ expect(result).to include('First branch')
209
+ expect(result).not_to include('Second branch')
210
+ expect(result).not_to include('Third branch')
211
+ end
212
+
213
+ it 'includes second branch when @if is false and @elsif is true' do
214
+ content = <<~CONTENT
215
+ @if 1 == 2
216
+ First branch
217
+ @elsif 2 == 2
218
+ Second branch
219
+ @else
220
+ Third branch
221
+ @end
222
+ CONTENT
223
+
224
+ result = described_class.process(content, {})
225
+ expect(result).not_to include('First branch')
226
+ expect(result).to include('Second branch')
227
+ expect(result).not_to include('Third branch')
228
+ end
229
+
230
+ it 'includes else branch when @if and @elsif are both false' do
231
+ content = <<~CONTENT
232
+ @if 1 == 2
233
+ First branch
234
+ @elsif 2 == 3
235
+ Second branch
236
+ @else
237
+ Third branch
238
+ @end
239
+ CONTENT
240
+
241
+ result = described_class.process(content, {})
242
+ expect(result).not_to include('First branch')
243
+ expect(result).not_to include('Second branch')
244
+ expect(result).to include('Third branch')
245
+ end
246
+
247
+ it 'handles multiple @elsif branches' do
248
+ content = <<~CONTENT
249
+ @if 1 == 2
250
+ First
251
+ @elsif 2 == 3
252
+ Second
253
+ @elsif 3 == 3
254
+ Third
255
+ @else
256
+ Fourth
257
+ @end
258
+ CONTENT
259
+
260
+ result = described_class.process(content, {})
261
+ expect(result).not_to include('First')
262
+ expect(result).not_to include('Second')
263
+ expect(result).to include('Third')
264
+ expect(result).not_to include('Fourth')
265
+ end
266
+
267
+ it 'handles nested @elsif blocks' do
268
+ content = <<~CONTENT
269
+ @if 1 == 1
270
+ Outer true
271
+ @if 2 == 2
272
+ Inner true
273
+ @elsif 3 == 3
274
+ Inner elsif
275
+ @else
276
+ Inner else
277
+ @end
278
+ @elsif 4 == 4
279
+ Outer elsif
280
+ @else
281
+ Outer else
282
+ @end
283
+ CONTENT
284
+
285
+ result = described_class.process(content, {})
286
+ expect(result).to include('Outer true')
287
+ expect(result).to include('Inner true')
288
+ expect(result).not_to include('Inner elsif')
289
+ expect(result).not_to include('Inner else')
290
+ expect(result).not_to include('Outer elsif')
291
+ expect(result).not_to include('Outer else')
292
+ end
293
+ end
294
+ end
295
+ end
296
+
@@ -0,0 +1,303 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Howzit::ScriptComm do
6
+ before do
7
+ Howzit.named_arguments = {}
8
+ Howzit.options[:log_level] = 0
9
+ # Clear any existing HOWZIT_COMM_FILE
10
+ ENV.delete('HOWZIT_COMM_FILE')
11
+ end
12
+
13
+ after do
14
+ # Clean up any leftover communication files
15
+ if ENV['HOWZIT_COMM_FILE'] && File.exist?(ENV['HOWZIT_COMM_FILE']) && File.file?(ENV['HOWZIT_COMM_FILE'])
16
+ begin
17
+ File.unlink(ENV['HOWZIT_COMM_FILE'])
18
+ rescue Errno::EPERM, Errno::ENOENT
19
+ # Ignore permission errors or missing files
20
+ end
21
+ end
22
+ ENV.delete('HOWZIT_COMM_FILE')
23
+ Howzit.named_arguments = {}
24
+ end
25
+
26
+ describe '.setup' do
27
+ it 'creates a communication file' do
28
+ comm_file = Howzit::ScriptComm.setup
29
+ expect(comm_file).to be_a(String)
30
+ expect(File.exist?(comm_file)).to be true
31
+ end
32
+
33
+ it 'sets HOWZIT_COMM_FILE environment variable' do
34
+ comm_file = Howzit::ScriptComm.setup
35
+ expect(ENV['HOWZIT_COMM_FILE']).to eq(comm_file)
36
+ end
37
+
38
+ it 'creates a writable file' do
39
+ comm_file = Howzit::ScriptComm.setup
40
+ expect { File.write(comm_file, 'test') }.not_to raise_error
41
+ end
42
+ end
43
+
44
+ describe '.process' do
45
+ it 'returns empty hash for non-existent file' do
46
+ result = Howzit::ScriptComm.process('/nonexistent/path')
47
+ expect(result).to eq({ logs: [], vars: {} })
48
+ end
49
+
50
+ it 'processes log messages' do
51
+ comm_file = Howzit::ScriptComm.setup
52
+ File.write(comm_file, "LOG:info:Test message\nLOG:warn:Warning message\n")
53
+ result = Howzit::ScriptComm.process(comm_file)
54
+ expect(result[:logs].length).to eq(2)
55
+ expect(result[:logs][0][:level]).to eq(:info)
56
+ expect(result[:logs][0][:message]).to eq('Test message')
57
+ expect(result[:logs][1][:level]).to eq(:warn)
58
+ expect(result[:logs][1][:message]).to eq('Warning message')
59
+ end
60
+
61
+ it 'processes variables' do
62
+ comm_file = Howzit::ScriptComm.setup
63
+ File.write(comm_file, "VAR:TEST_VAR=test_value\nVAR:ANOTHER_VAR=another_value\n")
64
+ result = Howzit::ScriptComm.process(comm_file)
65
+ expect(result[:vars]).to eq({ 'TEST_VAR' => 'test_value', 'ANOTHER_VAR' => 'another_value' })
66
+ end
67
+
68
+ it 'processes mixed logs and variables' do
69
+ comm_file = Howzit::ScriptComm.setup
70
+ File.write(comm_file, "LOG:info:Starting\nVAR:STATUS=running\nLOG:info:Done\nVAR:STATUS=complete\n")
71
+ result = Howzit::ScriptComm.process(comm_file)
72
+ expect(result[:logs].length).to eq(2)
73
+ expect(result[:vars]).to eq({ 'STATUS' => 'complete' })
74
+ end
75
+
76
+ it 'handles all log levels' do
77
+ comm_file = Howzit::ScriptComm.setup
78
+ File.write(comm_file, "LOG:info:Info message\nLOG:warn:Warn message\nLOG:error:Error message\nLOG:debug:Debug message\n")
79
+ result = Howzit::ScriptComm.process(comm_file)
80
+ expect(result[:logs].map { |l| l[:level] }).to contain_exactly(:info, :warn, :error, :debug)
81
+ end
82
+
83
+ it 'ignores empty lines' do
84
+ comm_file = Howzit::ScriptComm.setup
85
+ File.write(comm_file, "\nLOG:info:Message\n\nVAR:TEST=value\n\n")
86
+ result = Howzit::ScriptComm.process(comm_file)
87
+ expect(result[:logs].length).to eq(1)
88
+ expect(result[:vars]).to eq({ 'TEST' => 'value' })
89
+ end
90
+
91
+ it 'handles case-insensitive log levels' do
92
+ comm_file = Howzit::ScriptComm.setup
93
+ File.write(comm_file, "LOG:INFO:Uppercase\nLOG:Warn:Mixed\nLOG:error:lowercase\n")
94
+ result = Howzit::ScriptComm.process(comm_file)
95
+ expect(result[:logs].map { |l| l[:level] }).to contain_exactly(:info, :warn, :error)
96
+ end
97
+
98
+ it 'handles case-insensitive variable names' do
99
+ comm_file = Howzit::ScriptComm.setup
100
+ File.write(comm_file, "VAR:test_var=lowercase\nVAR:TEST_VAR=uppercase\n")
101
+ result = Howzit::ScriptComm.process(comm_file)
102
+ # Variable names match case-insensitively, but both are stored (last one wins)
103
+ # The regex captures the original case, so both keys are present
104
+ expect(result[:vars].keys).to include('TEST_VAR')
105
+ expect(result[:vars].keys).to include('test_var')
106
+ end
107
+
108
+ it 'removes the communication file after processing' do
109
+ comm_file = Howzit::ScriptComm.setup
110
+ File.write(comm_file, "VAR:TEST=value\n")
111
+ Howzit::ScriptComm.process(comm_file)
112
+ expect(File.exist?(comm_file)).to be false
113
+ end
114
+
115
+ it 'handles malformed lines gracefully' do
116
+ comm_file = Howzit::ScriptComm.setup
117
+ File.write(comm_file, "INVALID:line\nLOG:info:Valid message\nVAR:TEST=value\nBOGUS\n")
118
+ result = Howzit::ScriptComm.process(comm_file)
119
+ expect(result[:logs].length).to eq(1)
120
+ expect(result[:vars]).to eq({ 'TEST' => 'value' })
121
+ end
122
+
123
+ it 'handles file read errors gracefully' do
124
+ # Create a file that will cause a read error
125
+ comm_file = Howzit::ScriptComm.setup
126
+ # Make it unreadable (but this is platform-dependent, so just test that it doesn't crash)
127
+ # Instead, test with a file that doesn't exist after setup
128
+ File.unlink(comm_file) if File.exist?(comm_file)
129
+ result = Howzit::ScriptComm.process(comm_file)
130
+ expect(result).to eq({ logs: [], vars: {} })
131
+ end
132
+ end
133
+
134
+ describe '.apply' do
135
+ it 'applies log messages to console' do
136
+ comm_file = Howzit::ScriptComm.setup
137
+ File.write(comm_file, "LOG:info:Test info message\n")
138
+ expect(Howzit.console).to receive(:info).with('Test info message')
139
+ Howzit::ScriptComm.apply(comm_file)
140
+ end
141
+
142
+ it 'applies variables to named_arguments' do
143
+ comm_file = Howzit::ScriptComm.setup
144
+ File.write(comm_file, "VAR:TEST_VAR=test_value\n")
145
+ Howzit::ScriptComm.apply(comm_file)
146
+ expect(Howzit.named_arguments['TEST_VAR']).to eq('test_value')
147
+ end
148
+
149
+ it 'merges variables with existing named_arguments' do
150
+ Howzit.named_arguments = { 'EXISTING' => 'old_value' }
151
+ comm_file = Howzit::ScriptComm.setup
152
+ File.write(comm_file, "VAR:NEW_VAR=new_value\n")
153
+ Howzit::ScriptComm.apply(comm_file)
154
+ expect(Howzit.named_arguments).to eq({ 'EXISTING' => 'old_value', 'NEW_VAR' => 'new_value' })
155
+ end
156
+
157
+ it 'overwrites existing variables' do
158
+ Howzit.named_arguments = { 'TEST_VAR' => 'old_value' }
159
+ comm_file = Howzit::ScriptComm.setup
160
+ File.write(comm_file, "VAR:TEST_VAR=new_value\n")
161
+ Howzit::ScriptComm.apply(comm_file)
162
+ expect(Howzit.named_arguments['TEST_VAR']).to eq('new_value')
163
+ end
164
+
165
+ it 'handles multiple log levels' do
166
+ comm_file = Howzit::ScriptComm.setup
167
+ File.write(comm_file, "LOG:info:Info\nLOG:warn:Warn\nLOG:error:Error\nLOG:debug:Debug\n")
168
+ expect(Howzit.console).to receive(:info).with('Info')
169
+ expect(Howzit.console).to receive(:warn).with('Warn')
170
+ expect(Howzit.console).to receive(:error).with('Error')
171
+ expect(Howzit.console).to receive(:debug).with('Debug')
172
+ Howzit::ScriptComm.apply(comm_file)
173
+ end
174
+
175
+ it 'does nothing if file is empty' do
176
+ comm_file = Howzit::ScriptComm.setup
177
+ File.write(comm_file, "\n")
178
+ Howzit::ScriptComm.apply(comm_file)
179
+ expect(Howzit.named_arguments).to be_empty
180
+ end
181
+
182
+ it 'initializes named_arguments if nil' do
183
+ Howzit.named_arguments = nil
184
+ comm_file = Howzit::ScriptComm.setup
185
+ File.write(comm_file, "VAR:TEST=value\n")
186
+ Howzit::ScriptComm.apply(comm_file)
187
+ expect(Howzit.named_arguments).to eq({ 'TEST' => 'value' })
188
+ end
189
+ end
190
+
191
+ describe 'integration with Task#run_run' do
192
+ it 'processes communication file after script execution' do
193
+ # Create a temporary script that writes to communication file
194
+ script_file = Tempfile.new('test_script')
195
+ script_file.write(<<~SCRIPT)
196
+ #!/bin/bash
197
+ echo "VAR:TEST_VAR=script_value" >> "$HOWZIT_COMM_FILE"
198
+ echo "LOG:info:Script message" >> "$HOWZIT_COMM_FILE"
199
+ SCRIPT
200
+ script_file.close
201
+ File.chmod(0o755, script_file.path)
202
+
203
+ task = Howzit::Task.new({ type: :run,
204
+ title: 'Test Script',
205
+ action: script_file.path })
206
+
207
+ allow(Howzit.console).to receive(:info)
208
+ expect(Howzit.console).to receive(:info).with('Script message')
209
+
210
+ task.run
211
+
212
+ expect(Howzit.named_arguments['TEST_VAR']).to eq('script_value')
213
+
214
+ script_file.unlink
215
+ end
216
+
217
+ it 'makes variables available for subsequent tasks' do
218
+ # Create first script that sets a variable
219
+ script1 = Tempfile.new('script1')
220
+ script1.write(<<~SCRIPT)
221
+ #!/bin/bash
222
+ echo "VAR:BUILD_VERSION=1.2.3" >> "$HOWZIT_COMM_FILE"
223
+ SCRIPT
224
+ script1.close
225
+ File.chmod(0o755, script1.path)
226
+
227
+ # Create second script that uses the variable (simulated via echo)
228
+ script2 = Tempfile.new('script2')
229
+ script2.write(<<~SCRIPT)
230
+ #!/bin/bash
231
+ echo "Version would be: ${BUILD_VERSION}"
232
+ SCRIPT
233
+ script2.close
234
+ File.chmod(0o755, script2.path)
235
+
236
+ # Run first task
237
+ task1 = Howzit::Task.new({ type: :run,
238
+ title: 'Set Version',
239
+ action: script1.path })
240
+ allow(Howzit.console).to receive(:info)
241
+ task1.run
242
+
243
+ # Verify variable is set
244
+ expect(Howzit.named_arguments['BUILD_VERSION']).to eq('1.2.3')
245
+
246
+ # Create a task with variable substitution in the action
247
+ # Note: Variable substitution happens when Task is created,
248
+ # so we need to create task2 AFTER task1 runs
249
+ action_with_var = "echo Version: ${BUILD_VERSION}"
250
+ action_rendered = action_with_var.dup
251
+ action_rendered.render_named_placeholders
252
+ expect(action_rendered).to include('1.2.3')
253
+
254
+ script1.unlink
255
+ script2.unlink
256
+ end
257
+ end
258
+
259
+ describe 'integration with Task#run_block' do
260
+ it 'processes communication file after block execution' do
261
+ block_content = <<~BLOCK
262
+ #!/bin/bash
263
+ echo "VAR:BLOCK_VAR=block_value" >> "$HOWZIT_COMM_FILE"
264
+ echo "LOG:info:Block message" >> "$HOWZIT_COMM_FILE"
265
+ BLOCK
266
+
267
+ task = Howzit::Task.new({ type: :block,
268
+ title: 'Test Block',
269
+ action: block_content })
270
+
271
+ allow(Howzit.console).to receive(:info)
272
+ expect(Howzit.console).to receive(:info).with('Block message')
273
+
274
+ task.run
275
+
276
+ expect(Howzit.named_arguments['BLOCK_VAR']).to eq('block_value')
277
+ end
278
+
279
+ it 'cleans up communication file after block execution' do
280
+ comm_file_path = nil
281
+ allow(Howzit::ScriptComm).to receive(:setup).and_wrap_original do |m|
282
+ comm_file_path = m.call
283
+ comm_file_path
284
+ end
285
+
286
+ block_content = <<~BLOCK
287
+ #!/bin/bash
288
+ echo "VAR:TEST=value" >> "$HOWZIT_COMM_FILE"
289
+ BLOCK
290
+
291
+ task = Howzit::Task.new({ type: :block,
292
+ title: 'Test Block',
293
+ action: block_content })
294
+
295
+ allow(Howzit.console).to receive(:info)
296
+ task.run
297
+
298
+ # Communication file should be cleaned up
299
+ expect(File.exist?(comm_file_path)).to be false if comm_file_path
300
+ end
301
+ end
302
+ end
303
+
data/spec/spec_helper.rb CHANGED
@@ -16,6 +16,8 @@ RSpec.configure do |c|
16
16
  c.before(:each) do
17
17
  allow(FileUtils).to receive(:remove_entry_secure).with(anything)
18
18
  save_buildnote
19
+ # Reset buildnote cache to ensure fresh instance with updated file
20
+ Howzit.instance_variable_set(:@buildnote, nil)
19
21
  Howzit.options[:include_upstream] = false
20
22
  Howzit.options[:default] = true
21
23
  Howzit.options[:matching] = 'partial'
@@ -87,5 +89,5 @@ def save_buildnote
87
89
  end
88
90
 
89
91
  def delete_buildnote
90
- FileUtils.rm('builda.md')
92
+ FileUtils.rm_f('builda.md')
91
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howzit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.28
4
+ version: 2.1.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
@@ -127,14 +127,14 @@ dependencies:
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '0.28'
130
+ version: '1.60'
131
131
  type: :development
132
132
  prerelease: false
133
133
  version_requirements: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '0.28'
137
+ version: '1.60'
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: simplecov
140
140
  requirement: !ruby/object:Gem::Requirement
@@ -298,11 +298,14 @@ files:
298
298
  - lib/howzit.rb
299
299
  - lib/howzit/buildnote.rb
300
300
  - lib/howzit/colors.rb
301
+ - lib/howzit/condition_evaluator.rb
302
+ - lib/howzit/conditional_content.rb
301
303
  - lib/howzit/config.rb
302
304
  - lib/howzit/console_logger.rb
303
305
  - lib/howzit/hash.rb
304
306
  - lib/howzit/prompt.rb
305
307
  - lib/howzit/run_report.rb
308
+ - lib/howzit/script_comm.rb
306
309
  - lib/howzit/stringutils.rb
307
310
  - lib/howzit/task.rb
308
311
  - lib/howzit/topic.rb
@@ -311,9 +314,13 @@ files:
311
314
  - scripts/runtests.sh
312
315
  - spec/buildnote_spec.rb
313
316
  - spec/cli_spec.rb
317
+ - spec/condition_evaluator_spec.rb
318
+ - spec/conditional_blocks_integration_spec.rb
319
+ - spec/conditional_content_spec.rb
314
320
  - spec/prompt_spec.rb
315
321
  - spec/ruby_gem_spec.rb
316
322
  - spec/run_report_spec.rb
323
+ - spec/script_comm_spec.rb
317
324
  - spec/spec_helper.rb
318
325
  - spec/stringutils_spec.rb
319
326
  - spec/task_spec.rb
@@ -346,9 +353,13 @@ summary: Provides a way to access Markdown project notes by topic with query cap
346
353
  test_files:
347
354
  - spec/buildnote_spec.rb
348
355
  - spec/cli_spec.rb
356
+ - spec/condition_evaluator_spec.rb
357
+ - spec/conditional_blocks_integration_spec.rb
358
+ - spec/conditional_content_spec.rb
349
359
  - spec/prompt_spec.rb
350
360
  - spec/ruby_gem_spec.rb
351
361
  - spec/run_report_spec.rb
362
+ - spec/script_comm_spec.rb
352
363
  - spec/spec_helper.rb
353
364
  - spec/stringutils_spec.rb
354
365
  - spec/task_spec.rb