howzit 1.2.10 → 1.2.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +21 -4
- data/Gemfile +2 -0
- data/Guardfile +3 -1
- data/README.md +1 -0
- data/Rakefile +20 -2
- data/bin/howzit +4 -2
- data/howzit.gemspec +1 -1
- data/lib/howzit/buildnotes.rb +124 -100
- data/lib/howzit/colors.rb +323 -0
- data/lib/howzit/prompt.rb +3 -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 +30 -1
- data/spec/spec_helper.rb +8 -8
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36a27d1566deff8857d39035c0e40f696a29d78b7ae24274a73ceacc54541321
|
4
|
+
data.tar.gz: 7b13d6644bf397e10f629689b159102a33dd5aa2c3610f368819de3dc8736007
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9da1ea212df950e75a34006a44b0ade09c02fd4fe7c02ea0fddfffcf2936e6ca5db0d7f0c9e6cc44aac3d65eb4544aa9d4c03c156487f9311f39f08ee12199d4
|
7
|
+
data.tar.gz: 99f9be58ff9184a2f96e7db6fed83e3fc19f0945e31c9d58daa32db022b175a8c99a329a9c023528af52100f46583ac892091eb04ed5d9e9e791087fe8f8c82d
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
### 1.2.13
|
2
|
+
|
3
|
+
2022-08-01 20:50
|
4
|
+
|
5
|
+
### 1.2.12
|
6
|
+
|
7
|
+
2022-08-01 16:23
|
8
|
+
|
9
|
+
#### IMPROVED
|
10
|
+
|
11
|
+
- Replace ANSI escape codes with color template system
|
12
|
+
- When @including an external file, if the file doesn't contain any level 2+ headers, import it as plain text.
|
13
|
+
|
14
|
+
### 1.2.11
|
15
|
+
|
16
|
+
2022-08-01 08:23
|
17
|
+
|
18
|
+
#### IMPROVED
|
19
|
+
|
20
|
+
- Code cleanup and refactoring
|
21
|
+
|
1
22
|
### 1.2.10
|
2
23
|
|
3
24
|
2022-08-01 07:45
|
@@ -6,10 +27,6 @@
|
|
6
27
|
|
7
28
|
- Headline formatting when iTerm markers are inserted
|
8
29
|
|
9
|
-
### 1.2.9
|
10
|
-
|
11
|
-
2022-08-01 07:09
|
12
|
-
|
13
30
|
### 1.2.8
|
14
31
|
|
15
32
|
2022-08-01 07:01
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Howzit
|
2
2
|
|
3
3
|
[![Gem](https://img.shields.io/gem/v/howzit.svg)](https://rubygems.org/gems/howzit)
|
4
|
+
[![Travis](https://img.shields.io/travis/makenew/ruby-gem.svg)](https://travis-ci.org/makenew/ruby-gem)
|
4
5
|
[![GitHub license](https://img.shields.io/github/license/ttscoff/howzit.svg)](./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,19 @@ 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
|
32
|
+
|
33
|
+
desc 'Changelog version check'
|
34
|
+
task :cver do
|
35
|
+
puts IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
36
|
+
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
|
|
@@ -145,12 +146,12 @@ module Howzit
|
|
145
146
|
choices.each do |choice|
|
146
147
|
case choice
|
147
148
|
when /[A-Z]/
|
148
|
-
out.push("
|
149
|
+
out.push(Color.template("{bg}#{choice}{xg}"))
|
149
150
|
else
|
150
|
-
out.push(choice)
|
151
|
+
out.push(Color.template("{w}#{choice}"))
|
151
152
|
end
|
152
153
|
end
|
153
|
-
"
|
154
|
+
Color.template("{g}[#{out.join('/')}{g}]{x}")
|
154
155
|
end
|
155
156
|
|
156
157
|
# Create a buildnotes skeleton
|
@@ -159,30 +160,40 @@ module Howzit
|
|
159
160
|
warn "\nCanceled"
|
160
161
|
exit!
|
161
162
|
end
|
163
|
+
default = !$stdout.isatty || @options[:default]
|
162
164
|
# First make sure there isn't already a buildnotes file
|
163
165
|
if note_file
|
164
|
-
fname = "
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
166
|
+
fname = Color.template("{by}#{note_file}{bw}")
|
167
|
+
unless default
|
168
|
+
res = yn("#{fname} exists and appears to be a build note, continue anyway?", false)
|
169
|
+
unless res
|
170
|
+
puts 'Canceled'
|
171
|
+
Process.exit 0
|
172
|
+
end
|
169
173
|
end
|
170
174
|
end
|
171
175
|
|
172
176
|
title = File.basename(Dir.pwd)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
+
if default
|
178
|
+
input = title
|
179
|
+
else
|
180
|
+
printf Color.template("{bw}Project name {xg}[#{title}]{bw}: {x}")
|
181
|
+
input = $stdin.gets.chomp
|
182
|
+
title = input unless input.empty?
|
183
|
+
end
|
177
184
|
summary = ''
|
178
|
-
|
179
|
-
|
180
|
-
|
185
|
+
unless default
|
186
|
+
printf Color.template('{bw}Project summary: {x}')
|
187
|
+
input = $stdin.gets.chomp
|
188
|
+
summary = input unless input.empty?
|
189
|
+
end
|
181
190
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
191
|
+
fname = 'buildnotes.md'
|
192
|
+
unless default
|
193
|
+
printf Color.template("{bw}Build notes filename (must begin with 'howzit' or 'build')\n{xg}[#{fname}]{bw}: {x}")
|
194
|
+
input = $stdin.gets.chomp
|
195
|
+
fname = input unless input.empty?
|
196
|
+
end
|
186
197
|
|
187
198
|
note = <<~EOBUILDNOTES
|
188
199
|
# #{title}
|
@@ -209,8 +220,8 @@ module Howzit
|
|
209
220
|
|
210
221
|
EOBUILDNOTES
|
211
222
|
|
212
|
-
if File.exist?(
|
213
|
-
file = "
|
223
|
+
if File.exist?(fname) && !default
|
224
|
+
file = Color.template("{by}#{fname}")
|
214
225
|
res = yn("Are you absolutely sure you want to overwrite #{file}", false)
|
215
226
|
|
216
227
|
unless res
|
@@ -219,9 +230,9 @@ module Howzit
|
|
219
230
|
end
|
220
231
|
end
|
221
232
|
|
222
|
-
File.open(
|
233
|
+
File.open(fname, 'w') do |f|
|
223
234
|
f.puts note
|
224
|
-
puts "Build notes for #{title} written to #{
|
235
|
+
puts Color.template("{by}Build notes for #{title} written to #{fname}")
|
225
236
|
end
|
226
237
|
end
|
227
238
|
|
@@ -229,8 +240,8 @@ module Howzit
|
|
229
240
|
def format_header(title, opts = {})
|
230
241
|
options = {
|
231
242
|
hr: "\u{254C}",
|
232
|
-
color: '
|
233
|
-
border: '
|
243
|
+
color: '{bg}',
|
244
|
+
border: '{x}',
|
234
245
|
mark: false
|
235
246
|
}
|
236
247
|
|
@@ -239,29 +250,29 @@ module Howzit
|
|
239
250
|
cols = TTY::Screen.columns
|
240
251
|
|
241
252
|
cols = @options[:wrap] if (@options[:wrap]).positive? && cols > @options[:wrap]
|
242
|
-
title = "
|
253
|
+
title = Color.template("#{options[:border]}#{options[:hr] * 2}( #{options[:color]}#{title}#{options[:border]} )")
|
243
254
|
|
244
255
|
tail = if should_mark_iterm?
|
245
256
|
"#{options[:hr] * (cols - title.uncolor.length - 15)}#{options[:mark] ? iterm_marker : ''}"
|
246
257
|
else
|
247
258
|
options[:hr] * (cols - title.uncolor.length)
|
248
259
|
end
|
249
|
-
"#{title}#{tail}
|
260
|
+
Color.template("#{title}#{tail}{x}")
|
250
261
|
end
|
251
262
|
|
252
263
|
def os_open(command)
|
253
264
|
os = RbConfig::CONFIG['target_os']
|
254
|
-
out = "
|
265
|
+
out = Color.template("{bg}Opening {bw}#{command}")
|
255
266
|
case os
|
256
267
|
when /darwin.*/i
|
257
|
-
warn "#{out} (macOS)
|
268
|
+
warn Color.template("#{out} (macOS){x}") if @options[:log_level] < 2
|
258
269
|
`open #{Shellwords.escape(command)}`
|
259
270
|
when /mingw|mswin/i
|
260
|
-
warn "#{out} (Windows)
|
271
|
+
warn Color.template("#{out} (Windows){x}") if @options[:log_level] < 2
|
261
272
|
`start #{Shellwords.escape(command)}`
|
262
273
|
else
|
263
274
|
if 'xdg-open'.available?
|
264
|
-
warn "#{out} (Linux)
|
275
|
+
warn Color.template("#{out} (Linux){x}") if @options[:log_level] < 2
|
265
276
|
`xdg-open #{Shellwords.escape(command)}`
|
266
277
|
else
|
267
278
|
warn out if @options[:log_level] < 2
|
@@ -300,7 +311,7 @@ module Howzit
|
|
300
311
|
directives.each do |c|
|
301
312
|
if c[0].nil?
|
302
313
|
title = c[3] ? c[3].strip : ''
|
303
|
-
warn "
|
314
|
+
warn Color.template("{bg}Running block {bw}#{title}{x}") if @options[:log_level] < 2
|
304
315
|
block = c[4].strip
|
305
316
|
script = Tempfile.new('howzit_script')
|
306
317
|
begin
|
@@ -322,18 +333,18 @@ module Howzit
|
|
322
333
|
warn "No topic match for @include(#{search})"
|
323
334
|
else
|
324
335
|
if @included.include?(matches[0])
|
325
|
-
warn "
|
336
|
+
warn Color.template("{by}Tasks from {bw}#{matches[0]} already included, skipping{x}") if @options[:log_level] < 2
|
326
337
|
else
|
327
|
-
warn "
|
338
|
+
warn Color.template("{by}Including tasks from {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
328
339
|
process_topic(matches[0], true)
|
329
|
-
warn "
|
340
|
+
warn Color.template("{by}End include {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
330
341
|
end
|
331
342
|
end
|
332
343
|
when /run/i
|
333
|
-
warn "
|
344
|
+
warn Color.template("{bg}Running {bw}#{obj}{x}") if @options[:log_level] < 2
|
334
345
|
system(obj)
|
335
346
|
when /copy/i
|
336
|
-
warn "
|
347
|
+
warn Color.template("{bg}Copied {bw}#{obj}{bg} to clipboard{x}") if @options[:log_level] < 2
|
337
348
|
`echo #{Shellwords.escape(obj)}'\\c'|pbcopy`
|
338
349
|
when /open|url/i
|
339
350
|
os_open(obj)
|
@@ -341,7 +352,7 @@ module Howzit
|
|
341
352
|
end
|
342
353
|
end
|
343
354
|
else
|
344
|
-
warn "
|
355
|
+
warn Color.template("{r}--run: No {br}@directive{xr} found in {bw}#{key}{x}")
|
345
356
|
end
|
346
357
|
output.push("Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}") if @options[:log_level] < 2
|
347
358
|
|
@@ -371,12 +382,12 @@ module Howzit
|
|
371
382
|
unless matches.empty?
|
372
383
|
if opt[:single]
|
373
384
|
title = "From #{matches[0]}:"
|
374
|
-
color = '
|
375
|
-
rule = '
|
385
|
+
color = '{yK}'
|
386
|
+
rule = '{kK}'
|
376
387
|
else
|
377
388
|
title = "Include #{matches[0]}"
|
378
|
-
color = '
|
379
|
-
rule = '
|
389
|
+
color = '{yK}'
|
390
|
+
rule = '{x}'
|
380
391
|
end
|
381
392
|
output.push(format_header("#{'> ' * @nest_level}#{title}", { color: color, hr: '.', border: rule })) unless @included.include?(matches[0])
|
382
393
|
|
@@ -405,15 +416,15 @@ module Howzit
|
|
405
416
|
when /open|url/
|
406
417
|
"\u{279A}"
|
407
418
|
end
|
408
|
-
output.push("
|
419
|
+
output.push(Color.template("{bmK}#{icon} {bwK}#{obj}{x}"))
|
409
420
|
when /(`{3,})run *(.*?)$/i
|
410
421
|
m = Regexp.last_match
|
411
422
|
desc = m[2].length.positive? ? "Block: #{m[2]}" : 'Code Block'
|
412
|
-
output.push("\
|
423
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}\n```"))
|
413
424
|
when /@@@run *(.*?)$/i
|
414
425
|
m = Regexp.last_match
|
415
426
|
desc = m[1].length.positive? ? "Block: #{m[1]}" : 'Code Block'
|
416
|
-
output.push("\
|
427
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}"))
|
417
428
|
else
|
418
429
|
l.wrap!(@options[:wrap]) if (@options[:wrap]).positive?
|
419
430
|
output.push(l)
|
@@ -444,9 +455,9 @@ module Howzit
|
|
444
455
|
# Output a list of topic titles
|
445
456
|
def list_topics
|
446
457
|
output = []
|
447
|
-
output.push("\
|
458
|
+
output.push(Color.template("{bg}Topics:{x}\n"))
|
448
459
|
topics.each_key do |title|
|
449
|
-
output.push("-
|
460
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
450
461
|
end
|
451
462
|
output.join("\n")
|
452
463
|
end
|
@@ -456,14 +467,14 @@ module Howzit
|
|
456
467
|
topics.keys.join("\n")
|
457
468
|
end
|
458
469
|
|
459
|
-
def get_note_title(
|
470
|
+
def get_note_title(truncate = 0)
|
460
471
|
title = nil
|
461
|
-
help = IO.read(
|
472
|
+
help = IO.read(note_file).strip
|
462
473
|
title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
|
463
474
|
title = if title
|
464
475
|
title[1].nil? ? title[2] : title[1]
|
465
476
|
else
|
466
|
-
|
477
|
+
note_file.sub(/(\.\w+)?$/, '')
|
467
478
|
end
|
468
479
|
|
469
480
|
title && truncate.positive? ? title.trunc(truncate) : title
|
@@ -486,7 +497,7 @@ module Howzit
|
|
486
497
|
|
487
498
|
def list_runnable
|
488
499
|
output = []
|
489
|
-
output.push(%(
|
500
|
+
output.push(Color.template(%({bg}"Runnable" Topics:{x}\n)))
|
490
501
|
topics.each do |title, sect|
|
491
502
|
s_out = []
|
492
503
|
lines = sect.split(/\n/)
|
@@ -507,7 +518,7 @@ module Howzit
|
|
507
518
|
end
|
508
519
|
end
|
509
520
|
unless s_out.empty?
|
510
|
-
output.push("-
|
521
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
511
522
|
output.push(s_out.join("\n"))
|
512
523
|
end
|
513
524
|
end
|
@@ -531,8 +542,8 @@ module Howzit
|
|
531
542
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
532
543
|
required.each do |req|
|
533
544
|
unless @metadata.keys.include?(req.downcase)
|
534
|
-
warn %(
|
535
|
-
warn %(
|
545
|
+
warn Color.template(%({xr}ERROR: Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}))
|
546
|
+
warn Color.template(%({xr}Please define {by}#{req.downcase}{xr} in build notes{x}))
|
536
547
|
Process.exit 1
|
537
548
|
end
|
538
549
|
end
|
@@ -581,6 +592,24 @@ module Howzit
|
|
581
592
|
template_topics
|
582
593
|
end
|
583
594
|
|
595
|
+
def include_file(m)
|
596
|
+
file = File.expand_path(m[1])
|
597
|
+
|
598
|
+
return m[0] unless File.exist?(file)
|
599
|
+
|
600
|
+
content = IO.read(file)
|
601
|
+
home = ENV['HOME']
|
602
|
+
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
603
|
+
prefix = "#{short_path}/#{File.basename(file)}:"
|
604
|
+
parts = content.split(/^##+/)
|
605
|
+
parts.shift
|
606
|
+
if parts.empty?
|
607
|
+
content
|
608
|
+
else
|
609
|
+
"## #{parts.join('## ')}".gsub(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
584
613
|
# Read in the build notes file and output a hash of "Title" => contents
|
585
614
|
def read_help_file(path = nil)
|
586
615
|
filename = path.nil? ? note_file : path
|
@@ -588,21 +617,7 @@ module Howzit
|
|
588
617
|
help = IO.read(filename)
|
589
618
|
|
590
619
|
help.gsub!(/@include\((.*?)\)/) do
|
591
|
-
|
592
|
-
file = File.expand_path(m[1])
|
593
|
-
if File.exist?(file)
|
594
|
-
content = IO.read(file)
|
595
|
-
home = ENV['HOME']
|
596
|
-
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
597
|
-
prefix = "#{short_path}:"
|
598
|
-
parts = content.split(/^##+/)
|
599
|
-
parts.shift
|
600
|
-
content = '## ' + parts.join('## ')
|
601
|
-
content.gsub!(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
602
|
-
content
|
603
|
-
else
|
604
|
-
m[0]
|
605
|
-
end
|
620
|
+
include_file(Regexp.last_match)
|
606
621
|
end
|
607
622
|
|
608
623
|
template_topics = get_template_topics(help)
|
@@ -673,7 +688,8 @@ module Howzit
|
|
673
688
|
matches
|
674
689
|
end
|
675
690
|
|
676
|
-
def initialize(args)
|
691
|
+
def initialize(args = [])
|
692
|
+
Color.coloring = $stdout.isatty
|
677
693
|
flags = {
|
678
694
|
run: false,
|
679
695
|
list_topics: false,
|
@@ -683,7 +699,8 @@ module Howzit
|
|
683
699
|
title_only: false,
|
684
700
|
choose: false,
|
685
701
|
quiet: false,
|
686
|
-
verbose: false
|
702
|
+
verbose: false,
|
703
|
+
default: false
|
687
704
|
}
|
688
705
|
|
689
706
|
defaults = {
|
@@ -716,7 +733,8 @@ module Howzit
|
|
716
733
|
OptionParser.new do |opts|
|
717
734
|
opts.banner = "Usage: #{__FILE__} [OPTIONS] [TOPIC]"
|
718
735
|
opts.separator ''
|
719
|
-
opts.separator 'Show build notes for the current project (buildnotes.md).
|
736
|
+
opts.separator 'Show build notes for the current project (buildnotes.md).
|
737
|
+
Include a topic name to see just that topic, or no argument to display all.'
|
720
738
|
opts.separator ''
|
721
739
|
opts.separator 'Options:'
|
722
740
|
|
@@ -725,7 +743,8 @@ module Howzit
|
|
725
743
|
Process.exit 0
|
726
744
|
end
|
727
745
|
|
728
|
-
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
746
|
+
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
747
|
+
using $EDITOR") do
|
729
748
|
edit_note
|
730
749
|
Process.exit 0
|
731
750
|
end
|
@@ -743,7 +762,8 @@ module Howzit
|
|
743
762
|
@options[:list_topics] = true
|
744
763
|
end
|
745
764
|
|
746
|
-
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
765
|
+
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
766
|
+
'Topics matching type', "(#{MATCHING_OPTIONS.join(', ')})") do |c|
|
747
767
|
@options[:matching] = c
|
748
768
|
end
|
749
769
|
|
@@ -776,8 +796,8 @@ module Howzit
|
|
776
796
|
@options[:log_level] = 0
|
777
797
|
end
|
778
798
|
|
779
|
-
opts.on('-u', '--upstream', 'Traverse up parent directories for additional build notes') do
|
780
|
-
@options[:include_upstream] =
|
799
|
+
opts.on('-u', '--[no-]upstream', 'Traverse up parent directories for additional build notes') do |p|
|
800
|
+
@options[:include_upstream] = p
|
781
801
|
end
|
782
802
|
|
783
803
|
opts.on('--show-code', 'Display the content of fenced run blocks') do
|
@@ -788,7 +808,7 @@ module Howzit
|
|
788
808
|
@options[:wrap] = w.to_i
|
789
809
|
end
|
790
810
|
|
791
|
-
opts.on('--edit-config', "Edit configuration file using
|
811
|
+
opts.on('--edit-config', "Edit configuration file using default $EDITOR") do
|
792
812
|
edit_config(defaults)
|
793
813
|
Process.exit 0
|
794
814
|
end
|
@@ -802,21 +822,21 @@ module Howzit
|
|
802
822
|
Dir.chdir(template_folder)
|
803
823
|
Dir.glob('*.md').each do |file|
|
804
824
|
template = File.basename(file, '.md')
|
805
|
-
puts "
|
806
|
-
puts "
|
825
|
+
puts Color.template("{Mk}template:{Yk}#{template}{x}")
|
826
|
+
puts Color.template("{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}")
|
807
827
|
metadata = file.extract_metadata
|
808
828
|
topics = read_help_file(file)
|
809
|
-
topics.
|
810
|
-
puts "
|
829
|
+
topics.each_key do |topic|
|
830
|
+
puts Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.sub(/^.*?:/, '')}{x}")
|
811
831
|
end
|
812
832
|
if metadata.size > 0
|
813
833
|
meta = []
|
814
|
-
meta << metadata['required'].split(/\s*,\s*/).map {|m| "
|
834
|
+
meta << metadata['required'].split(/\s*,\s*/).map {|m| "*{bw}#{m}{xw}" } if metadata.key?('required')
|
815
835
|
meta << metadata['optional'].split(/\s*,\s*/).map {|m| "#{m}" } if metadata.key?('optional')
|
816
|
-
puts "
|
817
|
-
puts "
|
836
|
+
puts Color.template("{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}")
|
837
|
+
puts Color.template(" {bk}│ {xw}#{meta.join(", ")}{x}")
|
818
838
|
end
|
819
|
-
puts "
|
839
|
+
puts Color.template(" {bk}└───────────────────────────────────────────┘{x}")
|
820
840
|
end
|
821
841
|
Process.exit 0
|
822
842
|
end
|
@@ -843,9 +863,13 @@ module Howzit
|
|
843
863
|
puts "Howzit v#{VERSION}"
|
844
864
|
Process.exit 0
|
845
865
|
end
|
866
|
+
|
867
|
+
opts.on('--default', 'Answer all prompts with default response') do
|
868
|
+
@options[:default] = true
|
869
|
+
end
|
846
870
|
end.parse!(args)
|
847
871
|
|
848
|
-
|
872
|
+
@cli_args = args
|
849
873
|
end
|
850
874
|
|
851
875
|
def edit_note
|
@@ -862,7 +886,7 @@ module Howzit
|
|
862
886
|
end
|
863
887
|
|
864
888
|
##
|
865
|
-
##
|
889
|
+
## Traverse up directory tree looking for build notes
|
866
890
|
##
|
867
891
|
## @return topics dictionary
|
868
892
|
##
|
@@ -1031,7 +1055,7 @@ module Howzit
|
|
1031
1055
|
File.join(config_dir, 'templates')
|
1032
1056
|
end
|
1033
1057
|
|
1034
|
-
def create_config
|
1058
|
+
def create_config(defaults)
|
1035
1059
|
dir, file = [config_dir, config_file]
|
1036
1060
|
unless File.directory?(dir)
|
1037
1061
|
warn "Creating config directory at #{dir}"
|
@@ -1046,7 +1070,7 @@ module Howzit
|
|
1046
1070
|
end
|
1047
1071
|
|
1048
1072
|
def load_config(defaults)
|
1049
|
-
file = create_config
|
1073
|
+
file = create_config(defaults)
|
1050
1074
|
config = YAML.load(IO.read(file))
|
1051
1075
|
newconfig = config ? defaults.merge(config) : defaults
|
1052
1076
|
write_config(newconfig)
|
@@ -1064,7 +1088,7 @@ module Howzit
|
|
1064
1088
|
`#{ENV['EDITOR']} "#{config_file}"`
|
1065
1089
|
end
|
1066
1090
|
|
1067
|
-
def process
|
1091
|
+
def process
|
1068
1092
|
output = []
|
1069
1093
|
|
1070
1094
|
unless note_file
|
@@ -1080,13 +1104,13 @@ module Howzit
|
|
1080
1104
|
end
|
1081
1105
|
|
1082
1106
|
if @options[:title_only]
|
1083
|
-
out = get_note_title(
|
1107
|
+
out = get_note_title(20)
|
1084
1108
|
$stdout.print(out.strip)
|
1085
1109
|
Process.exit(0)
|
1086
1110
|
elsif @options[:output_title]
|
1087
|
-
title = get_note_title
|
1111
|
+
title = get_note_title
|
1088
1112
|
if title && !title.empty?
|
1089
|
-
header = format_header(title, { hr: "\u{2550}", color: '
|
1113
|
+
header = format_header(title, { hr: "\u{2550}", color: '{bwK}' })
|
1090
1114
|
output.push("#{header}\n")
|
1091
1115
|
end
|
1092
1116
|
end
|
@@ -1118,14 +1142,14 @@ module Howzit
|
|
1118
1142
|
elsif @options[:choose]
|
1119
1143
|
topic_match = choose(topics.keys)
|
1120
1144
|
# If there are arguments use those to search for a matching topic
|
1121
|
-
elsif
|
1145
|
+
elsif !@cli_args.empty?
|
1122
1146
|
|
1123
|
-
search =
|
1147
|
+
search = @cli_args.join(' ').strip.downcase
|
1124
1148
|
matches = match_topic(search)
|
1125
1149
|
|
1126
1150
|
if matches.empty?
|
1127
|
-
output.push(%(
|
1128
|
-
|
1151
|
+
output.push(Color.template(%({bR}ERROR:{xr} No topic match found for {bw}#{search}{x}\n)))
|
1152
|
+
unless @options[:show_all_on_error]
|
1129
1153
|
show(output.join("\n"), { color: true, highlight: false, paginate: false, wrap: 0 })
|
1130
1154
|
Process.exit 1
|
1131
1155
|
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/prompt.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Howzit
|
4
|
+
# Command line prompt utils
|
4
5
|
module Prompt
|
5
6
|
def yn(prompt, default = true)
|
7
|
+
return default if !$stdout.isatty
|
8
|
+
|
6
9
|
system 'stty cbreak'
|
7
10
|
yn = color_single_options(default ? %w[Y n] : %w[y N])
|
8
11
|
$stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m"
|
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,32 @@ describe Howzit::BuildNotes do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
describe Howzit::BuildNotes do
|
14
|
+
Dir.chdir('spec')
|
15
|
+
how = Howzit::BuildNotes.new(['--no-upstream', '--default'])
|
16
|
+
how.create_note
|
17
|
+
subject { how }
|
18
|
+
|
19
|
+
describe ".note_file" do
|
20
|
+
it "locates a build note file" do
|
21
|
+
expect(subject.note_file).not_to be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".grep_topics" do
|
26
|
+
it "found editable" do
|
27
|
+
expect(subject.grep_topics('editable')).to include('File Structure')
|
28
|
+
expect(subject.grep_topics('editable')).not_to include('Build')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".list_topic_titles" do
|
33
|
+
it "found 4 topics" do
|
34
|
+
expect(subject.topics.keys.count).to eq 4
|
35
|
+
end
|
36
|
+
it "outputs a newline-separated string" do
|
37
|
+
expect(subject.list_topic_titles.scan(/\n/).count).to eq 3
|
38
|
+
end
|
39
|
+
end
|
40
|
+
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,14 +1,14 @@
|
|
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.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -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
|