howzit 2.1.10 → 2.1.13
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/.rubocop.yml +36 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +3 -0
- data/README.md +3 -4
- data/Rakefile +31 -0
- data/lib/howzit/buildnote.rb +23 -21
- data/lib/howzit/colors.rb +30 -4
- data/lib/howzit/config.rb +3 -1
- data/lib/howzit/prompt.rb +1 -1
- data/lib/howzit/stringutils.rb +5 -5
- data/lib/howzit/task.rb +4 -3
- data/lib/howzit/topic.rb +182 -160
- data/lib/howzit/util.rb +27 -0
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +2 -3
- data/spec/topic_spec.rb +11 -4
- data/src/_README.md +145 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0fc931036b21c7bb13c805751a146432d14c40a9a910fd9999aa42fb34658cb
|
4
|
+
data.tar.gz: 31b927c85e4c7ba6938eff929e7670c1a997d79f21053ce230da3a1a5ca4b246
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6382fd78151da4a021d605276121fc48f0b1cb7692ee3a4657fd4dee820577f0f5357aa98be565dd120e440619906b1881da2269fe0e53c2321160a34dee26ac
|
7
|
+
data.tar.gz: d402a1dcf7715f04ed32fc282450c4132bf13cd3a43830eb464c298f79dc86fa4c47f30a6bd8d3698e588468f107b0b4eae6ad90c89195d878ef1f610846ab78
|
data/.rubocop.yml
CHANGED
@@ -1,15 +1,51 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
- rubocop-rake
|
4
|
+
|
1
5
|
AllCops:
|
2
6
|
Include:
|
3
7
|
- Gemfile
|
4
8
|
- Guardfile
|
5
9
|
- Rakefile
|
10
|
+
- bin/howzit
|
11
|
+
- lib/**/*.rb
|
12
|
+
|
13
|
+
Style/StringLiterals:
|
14
|
+
Enabled: true
|
15
|
+
EnforcedStyle: single_quotes
|
16
|
+
|
17
|
+
Style/StringLiteralsInInterpolation:
|
18
|
+
Enabled: true
|
19
|
+
EnforcedStyle: single_quotes
|
20
|
+
|
21
|
+
Layout/LineLength:
|
22
|
+
Max: 120
|
23
|
+
|
24
|
+
Metrics/MethodLength:
|
25
|
+
Max: 40
|
6
26
|
|
7
27
|
Metrics/BlockLength:
|
28
|
+
Max: 40
|
8
29
|
Exclude:
|
9
30
|
- Rakefile
|
10
31
|
- bin/howzit
|
11
32
|
- lib/*.rb
|
12
33
|
|
34
|
+
Metrics/ClassLength:
|
35
|
+
Max: 300
|
36
|
+
|
37
|
+
Metrics/CyclomaticComplexity:
|
38
|
+
Max: 10
|
39
|
+
|
40
|
+
Metrics/PerceivedComplexity:
|
41
|
+
Max: 30
|
42
|
+
|
43
|
+
Metrics/AbcSize:
|
44
|
+
Max: 45
|
45
|
+
|
46
|
+
Metrics/CyclomaticComplexity:
|
47
|
+
Max: 15
|
48
|
+
|
13
49
|
Style/RegexpLiteral:
|
14
50
|
Exclude:
|
15
51
|
- Guardfile
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# Howzit
|
2
3
|
|
3
4
|
[](https://rubygems.org/gems/howzit)
|
@@ -8,8 +9,6 @@ A command-line reference tool for tracking project build systems
|
|
8
9
|
|
9
10
|
Howzit is a tool that allows you to keep Markdown-formatted notes about a project's tools and procedures. It functions as an easy lookup for notes about a particular task, as well as a task runner to automatically execute appropriate commands.
|
10
11
|
|
11
|
-
<!--README-->
|
12
|
-
|
13
12
|
## Features
|
14
13
|
|
15
14
|
- Match topic titles with any portion of title
|
@@ -55,8 +54,6 @@ If you run into permission errors using the above command, you'll need to use `g
|
|
55
54
|
|
56
55
|
This project is licensed under the MIT License - see the [LICENSE.txt](LICENSE.txt) file for details.
|
57
56
|
|
58
|
-
<!--END README-->
|
59
|
-
|
60
57
|
## Warranty
|
61
58
|
|
62
59
|
This software is provided "as is" and without any express or
|
@@ -74,6 +71,7 @@ purpose.
|
|
74
71
|
[RubyDoc]: http://www.rubydoc.info/gems/howzit
|
75
72
|
[Omniref]: https://www.omniref.com/ruby/gems/howzit
|
76
73
|
|
74
|
+
|
77
75
|
## Development and Testing
|
78
76
|
|
79
77
|
### Source Code
|
@@ -143,3 +141,4 @@ To submit a patch:
|
|
143
141
|
5. Push to the branch (`git push origin my-new-feature`).
|
144
142
|
6. Create a new Pull Request.
|
145
143
|
|
144
|
+
|
data/Rakefile
CHANGED
@@ -76,4 +76,35 @@ task :dockertest, :version, :login do |_, args|
|
|
76
76
|
# puts commit&.empty? ? "Error commiting Docker tag #{img}" : "Committed Docker tag #{img}"
|
77
77
|
end
|
78
78
|
|
79
|
+
desc 'Alias for build'
|
79
80
|
task package: :build
|
81
|
+
|
82
|
+
desc 'Bump incremental version number'
|
83
|
+
task :bump, :type do |_, args|
|
84
|
+
args.with_defaults(type: 'inc')
|
85
|
+
version_file = 'lib/howzit/version.rb'
|
86
|
+
content = IO.read(version_file)
|
87
|
+
content.sub!(/VERSION = '(?<major>\d+)\.(?<minor>\d+)\.(?<inc>\d+)(?<pre>\S+)?'/) do
|
88
|
+
m = Regexp.last_match
|
89
|
+
major = m['major'].to_i
|
90
|
+
minor = m['minor'].to_i
|
91
|
+
inc = m['inc'].to_i
|
92
|
+
pre = m['pre']
|
93
|
+
|
94
|
+
case args[:type]
|
95
|
+
when /^maj/
|
96
|
+
major += 1
|
97
|
+
minor = 0
|
98
|
+
inc = 0
|
99
|
+
when /^min/
|
100
|
+
minor += 1
|
101
|
+
inc = 0
|
102
|
+
else
|
103
|
+
inc += 1
|
104
|
+
end
|
105
|
+
|
106
|
+
$stdout.puts "At version #{major}.#{minor}.#{inc}#{pre}"
|
107
|
+
"VERSION = '#{major}.#{minor}.#{inc}#{pre}'"
|
108
|
+
end
|
109
|
+
File.open(version_file, 'w+') { |f| f.puts content }
|
110
|
+
end
|
data/lib/howzit/buildnote.rb
CHANGED
@@ -69,6 +69,7 @@ module Howzit
|
|
69
69
|
##
|
70
70
|
def find_topic(term = nil)
|
71
71
|
return @topics if term.nil?
|
72
|
+
|
72
73
|
@topics.filter do |topic|
|
73
74
|
rx = term.to_rx
|
74
75
|
topic.title.downcase.sub(/ *\(.*?\) *$/, '') =~ rx
|
@@ -114,7 +115,7 @@ module Howzit
|
|
114
115
|
## @return [Array] array of topic titles
|
115
116
|
##
|
116
117
|
def list_topics
|
117
|
-
@topics.map
|
118
|
+
@topics.map(&:title)
|
118
119
|
end
|
119
120
|
|
120
121
|
##
|
@@ -360,19 +361,21 @@ module Howzit
|
|
360
361
|
##
|
361
362
|
def ensure_requirements(template)
|
362
363
|
t_leader = Util.read_file(template).split(/^#/)[0].strip
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
364
|
+
return unless t_leader.length.positive?
|
365
|
+
|
366
|
+
t_meta = t_leader.get_metadata
|
367
|
+
|
368
|
+
return unless t_meta.key?('required')
|
369
|
+
|
370
|
+
required = t_meta['required'].strip.split(/\s*,\s*/)
|
371
|
+
required.each do |req|
|
372
|
+
next if @metadata.keys.include?(req.downcase)
|
373
|
+
|
374
|
+
Howzit.console.error %({bRw}ERROR:{xbr} Missing required metadata key from template '{bw}#{File.basename(
|
375
|
+
template, '.md'
|
376
|
+
)}{xr}'{x}).c
|
377
|
+
Howzit.console.error %({br}Please define {by}#{req.downcase}{xr} in build notes{x}).c
|
378
|
+
Process.exit 1
|
376
379
|
end
|
377
380
|
end
|
378
381
|
|
@@ -388,7 +391,7 @@ module Howzit
|
|
388
391
|
subtopics = nil
|
389
392
|
|
390
393
|
if template =~ /\[(.*?)\]$/
|
391
|
-
subtopics = Regexp.last_match[1].split(/\s*\|\s*/).map { |t| t.gsub(/\*/, '.*?')}
|
394
|
+
subtopics = Regexp.last_match[1].split(/\s*\|\s*/).map { |t| t.gsub(/\*/, '.*?') }
|
392
395
|
template.sub!(/\[.*?\]$/, '').strip
|
393
396
|
end
|
394
397
|
|
@@ -640,11 +643,10 @@ module Howzit
|
|
640
643
|
Howzit.has_read_upstream = true
|
641
644
|
end
|
642
645
|
|
643
|
-
|
644
|
-
Howzit.console.error("{br}Note file found but no topics detected in #{note_file}{x}".c)
|
645
|
-
Process.exit 1
|
646
|
-
end
|
646
|
+
return unless note_file && @topics.empty?
|
647
647
|
|
648
|
+
Howzit.console.error("{br}Note file found but no topics detected in #{note_file}{x}".c)
|
649
|
+
Process.exit 1
|
648
650
|
end
|
649
651
|
|
650
652
|
##
|
@@ -704,7 +706,7 @@ module Howzit
|
|
704
706
|
new_topic.print_out({ single: single })
|
705
707
|
end
|
706
708
|
|
707
|
-
output.nil? ? '' : output.join("\n")
|
709
|
+
output.nil? ? '' : output.join("\n\n")
|
708
710
|
end
|
709
711
|
|
710
712
|
##
|
@@ -782,7 +784,7 @@ module Howzit
|
|
782
784
|
when :all
|
783
785
|
topic_matches.concat(matches)
|
784
786
|
else
|
785
|
-
titles = matches.map
|
787
|
+
titles = matches.map(&:title)
|
786
788
|
res = Prompt.choose(titles)
|
787
789
|
old_matching = Howzit.options[:matching]
|
788
790
|
Howzit.options[:matching] = 'exact'
|
data/lib/howzit/colors.rb
CHANGED
@@ -5,7 +5,7 @@ module Howzit
|
|
5
5
|
# Terminal output color functions.
|
6
6
|
module Color
|
7
7
|
# Regexp to match excape sequences
|
8
|
-
ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)
|
8
|
+
ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/
|
9
9
|
|
10
10
|
# All available color names. Available as methods and string extensions.
|
11
11
|
#
|
@@ -113,7 +113,9 @@ module Howzit
|
|
113
113
|
compiled = ''
|
114
114
|
normalize_color.split('').each do |char|
|
115
115
|
compiled += char
|
116
|
-
|
116
|
+
if Color.attributes.include?(compiled.to_sym) || compiled =~ /^([fb]g?)?#([a-f0-9]{6})$/i
|
117
|
+
valid_color = compiled
|
118
|
+
end
|
117
119
|
end
|
118
120
|
|
119
121
|
valid_color
|
@@ -271,7 +273,12 @@ module Howzit
|
|
271
273
|
input = input.join(' ') if input.is_a? Array
|
272
274
|
fmt = input.gsub(/%/, '%%')
|
273
275
|
fmt = fmt.gsub(/(?<!\\u|\$)\{(\w+)\}/i) do
|
274
|
-
Regexp.last_match(1)
|
276
|
+
m = Regexp.last_match(1)
|
277
|
+
if m =~ /^[wkglycmrWKGLYCMRdbuix]+$/
|
278
|
+
m.split('').map { |c| "%<#{c}>s" }.join('')
|
279
|
+
else
|
280
|
+
Regexp.last_match(0)
|
281
|
+
end
|
275
282
|
end
|
276
283
|
|
277
284
|
colors = { w: white, k: black, g: green, l: blue,
|
@@ -333,9 +340,28 @@ module Howzit
|
|
333
340
|
module_eval(new_method)
|
334
341
|
end
|
335
342
|
|
343
|
+
##
|
344
|
+
## Generate escape codes for hex colors
|
345
|
+
##
|
346
|
+
## @param hex [String] The hexadecimal color code
|
347
|
+
##
|
348
|
+
## @return [String] ANSI escape string
|
349
|
+
##
|
350
|
+
def rgb(hex)
|
351
|
+
is_bg = hex.match(/^bg?#/) ? true : false
|
352
|
+
hex_string = hex.sub(/^([fb]g?)?#/, '')
|
353
|
+
|
354
|
+
parts = hex_string.match(/(?<r>..)(?<g>..)(?<b>..)/)
|
355
|
+
t = []
|
356
|
+
%w[r g b].each do |e|
|
357
|
+
t << parts[e].hex
|
358
|
+
end
|
359
|
+
"\e[#{is_bg ? '48' : '38'};2;#{t.join(';')}m"
|
360
|
+
end
|
361
|
+
|
336
362
|
# Regular expression that is used to scan for ANSI-sequences while
|
337
363
|
# uncoloring strings.
|
338
|
-
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m
|
364
|
+
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/
|
339
365
|
|
340
366
|
# Returns an uncolored version of the string, that is all
|
341
367
|
# ANSI-sequences are stripped from the string.
|
data/lib/howzit/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Howzit
|
2
4
|
# Config Class
|
3
5
|
class Config
|
@@ -95,7 +97,7 @@ module Howzit
|
|
95
97
|
def should_ignore(filename)
|
96
98
|
return false unless File.exist?(ignore_file)
|
97
99
|
|
98
|
-
@ignore_patterns ||= YAML.
|
100
|
+
@ignore_patterns ||= YAML.load(Util.read_file(ignore_file))
|
99
101
|
|
100
102
|
ignore = false
|
101
103
|
|
data/lib/howzit/prompt.rb
CHANGED
data/lib/howzit/stringutils.rb
CHANGED
@@ -103,7 +103,7 @@ module Howzit
|
|
103
103
|
|
104
104
|
# Just strip out color codes when requested
|
105
105
|
def uncolor
|
106
|
-
gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'')
|
106
|
+
gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/, '')
|
107
107
|
end
|
108
108
|
|
109
109
|
# Wrap text at a specified width.
|
@@ -277,7 +277,7 @@ module Howzit
|
|
277
277
|
def extract_metadata
|
278
278
|
if File.exist?(self)
|
279
279
|
leader = Util.read_file(self).split(/^#/)[0].strip
|
280
|
-
leader.length
|
280
|
+
leader.length.positive? ? leader.get_metadata : {}
|
281
281
|
else
|
282
282
|
{}
|
283
283
|
end
|
@@ -361,11 +361,11 @@ module Howzit
|
|
361
361
|
|
362
362
|
case Howzit.options[:header_format]
|
363
363
|
when :block
|
364
|
-
Color.template("#{options[:color]}\u{258C}#{title}#{should_mark_iterm? && options[:mark] ? iterm_marker : ''}{x}")
|
364
|
+
Color.template("\n\n#{options[:color]}\u{258C}#{title}#{should_mark_iterm? && options[:mark] ? iterm_marker : ''}{x}")
|
365
365
|
else
|
366
366
|
cols = TTY::Screen.columns
|
367
367
|
|
368
|
-
cols = Howzit.options[:wrap] if
|
368
|
+
cols = Howzit.options[:wrap] if Howzit.options[:wrap].positive? && cols > Howzit.options[:wrap]
|
369
369
|
title = Color.template("#{options[:border]}#{options[:hr] * 2}( #{options[:color]}#{title}#{options[:border]} )")
|
370
370
|
|
371
371
|
tail = if should_mark_iterm?
|
@@ -373,7 +373,7 @@ module Howzit
|
|
373
373
|
else
|
374
374
|
options[:hr] * (cols - title.uncolor.length)
|
375
375
|
end
|
376
|
-
Color.template("#{title}#{tail}{x}")
|
376
|
+
Color.template("\n\n#{title}#{tail}{x}")
|
377
377
|
end
|
378
378
|
end
|
379
379
|
end
|
data/lib/howzit/task.rb
CHANGED
@@ -39,7 +39,7 @@ module Howzit
|
|
39
39
|
## @return [String] description
|
40
40
|
##
|
41
41
|
def inspect
|
42
|
-
%(<#Howzit::Task @type=:#{@type} @title="#{@title}" @arguments=#{@arguments} @block?=#{@action.split(/\n/).count > 1}>)
|
42
|
+
%(<#Howzit::Task @type=:#{@type} @title="#{@title}" @action="#{@action}" @arguments=#{@arguments} @block?=#{@action.split(/\n/).count > 1}>)
|
43
43
|
end
|
44
44
|
|
45
45
|
##
|
@@ -95,7 +95,8 @@ module Howzit
|
|
95
95
|
def run_run
|
96
96
|
title = Howzit.options[:show_all_code] ? @action : @title
|
97
97
|
Howzit.console.info("#{@prefix}{bg}Running {bw}#{title}{x}".c)
|
98
|
-
|
98
|
+
ENV['HOWZIT_SCRIPTS'] = File.expand_path('~/.config/howzit/scripts')
|
99
|
+
system(@action)
|
99
100
|
end
|
100
101
|
|
101
102
|
##
|
@@ -105,7 +106,7 @@ module Howzit
|
|
105
106
|
title = Howzit.options[:show_all_code] ? @action : @title
|
106
107
|
Howzit.console.info("#{@prefix}{bg}Copied {bw}#{title}{bg} to clipboard{x}".c)
|
107
108
|
Util.os_copy(@action)
|
108
|
-
|
109
|
+
true
|
109
110
|
end
|
110
111
|
|
111
112
|
##
|
data/lib/howzit/topic.rb
CHANGED
@@ -56,15 +56,28 @@ module Howzit
|
|
56
56
|
@title =~ /#{term}/i || @content =~ /#{term}/i
|
57
57
|
end
|
58
58
|
|
59
|
+
def ask_task(task)
|
60
|
+
note = if task.type == :include
|
61
|
+
task_count = Howzit.buildnote.find_topic(task.action)[0].tasks.count
|
62
|
+
" (#{task_count} tasks)"
|
63
|
+
else
|
64
|
+
''
|
65
|
+
end
|
66
|
+
q = %({bg}#{task.type.to_s.capitalize} {xw}"{bw}#{task.title}{xw}"#{note}{x}).c
|
67
|
+
Prompt.yn(q, default: task.default)
|
68
|
+
end
|
69
|
+
|
70
|
+
def check_cols
|
71
|
+
TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
|
72
|
+
rescue StandardError
|
73
|
+
60
|
74
|
+
end
|
75
|
+
|
59
76
|
# Handle run command, execute directives in topic
|
60
77
|
def run(nested: false)
|
61
78
|
output = []
|
62
79
|
|
63
|
-
cols =
|
64
|
-
TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
|
65
|
-
rescue StandardError
|
66
|
-
60
|
67
|
-
end
|
80
|
+
cols = check_cols
|
68
81
|
|
69
82
|
if @tasks.count.positive?
|
70
83
|
unless @prereqs.empty?
|
@@ -75,18 +88,8 @@ module Howzit
|
|
75
88
|
end
|
76
89
|
|
77
90
|
@tasks.each do |task|
|
78
|
-
if task.optional || Howzit.options[:ask]
|
79
|
-
note = if task.type == :include
|
80
|
-
task_count = Howzit.buildnote.find_topic(task.action)[0].tasks.count
|
81
|
-
" (#{task_count} tasks)"
|
82
|
-
else
|
83
|
-
''
|
84
|
-
end
|
85
|
-
q = %({bg}#{task.type.to_s.capitalize} {xw}"{bw}#{task.title}{xw}"#{note}{x}).c
|
86
|
-
res = Prompt.yn(q, default: task.default)
|
87
|
-
next unless res
|
91
|
+
next if (task.optional || Howzit.options[:ask]) && !ask_task(task)
|
88
92
|
|
89
|
-
end
|
90
93
|
run_output, total, success = task.run
|
91
94
|
|
92
95
|
output.concat(run_output)
|
@@ -123,6 +126,116 @@ module Howzit
|
|
123
126
|
output
|
124
127
|
end
|
125
128
|
|
129
|
+
def title_option(color, topic, keys, opt)
|
130
|
+
option = colored_option(color, topic, keys)
|
131
|
+
"#{opt[:single] ? 'From' : 'Include'} #{topic.title}#{option}:"
|
132
|
+
end
|
133
|
+
|
134
|
+
def colored_option(color, topic, keys)
|
135
|
+
if topic.tasks.empty?
|
136
|
+
''
|
137
|
+
else
|
138
|
+
optional = keys[:optional] =~ /[?!]+/ ? true : false
|
139
|
+
default = keys[:optional] =~ /!/ ? false : true
|
140
|
+
if optional
|
141
|
+
colored_yn(color, default)
|
142
|
+
else
|
143
|
+
''
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def colored_yn(color, default)
|
149
|
+
if default
|
150
|
+
" {xKk}[{gbK}Y{xKk}/{dbwK}n{xKk}]{x}#{color}".c
|
151
|
+
else
|
152
|
+
" {xKk}[{dbwK}y{xKk}/{bgK}N{xKk}]{x}#{color}".c
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
## Handle an include statement
|
158
|
+
##
|
159
|
+
## @param keys [Hash] The symbolized keys and values from the regex
|
160
|
+
## that found the statement
|
161
|
+
## @param opt [Hash] Options
|
162
|
+
##
|
163
|
+
def process_include(keys, opt)
|
164
|
+
output = []
|
165
|
+
|
166
|
+
if keys[:action] =~ / *\[(.*?)\] *$/
|
167
|
+
Howzit.named_arguments = @named_args
|
168
|
+
Howzit.arguments = Regexp.last_match(1).split(/ *, */).map!(&:render_arguments)
|
169
|
+
end
|
170
|
+
|
171
|
+
matches = Howzit.buildnote.find_topic(keys[:action].sub(/ *\[.*?\] *$/, ''))
|
172
|
+
|
173
|
+
return [] if matches.empty?
|
174
|
+
|
175
|
+
topic = matches[0]
|
176
|
+
|
177
|
+
rule = '{kKd}'
|
178
|
+
color = '{Kyd}'
|
179
|
+
title = title_option(color, topic, keys, opt)
|
180
|
+
options = { color: color, hr: '.', border: rule }
|
181
|
+
|
182
|
+
output.push("#{'> ' * @nest_level}#{title}".format_header(options)) unless Howzit.inclusions.include?(topic)
|
183
|
+
|
184
|
+
if opt[:single] && Howzit.inclusions.include?(topic)
|
185
|
+
output.push("#{'> ' * @nest_level}#{title} included above".format_header(options))
|
186
|
+
elsif opt[:single]
|
187
|
+
@nest_level += 1
|
188
|
+
|
189
|
+
output.concat(topic.print_out({ single: true, header: false }))
|
190
|
+
output.push("#{'> ' * @nest_level}...".format_header(options))
|
191
|
+
@nest_level -= 1
|
192
|
+
end
|
193
|
+
Howzit.inclusions.push(topic)
|
194
|
+
|
195
|
+
output
|
196
|
+
end
|
197
|
+
|
198
|
+
def color_directive_yn(keys)
|
199
|
+
optional, default = define_optional(keys[:optional])
|
200
|
+
if optional
|
201
|
+
default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
|
202
|
+
else
|
203
|
+
''
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def process_directive(keys)
|
208
|
+
cmd = keys[:cmd]
|
209
|
+
obj = keys[:action]
|
210
|
+
title = keys[:title].empty? ? obj : keys[:title].strip
|
211
|
+
title = Howzit.options[:show_all_code] ? obj : title
|
212
|
+
option = color_directive_yn(keys)
|
213
|
+
icon = case cmd
|
214
|
+
when 'run'
|
215
|
+
"\u{25B6}"
|
216
|
+
when 'copy'
|
217
|
+
"\u{271A}"
|
218
|
+
when /open|url/
|
219
|
+
"\u{279A}"
|
220
|
+
end
|
221
|
+
|
222
|
+
"{bmK}#{icon} {bwK}#{title.preserve_escapes}{x}#{option}".c
|
223
|
+
end
|
224
|
+
|
225
|
+
def define_optional(optional)
|
226
|
+
is_optional = optional =~ /[?!]+/ ? true : false
|
227
|
+
default = optional =~ /!/ ? false : true
|
228
|
+
[is_optional, default]
|
229
|
+
end
|
230
|
+
|
231
|
+
def title_code_block(keys)
|
232
|
+
if keys[:title].length.positive?
|
233
|
+
"Block: #{keys[:title]}#{color_directive_yn(keys)}"
|
234
|
+
else
|
235
|
+
"Code Block#{color_directive_yn(keys)}"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
126
239
|
# Output a topic with fancy title and bright white text.
|
127
240
|
#
|
128
241
|
# @param options [Hash] The options
|
@@ -139,99 +252,23 @@ module Howzit
|
|
139
252
|
output.push('')
|
140
253
|
end
|
141
254
|
topic = @content.dup
|
142
|
-
|
255
|
+
unless Howzit.options[:show_all_code]
|
256
|
+
topic.gsub!(/(?mix)^(`{3,})run([?!]*)\s*
|
257
|
+
([^\n]*)[\s\S]*?\n\1\s*$/, '@@@run\2 \3')
|
258
|
+
end
|
143
259
|
topic.split(/\n/).each do |l|
|
144
260
|
case l
|
145
261
|
when /@(before|after|prereq|end)/
|
146
262
|
next
|
147
|
-
when /@include(?<optional>[!?]{1,2})?\((?<action>[
|
148
|
-
|
149
|
-
|
150
|
-
if m[:action] =~ / *\[(.*?)\] *$/
|
151
|
-
Howzit.named_arguments = @named_args
|
152
|
-
Howzit.arguments = Regexp.last_match(1).split(/ *, */).map!(&:render_arguments)
|
153
|
-
end
|
154
|
-
|
155
|
-
matches = Howzit.buildnote.find_topic(m[:action].sub(/ *\[.*?\] *$/, ''))
|
156
|
-
|
157
|
-
unless matches.empty?
|
158
|
-
i_topic = matches[0]
|
159
|
-
|
160
|
-
rule = '{kKd}'
|
161
|
-
color = '{Kyd}'
|
162
|
-
option = if i_topic.tasks.empty?
|
163
|
-
''
|
164
|
-
else
|
165
|
-
optional = m[:optional] =~ /[?!]+/ ? true : false
|
166
|
-
default = m[:optional] =~ /!/ ? false : true
|
167
|
-
if optional
|
168
|
-
default ? " {xKk}[{gbK}Y{xKk}/{dbwK}n{xKk}]{x}#{color}".c : " {xKk}[{dbwK}y{xKk}/{bgK}N{xKk}]{x}#{color}".c
|
169
|
-
else
|
170
|
-
''
|
171
|
-
end
|
172
|
-
end
|
173
|
-
title = "#{opt[:single] ? 'From' : 'Include'} #{i_topic.title}#{option}:"
|
174
|
-
options = { color: color, hr: '.', border: rule }
|
175
|
-
unless Howzit.inclusions.include?(i_topic)
|
176
|
-
output.push("#{'> ' * @nest_level}#{title}".format_header(options))
|
177
|
-
end
|
178
|
-
|
179
|
-
if opt[:single] && Howzit.inclusions.include?(i_topic)
|
180
|
-
output.push("#{'> ' * @nest_level}#{title} included above".format_header(options))
|
181
|
-
elsif opt[:single]
|
182
|
-
@nest_level += 1
|
183
|
-
|
184
|
-
output.concat(i_topic.print_out({ single: true, header: false }))
|
185
|
-
output.push("#{'> ' * @nest_level}...".format_header(options))
|
186
|
-
@nest_level -= 1
|
187
|
-
end
|
188
|
-
Howzit.inclusions.push(i_topic)
|
189
|
-
end
|
263
|
+
when /@include(?<optional>[!?]{1,2})?\((?<action>[^)]+)\)/
|
264
|
+
output.concat(process_include(Regexp.last_match.named_captures.symbolize_keys, opt))
|
190
265
|
when /@(?<cmd>run|copy|open|url)(?<optional>[?!]{1,2})?\((?<action>.*?)\) *(?<title>.*?)$/
|
191
|
-
|
192
|
-
cmd = m[:cmd]
|
193
|
-
obj = m[:action]
|
194
|
-
title = m[:title].empty? ? obj : m[:title].strip
|
195
|
-
title = Howzit.options[:show_all_code] ? obj : title
|
196
|
-
optional = m[:optional] =~ /[?!]+/ ? true : false
|
197
|
-
default = m[:optional] =~ /!/ ? false : true
|
198
|
-
option = if optional
|
199
|
-
default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
|
200
|
-
else
|
201
|
-
''
|
202
|
-
end
|
203
|
-
icon = case cmd
|
204
|
-
when 'run'
|
205
|
-
"\u{25B6}"
|
206
|
-
when 'copy'
|
207
|
-
"\u{271A}"
|
208
|
-
when /open|url/
|
209
|
-
"\u{279A}"
|
210
|
-
end
|
211
|
-
|
212
|
-
output.push("{bmK}#{icon} {bwK}#{title.preserve_escapes}{x}#{option}".c)
|
266
|
+
output.push(process_directive(Regexp.last_match.named_captures.symbolize_keys))
|
213
267
|
when /(?<fence>`{3,})run(?<optional>[!?]{1,2})? *(?<title>.*?)$/i
|
214
|
-
|
215
|
-
optional = m[:optional] =~ /[?!]+/ ? true : false
|
216
|
-
default = m[:optional] =~ /!/ ? false : true
|
217
|
-
option = if optional
|
218
|
-
default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
|
219
|
-
else
|
220
|
-
''
|
221
|
-
end
|
222
|
-
desc = m[:title].length.positive? ? "Block: #{m[:title]}#{option}" : "Code Block#{option}"
|
268
|
+
desc = title_code_block(Regexp.last_match.named_captures.symbolize_keys)
|
223
269
|
output.push("{bmK}\u{25B6} {bwK}#{desc}{x}\n```".c)
|
224
270
|
when /@@@run(?<optional>[!?]{1,2})? *(?<title>.*?)$/i
|
225
|
-
|
226
|
-
optional = m[:optional] =~ /[?!]+/ ? true : false
|
227
|
-
default = m[:optional] =~ /!/ ? false : true
|
228
|
-
option = if optional
|
229
|
-
default ? ' {xk}[{g}Y{xk}/{dbw}n{xk}]{x}'.c : ' {xk}[{dbw}y{xk}/{g}N{xk}]{x}'.c
|
230
|
-
else
|
231
|
-
''
|
232
|
-
end
|
233
|
-
desc = m[:title].length.positive? ? "Block: #{m[:title]}#{option}" : "Code Block#{option}"
|
234
|
-
output.push("{bmK}\u{25B6} {bwK}#{desc}{x}".c)
|
271
|
+
output.push("{bmK}\u{25B6} {bwK}#{title_code_block(Regexp.last_match.named_captures.symbolize_keys)}{x}".c)
|
235
272
|
else
|
236
273
|
l.wrap!(Howzit.options[:wrap]) if Howzit.options[:wrap].positive?
|
237
274
|
output.push(l)
|
@@ -241,6 +278,45 @@ module Howzit
|
|
241
278
|
output.push('').map(&:render_arguments)
|
242
279
|
end
|
243
280
|
|
281
|
+
include Comparable
|
282
|
+
def <=>(other)
|
283
|
+
@title <=> other.title
|
284
|
+
end
|
285
|
+
|
286
|
+
def define_task_args(keys)
|
287
|
+
cmd = keys[:cmd]
|
288
|
+
obj = keys[:action]
|
289
|
+
title = keys[:title].nil? ? obj : keys[:title].strip
|
290
|
+
title = Howzit.options[:show_all_code] ? obj : title
|
291
|
+
task_args = { type: :include,
|
292
|
+
arguments: nil,
|
293
|
+
title: title,
|
294
|
+
action: obj,
|
295
|
+
parent: self }
|
296
|
+
case cmd
|
297
|
+
when /include/i
|
298
|
+
if title =~ /\[(.*?)\] *$/
|
299
|
+
Howzit.named_arguments = @named_args
|
300
|
+
args = Regexp.last_match(1).split(/ *, */).map(&:render_arguments)
|
301
|
+
Howzit.arguments = args
|
302
|
+
arguments
|
303
|
+
title.sub!(/ *\[.*?\] *$/, '')
|
304
|
+
end
|
305
|
+
|
306
|
+
task_args[:type] = :include
|
307
|
+
task_args[:arguments] = Howzit.named_arguments
|
308
|
+
when /run/i
|
309
|
+
task_args[:type] = :run
|
310
|
+
when /copy/i
|
311
|
+
task_args[:type] = :copy
|
312
|
+
task_args[:action] = Shellwords.escape(obj)
|
313
|
+
when /open|url/i
|
314
|
+
task_args[:type] = :open
|
315
|
+
end
|
316
|
+
|
317
|
+
task_args
|
318
|
+
end
|
319
|
+
|
244
320
|
private
|
245
321
|
|
246
322
|
##
|
@@ -264,8 +340,7 @@ module Howzit
|
|
264
340
|
Howzit.named_arguments = @named_args
|
265
341
|
|
266
342
|
if c[:cmd].nil?
|
267
|
-
optional = c[:optional2]
|
268
|
-
default = c[:optional2] =~ /!/ ? false : true
|
343
|
+
optional, default = define_optional(c[:optional2])
|
269
344
|
title = c[:title2].nil? ? '' : c[:title2].strip
|
270
345
|
block = c[:block]&.strip
|
271
346
|
runnable << Howzit::Task.new({ type: :block,
|
@@ -275,63 +350,10 @@ module Howzit
|
|
275
350
|
optional: optional,
|
276
351
|
default: default)
|
277
352
|
else
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
title = c[:title].nil? ? obj : c[:title].strip
|
283
|
-
title = Howzit.options[:show_all_code] ? obj : title
|
284
|
-
case cmd
|
285
|
-
when /include/i
|
286
|
-
# matches = Howzit.buildnote.find_topic(obj)
|
287
|
-
# unless matches.empty? || Howzit.inclusions.include?(matches[0].title)
|
288
|
-
# tasks = matches[0].tasks.map do |inc|
|
289
|
-
# Howzit.inclusions.push(matches[0].title)
|
290
|
-
# inc.parent = matches[0]
|
291
|
-
# inc
|
292
|
-
# end
|
293
|
-
# runnable.concat(tasks)
|
294
|
-
# end
|
295
|
-
args = []
|
296
|
-
if title =~ /\[(.*?)\] *$/
|
297
|
-
Howzit.named_arguments = @named_args
|
298
|
-
args = Regexp.last_match(1).split(/ *, */).map(&:render_arguments)
|
299
|
-
Howzit.arguments = args
|
300
|
-
arguments
|
301
|
-
title.sub!(/ *\[.*?\] *$/, '')
|
302
|
-
end
|
303
|
-
|
304
|
-
runnable << Howzit::Task.new({ type: :include,
|
305
|
-
arguments: Howzit.named_arguments,
|
306
|
-
title: title,
|
307
|
-
action: obj,
|
308
|
-
parent: self },
|
309
|
-
optional: optional,
|
310
|
-
default: default)
|
311
|
-
when /run/i
|
312
|
-
# warn "{bg}Running {bw}#{obj}{x}".c if Howzit.options[:log_level] < 2
|
313
|
-
runnable << Howzit::Task.new({ type: :run,
|
314
|
-
title: title,
|
315
|
-
action: obj,
|
316
|
-
parent: self },
|
317
|
-
optional: optional,
|
318
|
-
default: default)
|
319
|
-
when /copy/i
|
320
|
-
# warn "{bg}Copied {bw}#{obj}{bg} to clipboard{x}".c if Howzit.options[:log_level] < 2
|
321
|
-
runnable << Howzit::Task.new({ type: :copy,
|
322
|
-
title: title,
|
323
|
-
action: Shellwords.escape(obj),
|
324
|
-
parent: self },
|
325
|
-
optional: optional,
|
326
|
-
default: default)
|
327
|
-
when /open|url/i
|
328
|
-
runnable << Howzit::Task.new({ type: :open,
|
329
|
-
title: title,
|
330
|
-
action: obj,
|
331
|
-
parent: self },
|
332
|
-
optional: optional,
|
333
|
-
default: default)
|
334
|
-
end
|
353
|
+
optional, default = define_optional(c[:optional])
|
354
|
+
runnable << Howzit::Task.new(define_task_args(c),
|
355
|
+
optional: optional,
|
356
|
+
default: default)
|
335
357
|
end
|
336
358
|
end
|
337
359
|
|
data/lib/howzit/util.rb
CHANGED
@@ -210,6 +210,33 @@ module Howzit
|
|
210
210
|
end
|
211
211
|
end
|
212
212
|
|
213
|
+
##
|
214
|
+
## Platform-agnostic paste-from-clipboard
|
215
|
+
##
|
216
|
+
def os_paste
|
217
|
+
os = RbConfig::CONFIG['target_os']
|
218
|
+
out = "{bg}Pasting from clipboard".c
|
219
|
+
case os
|
220
|
+
when /darwin.*/i
|
221
|
+
Howzit.console.debug("#{out} (macOS){x}".c)
|
222
|
+
`pbpaste`
|
223
|
+
when /mingw|mswin/i
|
224
|
+
Howzit.console.debug("#{out} (Windows){x}".c)
|
225
|
+
`cat /dev/clipboard`
|
226
|
+
else
|
227
|
+
if 'xsel'.available?
|
228
|
+
Howzit.console.debug("#{out} (Linux, xsel){x}".c)
|
229
|
+
`xsel --clipboard --output`
|
230
|
+
elsif 'xclip'.available?
|
231
|
+
Howzit.console.debug("#{out} (Linux, xclip){x}".c)
|
232
|
+
`xclip -selection clipboard -o`
|
233
|
+
else
|
234
|
+
Howzit.console.debug(out)
|
235
|
+
Howzit.console.warn('Unable to determine executable for clipboard.')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
213
240
|
##
|
214
241
|
## Platform-agnostic open command
|
215
242
|
##
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
@@ -50,6 +50,7 @@ require 'tty/box'
|
|
50
50
|
module Howzit
|
51
51
|
class << self
|
52
52
|
attr_accessor :arguments, :named_arguments, :cli_args
|
53
|
+
|
53
54
|
##
|
54
55
|
## Holds a Configuration object with methods and a @settings hash
|
55
56
|
##
|
@@ -91,8 +92,6 @@ module Howzit
|
|
91
92
|
@has_read_upstream ||= false
|
92
93
|
end
|
93
94
|
|
94
|
-
|
95
|
-
@has_read_upstream = has_read
|
96
|
-
end
|
95
|
+
attr_writer :has_read_upstream
|
97
96
|
end
|
98
97
|
end
|
data/spec/topic_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe Howzit::Topic do
|
|
9
9
|
|
10
10
|
describe '.new' do
|
11
11
|
it 'makes a new topic instance' do
|
12
|
-
expect(topic).to be_a
|
12
|
+
expect(topic).to be_a described_class
|
13
13
|
end
|
14
14
|
it 'has the correct title' do
|
15
15
|
expect(topic.title).to eq title
|
@@ -51,9 +51,11 @@ describe Howzit::Topic do
|
|
51
51
|
it 'returns true for matching pattern in content' do
|
52
52
|
expect(topic.grep('prereq.*?ite')).to be_truthy
|
53
53
|
end
|
54
|
+
|
54
55
|
it 'returns true for matching pattern in title' do
|
55
56
|
expect(topic.grep('bal.*?na')).to be_truthy
|
56
57
|
end
|
58
|
+
|
57
59
|
it 'fails on bad pattern' do
|
58
60
|
expect(topic.grep('xxx+')).to_not be_truthy
|
59
61
|
end
|
@@ -61,10 +63,12 @@ describe Howzit::Topic do
|
|
61
63
|
|
62
64
|
describe '.run' do
|
63
65
|
Howzit.options[:default] = true
|
66
|
+
|
64
67
|
it 'shows prereq and postreq' do
|
65
68
|
expect { topic.run }.to output(/prerequisite/).to_stdout
|
66
69
|
expect { topic.run }.to output(/postrequisite/).to_stdout
|
67
70
|
end
|
71
|
+
|
68
72
|
it 'Copies to clipboard' do
|
69
73
|
expect {
|
70
74
|
ENV['RUBYOPT'] = '-W1'
|
@@ -77,15 +81,18 @@ describe Howzit::Topic do
|
|
77
81
|
describe '.print_out' do
|
78
82
|
Howzit.options[:header_format] = :block
|
79
83
|
Howzit.options[:color] = false
|
84
|
+
|
80
85
|
it 'prints the topic title' do
|
81
|
-
expect(topic.print_out({single: true, header: true}).join("\n").uncolor).to match(/▌Topic Balogna/)
|
86
|
+
expect(topic.print_out({ single: true, header: true }).join("\n").uncolor).to match(/▌Topic Balogna/)
|
82
87
|
end
|
88
|
+
|
83
89
|
it 'prints a task title' do
|
84
|
-
expect(topic.print_out({single: true, header: true}).join("\n").uncolor).to match(/▶ Null Output/)
|
90
|
+
expect(topic.print_out({ single: true, header: true }).join("\n").uncolor).to match(/▶ Null Output/)
|
85
91
|
end
|
92
|
+
|
86
93
|
it 'prints task action with --show-code' do
|
87
94
|
Howzit.options[:show_all_code] = true
|
88
|
-
expect(topic.print_out({single: true, header: true}).join("\n").uncolor).to match(/▶ ls -1/)
|
95
|
+
expect(topic.print_out({ single: true, header: true }).join("\n").uncolor).to match(/▶ ls -1/)
|
89
96
|
end
|
90
97
|
end
|
91
98
|
end
|
data/src/_README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
<!--README--><!--GITHUB-->
|
2
|
+
# Howzit
|
3
|
+
|
4
|
+
[](https://rubygems.org/gems/howzit)
|
5
|
+
[](https://travis-ci.org/makenew/ruby-gem)
|
6
|
+
[](./LICENSE.txt)
|
7
|
+
<!--END GITHUB-->
|
8
|
+
A command-line reference tool for tracking project build systems
|
9
|
+
|
10
|
+
Howzit is a tool that allows you to keep Markdown-formatted notes about a project's tools and procedures. It functions as an easy lookup for notes about a particular task, as well as a task runner to automatically execute appropriate commands.
|
11
|
+
|
12
|
+
## Features
|
13
|
+
|
14
|
+
- Match topic titles with any portion of title
|
15
|
+
- Automatic pagination of output, with optional Markdown highlighting
|
16
|
+
- Use `@run()`, `@copy()`, and `@open()` to perform actions within a build notes file
|
17
|
+
- Use `@include()` to import another topic's tasks
|
18
|
+
- Use fenced code blocks to include/run embedded scripts
|
19
|
+
- Sets iTerm 2 marks on topic titles for navigation when paging is disabled
|
20
|
+
- Inside of git repositories, howzit will work from subdirectories, assuming build notes are in top level of repo
|
21
|
+
- Templates for easily including repeat tasks
|
22
|
+
- Grep topics for pattern and choose from matches
|
23
|
+
- Use positional and named variables when executing tasks
|
24
|
+
|
25
|
+
## Getting Started
|
26
|
+
|
27
|
+
### Prerequisites
|
28
|
+
|
29
|
+
- Ruby 2.4+ (It probably works on older Rubys, but is untested prior to 2.4.1.)
|
30
|
+
- Optional: if [`fzf`](https://github.com/junegunn/fzf) is available, it will be used for handling multiple choice selections
|
31
|
+
- Optional: if [`bat`](https://github.com/sharkdp/bat) is available it will page with that
|
32
|
+
- Optional: [`mdless`](https://github.com/ttscoff/mdless) or [`mdcat`](https://github.com/lunaryorn/mdcat) for formatting output
|
33
|
+
|
34
|
+
### Installing
|
35
|
+
|
36
|
+
You can install `howzit` by running:
|
37
|
+
|
38
|
+
gem install howzit
|
39
|
+
|
40
|
+
If you run into permission errors using the above command, you'll need to use `gem install --user-install howzit`. If that fails, either use `sudo` (`sudo gem install howzit`) or if you're using Homebrew, you have the option to install via [brew-gem](https://github.com/sportngin/brew-gem):
|
41
|
+
|
42
|
+
brew install brew-gem
|
43
|
+
brew gem install howzit
|
44
|
+
|
45
|
+
### Usage
|
46
|
+
|
47
|
+
[See the wiki](https://github.com/ttscoff/howzit/wiki) for documentation.
|
48
|
+
|
49
|
+
## Author
|
50
|
+
|
51
|
+
**Brett Terpstra** - [brettterpstra.com](https://brettterpstra.com)
|
52
|
+
|
53
|
+
## License
|
54
|
+
|
55
|
+
This project is licensed under the MIT License - see the [LICENSE.txt](LICENSE.txt) file for details.
|
56
|
+
|
57
|
+
## Warranty
|
58
|
+
|
59
|
+
This software is provided "as is" and without any express or
|
60
|
+
implied warranties, including, without limitation, the implied
|
61
|
+
warranties of merchantibility and fitness for a particular
|
62
|
+
purpose.
|
63
|
+
|
64
|
+
## Documentation
|
65
|
+
|
66
|
+
- [Howzit Wiki][Wiki].
|
67
|
+
- [YARD documentation][RubyDoc] is hosted by RubyDoc.info.
|
68
|
+
- [Interactive documentation][Omniref] is hosted by Omniref.
|
69
|
+
|
70
|
+
[Wiki]: https://github.com/ttscoff/howzit/wiki
|
71
|
+
[RubyDoc]: http://www.rubydoc.info/gems/howzit
|
72
|
+
[Omniref]: https://www.omniref.com/ruby/gems/howzit
|
73
|
+
|
74
|
+
<!--GITHUB-->
|
75
|
+
## Development and Testing
|
76
|
+
|
77
|
+
### Source Code
|
78
|
+
|
79
|
+
The [howzit source] is hosted on GitHub.
|
80
|
+
Clone the project with
|
81
|
+
|
82
|
+
```
|
83
|
+
$ git clone https://github.com/ttscoff/howzit.git
|
84
|
+
```
|
85
|
+
|
86
|
+
[howzit source]: https://github.com/ttscoff/howzit
|
87
|
+
|
88
|
+
### Requirements
|
89
|
+
|
90
|
+
You will need [Ruby] with [Bundler].
|
91
|
+
|
92
|
+
Install the development dependencies with
|
93
|
+
|
94
|
+
```
|
95
|
+
$ bundle
|
96
|
+
```
|
97
|
+
|
98
|
+
[Bundler]: http://bundler.io/
|
99
|
+
[Ruby]: https://www.ruby-lang.org/
|
100
|
+
|
101
|
+
### Rake
|
102
|
+
|
103
|
+
Run `$ rake -T` to see all Rake tasks.
|
104
|
+
|
105
|
+
```
|
106
|
+
rake build # Build howzit-2.0.1.gem into the pkg directory
|
107
|
+
rake bump:current[tag] # Show current gem version
|
108
|
+
rake bump:major[tag] # Bump major part of gem version
|
109
|
+
rake bump:minor[tag] # Bump minor part of gem version
|
110
|
+
rake bump:patch[tag] # Bump patch part of gem version
|
111
|
+
rake bump:pre[tag] # Bump pre part of gem version
|
112
|
+
rake bump:set # Sets the version number using the VERSION environment variable
|
113
|
+
rake clean # Remove any temporary products
|
114
|
+
rake clobber # Remove any generated files
|
115
|
+
rake install # Build and install howzit-2.0.1.gem into system gems
|
116
|
+
rake install:local # Build and install howzit-2.0.1.gem into system gems without network access
|
117
|
+
rake release[remote] # Create tag v2.0.1 and build and push howzit-2.0.1.gem to Rubygems
|
118
|
+
rake rubocop # Run RuboCop
|
119
|
+
rake rubocop:auto_correct # Auto-correct RuboCop offenses
|
120
|
+
rake spec # Run RSpec code examples
|
121
|
+
rake test # Run test suite
|
122
|
+
rake yard # Generate YARD Documentation
|
123
|
+
```
|
124
|
+
|
125
|
+
### Guard
|
126
|
+
|
127
|
+
Guard tasks have been separated into the following groups:
|
128
|
+
`doc`, `lint`, and `unit`.
|
129
|
+
By default, `$ guard` will generate documentation, lint, and run unit tests.
|
130
|
+
|
131
|
+
## Contributing
|
132
|
+
|
133
|
+
Please submit and comment on bug reports and feature requests.
|
134
|
+
|
135
|
+
To submit a patch:
|
136
|
+
|
137
|
+
1. Fork it (https://github.com/ttscoff/howzit/fork).
|
138
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
139
|
+
3. Make changes. Write and run tests.
|
140
|
+
4. Commit your changes (`git commit -am 'Add some feature'`).
|
141
|
+
5. Push to the branch (`git push origin my-new-feature`).
|
142
|
+
6. Create a new Pull Request.
|
143
|
+
|
144
|
+
<!--END GITHUB-->
|
145
|
+
<!--END README-->
|
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: 2.1.
|
4
|
+
version: 2.1.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: 2024-
|
11
|
+
date: 2024-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -339,6 +339,7 @@ files:
|
|
339
339
|
- spec/task_spec.rb
|
340
340
|
- spec/topic_spec.rb
|
341
341
|
- spec/util_spec.rb
|
342
|
+
- src/_README.md
|
342
343
|
- update_readmes.rb
|
343
344
|
homepage: https://github.com/ttscoff/howzit
|
344
345
|
licenses:
|
@@ -359,7 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
359
360
|
- !ruby/object:Gem::Version
|
360
361
|
version: '0'
|
361
362
|
requirements: []
|
362
|
-
rubygems_version: 3.2.
|
363
|
+
rubygems_version: 3.2.15
|
363
364
|
signing_key:
|
364
365
|
specification_version: 4
|
365
366
|
summary: Provides a way to access Markdown project notes by topic with query capabilities
|