howzit 2.1.26 → 2.1.27

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: 19fc185635709d53c4d7dcf0b437d4ec6b00cdd341d734e4655ef4e8e1dbfd3a
4
- data.tar.gz: 9305e6edf7a8c4f7bf6d2d6a4a1aed14313aac73b658595a877314e929c15c8b
3
+ metadata.gz: cfddcd9969d36eaa46a5441a912b60a0d4622c7536ffd34c6aebe83cc3c840a3
4
+ data.tar.gz: 9e5d7fee17c7931fc03b455eebe411f1490e1c27d70545f5e5a3d62f492a2f50
5
5
  SHA512:
6
- metadata.gz: a35475dfaf7aa381157964466046ff8c94b0a4282bd9bbb8c067b7d344527d8ba95a296934ce935375111c4c255122cd3c684829d761b4962c517ea6dfadc14b
7
- data.tar.gz: 41ae72b53d9602fb9b6df8231a4d1db8d9f134b78460e2243e8afaf616528279d0e7b08d68820a330994935579186058838a5d5e5c288b809aa46d0670b71b0f
6
+ metadata.gz: '019b3813e1f3ed8a79f70711a0f2dae38a83f0cfca205a32d9ab14794ba9815ce8d971d26f6bed0afbb90ce9d4ffd5d0d926cf50ef965cf806ffa45565203611'
7
+ data.tar.gz: c77fdeea70957604027d8152517498e8fe6df7043f36e139f8a81b23daca958d701a2dda786385921a6d9bf5c01acaca068375e7d3b9bd680091a3e988275069
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ### 2.1.27
2
+
3
+ 2025-12-26 08:59
4
+
5
+ #### IMPROVED
6
+
7
+ - Task titles now support variable substitution using ${VAR} syntax, so titles like "@run(echo test) Title with ${var}" will replace ${var} with its value from topic metadata. This applies to all task types (run, copy, open, include) and code block titles.
8
+
9
+ #### FIXED
10
+
11
+ - Task and topic names containing dollar signs (like $text$ or ${VAR}) now display correctly in run report output without causing color code interpretation issues. Dollar signs are properly escaped during formatting and unescaped in the final output.
12
+
1
13
  ### 2.1.26
2
14
 
3
15
  2025-12-26 04:53
data/lib/howzit/colors.rb CHANGED
@@ -288,8 +288,8 @@ module Howzit
288
288
  d: dark, b: bold, u: underline, i: italic, x: reset }
289
289
 
290
290
  result = fmt.empty? ? input : format(fmt, colors)
291
- # Unescape braces that were escaped to prevent color code interpretation
292
- result.gsub(/\\\{/, '{').gsub(/\\\}/, '}')
291
+ # Unescape braces and dollar signs that were escaped to prevent color code interpretation
292
+ result.gsub(/\\\{/, '{').gsub(/\\\}/, '}').gsub(/\\\$/, '$')
293
293
  end
294
294
  end
295
295
 
@@ -30,13 +30,13 @@ module Howzit
30
30
  symbol = entry[:success] ? '✅' : '❌'
31
31
  parts = ["#{symbol} "]
32
32
  if prefix_topic && entry[:topic] && !entry[:topic].empty?
33
- # Escape braces in topic name to prevent color code interpretation
34
- topic_escaped = entry[:topic].gsub(/\{/, '\\{').gsub(/\}/, '\\}')
33
+ # Escape braces and dollar signs in topic name to prevent color code interpretation
34
+ topic_escaped = entry[:topic].gsub(/\{/, '\\{').gsub(/\}/, '\\}').gsub(/\$/, '\\$')
35
35
  parts << "{bw}#{topic_escaped}{x}: "
36
36
  end
37
- # Escape braces in task name to prevent color code interpretation
38
- task_escaped = entry[:task].gsub(/\{/, '\\{').gsub(/\}/, '\\}')
39
- parts << "{by}#{task_escaped}{x}"
37
+ # Escape braces and dollar signs in task name to prevent color code interpretation
38
+ task_escaped = entry[:task].gsub(/\{/, '\\{').gsub(/\}/, '\\}').gsub(/\$/, '\\$')
39
+ parts << "{by}#{task_escaped} {x}"
40
40
  unless entry[:success]
41
41
  reason = entry[:exit_status] ? "exit code #{entry[:exit_status]}" : 'failed'
42
42
  parts << " {br}(#{reason}){x}"
@@ -82,15 +82,15 @@ module Howzit
82
82
  task_parts_plain = []
83
83
 
84
84
  if prefix_topic && entry[:topic] && !entry[:topic].empty?
85
- # Escape braces in topic name to prevent color code interpretation
86
- topic_escaped = entry[:topic].gsub(/\{/, '\\{').gsub(/\}/, '\\}')
85
+ # Escape braces and dollar signs in topic name to prevent color code interpretation
86
+ topic_escaped = entry[:topic].gsub(/\{/, '\\{').gsub(/\}/, '\\}').gsub(/\$/, '\\$')
87
87
  task_parts << "{bw}#{topic_escaped}{x}: "
88
88
  task_parts_plain << "#{entry[:topic]}: "
89
89
  end
90
90
 
91
- # Escape braces in task name to prevent color code interpretation
92
- task_escaped = entry[:task].gsub(/\{/, '\\{').gsub(/\}/, '\\}')
93
- task_parts << "{by}#{task_escaped}{x}"
91
+ # Escape braces and dollar signs in task name to prevent color code interpretation
92
+ task_escaped = entry[:task].gsub(/\{/, '\\{').gsub(/\}/, '\\}').gsub(/\$/, '\\$')
93
+ task_parts << "{by}#{task_escaped} {x}"
94
94
  task_parts_plain << entry[:task]
95
95
 
96
96
  unless entry[:success]
data/lib/howzit/topic.rb CHANGED
@@ -302,26 +302,31 @@ module Howzit
302
302
  title: title.dup, # Make a copy to avoid reference issues
303
303
  action: obj,
304
304
  parent: self }
305
+ # Set named_arguments before processing titles for variable substitution
306
+ Howzit.named_arguments = @named_args
305
307
  case cmd
306
308
  when /include/i
307
309
  if title =~ /\[(.*?)\] *$/
308
- Howzit.named_arguments = @named_args
309
310
  args = Regexp.last_match(1).split(/ *, */).map(&:render_arguments)
310
311
  Howzit.arguments = args
311
312
  arguments
312
313
  title.sub!(/ *\[.*?\] *$/, '')
313
- task_args[:title] = title
314
314
  end
315
+ # Apply variable substitution to title after bracket processing
316
+ task_args[:title] = title.render_arguments
315
317
 
316
318
  task_args[:type] = :include
317
319
  task_args[:arguments] = Howzit.named_arguments
318
320
  when /run/i
319
321
  task_args[:type] = :run
322
+ task_args[:title] = title.render_arguments
320
323
  when /copy/i
321
324
  task_args[:type] = :copy
322
325
  task_args[:action] = Shellwords.escape(obj)
326
+ task_args[:title] = title.render_arguments
323
327
  when /open|url/i
324
328
  task_args[:type] = :open
329
+ task_args[:title] = title.render_arguments
325
330
  end
326
331
 
327
332
  task_args
@@ -373,6 +378,8 @@ module Howzit
373
378
  if c[:cmd].nil?
374
379
  optional, default = define_optional(c[:optional2])
375
380
  title = c[:title2].nil? ? '' : c[:title2].strip
381
+ # Apply variable substitution to block title
382
+ title = title.render_arguments if title && !title.empty?
376
383
  block = c[:block]&.strip
377
384
  runnable << Howzit::Task.new({ type: :block,
378
385
  title: title,
@@ -3,5 +3,5 @@
3
3
  # Primary module for this gem.
4
4
  module Howzit
5
5
  # Current Howzit version.
6
- VERSION = '2.1.26'
6
+ VERSION = '2.1.27'
7
7
  end
@@ -47,5 +47,25 @@ describe Howzit::RunReport do
47
47
  # Second line should be separator
48
48
  expect(lines[1]).to match(/^\|[\s:-]+\|[\s:-]+\|$/)
49
49
  end
50
+
51
+ it 'preserves dollar signs in task names without interfering with color codes' do
52
+ Howzit::RunReport.log({ topic: 'Test Topic', task: '$text$', success: true, exit_status: 0 })
53
+ Howzit::RunReport.log({ topic: 'Test', task: 'echo ${VAR}', success: true, exit_status: 0 })
54
+ plain = Howzit::RunReport.format.uncolor
55
+ expect(plain).to include('$text$')
56
+ expect(plain).to include('${VAR}')
57
+ # Verify dollar signs are preserved and not causing color code issues
58
+ expect(plain).not_to include('{x}')
59
+ expect(plain.scan(/\$\{x\}/).length).to eq(0)
60
+ end
61
+
62
+ it 'preserves dollar signs in topic names without interfering with color codes' do
63
+ Howzit.multi_topic_run = true
64
+ Howzit::RunReport.log({ topic: '$dollar$ Topic', task: 'Some Task', success: true, exit_status: 0 })
65
+ plain = Howzit::RunReport.format.uncolor
66
+ expect(plain).to include('$dollar$ Topic')
67
+ expect(plain).not_to include('{x}')
68
+ expect(plain.scan(/\$\{x\}/).length).to eq(0)
69
+ end
50
70
  end
51
71
 
data/spec/topic_spec.rb CHANGED
@@ -101,4 +101,33 @@ describe Howzit::Topic do
101
101
  expect(topic.print_out({ single: true, header: true }).join("\n").uncolor).to match(/▶ ls -1/)
102
102
  end
103
103
  end
104
+
105
+
106
+ describe '.arguments' do
107
+ before do
108
+ Howzit.arguments = []
109
+ end
110
+
111
+ it 'extracts named arguments from topic title with defaults' do
112
+ topic = Howzit::Topic.new('Test Topic (var1:default1, var2:default2)', 'Content')
113
+ expect(topic.named_args['var1']).to eq('default1')
114
+ expect(topic.named_args['var2']).to eq('default2')
115
+ end
116
+
117
+ it 'does nothing when title has no arguments' do
118
+ topic = Howzit::Topic.new('Test Topic', 'Content')
119
+ expect(topic.named_args).to eq({})
120
+ end
121
+
122
+ it 'cleans title after extracting arguments' do
123
+ topic = Howzit::Topic.new('Test Topic (var:val)', 'Content')
124
+ expect(topic.title).to eq('Test Topic')
125
+ end
126
+
127
+ it 'uses provided arguments over defaults' do
128
+ Howzit.arguments = ['provided_value']
129
+ topic = Howzit::Topic.new('Test Topic (var:default_value)', 'Content')
130
+ expect(topic.named_args['var']).to eq('provided_value')
131
+ end
132
+ end
104
133
  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.26
4
+ version: 2.1.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra