howzit 1.2.9 → 1.2.12
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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +23 -2
- data/Gemfile +2 -0
- data/Guardfile +3 -1
- data/README.md +1 -0
- data/Rakefile +15 -2
- data/bin/howzit +4 -2
- data/howzit.gemspec +1 -1
- data/lib/howzit/buildnotes.rb +112 -92
- data/lib/howzit/colors.rb +323 -0
- data/lib/howzit/stringutils.rb +1 -1
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +1 -0
- data/spec/ruby_gem_spec.rb +34 -1
- data/spec/spec_helper.rb +8 -8
- metadata +2 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 875d039552876588bf298e4297ffec3955a6a73da6c2f89f608f7d11ed9d4e93
|
|
4
|
+
data.tar.gz: ecd7f0dd8f67999de4e223745f79096cc06ebd84e867400bc729f2323e8f8360
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfcad0fc1a4fbf0140dc91ae5cf03e52c3d42aed4a404c91fab642db05d9849b92c0c73d4f87d79ca0b58d1583a6a0ab5ef0ef9936812913567aeb3f24508a93
|
|
7
|
+
data.tar.gz: db44b03b2f2c25c84187692a9d46a328a22d4a7dce0adc20304ab31fe58e91b6ca4bef6848ab69efcce5e0c60e9c8955501f4232d5643f664d35cb81da9bcbdf
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
### 1.2.
|
|
1
|
+
### 1.2.12
|
|
2
2
|
|
|
3
|
-
2022-08-01
|
|
3
|
+
2022-08-01 16:23
|
|
4
|
+
|
|
5
|
+
#### IMPROVED
|
|
6
|
+
|
|
7
|
+
- Replace ANSI escape codes with color template system
|
|
8
|
+
- When @including an external file, if the file doesn't contain any level 2+ headers, import it as plain text.
|
|
9
|
+
|
|
10
|
+
### 1.2.11
|
|
11
|
+
|
|
12
|
+
2022-08-01 08:23
|
|
13
|
+
|
|
14
|
+
#### IMPROVED
|
|
15
|
+
|
|
16
|
+
- Code cleanup and refactoring
|
|
17
|
+
|
|
18
|
+
### 1.2.10
|
|
19
|
+
|
|
20
|
+
2022-08-01 07:45
|
|
21
|
+
|
|
22
|
+
#### FIXED
|
|
23
|
+
|
|
24
|
+
- Headline formatting when iTerm markers are inserted
|
|
4
25
|
|
|
5
26
|
### 1.2.8
|
|
6
27
|
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Howzit
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/howzit)
|
|
4
|
+
[](https://travis-ci.org/makenew/ruby-gem)
|
|
4
5
|
[](./LICENSE.txt)
|
|
5
6
|
|
|
6
7
|
A command-line reference tool for tracking project build systems
|
data/Rakefile
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'bump/tasks'
|
|
2
4
|
require 'bundler/gem_tasks'
|
|
3
5
|
require 'rspec/core/rake_task'
|
|
4
6
|
require 'rubocop/rake_task'
|
|
5
7
|
require 'yard'
|
|
6
8
|
|
|
7
|
-
task default: [
|
|
9
|
+
task default: %i[test yard]
|
|
8
10
|
|
|
9
11
|
desc 'Run test suite'
|
|
10
|
-
task test: [
|
|
12
|
+
task test: %i[rubocop spec]
|
|
11
13
|
|
|
12
14
|
RSpec::Core::RakeTask.new
|
|
13
15
|
|
|
@@ -16,3 +18,14 @@ RuboCop::RakeTask.new do |t|
|
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
YARD::Rake::YardocTask.new
|
|
21
|
+
|
|
22
|
+
desc 'Development version check'
|
|
23
|
+
task :ver do
|
|
24
|
+
gver = `git ver`
|
|
25
|
+
cver = IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
|
26
|
+
res = `grep VERSION lib/howzit/version.rb`
|
|
27
|
+
version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
|
|
28
|
+
puts "git tag: #{gver}"
|
|
29
|
+
puts "version.rb: #{version}"
|
|
30
|
+
puts "changelog: #{cver}"
|
|
31
|
+
end
|
data/bin/howzit
CHANGED
data/howzit.gemspec
CHANGED
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.add_development_dependency 'rubocop', '~> 0.28'
|
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
|
33
33
|
spec.add_development_dependency 'simplecov', '~> 0.9'
|
|
34
|
-
spec.add_development_dependency 'codecov', '~> 0.1'
|
|
34
|
+
# spec.add_development_dependency 'codecov', '~> 0.1'
|
|
35
35
|
spec.add_development_dependency 'fuubar', '~> 2.0'
|
|
36
36
|
|
|
37
37
|
spec.add_development_dependency 'yard', '~> 0.9.5'
|
data/lib/howzit/buildnotes.rb
CHANGED
|
@@ -2,8 +2,9 @@ module Howzit
|
|
|
2
2
|
# Primary Class for this module
|
|
3
3
|
class BuildNotes
|
|
4
4
|
include Prompt
|
|
5
|
+
include Color
|
|
5
6
|
|
|
6
|
-
attr_accessor :arguments, :metadata
|
|
7
|
+
attr_accessor :cli_args, :options, :arguments, :metadata
|
|
7
8
|
|
|
8
9
|
def topics
|
|
9
10
|
@topics ||= read_help
|
|
@@ -40,8 +41,8 @@ module Howzit
|
|
|
40
41
|
# favoring environment settings
|
|
41
42
|
def which_pager
|
|
42
43
|
if @options[:pager] =~ /auto/i
|
|
43
|
-
pagers = [ENV['
|
|
44
|
-
'bat', 'less', 'more', '
|
|
44
|
+
pagers = [ENV['PAGER'], ENV['GIT_PAGER'],
|
|
45
|
+
'bat', 'less', 'more', 'pager']
|
|
45
46
|
pagers.delete_if(&:nil?).select!(&:available?)
|
|
46
47
|
return nil if pagers.empty?
|
|
47
48
|
|
|
@@ -132,8 +133,12 @@ module Howzit
|
|
|
132
133
|
end
|
|
133
134
|
end
|
|
134
135
|
|
|
136
|
+
def should_mark_iterm?
|
|
137
|
+
ENV['TERM_PROGRAM'] =~ /^iTerm/ && !@options[:run] && !@options[:paginate]
|
|
138
|
+
end
|
|
139
|
+
|
|
135
140
|
def iterm_marker
|
|
136
|
-
"\e]1337;SetMark\a
|
|
141
|
+
"\e]1337;SetMark\a" if should_mark_iterm?
|
|
137
142
|
end
|
|
138
143
|
|
|
139
144
|
def color_single_options(choices = %w[y n])
|
|
@@ -141,12 +146,12 @@ module Howzit
|
|
|
141
146
|
choices.each do |choice|
|
|
142
147
|
case choice
|
|
143
148
|
when /[A-Z]/
|
|
144
|
-
out.push("
|
|
149
|
+
out.push(Color.template("{bg}#{choice}{xg}"))
|
|
145
150
|
else
|
|
146
|
-
out.push(choice)
|
|
151
|
+
out.push(Color.template("{w}#{choice}"))
|
|
147
152
|
end
|
|
148
153
|
end
|
|
149
|
-
"
|
|
154
|
+
Color.template("{g}[#{out.join('/')}{g}]{x}")
|
|
150
155
|
end
|
|
151
156
|
|
|
152
157
|
# Create a buildnotes skeleton
|
|
@@ -157,7 +162,7 @@ module Howzit
|
|
|
157
162
|
end
|
|
158
163
|
# First make sure there isn't already a buildnotes file
|
|
159
164
|
if note_file
|
|
160
|
-
fname = "
|
|
165
|
+
fname = Color.template("{by}#{note_file}{bw}")
|
|
161
166
|
res = yn("#{fname} exists and appears to be a build note, continue anyway?", false)
|
|
162
167
|
unless res
|
|
163
168
|
puts 'Canceled'
|
|
@@ -166,19 +171,19 @@ module Howzit
|
|
|
166
171
|
end
|
|
167
172
|
|
|
168
173
|
title = File.basename(Dir.pwd)
|
|
169
|
-
printf "
|
|
170
|
-
input =
|
|
174
|
+
printf Color.template("{bw}Project name {xg}[#{title}]{bw}: {x}")
|
|
175
|
+
input = $stdin.gets.chomp
|
|
171
176
|
title = input unless input.empty?
|
|
172
177
|
|
|
173
178
|
summary = ''
|
|
174
|
-
printf
|
|
175
|
-
input =
|
|
179
|
+
printf Color.template('{bw}Project summary: {x}')
|
|
180
|
+
input = $stdin.gets.chomp
|
|
176
181
|
summary = input unless input.empty?
|
|
177
182
|
|
|
178
|
-
|
|
179
|
-
printf "
|
|
180
|
-
input =
|
|
181
|
-
|
|
183
|
+
fname = 'buildnotes.md'
|
|
184
|
+
printf Color.template("{bw}Build notes filename (must begin with 'howzit' or 'build')\n{xg}[#{fname}]{bw}: {x}")
|
|
185
|
+
input = $stdin.gets.chomp
|
|
186
|
+
fname = input unless input.empty?
|
|
182
187
|
|
|
183
188
|
note = <<~EOBUILDNOTES
|
|
184
189
|
# #{title}
|
|
@@ -205,8 +210,8 @@ module Howzit
|
|
|
205
210
|
|
|
206
211
|
EOBUILDNOTES
|
|
207
212
|
|
|
208
|
-
if File.exist?(
|
|
209
|
-
file = "
|
|
213
|
+
if File.exist?(fname)
|
|
214
|
+
file = Color.template("{by}#{fname}")
|
|
210
215
|
res = yn("Are you absolutely sure you want to overwrite #{file}", false)
|
|
211
216
|
|
|
212
217
|
unless res
|
|
@@ -215,9 +220,9 @@ module Howzit
|
|
|
215
220
|
end
|
|
216
221
|
end
|
|
217
222
|
|
|
218
|
-
File.open(
|
|
223
|
+
File.open(fname, 'w') do |f|
|
|
219
224
|
f.puts note
|
|
220
|
-
puts "Build notes for #{title} written to #{
|
|
225
|
+
puts Color.template("{by}Build notes for #{title} written to #{fname}")
|
|
221
226
|
end
|
|
222
227
|
end
|
|
223
228
|
|
|
@@ -225,32 +230,39 @@ module Howzit
|
|
|
225
230
|
def format_header(title, opts = {})
|
|
226
231
|
options = {
|
|
227
232
|
hr: "\u{254C}",
|
|
228
|
-
color: '
|
|
229
|
-
border: '
|
|
233
|
+
color: '{bg}',
|
|
234
|
+
border: '{x}',
|
|
235
|
+
mark: false
|
|
230
236
|
}
|
|
231
237
|
|
|
232
238
|
options.merge!(opts)
|
|
233
239
|
|
|
234
240
|
cols = TTY::Screen.columns
|
|
241
|
+
|
|
235
242
|
cols = @options[:wrap] if (@options[:wrap]).positive? && cols > @options[:wrap]
|
|
236
|
-
title = "
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
title = Color.template("#{options[:border]}#{options[:hr] * 2}( #{options[:color]}#{title}#{options[:border]} )")
|
|
244
|
+
|
|
245
|
+
tail = if should_mark_iterm?
|
|
246
|
+
"#{options[:hr] * (cols - title.uncolor.length - 15)}#{options[:mark] ? iterm_marker : ''}"
|
|
247
|
+
else
|
|
248
|
+
options[:hr] * (cols - title.uncolor.length)
|
|
249
|
+
end
|
|
250
|
+
Color.template("#{title}#{tail}{x}")
|
|
239
251
|
end
|
|
240
252
|
|
|
241
253
|
def os_open(command)
|
|
242
254
|
os = RbConfig::CONFIG['target_os']
|
|
243
|
-
out = "
|
|
255
|
+
out = Color.template("{bg}Opening {bw}#{command}")
|
|
244
256
|
case os
|
|
245
257
|
when /darwin.*/i
|
|
246
|
-
warn "#{out} (macOS)
|
|
258
|
+
warn Color.template("#{out} (macOS){x}") if @options[:log_level] < 2
|
|
247
259
|
`open #{Shellwords.escape(command)}`
|
|
248
260
|
when /mingw|mswin/i
|
|
249
|
-
warn "#{out} (Windows)
|
|
261
|
+
warn Color.template("#{out} (Windows){x}") if @options[:log_level] < 2
|
|
250
262
|
`start #{Shellwords.escape(command)}`
|
|
251
263
|
else
|
|
252
264
|
if 'xdg-open'.available?
|
|
253
|
-
warn "#{out} (Linux)
|
|
265
|
+
warn Color.template("#{out} (Linux){x}") if @options[:log_level] < 2
|
|
254
266
|
`xdg-open #{Shellwords.escape(command)}`
|
|
255
267
|
else
|
|
256
268
|
warn out if @options[:log_level] < 2
|
|
@@ -289,7 +301,7 @@ module Howzit
|
|
|
289
301
|
directives.each do |c|
|
|
290
302
|
if c[0].nil?
|
|
291
303
|
title = c[3] ? c[3].strip : ''
|
|
292
|
-
warn "
|
|
304
|
+
warn Color.template("{bg}Running block {bw}#{title}{x}") if @options[:log_level] < 2
|
|
293
305
|
block = c[4].strip
|
|
294
306
|
script = Tempfile.new('howzit_script')
|
|
295
307
|
begin
|
|
@@ -311,18 +323,18 @@ module Howzit
|
|
|
311
323
|
warn "No topic match for @include(#{search})"
|
|
312
324
|
else
|
|
313
325
|
if @included.include?(matches[0])
|
|
314
|
-
warn "
|
|
326
|
+
warn Color.template("{by}Tasks from {bw}#{matches[0]} already included, skipping{x}") if @options[:log_level] < 2
|
|
315
327
|
else
|
|
316
|
-
warn "
|
|
328
|
+
warn Color.template("{by}Including tasks from {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
|
317
329
|
process_topic(matches[0], true)
|
|
318
|
-
warn "
|
|
330
|
+
warn Color.template("{by}End include {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
|
319
331
|
end
|
|
320
332
|
end
|
|
321
333
|
when /run/i
|
|
322
|
-
warn "
|
|
334
|
+
warn Color.template("{bg}Running {bw}#{obj}{x}") if @options[:log_level] < 2
|
|
323
335
|
system(obj)
|
|
324
336
|
when /copy/i
|
|
325
|
-
warn "
|
|
337
|
+
warn Color.template("{bg}Copied {bw}#{obj}{bg} to clipboard{x}") if @options[:log_level] < 2
|
|
326
338
|
`echo #{Shellwords.escape(obj)}'\\c'|pbcopy`
|
|
327
339
|
when /open|url/i
|
|
328
340
|
os_open(obj)
|
|
@@ -330,7 +342,7 @@ module Howzit
|
|
|
330
342
|
end
|
|
331
343
|
end
|
|
332
344
|
else
|
|
333
|
-
warn "
|
|
345
|
+
warn Color.template("{r}--run: No {br}@directive{xr} found in {bw}#{key}{x}")
|
|
334
346
|
end
|
|
335
347
|
output.push("Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}") if @options[:log_level] < 2
|
|
336
348
|
|
|
@@ -344,7 +356,7 @@ module Howzit
|
|
|
344
356
|
|
|
345
357
|
output = []
|
|
346
358
|
if opt[:header]
|
|
347
|
-
output.push(format_header(key))
|
|
359
|
+
output.push(format_header(key, { mark: should_mark_iterm? }))
|
|
348
360
|
output.push('')
|
|
349
361
|
end
|
|
350
362
|
topic = topics[key].strip
|
|
@@ -360,12 +372,12 @@ module Howzit
|
|
|
360
372
|
unless matches.empty?
|
|
361
373
|
if opt[:single]
|
|
362
374
|
title = "From #{matches[0]}:"
|
|
363
|
-
color = '
|
|
364
|
-
rule = '
|
|
375
|
+
color = '{yK}'
|
|
376
|
+
rule = '{kK}'
|
|
365
377
|
else
|
|
366
378
|
title = "Include #{matches[0]}"
|
|
367
|
-
color = '
|
|
368
|
-
rule = '
|
|
379
|
+
color = '{yK}'
|
|
380
|
+
rule = '{x}'
|
|
369
381
|
end
|
|
370
382
|
output.push(format_header("#{'> ' * @nest_level}#{title}", { color: color, hr: '.', border: rule })) unless @included.include?(matches[0])
|
|
371
383
|
|
|
@@ -394,15 +406,15 @@ module Howzit
|
|
|
394
406
|
when /open|url/
|
|
395
407
|
"\u{279A}"
|
|
396
408
|
end
|
|
397
|
-
output.push("
|
|
409
|
+
output.push(Color.template("{bmK}#{icon} {bwK}#{obj}{x}"))
|
|
398
410
|
when /(`{3,})run *(.*?)$/i
|
|
399
411
|
m = Regexp.last_match
|
|
400
412
|
desc = m[2].length.positive? ? "Block: #{m[2]}" : 'Code Block'
|
|
401
|
-
output.push("\
|
|
413
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}\n```"))
|
|
402
414
|
when /@@@run *(.*?)$/i
|
|
403
415
|
m = Regexp.last_match
|
|
404
416
|
desc = m[1].length.positive? ? "Block: #{m[1]}" : 'Code Block'
|
|
405
|
-
output.push("\
|
|
417
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}"))
|
|
406
418
|
else
|
|
407
419
|
l.wrap!(@options[:wrap]) if (@options[:wrap]).positive?
|
|
408
420
|
output.push(l)
|
|
@@ -433,9 +445,9 @@ module Howzit
|
|
|
433
445
|
# Output a list of topic titles
|
|
434
446
|
def list_topics
|
|
435
447
|
output = []
|
|
436
|
-
output.push("\
|
|
448
|
+
output.push(Color.template("{bg}Topics:{x}\n"))
|
|
437
449
|
topics.each_key do |title|
|
|
438
|
-
output.push("-
|
|
450
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
|
439
451
|
end
|
|
440
452
|
output.join("\n")
|
|
441
453
|
end
|
|
@@ -445,14 +457,14 @@ module Howzit
|
|
|
445
457
|
topics.keys.join("\n")
|
|
446
458
|
end
|
|
447
459
|
|
|
448
|
-
def get_note_title(
|
|
460
|
+
def get_note_title(truncate = 0)
|
|
449
461
|
title = nil
|
|
450
|
-
help = IO.read(
|
|
462
|
+
help = IO.read(note_file).strip
|
|
451
463
|
title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
|
|
452
464
|
title = if title
|
|
453
465
|
title[1].nil? ? title[2] : title[1]
|
|
454
466
|
else
|
|
455
|
-
|
|
467
|
+
note_file.sub(/(\.\w+)?$/, '')
|
|
456
468
|
end
|
|
457
469
|
|
|
458
470
|
title && truncate.positive? ? title.trunc(truncate) : title
|
|
@@ -475,7 +487,7 @@ module Howzit
|
|
|
475
487
|
|
|
476
488
|
def list_runnable
|
|
477
489
|
output = []
|
|
478
|
-
output.push(%(
|
|
490
|
+
output.push(Color.template(%({bg}"Runnable" Topics:{x}\n)))
|
|
479
491
|
topics.each do |title, sect|
|
|
480
492
|
s_out = []
|
|
481
493
|
lines = sect.split(/\n/)
|
|
@@ -496,7 +508,7 @@ module Howzit
|
|
|
496
508
|
end
|
|
497
509
|
end
|
|
498
510
|
unless s_out.empty?
|
|
499
|
-
output.push("-
|
|
511
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
|
500
512
|
output.push(s_out.join("\n"))
|
|
501
513
|
end
|
|
502
514
|
end
|
|
@@ -520,8 +532,8 @@ module Howzit
|
|
|
520
532
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
|
521
533
|
required.each do |req|
|
|
522
534
|
unless @metadata.keys.include?(req.downcase)
|
|
523
|
-
warn %(
|
|
524
|
-
warn %(
|
|
535
|
+
warn Color.template(%({xr}ERROR: Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}))
|
|
536
|
+
warn Color.template(%({xr}Please define {by}#{req.downcase}{xr} in build notes{x}))
|
|
525
537
|
Process.exit 1
|
|
526
538
|
end
|
|
527
539
|
end
|
|
@@ -570,6 +582,24 @@ module Howzit
|
|
|
570
582
|
template_topics
|
|
571
583
|
end
|
|
572
584
|
|
|
585
|
+
def include_file(m)
|
|
586
|
+
file = File.expand_path(m[1])
|
|
587
|
+
|
|
588
|
+
return m[0] unless File.exist?(file)
|
|
589
|
+
|
|
590
|
+
content = IO.read(file)
|
|
591
|
+
home = ENV['HOME']
|
|
592
|
+
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
|
593
|
+
prefix = "#{short_path}/#{File.basename(file)}:"
|
|
594
|
+
parts = content.split(/^##+/)
|
|
595
|
+
parts.shift
|
|
596
|
+
if parts.empty?
|
|
597
|
+
content
|
|
598
|
+
else
|
|
599
|
+
"## #{parts.join('## ')}".gsub(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
573
603
|
# Read in the build notes file and output a hash of "Title" => contents
|
|
574
604
|
def read_help_file(path = nil)
|
|
575
605
|
filename = path.nil? ? note_file : path
|
|
@@ -577,21 +607,7 @@ module Howzit
|
|
|
577
607
|
help = IO.read(filename)
|
|
578
608
|
|
|
579
609
|
help.gsub!(/@include\((.*?)\)/) do
|
|
580
|
-
|
|
581
|
-
file = File.expand_path(m[1])
|
|
582
|
-
if File.exist?(file)
|
|
583
|
-
content = IO.read(file)
|
|
584
|
-
home = ENV['HOME']
|
|
585
|
-
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
|
586
|
-
prefix = "#{short_path}:"
|
|
587
|
-
parts = content.split(/^##+/)
|
|
588
|
-
parts.shift
|
|
589
|
-
content = '## ' + parts.join('## ')
|
|
590
|
-
content.gsub!(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
|
591
|
-
content
|
|
592
|
-
else
|
|
593
|
-
m[0]
|
|
594
|
-
end
|
|
610
|
+
include_file(Regexp.last_match)
|
|
595
611
|
end
|
|
596
612
|
|
|
597
613
|
template_topics = get_template_topics(help)
|
|
@@ -662,7 +678,8 @@ module Howzit
|
|
|
662
678
|
matches
|
|
663
679
|
end
|
|
664
680
|
|
|
665
|
-
def initialize(args)
|
|
681
|
+
def initialize(args = [])
|
|
682
|
+
Color.coloring = $stdout.isatty
|
|
666
683
|
flags = {
|
|
667
684
|
run: false,
|
|
668
685
|
list_topics: false,
|
|
@@ -705,7 +722,8 @@ module Howzit
|
|
|
705
722
|
OptionParser.new do |opts|
|
|
706
723
|
opts.banner = "Usage: #{__FILE__} [OPTIONS] [TOPIC]"
|
|
707
724
|
opts.separator ''
|
|
708
|
-
opts.separator 'Show build notes for the current project (buildnotes.md).
|
|
725
|
+
opts.separator 'Show build notes for the current project (buildnotes.md).
|
|
726
|
+
Include a topic name to see just that topic, or no argument to display all.'
|
|
709
727
|
opts.separator ''
|
|
710
728
|
opts.separator 'Options:'
|
|
711
729
|
|
|
@@ -714,7 +732,8 @@ module Howzit
|
|
|
714
732
|
Process.exit 0
|
|
715
733
|
end
|
|
716
734
|
|
|
717
|
-
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
|
735
|
+
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
|
736
|
+
using #{File.basename(ENV['EDITOR'])}") do
|
|
718
737
|
edit_note
|
|
719
738
|
Process.exit 0
|
|
720
739
|
end
|
|
@@ -732,7 +751,8 @@ module Howzit
|
|
|
732
751
|
@options[:list_topics] = true
|
|
733
752
|
end
|
|
734
753
|
|
|
735
|
-
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
|
754
|
+
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
|
755
|
+
'Topics matching type', "(#{MATCHING_OPTIONS.join(', ')})") do |c|
|
|
736
756
|
@options[:matching] = c
|
|
737
757
|
end
|
|
738
758
|
|
|
@@ -765,8 +785,8 @@ module Howzit
|
|
|
765
785
|
@options[:log_level] = 0
|
|
766
786
|
end
|
|
767
787
|
|
|
768
|
-
opts.on('-u', '--upstream', 'Traverse up parent directories for additional build notes') do
|
|
769
|
-
@options[:include_upstream] =
|
|
788
|
+
opts.on('-u', '--[no-]upstream', 'Traverse up parent directories for additional build notes') do |p|
|
|
789
|
+
@options[:include_upstream] = p
|
|
770
790
|
end
|
|
771
791
|
|
|
772
792
|
opts.on('--show-code', 'Display the content of fenced run blocks') do
|
|
@@ -791,21 +811,21 @@ module Howzit
|
|
|
791
811
|
Dir.chdir(template_folder)
|
|
792
812
|
Dir.glob('*.md').each do |file|
|
|
793
813
|
template = File.basename(file, '.md')
|
|
794
|
-
puts "
|
|
795
|
-
puts "
|
|
814
|
+
puts Color.template("{Mk}template:{Yk}#{template}{x}")
|
|
815
|
+
puts Color.template("{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}")
|
|
796
816
|
metadata = file.extract_metadata
|
|
797
817
|
topics = read_help_file(file)
|
|
798
|
-
topics.
|
|
799
|
-
puts "
|
|
818
|
+
topics.each_key do |topic|
|
|
819
|
+
puts Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.sub(/^.*?:/, '')}{x}")
|
|
800
820
|
end
|
|
801
821
|
if metadata.size > 0
|
|
802
822
|
meta = []
|
|
803
|
-
meta << metadata['required'].split(/\s*,\s*/).map {|m| "
|
|
823
|
+
meta << metadata['required'].split(/\s*,\s*/).map {|m| "*{bw}#{m}{xw}" } if metadata.key?('required')
|
|
804
824
|
meta << metadata['optional'].split(/\s*,\s*/).map {|m| "#{m}" } if metadata.key?('optional')
|
|
805
|
-
puts "
|
|
806
|
-
puts "
|
|
825
|
+
puts Color.template("{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}")
|
|
826
|
+
puts Color.template(" {bk}│ {xw}#{meta.join(", ")}{x}")
|
|
807
827
|
end
|
|
808
|
-
puts "
|
|
828
|
+
puts Color.template(" {bk}└───────────────────────────────────────────┘{x}")
|
|
809
829
|
end
|
|
810
830
|
Process.exit 0
|
|
811
831
|
end
|
|
@@ -834,7 +854,7 @@ module Howzit
|
|
|
834
854
|
end
|
|
835
855
|
end.parse!(args)
|
|
836
856
|
|
|
837
|
-
|
|
857
|
+
@cli_args = args
|
|
838
858
|
end
|
|
839
859
|
|
|
840
860
|
def edit_note
|
|
@@ -851,7 +871,7 @@ module Howzit
|
|
|
851
871
|
end
|
|
852
872
|
|
|
853
873
|
##
|
|
854
|
-
##
|
|
874
|
+
## Traverse up directory tree looking for build notes
|
|
855
875
|
##
|
|
856
876
|
## @return topics dictionary
|
|
857
877
|
##
|
|
@@ -1053,7 +1073,7 @@ module Howzit
|
|
|
1053
1073
|
`#{ENV['EDITOR']} "#{config_file}"`
|
|
1054
1074
|
end
|
|
1055
1075
|
|
|
1056
|
-
def process
|
|
1076
|
+
def process
|
|
1057
1077
|
output = []
|
|
1058
1078
|
|
|
1059
1079
|
unless note_file
|
|
@@ -1069,13 +1089,13 @@ module Howzit
|
|
|
1069
1089
|
end
|
|
1070
1090
|
|
|
1071
1091
|
if @options[:title_only]
|
|
1072
|
-
out = get_note_title(
|
|
1092
|
+
out = get_note_title(20)
|
|
1073
1093
|
$stdout.print(out.strip)
|
|
1074
1094
|
Process.exit(0)
|
|
1075
1095
|
elsif @options[:output_title]
|
|
1076
|
-
title = get_note_title
|
|
1096
|
+
title = get_note_title
|
|
1077
1097
|
if title && !title.empty?
|
|
1078
|
-
header = format_header(title, { hr: "\u{2550}", color: '
|
|
1098
|
+
header = format_header(title, { hr: "\u{2550}", color: '{bwK}' })
|
|
1079
1099
|
output.push("#{header}\n")
|
|
1080
1100
|
end
|
|
1081
1101
|
end
|
|
@@ -1107,14 +1127,14 @@ module Howzit
|
|
|
1107
1127
|
elsif @options[:choose]
|
|
1108
1128
|
topic_match = choose(topics.keys)
|
|
1109
1129
|
# If there are arguments use those to search for a matching topic
|
|
1110
|
-
elsif
|
|
1130
|
+
elsif !@cli_args.empty?
|
|
1111
1131
|
|
|
1112
|
-
search =
|
|
1132
|
+
search = @cli_args.join(' ').strip.downcase
|
|
1113
1133
|
matches = match_topic(search)
|
|
1114
1134
|
|
|
1115
1135
|
if matches.empty?
|
|
1116
|
-
output.push(%(
|
|
1117
|
-
|
|
1136
|
+
output.push(Color.template(%({bR}ERROR:{xr} No topic match found for {bw}#{search}{x}\n)))
|
|
1137
|
+
unless @options[:show_all_on_error]
|
|
1118
1138
|
show(output.join("\n"), { color: true, highlight: false, paginate: false, wrap: 0 })
|
|
1119
1139
|
Process.exit 1
|
|
1120
1140
|
end
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Cribbed from <https://github.com/flori/term-ansicolor>
|
|
4
|
+
module Howzit
|
|
5
|
+
# Terminal output color functions.
|
|
6
|
+
module Color
|
|
7
|
+
ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/.freeze
|
|
8
|
+
# All available color names. Available as methods and string extensions.
|
|
9
|
+
#
|
|
10
|
+
# @example Use a color as a method. Color reset will be added to end of string.
|
|
11
|
+
# Color.yellow('This text is yellow') => "\e[33mThis text is yellow\e[0m"
|
|
12
|
+
#
|
|
13
|
+
# @example Use a color as a string extension. Color reset added automatically.
|
|
14
|
+
# 'This text is green'.green => "\e[1;32mThis text is green\e[0m"
|
|
15
|
+
#
|
|
16
|
+
# @example Send a text string as a color
|
|
17
|
+
# Color.send('red') => "\e[31m"
|
|
18
|
+
ATTRIBUTES = [
|
|
19
|
+
[:clear, 0], # String#clear is already used to empty string in Ruby 1.9
|
|
20
|
+
[:reset, 0], # synonym for :clear
|
|
21
|
+
[:bold, 1],
|
|
22
|
+
[:dark, 2],
|
|
23
|
+
[:italic, 3], # not widely implemented
|
|
24
|
+
[:underline, 4],
|
|
25
|
+
[:underscore, 4], # synonym for :underline
|
|
26
|
+
[:blink, 5],
|
|
27
|
+
[:rapid_blink, 6], # not widely implemented
|
|
28
|
+
[:negative, 7], # no reverse because of String#reverse
|
|
29
|
+
[:concealed, 8],
|
|
30
|
+
[:strikethrough, 9], # not widely implemented
|
|
31
|
+
[:strike, 9], # not widely implemented
|
|
32
|
+
[:black, 30],
|
|
33
|
+
[:red, 31],
|
|
34
|
+
[:green, 32],
|
|
35
|
+
[:yellow, 33],
|
|
36
|
+
[:blue, 34],
|
|
37
|
+
[:magenta, 35],
|
|
38
|
+
[:purple, 35],
|
|
39
|
+
[:cyan, 36],
|
|
40
|
+
[:white, 37],
|
|
41
|
+
[:bgblack, 40],
|
|
42
|
+
[:bgred, 41],
|
|
43
|
+
[:bggreen, 42],
|
|
44
|
+
[:bgyellow, 43],
|
|
45
|
+
[:bgblue, 44],
|
|
46
|
+
[:bgmagenta, 45],
|
|
47
|
+
[:bgpurple, 45],
|
|
48
|
+
[:bgcyan, 46],
|
|
49
|
+
[:bgwhite, 47],
|
|
50
|
+
[:boldblack, 90],
|
|
51
|
+
[:boldred, 91],
|
|
52
|
+
[:boldgreen, 92],
|
|
53
|
+
[:boldyellow, 93],
|
|
54
|
+
[:boldblue, 94],
|
|
55
|
+
[:boldmagenta, 95],
|
|
56
|
+
[:boldpurple, 95],
|
|
57
|
+
[:boldcyan, 96],
|
|
58
|
+
[:boldwhite, 97],
|
|
59
|
+
[:boldbgblack, 100],
|
|
60
|
+
[:boldbgred, 101],
|
|
61
|
+
[:boldbggreen, 102],
|
|
62
|
+
[:boldbgyellow, 103],
|
|
63
|
+
[:boldbgblue, 104],
|
|
64
|
+
[:boldbgmagenta, 105],
|
|
65
|
+
[:boldbgpurple, 105],
|
|
66
|
+
[:boldbgcyan, 106],
|
|
67
|
+
[:boldbgwhite, 107],
|
|
68
|
+
[:softpurple, '0;35;40'],
|
|
69
|
+
[:hotpants, '7;34;40'],
|
|
70
|
+
[:knightrider, '7;30;40'],
|
|
71
|
+
[:flamingo, '7;31;47'],
|
|
72
|
+
[:yeller, '1;37;43'],
|
|
73
|
+
[:whiteboard, '1;30;47'],
|
|
74
|
+
[:chalkboard, '1;37;40'],
|
|
75
|
+
[:led, '0;32;40'],
|
|
76
|
+
[:redacted, '0;30;40'],
|
|
77
|
+
[:alert, '1;31;43'],
|
|
78
|
+
[:error, '1;37;41'],
|
|
79
|
+
[:default, '0;39']
|
|
80
|
+
].map(&:freeze).freeze
|
|
81
|
+
|
|
82
|
+
ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
|
|
83
|
+
|
|
84
|
+
# Returns true if Howzit::Color supports the +feature+.
|
|
85
|
+
#
|
|
86
|
+
# The feature :clear, that is mixing the clear color attribute into String,
|
|
87
|
+
# is only supported on ruby implementations, that do *not* already
|
|
88
|
+
# implement the String#clear method. It's better to use the reset color
|
|
89
|
+
# attribute instead.
|
|
90
|
+
def support?(feature)
|
|
91
|
+
case feature
|
|
92
|
+
when :clear
|
|
93
|
+
!String.instance_methods(false).map(&:to_sym).include?(:clear)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Template coloring
|
|
98
|
+
class ::String
|
|
99
|
+
##
|
|
100
|
+
## Extract the longest valid %color name from a string.
|
|
101
|
+
##
|
|
102
|
+
## Allows %colors to bleed into other text and still
|
|
103
|
+
## be recognized, e.g. %greensomething still finds
|
|
104
|
+
## %green.
|
|
105
|
+
##
|
|
106
|
+
## @return [String] a valid color name
|
|
107
|
+
##
|
|
108
|
+
def validate_color
|
|
109
|
+
valid_color = nil
|
|
110
|
+
compiled = ''
|
|
111
|
+
normalize_color.split('').each do |char|
|
|
112
|
+
compiled += char
|
|
113
|
+
valid_color = compiled if Color.attributes.include?(compiled.to_sym) || compiled =~ /^([fb]g?)?#([a-f0-9]{6})$/i
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
valid_color
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
## Normalize a color name, removing underscores,
|
|
121
|
+
## replacing "bright" with "bold", and converting
|
|
122
|
+
## bgbold to boldbg
|
|
123
|
+
##
|
|
124
|
+
## @return [String] Normalized color name
|
|
125
|
+
##
|
|
126
|
+
def normalize_color
|
|
127
|
+
gsub(/_/, '').sub(/bright/i, 'bold').sub(/bgbold/, 'boldbg')
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Get the calculated ANSI color at the end of the
|
|
131
|
+
# string
|
|
132
|
+
#
|
|
133
|
+
# @return ANSI escape sequence to match color
|
|
134
|
+
#
|
|
135
|
+
def last_color_code
|
|
136
|
+
m = scan(ESCAPE_REGEX)
|
|
137
|
+
|
|
138
|
+
em = ['0']
|
|
139
|
+
fg = nil
|
|
140
|
+
bg = nil
|
|
141
|
+
rgbf = nil
|
|
142
|
+
rgbb = nil
|
|
143
|
+
|
|
144
|
+
m.each do |c|
|
|
145
|
+
case c
|
|
146
|
+
when '0'
|
|
147
|
+
em = ['0']
|
|
148
|
+
fg, bg, rgbf, rgbb = nil
|
|
149
|
+
when /^[34]8/
|
|
150
|
+
case c
|
|
151
|
+
when /^3/
|
|
152
|
+
fg = nil
|
|
153
|
+
rgbf = c
|
|
154
|
+
when /^4/
|
|
155
|
+
bg = nil
|
|
156
|
+
rgbb = c
|
|
157
|
+
end
|
|
158
|
+
else
|
|
159
|
+
c.split(/;/).each do |i|
|
|
160
|
+
x = i.to_i
|
|
161
|
+
if x <= 9
|
|
162
|
+
em << x
|
|
163
|
+
elsif x >= 30 && x <= 39
|
|
164
|
+
rgbf = nil
|
|
165
|
+
fg = x
|
|
166
|
+
elsif x >= 40 && x <= 49
|
|
167
|
+
rgbb = nil
|
|
168
|
+
bg = x
|
|
169
|
+
elsif x >= 90 && x <= 97
|
|
170
|
+
rgbf = nil
|
|
171
|
+
fg = x
|
|
172
|
+
elsif x >= 100 && x <= 107
|
|
173
|
+
rgbb = nil
|
|
174
|
+
bg = x
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
escape = "\e[#{em.join(';')}m"
|
|
181
|
+
escape += "\e[#{rgbb}m" if rgbb
|
|
182
|
+
escape += "\e[#{rgbf}m" if rgbf
|
|
183
|
+
escape + "\e[#{[fg, bg].delete_if(&:nil?).join(';')}m"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
class << self
|
|
188
|
+
# Returns true if the coloring function of this module
|
|
189
|
+
# is switched on, false otherwise.
|
|
190
|
+
def coloring?
|
|
191
|
+
@coloring
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
attr_writer :coloring
|
|
195
|
+
|
|
196
|
+
##
|
|
197
|
+
## Enables colored output
|
|
198
|
+
##
|
|
199
|
+
## @example Turn color on or off based on TTY
|
|
200
|
+
## Howzit::Color.coloring = STDOUT.isatty
|
|
201
|
+
def coloring
|
|
202
|
+
@coloring ||= true
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
##
|
|
206
|
+
## Convert a template string to a colored string.
|
|
207
|
+
## Colors are specified with single letters inside
|
|
208
|
+
## curly braces. Uppercase changes background color.
|
|
209
|
+
##
|
|
210
|
+
## w: white, k: black, g: green, l: blue, y: yellow, c: cyan,
|
|
211
|
+
## m: magenta, r: red, b: bold, u: underline, i: italic,
|
|
212
|
+
## x: reset (remove background, color, emphasis)
|
|
213
|
+
##
|
|
214
|
+
## @example Convert a templated string
|
|
215
|
+
## Color.template('{Rwb}Warning:{x} {w}you look a little {g}ill{x}')
|
|
216
|
+
##
|
|
217
|
+
## @param input [String, Array] The template
|
|
218
|
+
## string. If this is an array, the
|
|
219
|
+
## elements will be joined with a
|
|
220
|
+
## space.
|
|
221
|
+
##
|
|
222
|
+
## @return [String] Colorized string
|
|
223
|
+
##
|
|
224
|
+
def template(input)
|
|
225
|
+
input = input.join(' ') if input.is_a? Array
|
|
226
|
+
input.gsub!(/%/, '%%')
|
|
227
|
+
fmt = input.gsub(/\{(\w+)\}/) do
|
|
228
|
+
Regexp.last_match(1).split('').map { |c| "%<#{c}>s" }.join('')
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
colors = { w: white, k: black, g: green, l: blue,
|
|
232
|
+
y: yellow, c: cyan, m: magenta, r: red,
|
|
233
|
+
W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
|
|
234
|
+
Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
|
|
235
|
+
b: bold, u: underline, i: italic, x: reset }
|
|
236
|
+
|
|
237
|
+
format(fmt, colors)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
ATTRIBUTES.each do |c, v|
|
|
242
|
+
new_method = <<-EOSCRIPT
|
|
243
|
+
def #{c}(string = nil)
|
|
244
|
+
result = ''
|
|
245
|
+
result << "\e[#{v}m" if Howzit::Color.coloring?
|
|
246
|
+
if block_given?
|
|
247
|
+
result << yield
|
|
248
|
+
elsif string.respond_to?(:to_str)
|
|
249
|
+
result << string.to_str
|
|
250
|
+
elsif respond_to?(:to_str)
|
|
251
|
+
result << to_str
|
|
252
|
+
else
|
|
253
|
+
return result #only switch on
|
|
254
|
+
end
|
|
255
|
+
result << "\e[0m" if Howzit::Color.coloring?
|
|
256
|
+
result
|
|
257
|
+
end
|
|
258
|
+
EOSCRIPT
|
|
259
|
+
|
|
260
|
+
module_eval(new_method)
|
|
261
|
+
|
|
262
|
+
next unless c =~ /bold/
|
|
263
|
+
|
|
264
|
+
# Accept brightwhite in addition to boldwhite
|
|
265
|
+
new_method = <<-EOSCRIPT
|
|
266
|
+
def #{c.to_s.sub(/bold/, 'bright')}(string = nil)
|
|
267
|
+
result = ''
|
|
268
|
+
result << "\e[#{v}m" if Howzit::Color.coloring?
|
|
269
|
+
if block_given?
|
|
270
|
+
result << yield
|
|
271
|
+
elsif string.respond_to?(:to_str)
|
|
272
|
+
result << string.to_str
|
|
273
|
+
elsif respond_to?(:to_str)
|
|
274
|
+
result << to_str
|
|
275
|
+
else
|
|
276
|
+
return result #only switch on
|
|
277
|
+
end
|
|
278
|
+
result << "\e[0m" if Howzit::Color.coloring?
|
|
279
|
+
result
|
|
280
|
+
end
|
|
281
|
+
EOSCRIPT
|
|
282
|
+
|
|
283
|
+
module_eval(new_method)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def rgb(hex)
|
|
287
|
+
is_bg = hex.match(/^bg?#/) ? true : false
|
|
288
|
+
hex_string = hex.sub(/^([fb]g?)?#/, '')
|
|
289
|
+
|
|
290
|
+
parts = hex_string.match(/(?<r>..)(?<g>..)(?<b>..)/)
|
|
291
|
+
t = []
|
|
292
|
+
%w[r g b].each do |e|
|
|
293
|
+
t << parts[e].hex
|
|
294
|
+
end
|
|
295
|
+
color =
|
|
296
|
+
"\e[#{is_bg ? '48' : '38'};2;#{t.join(';')}m"
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Regular expression that is used to scan for ANSI-sequences while
|
|
300
|
+
# uncoloring strings.
|
|
301
|
+
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/.freeze
|
|
302
|
+
|
|
303
|
+
# Returns an uncolored version of the string, that is all
|
|
304
|
+
# ANSI-sequences are stripped from the string.
|
|
305
|
+
def uncolor(string = nil) # :yields:
|
|
306
|
+
if block_given?
|
|
307
|
+
yield.to_str.gsub(COLORED_REGEXP, '')
|
|
308
|
+
elsif string.respond_to?(:to_str)
|
|
309
|
+
string.to_str.gsub(COLORED_REGEXP, '')
|
|
310
|
+
elsif respond_to?(:to_str)
|
|
311
|
+
to_str.gsub(COLORED_REGEXP, '')
|
|
312
|
+
else
|
|
313
|
+
''
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Returns an array of all Howzit::Color attributes as symbols.
|
|
318
|
+
def attributes
|
|
319
|
+
ATTRIBUTE_NAMES
|
|
320
|
+
end
|
|
321
|
+
extend self
|
|
322
|
+
end
|
|
323
|
+
end
|
data/lib/howzit/stringutils.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Howzit
|
|
|
5
5
|
module StringUtils
|
|
6
6
|
# Just strip out color codes when requested
|
|
7
7
|
def uncolor
|
|
8
|
-
gsub(/\e\[[\d;]+m/, '').gsub(/\e]1337;SetMark/,'')
|
|
8
|
+
gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# Adapted from https://github.com/pazdera/word_wrap/,
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
data/spec/ruby_gem_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Howzit::BuildNotes do
|
|
4
|
-
subject(:ruby_gem) { Howzit::BuildNotes.new }
|
|
4
|
+
subject(:ruby_gem) { Howzit::BuildNotes.new([]) }
|
|
5
5
|
|
|
6
6
|
describe ".new" do
|
|
7
7
|
it "makes a new instance" do
|
|
@@ -9,3 +9,36 @@ describe Howzit::BuildNotes do
|
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
describe Howzit::BuildNotes do
|
|
14
|
+
Dir.chdir('spec')
|
|
15
|
+
subject { Howzit::BuildNotes.new(['--no-upstream']) }
|
|
16
|
+
|
|
17
|
+
describe ".note_file" do
|
|
18
|
+
it "locates a build note file" do
|
|
19
|
+
expect(subject.note_file).not_to be_empty
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe ".get_note_title" do
|
|
24
|
+
it "is named howzit test" do
|
|
25
|
+
expect(subject.get_note_title).to match(/howzit test/)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe ".grep_topics" do
|
|
30
|
+
it "found editable" do
|
|
31
|
+
expect(subject.grep_topics('editable')).to include('File Structure')
|
|
32
|
+
expect(subject.grep_topics('editable')).not_to include('Build')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe ".list_topic_titles" do
|
|
37
|
+
it "found 4 topics" do
|
|
38
|
+
expect(subject.topics.keys.count).to eq 4
|
|
39
|
+
end
|
|
40
|
+
it "outputs a newline-separated string" do
|
|
41
|
+
expect(subject.list_topic_titles.scan(/\n/).count).to eq 3
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
require 'simplecov'
|
|
1
|
+
# require 'simplecov'
|
|
2
2
|
|
|
3
|
-
SimpleCov.start
|
|
3
|
+
# SimpleCov.start
|
|
4
4
|
|
|
5
|
-
if ENV['CI'] == 'true'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
else
|
|
9
|
-
|
|
10
|
-
end
|
|
5
|
+
# if ENV['CI'] == 'true'
|
|
6
|
+
# require 'codecov'
|
|
7
|
+
# SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
|
8
|
+
# else
|
|
9
|
+
# SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
|
10
|
+
# end
|
|
11
11
|
|
|
12
12
|
require 'howzit'
|
|
13
13
|
|
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: 1.2.
|
|
4
|
+
version: 1.2.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
@@ -150,20 +150,6 @@ dependencies:
|
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '0.9'
|
|
153
|
-
- !ruby/object:Gem::Dependency
|
|
154
|
-
name: codecov
|
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
|
156
|
-
requirements:
|
|
157
|
-
- - "~>"
|
|
158
|
-
- !ruby/object:Gem::Version
|
|
159
|
-
version: '0.1'
|
|
160
|
-
type: :development
|
|
161
|
-
prerelease: false
|
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
-
requirements:
|
|
164
|
-
- - "~>"
|
|
165
|
-
- !ruby/object:Gem::Version
|
|
166
|
-
version: '0.1'
|
|
167
153
|
- !ruby/object:Gem::Dependency
|
|
168
154
|
name: fuubar
|
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -283,6 +269,7 @@ files:
|
|
|
283
269
|
- lib/.rubocop.yml
|
|
284
270
|
- lib/howzit.rb
|
|
285
271
|
- lib/howzit/buildnotes.rb
|
|
272
|
+
- lib/howzit/colors.rb
|
|
286
273
|
- lib/howzit/prompt.rb
|
|
287
274
|
- lib/howzit/stringutils.rb
|
|
288
275
|
- lib/howzit/version.rb
|