doing 2.1.22 → 2.1.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardoc/checksums +17 -14
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +323 -111
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +2 -1
- data/bin/commands/add_section.rb +13 -0
- data/bin/commands/again.rb +99 -0
- data/bin/commands/archive.rb +96 -0
- data/bin/commands/cancel.rb +102 -0
- data/bin/commands/changes.rb +42 -0
- data/bin/commands/choose.rb +9 -0
- data/bin/commands/colors.rb +19 -0
- data/bin/commands/commands.rb +87 -0
- data/bin/commands/commands_accepting.rb +25 -0
- data/bin/commands/completion.rb +24 -0
- data/bin/commands/config.rb +245 -0
- data/bin/commands/done.rb +249 -0
- data/bin/commands/finish.rb +149 -0
- data/bin/commands/flag.rb +126 -0
- data/bin/commands/grep.rb +124 -0
- data/bin/commands/import.rb +101 -0
- data/bin/commands/install_fzf.rb +17 -0
- data/bin/commands/last.rb +114 -0
- data/bin/commands/meanwhile.rb +86 -0
- data/bin/commands/note.rb +130 -0
- data/bin/commands/now.rb +151 -0
- data/bin/commands/on.rb +66 -0
- data/bin/commands/open.rb +53 -0
- data/bin/commands/plugins.rb +23 -0
- data/bin/commands/recent.rb +78 -0
- data/bin/commands/redo.rb +22 -0
- data/bin/commands/reset.rb +106 -0
- data/bin/commands/rotate.rb +73 -0
- data/bin/commands/sections.rb +11 -0
- data/bin/commands/select.rb +123 -0
- data/bin/commands/show.rb +231 -0
- data/bin/commands/since.rb +64 -0
- data/bin/commands/tag.rb +179 -0
- data/bin/commands/tag_dir.rb +29 -0
- data/bin/commands/tags.rb +93 -0
- data/bin/commands/template.rb +61 -0
- data/bin/commands/today.rb +65 -0
- data/bin/commands/undo.rb +49 -0
- data/bin/commands/view.rb +238 -0
- data/bin/commands/views.rb +11 -0
- data/bin/commands/yesterday.rb +73 -0
- data/bin/doing +54 -3505
- data/docs/doc/Array.html +79 -11
- data/docs/doc/BooleanTermParser/Clause.html +5 -5
- data/docs/doc/BooleanTermParser/Operator.html +4 -4
- data/docs/doc/BooleanTermParser/Query.html +8 -8
- data/docs/doc/BooleanTermParser/QueryParser.html +2 -2
- data/docs/doc/BooleanTermParser/QueryTransformer.html +2 -2
- data/docs/doc/BooleanTermParser.html +1 -1
- data/docs/doc/Doing/Color.html +4 -4
- data/docs/doc/Doing/Completion.html +2 -2
- data/docs/doc/Doing/Configuration.html +17 -18
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +2 -2
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +2 -2
- data/docs/doc/Doing/Errors/DoingStandardError.html +2 -2
- data/docs/doc/Doing/Errors/EmptyInput.html +2 -2
- data/docs/doc/Doing/Errors/NoResults.html +2 -2
- data/docs/doc/Doing/Errors/PluginException.html +3 -3
- data/docs/doc/Doing/Errors/UserCancelled.html +2 -2
- data/docs/doc/Doing/Errors/WrongCommand.html +2 -2
- data/docs/doc/Doing/Errors.html +1 -1
- data/docs/doc/Doing/Hooks.html +6 -6
- data/docs/doc/Doing/Item.html +50 -16
- data/docs/doc/Doing/Items.html +10 -10
- data/docs/doc/Doing/LogAdapter.html +24 -24
- data/docs/doc/Doing/Note.html +7 -7
- data/docs/doc/Doing/Pager.html +4 -4
- data/docs/doc/Doing/Plugins.html +7 -7
- data/docs/doc/Doing/Prompt.html +59 -14
- data/docs/doc/Doing/Section.html +6 -6
- data/docs/doc/Doing/TemplateString.html +8 -8
- data/docs/doc/Doing/Types.html +206 -0
- data/docs/doc/Doing/Util/Backup.html +10 -10
- data/docs/doc/Doing/Util.html +16 -19
- data/docs/doc/Doing/WWID.html +65 -53
- data/docs/doc/Doing.html +3 -3
- data/docs/doc/FalseClass.html +201 -0
- data/docs/doc/GLI/Commands/Help.html +185 -0
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +17 -17
- data/docs/doc/GLI/Commands.html +5 -3
- data/docs/doc/GLI.html +4 -2
- data/docs/doc/Hash.html +47 -21
- data/docs/doc/Numeric.html +5 -5
- data/docs/doc/Object.html +203 -0
- data/docs/doc/PhraseParser/Operator.html +4 -4
- data/docs/doc/PhraseParser/PhraseClause.html +5 -5
- data/docs/doc/PhraseParser/Query.html +10 -10
- data/docs/doc/PhraseParser/QueryParser.html +2 -2
- data/docs/doc/PhraseParser/QueryTransformer.html +2 -2
- data/docs/doc/PhraseParser/TermClause.html +5 -5
- data/docs/doc/PhraseParser.html +1 -1
- data/docs/doc/Status.html +7 -7
- data/docs/doc/String.html +144 -51
- data/docs/doc/Symbol.html +8 -8
- data/docs/doc/Time.html +6 -6
- data/docs/doc/TrueClass.html +201 -0
- data/docs/doc/_index.html +46 -16
- data/docs/doc/class_list.html +1 -1
- data/docs/doc/file.README.html +2 -2
- data/docs/doc/index.html +2 -2
- data/docs/doc/method_list.html +292 -212
- data/docs/doc/top-level-namespace.html +2 -2
- data/docs/index.md +1 -1
- data/doing.rdoc +178 -16
- data/example_plugin.rb +2 -2
- data/lib/completion/_doing.zsh +27 -27
- data/lib/completion/doing.bash +31 -20
- data/lib/completion/doing.fish +33 -11
- data/lib/doing/array.rb +2 -2
- data/lib/doing/changelog/change.rb +115 -0
- data/lib/doing/changelog/changes.rb +73 -0
- data/lib/doing/changelog/entry.rb +21 -0
- data/lib/doing/changelog/version.rb +97 -0
- data/lib/doing/changelog.rb +6 -0
- data/lib/doing/completion/fish_completion.rb +2 -1
- data/lib/doing/configuration.rb +20 -13
- data/lib/doing/good.rb +64 -0
- data/lib/doing/hash.rb +7 -2
- data/lib/doing/help_monkey_patch.rb +31 -0
- data/lib/doing/hooks.rb +8 -4
- data/lib/doing/item.rb +24 -35
- data/lib/doing/pager.rb +1 -0
- data/lib/doing/plugins/export/template_export.rb +1 -1
- data/lib/doing/plugins/import/calendar_import.rb +1 -1
- data/lib/doing/plugins/import/doing_import.rb +1 -1
- data/lib/doing/plugins/import/timing_import.rb +1 -1
- data/lib/doing/prompt.rb +8 -0
- data/lib/doing/string.rb +20 -11
- data/lib/doing/string_chronify.rb +1 -1
- data/lib/doing/template_string.rb +2 -2
- data/lib/doing/types.rb +3 -0
- data/lib/doing/util.rb +12 -11
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +62 -37
- data/lib/doing.rb +2 -0
- data/lib/examples/commands/wiki.rb +6 -7
- data/lib/helpers/threaded_tests.rb +61 -71
- data/lib/helpers/threaded_tests_string.rb +50 -0
- metadata +56 -2
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doing
|
4
|
+
# A single version's entries
|
5
|
+
class Change
|
6
|
+
attr_reader :version, :content
|
7
|
+
|
8
|
+
attr_accessor :entries
|
9
|
+
|
10
|
+
def initialize(version, content)
|
11
|
+
@version = Version.new(version)
|
12
|
+
@content = content
|
13
|
+
parse_entries
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_entries
|
17
|
+
@entries = []
|
18
|
+
types = @content.scan(/(?<=\n|\A)#### (NEW|IMPROVED|FIXED)(.*?)(?=\n####|\Z)/m)
|
19
|
+
types.each do |type|
|
20
|
+
type[1].scan(/\s*- +(.*?)$/).each do |entry|
|
21
|
+
@entries << Entry.new(entry[0].strip, type[0])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def search_entries(search_string)
|
27
|
+
case_type = :ignore
|
28
|
+
|
29
|
+
matches = []
|
30
|
+
|
31
|
+
if search_string.is_rx?
|
32
|
+
matches = @entries.select { |e| e.string =~ search_string.to_rx(distance: 2, case_type: case_type) }
|
33
|
+
else
|
34
|
+
query = search_string.gsub(/(-)?--/, '\1]]').to_phrase_query
|
35
|
+
|
36
|
+
if query[:must].nil? && query[:must_not].nil?
|
37
|
+
query[:must] = query[:should]
|
38
|
+
query[:should] = []
|
39
|
+
end
|
40
|
+
|
41
|
+
@entries.each do |entry|
|
42
|
+
m = no_searches?(entry.string, query[:must_not])
|
43
|
+
m &&= all_searches?(entry.string, query[:must])
|
44
|
+
m &&= any_searches?(entry.string, query[:should])
|
45
|
+
matches << entry if m
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@entries = matches.count.positive? ? matches : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_h
|
53
|
+
{ version: @version, content: @content }
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
out = ["### #{@version}"]
|
58
|
+
items = {
|
59
|
+
new: [],
|
60
|
+
improved: [],
|
61
|
+
fixed: [],
|
62
|
+
other: []
|
63
|
+
}
|
64
|
+
@entries.each do |e|
|
65
|
+
type = e.type.downcase.to_sym
|
66
|
+
if items.key?(type)
|
67
|
+
items[type] << e
|
68
|
+
else
|
69
|
+
items[:other] << e
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
items.each do |type, members|
|
74
|
+
if members.count.positive?
|
75
|
+
out << "#### #{type.to_s.capitalize}"
|
76
|
+
out << members.map(&:to_s).join("\n")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
out.join("\n\n")
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def all_searches?(text, searches)
|
86
|
+
return true if searches.nil? || searches.empty?
|
87
|
+
|
88
|
+
searches.each do |s|
|
89
|
+
rx = Regexp.new(s.wildcard_to_rx, true)
|
90
|
+
return false unless text =~ rx
|
91
|
+
end
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
def no_searches?(text, searches)
|
96
|
+
return true if searches.nil? || searches.empty?
|
97
|
+
|
98
|
+
searches.each do |s|
|
99
|
+
rx = Regexp.new(s.wildcard_to_rx, true)
|
100
|
+
return false if text =~ rx
|
101
|
+
end
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
def any_searches?(text, searches)
|
106
|
+
return true if searches.nil? || searches.empty?
|
107
|
+
|
108
|
+
searches.each do |s|
|
109
|
+
rx = Regexp.new(s.wildcard_to_rx, true)
|
110
|
+
return true if text =~ rx
|
111
|
+
end
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doing
|
4
|
+
# A collection of Changes
|
5
|
+
class Changes
|
6
|
+
attr_reader :changes
|
7
|
+
|
8
|
+
def initialize(lookup: nil, search: nil)
|
9
|
+
changelog = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'CHANGELOG.md'))
|
10
|
+
raise 'Error locating changelog' unless File.exist?(changelog)
|
11
|
+
|
12
|
+
@content = IO.read(changelog)
|
13
|
+
parse_changes(lookup, search)
|
14
|
+
end
|
15
|
+
|
16
|
+
def latest
|
17
|
+
@changes[0].to_s.force_encoding('utf-8')
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
@changes.map(&:to_s).join("\n\n").force_encoding('utf-8')
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_changes(lookup, search)
|
27
|
+
change_rx = /(?<=\n|\A)### (\d+\.\d+\.\d+(?:\w*))(.*?)(?=\n### |\Z)/m
|
28
|
+
@changes = @content.scan(change_rx).each_with_object([]) do |m, a|
|
29
|
+
next if m[0].nil? || m[1].nil?
|
30
|
+
|
31
|
+
a << Change.new(m[0], m[1].strip)
|
32
|
+
end
|
33
|
+
|
34
|
+
lookup(lookup) unless lookup.nil?
|
35
|
+
search(search) unless search.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def lookup(lookup_version)
|
39
|
+
range = []
|
40
|
+
|
41
|
+
if lookup_version =~ /([\d.]+) *-+ *([\d.]+)/
|
42
|
+
m = Regexp.last_match
|
43
|
+
lookup("> #{m[1]}")
|
44
|
+
lookup("< #{m[2]}")
|
45
|
+
elsif lookup_version.scan(/[<>]/).count > 1
|
46
|
+
params = lookup_version.scan(/[<>] [\d.]+/)
|
47
|
+
params.each { |query| lookup(query) }
|
48
|
+
else
|
49
|
+
comp = case lookup_version
|
50
|
+
when /(<|prior|before|older)/
|
51
|
+
:older
|
52
|
+
when />|since|after|newer/
|
53
|
+
:newer
|
54
|
+
else
|
55
|
+
:equal
|
56
|
+
end
|
57
|
+
version = Version.new(lookup_version)
|
58
|
+
|
59
|
+
@changes.select! do |change|
|
60
|
+
change.version.compare(version, comp)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def search(query)
|
66
|
+
@changes.map do |c|
|
67
|
+
c.entries = c.search_entries(query)
|
68
|
+
end
|
69
|
+
|
70
|
+
@changes.delete_if { |c| c.nil? || c.entries.nil? }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doing
|
4
|
+
# An individual changelog item
|
5
|
+
class Entry
|
6
|
+
attr_reader :type, :string
|
7
|
+
|
8
|
+
def initialize(string, type)
|
9
|
+
@string = string
|
10
|
+
@type = type
|
11
|
+
end
|
12
|
+
|
13
|
+
def clean(string)
|
14
|
+
string.gsub(/\|/, '\|')
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"- #{clean(@string)}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doing
|
4
|
+
# Semantic versioning
|
5
|
+
class Version
|
6
|
+
attr_reader :maj, :min, :patch
|
7
|
+
|
8
|
+
def initialize(string)
|
9
|
+
@maj, @min, @patch = version_to_a(string)
|
10
|
+
end
|
11
|
+
|
12
|
+
def version_to_a(string)
|
13
|
+
raise 'Version not a string' unless string.is_a?(String)
|
14
|
+
|
15
|
+
v = string.match(/(?<maj>\d+)(?:\.(?<min>[\d*?]+))?(?:\.(?<patch>[\d*?]+))?/)
|
16
|
+
|
17
|
+
raise 'Error parsing semantic version string' if v.nil?
|
18
|
+
|
19
|
+
maj = v['maj'].to_i
|
20
|
+
min = case v['min']
|
21
|
+
when /[*?]/
|
22
|
+
v['min'].sub(/(\d+)?[^\d]/, '\1\d+')
|
23
|
+
when /^[0-9]+$/
|
24
|
+
v['min'].to_i
|
25
|
+
end
|
26
|
+
pat = case v['patch']
|
27
|
+
when /[*?]/
|
28
|
+
v['patch'].sub(/(\d+)?[^\d]/, '\1\d+')
|
29
|
+
when /^[0-9]+$/
|
30
|
+
v['patch'].to_i
|
31
|
+
end
|
32
|
+
[maj, min, pat]
|
33
|
+
end
|
34
|
+
|
35
|
+
def wild?(val)
|
36
|
+
val.is_a?(String)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def compare(other, comp)
|
41
|
+
case comp
|
42
|
+
when :older
|
43
|
+
if @maj <= other.maj
|
44
|
+
if @maj < other.maj
|
45
|
+
true
|
46
|
+
elsif @maj == other.maj && (other.min.nil? || @min < other.min)
|
47
|
+
true
|
48
|
+
elsif @maj == other.maj && @min == other.min
|
49
|
+
other.patch.nil? ? false : @patch < other.patch
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
56
|
+
when :newer
|
57
|
+
if @maj >= other.maj
|
58
|
+
if @maj > other.maj
|
59
|
+
true
|
60
|
+
elsif @maj == other.maj && (other.min.nil? || @min > other.min)
|
61
|
+
true
|
62
|
+
elsif @maj == other.maj && @min == other.min
|
63
|
+
other.patch.nil? || @patch >= other.patch
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
else
|
68
|
+
false
|
69
|
+
end
|
70
|
+
when :equal
|
71
|
+
if @maj == other.maj
|
72
|
+
if other.min.nil?
|
73
|
+
true
|
74
|
+
elsif wild?(other.min)
|
75
|
+
@min.to_s =~ /^#{other.min}/ ? true : false
|
76
|
+
else
|
77
|
+
if @min == other.min
|
78
|
+
if other.patch.nil?
|
79
|
+
true
|
80
|
+
elsif wild?(other.patch)
|
81
|
+
@patch.to_s =~ /^#{other.patch}/ ? true : false
|
82
|
+
else
|
83
|
+
@patch == other.patch
|
84
|
+
end
|
85
|
+
else
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
"#{@maj}.#{@min || 0}.#{@patch || 0}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -123,8 +123,9 @@ module Doing
|
|
123
123
|
complete -f -c doing -n '__fish_doing_using_command view' -a '(__fish_doing_complete_views)'
|
124
124
|
complete -f -c doing -n '__fish_doing_using_command template' -a '(__fish_doing_complete_templates)'
|
125
125
|
complete -f -c doing -s t -l type -x -n '__fish_doing_using_command import' -a '(__fish_doing_import_plugins)'
|
126
|
+
complete -f -c doing -n '__fish_doing_using_command help' -a '(__fish_doing_subcommands)'
|
126
127
|
|
127
|
-
complete -xc doing -n '__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from (doing help -c)' -a "(doing help -c)"
|
128
|
+
# complete -xc doing -n '__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from (doing help -c)' -a "(doing help -c)"
|
128
129
|
|
129
130
|
function __fish_doing_complete_args
|
130
131
|
for cmd in (doing commands_accepting -c $argv[1])
|
data/lib/doing/configuration.rb
CHANGED
@@ -29,6 +29,7 @@ module Doing
|
|
29
29
|
'plugin_path' => File.join(Util.user_home, '.config', 'doing', 'plugins'),
|
30
30
|
'command_path' => File.join(Util.user_home, '.config', 'doing', 'commands')
|
31
31
|
},
|
32
|
+
'disabled_commands' => [],
|
32
33
|
'doing_file' => '~/.local/share/doing/what_was_i_doing.md',
|
33
34
|
'doing_file_sort' => 'desc',
|
34
35
|
'backup_dir' => '~/.local/share/doing/doing_backup',
|
@@ -45,8 +46,7 @@ module Doing
|
|
45
46
|
'templates' => {
|
46
47
|
'default' => {
|
47
48
|
'date_format' => '%Y-%m-%d %H:%M',
|
48
|
-
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %
|
49
|
-
%yellow%interval%boldred%duration%dark%white%80_14┃ note',
|
49
|
+
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %boldmagenta[%boldwhite%-10section%boldmagenta]%reset %yellow%interval%boldred%duration%white%80_14┃ note',
|
50
50
|
'wrap_width' => 0,
|
51
51
|
'order' => 'asc'
|
52
52
|
},
|
@@ -63,8 +63,7 @@ module Doing
|
|
63
63
|
},
|
64
64
|
'recent' => {
|
65
65
|
'date_format' => '%_I:%M%P',
|
66
|
-
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %
|
67
|
-
%yellow%interval%boldred%duration%dark%white%80_14┃ note',
|
66
|
+
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %boldmagenta[%boldwhite%-10section%boldmagenta]%reset %yellow%interval%boldred%duration%white%80_14┃ note',
|
68
67
|
'wrap_width' => 88,
|
69
68
|
'count' => 10,
|
70
69
|
'order' => 'asc'
|
@@ -190,7 +189,7 @@ module Doing
|
|
190
189
|
## matched, first match wins)
|
191
190
|
## @return [Array] ordered array of resolved keys
|
192
191
|
##
|
193
|
-
def resolve_key_path(keypath, create: false)
|
192
|
+
def resolve_key_path(keypath, create: false, distance: 2)
|
194
193
|
cfg = @settings
|
195
194
|
real_path = []
|
196
195
|
unless keypath =~ /^[.*]?$/
|
@@ -198,16 +197,24 @@ module Doing
|
|
198
197
|
while paths.length.positive? && !cfg.nil?
|
199
198
|
path = paths.shift
|
200
199
|
new_cfg = nil
|
201
|
-
cfg.each do |key, val|
|
202
|
-
next unless key =~ path.to_rx(distance: 4)
|
203
200
|
|
204
|
-
|
205
|
-
|
206
|
-
|
201
|
+
if cfg.is_a?(Hash)
|
202
|
+
matches = cfg.select { |key, val| key =~ path.to_rx(distance: distance) }
|
203
|
+
if matches.count.positive?
|
204
|
+
shortest = matches.keys.group_by(&:length).min.last[0]
|
205
|
+
real_path << shortest
|
206
|
+
new_cfg = matches[shortest]
|
207
|
+
end
|
208
|
+
else
|
209
|
+
new_cfg = cfg
|
207
210
|
end
|
208
211
|
|
209
212
|
if new_cfg.nil?
|
210
|
-
|
213
|
+
if distance < 5 && !create
|
214
|
+
return resolve_key_path(keypath, create: false, distance: distance + 1)
|
215
|
+
else
|
216
|
+
return nil unless create
|
217
|
+
end
|
211
218
|
|
212
219
|
resolved = real_path.count.positive? ? "Resolved #{real_path.join('->')}, but " : ''
|
213
220
|
Doing.logger.log_now(:warn, "#{resolved}#{path} is unknown")
|
@@ -306,7 +313,7 @@ module Doing
|
|
306
313
|
|
307
314
|
@ignore_local = opt[:ignore_local] if opt[:ignore_local]
|
308
315
|
|
309
|
-
config = read_config.
|
316
|
+
config = read_config.clone
|
310
317
|
|
311
318
|
plugin_config = Util.deep_merge_hashes(DEFAULTS['plugins'], config['plugins'] || {})
|
312
319
|
|
@@ -314,7 +321,7 @@ module Doing
|
|
314
321
|
|
315
322
|
Plugins.plugins.each do |_type, plugins|
|
316
323
|
plugins.each do |title, plugin|
|
317
|
-
plugin_config[title] = plugin[:config] if plugin[:config]
|
324
|
+
plugin_config[title] = plugin[:config] if plugin[:config].good?
|
318
325
|
config['export_templates'][title] ||= nil if plugin[:templates] && !plugin[:templates].empty?
|
319
326
|
end
|
320
327
|
end
|
data/lib/doing/good.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doing
|
4
|
+
# Object helpers
|
5
|
+
class ::Object
|
6
|
+
##
|
7
|
+
## Tests if object is nil or empty
|
8
|
+
##
|
9
|
+
## @return [Boolean] true if object is defined and
|
10
|
+
## has content
|
11
|
+
##
|
12
|
+
def good?
|
13
|
+
!nil? && !empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class ::String
|
18
|
+
##
|
19
|
+
## Tests if object is nil or empty
|
20
|
+
##
|
21
|
+
## @return [Boolean] true if object is defined and
|
22
|
+
## has content
|
23
|
+
##
|
24
|
+
def good?
|
25
|
+
!strip.empty?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ::Array
|
30
|
+
##
|
31
|
+
## Tests if object is nil or empty
|
32
|
+
##
|
33
|
+
## @return [Boolean] true if object is defined and
|
34
|
+
## has content
|
35
|
+
##
|
36
|
+
def good?
|
37
|
+
!nil? && !empty?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ::FalseClass
|
42
|
+
##
|
43
|
+
## Tests if object is nil or empty
|
44
|
+
##
|
45
|
+
## @return [Boolean] true if object is defined and
|
46
|
+
## has content
|
47
|
+
##
|
48
|
+
def good?
|
49
|
+
false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ::TrueClass
|
54
|
+
##
|
55
|
+
## Tests if object is nil or empty
|
56
|
+
##
|
57
|
+
## @return [Boolean] true if object is defined and
|
58
|
+
## has content
|
59
|
+
##
|
60
|
+
def good?
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/doing/hash.rb
CHANGED
@@ -34,6 +34,10 @@ module Doing
|
|
34
34
|
replace deep_thaw
|
35
35
|
end
|
36
36
|
|
37
|
+
def clone
|
38
|
+
Marshal.load(Marshal.dump(self))
|
39
|
+
end
|
40
|
+
|
37
41
|
# Turn all keys into string
|
38
42
|
#
|
39
43
|
# Return a copy of the hash where all its keys are strings
|
@@ -48,8 +52,9 @@ module Doing
|
|
48
52
|
|
49
53
|
# Set a nested hash value using an array
|
50
54
|
#
|
51
|
-
# @example
|
52
|
-
#
|
55
|
+
# @example
|
56
|
+
# {}.deep_set(['one', 'two'], 'value')
|
57
|
+
# # => { 'one' => { 'two' => 'value' } }
|
53
58
|
#
|
54
59
|
# @param path [Array] key path
|
55
60
|
# @param value The value
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GLI
|
4
|
+
module Commands
|
5
|
+
# Help Command Monkeypatch for paginated output
|
6
|
+
class Help < Command
|
7
|
+
def show_help(global_options,options,arguments,out,error)
|
8
|
+
Doing::Pager.paginate = true
|
9
|
+
|
10
|
+
command_finder = HelpModules::CommandFinder.new(@app,arguments,error)
|
11
|
+
if options[:c]
|
12
|
+
help_output = HelpModules::HelpCompletionFormat.new(@app,command_finder,arguments).format
|
13
|
+
out.puts help_output unless help_output.nil?
|
14
|
+
elsif arguments.empty? || options[:c]
|
15
|
+
Doing::Pager.page HelpModules::GlobalHelpFormat.new(@app,@sorter,@text_wrapping_class).format
|
16
|
+
else
|
17
|
+
name = arguments.shift
|
18
|
+
command = command_finder.find_command(name)
|
19
|
+
unless command.nil?
|
20
|
+
Doing::Pager.page HelpModules::CommandHelpFormat.new(
|
21
|
+
command,
|
22
|
+
@app,
|
23
|
+
@sorter,
|
24
|
+
@synopsis_formatter_class,
|
25
|
+
@text_wrapping_class).format
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/doing/hooks.rb
CHANGED
@@ -10,8 +10,8 @@ module Doing
|
|
10
10
|
post_local_config: [], # wwid
|
11
11
|
post_read: [], # wwid
|
12
12
|
pre_entry_add: [], # wwid, new_entry
|
13
|
-
post_entry_added: [], # wwid, new_entry
|
14
|
-
post_entry_updated: [], # wwid, entry
|
13
|
+
post_entry_added: [], # wwid, new_entry
|
14
|
+
post_entry_updated: [], # wwid, entry, old_entry
|
15
15
|
post_entry_removed: [], # wwid, entry.dup
|
16
16
|
pre_export: [], # wwid, format, entries
|
17
17
|
pre_write: [], # wwid, file
|
@@ -23,7 +23,11 @@ module Doing
|
|
23
23
|
|
24
24
|
# register hook(s) to be called later, public API
|
25
25
|
def self.register(event, priority: DEFAULT_PRIORITY, &block)
|
26
|
-
|
26
|
+
if event.is_a?(Array)
|
27
|
+
event.each { |ev| register_one(ev, priority_value(priority), &block) }
|
28
|
+
else
|
29
|
+
register_one(event, priority_value(priority), &block)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
# Ensure the priority is a Fixnum
|
@@ -53,7 +57,7 @@ module Doing
|
|
53
57
|
|
54
58
|
def self.trigger(event, *args)
|
55
59
|
hooks = @registry[event]
|
56
|
-
return
|
60
|
+
return unless hooks.good?
|
57
61
|
|
58
62
|
# sort and call hooks according to priority and load order
|
59
63
|
hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
|