doing 2.0.5.pre → 2.0.6.pre
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/CHANGELOG.md +20 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/bin/doing +133 -98
- data/doing.rdoc +88 -8
- data/generate_completions.sh +1 -0
- data/lib/completion/_doing.zsh +179 -127
- data/lib/completion/doing.bash +60 -27
- data/lib/completion/doing.fish +74 -23
- data/lib/doing/cli_status.rb +4 -0
- data/lib/doing/errors.rb +22 -15
- data/lib/doing/log_adapter.rb +27 -25
- data/lib/doing/plugin_manager.rb +1 -1
- data/lib/doing/string.rb +7 -6
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +83 -76
- data/lib/examples/commands/autotag.rb +63 -0
- data/scripts/generate_bash_completions.rb +3 -2
- data/scripts/generate_fish_completions.rb +4 -1
- data/scripts/generate_zsh_completions.rb +42 -38
- metadata +2 -2
- data/doing.fish +0 -278
data/bin/doing
CHANGED
@@ -57,8 +57,8 @@ config = Doing.config
|
|
57
57
|
settings = config.settings
|
58
58
|
wwid.config = settings
|
59
59
|
|
60
|
-
if
|
61
|
-
commands_from File.expand_path(
|
60
|
+
if settings.dig('plugins', 'command_path')
|
61
|
+
commands_from File.expand_path(settings.dig('plugins', 'command_path'))
|
62
62
|
end
|
63
63
|
|
64
64
|
program_desc 'A CLI for a What Was I Doing system'
|
@@ -137,7 +137,7 @@ command %i[now next] do |c|
|
|
137
137
|
if options[:back]
|
138
138
|
date = wwid.chronify(options[:back], guess: :begin)
|
139
139
|
|
140
|
-
raise
|
140
|
+
raise InvalidTimeExpression.new('unable to parse date string', topic: 'Date parser:') if date.nil?
|
141
141
|
else
|
142
142
|
date = Time.now
|
143
143
|
end
|
@@ -149,13 +149,13 @@ command %i[now next] do |c|
|
|
149
149
|
end
|
150
150
|
|
151
151
|
if options[:e] || (args.empty? && $stdin.stat.size.zero?)
|
152
|
-
raise
|
152
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
153
153
|
|
154
154
|
input = ''
|
155
155
|
input += args.join(' ') unless args.empty?
|
156
156
|
input = wwid.fork_editor(input).strip
|
157
157
|
|
158
|
-
raise
|
158
|
+
raise EmptyInput, 'No content' if input.empty?
|
159
159
|
|
160
160
|
title, note = wwid.format_input(input)
|
161
161
|
note.push(options[:n]) if options[:n]
|
@@ -173,7 +173,7 @@ command %i[now next] do |c|
|
|
173
173
|
wwid.add_item(title.cap_first, section, { note: note, back: date, timed: options[:f] })
|
174
174
|
wwid.write(wwid.doing_file)
|
175
175
|
else
|
176
|
-
raise
|
176
|
+
raise EmptyInput, 'You must provide content when creating a new entry'
|
177
177
|
end
|
178
178
|
end
|
179
179
|
end
|
@@ -291,7 +291,7 @@ command :note do |c|
|
|
291
291
|
new_note = Doing::Note.new
|
292
292
|
|
293
293
|
if options[:e] || (args.empty? && $stdin.stat.size.zero? && !options[:r])
|
294
|
-
raise
|
294
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
295
295
|
|
296
296
|
input = !args.empty? ? args.join(' ') : ''
|
297
297
|
|
@@ -312,7 +312,7 @@ command :note do |c|
|
|
312
312
|
elsif $stdin.stat.size.positive?
|
313
313
|
new_note.add($stdin.read)
|
314
314
|
else
|
315
|
-
raise
|
315
|
+
raise EmptyInput, 'You must provide content when adding a note' unless options[:remove]
|
316
316
|
end
|
317
317
|
|
318
318
|
if last_note.equal?(new_note)
|
@@ -338,7 +338,7 @@ command :meanwhile do |c|
|
|
338
338
|
c.switch %i[e editor], negatable: false, default_value: false
|
339
339
|
|
340
340
|
c.desc 'Archive previous @meanwhile entry'
|
341
|
-
c.switch %i[a archive], default_value: false
|
341
|
+
c.switch %i[a archive], negatable: false, default_value: false
|
342
342
|
|
343
343
|
c.desc 'Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]'
|
344
344
|
c.arg_name 'DATE_STRING'
|
@@ -352,7 +352,7 @@ command :meanwhile do |c|
|
|
352
352
|
if options[:back]
|
353
353
|
date = wwid.chronify(options[:back], guess: :begin)
|
354
354
|
|
355
|
-
raise
|
355
|
+
raise InvalidTimeExpression, 'Unable to parse date string' if date.nil?
|
356
356
|
else
|
357
357
|
date = Time.now
|
358
358
|
end
|
@@ -365,7 +365,7 @@ command :meanwhile do |c|
|
|
365
365
|
input = ''
|
366
366
|
|
367
367
|
if options[:e]
|
368
|
-
raise
|
368
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
369
369
|
|
370
370
|
input += args.join(' ') unless args.empty?
|
371
371
|
input = wwid.fork_editor(input).strip
|
@@ -403,7 +403,7 @@ long_desc %(
|
|
403
403
|
arg_name 'TYPE', must_match: Doing::Plugins.template_regex
|
404
404
|
command :template do |c|
|
405
405
|
c.desc 'List all available templates'
|
406
|
-
c.switch %i[l list]
|
406
|
+
c.switch %i[l list], negatable: false
|
407
407
|
|
408
408
|
c.desc 'List in single column for completion'
|
409
409
|
c.switch %i[c]
|
@@ -424,7 +424,7 @@ command :template do |c|
|
|
424
424
|
type = args[0]
|
425
425
|
end
|
426
426
|
|
427
|
-
raise
|
427
|
+
raise InvalidPluginType, "No type specified, use `doing template [#{Doing::Plugins.plugin_templates.join('|')}]`" unless type
|
428
428
|
|
429
429
|
$stdout.puts Doing::Plugins.template_for_trigger(type)
|
430
430
|
|
@@ -503,12 +503,12 @@ command :select do |c|
|
|
503
503
|
c.flag %i[o output]
|
504
504
|
|
505
505
|
c.desc "Copy selection as a new entry with current time and no @done tag. Only works with single selections. Can be combined with --editor."
|
506
|
-
c.switch %i[again resume]
|
506
|
+
c.switch %i[again resume], negatable: false, default_value: false
|
507
507
|
|
508
508
|
c.action do |_global_options, options, args|
|
509
|
-
raise
|
509
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
510
510
|
|
511
|
-
raise
|
511
|
+
raise InvalidArgument, '--no-menu requires --query' if !options[:menu] && !options[:query]
|
512
512
|
|
513
513
|
wwid.interactive(options)
|
514
514
|
end
|
@@ -531,17 +531,17 @@ command :later do |c|
|
|
531
531
|
c.action do |_global_options, options, args|
|
532
532
|
if options[:back]
|
533
533
|
date = wwid.chronify(options[:back], guess: :begin)
|
534
|
-
raise
|
534
|
+
raise InvalidTimeExpression, 'Unable to parse date string' if date.nil?
|
535
535
|
else
|
536
536
|
date = Time.now
|
537
537
|
end
|
538
538
|
|
539
539
|
if options[:editor] || (args.empty? && $stdin.stat.size.zero?)
|
540
|
-
raise
|
540
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
541
541
|
|
542
542
|
input = args.empty? ? '' : args.join(' ')
|
543
543
|
input = wwid.fork_editor(input).strip
|
544
|
-
raise
|
544
|
+
raise EmptyInput, 'No content' unless input && !input.empty?
|
545
545
|
|
546
546
|
title, note = wwid.format_input(input)
|
547
547
|
note.push(options[:n]) if options[:n]
|
@@ -558,7 +558,7 @@ command :later do |c|
|
|
558
558
|
wwid.add_item(title.cap_first, 'Later', { note: note, back: date })
|
559
559
|
wwid.write(wwid.doing_file)
|
560
560
|
else
|
561
|
-
raise
|
561
|
+
raise EmptyInput, 'You must provide content when creating a new entry'
|
562
562
|
end
|
563
563
|
end
|
564
564
|
end
|
@@ -614,19 +614,19 @@ command %i[done did] do |c|
|
|
614
614
|
|
615
615
|
if options[:took]
|
616
616
|
took = wwid.chronify_qty(options[:took])
|
617
|
-
raise
|
617
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --took' if took.nil?
|
618
618
|
end
|
619
619
|
|
620
620
|
if options[:back]
|
621
621
|
date = wwid.chronify(options[:back], guess: :begin)
|
622
|
-
raise
|
622
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --back' if date.nil?
|
623
623
|
else
|
624
624
|
date = options[:took] ? Time.now - took : Time.now
|
625
625
|
end
|
626
626
|
|
627
627
|
if options[:at]
|
628
628
|
finish_date = wwid.chronify(options[:at], guess: :begin)
|
629
|
-
raise
|
629
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --at' if finish_date.nil?
|
630
630
|
|
631
631
|
date = options[:took] ? finish_date - took : finish_date
|
632
632
|
elsif options[:took]
|
@@ -651,7 +651,7 @@ command %i[done did] do |c|
|
|
651
651
|
note.add(options[:note]) if options[:note]
|
652
652
|
|
653
653
|
if options[:editor]
|
654
|
-
raise
|
654
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
655
655
|
is_new = false
|
656
656
|
|
657
657
|
if args.empty?
|
@@ -659,7 +659,7 @@ command %i[done did] do |c|
|
|
659
659
|
|
660
660
|
unless last_entry
|
661
661
|
Doing.logger.debug('Skipped:', options[:unfinished] ? 'No unfinished entry' : 'Last entry already @done')
|
662
|
-
raise
|
662
|
+
raise NoResults, 'No results'
|
663
663
|
end
|
664
664
|
|
665
665
|
old_entry = last_entry.dup
|
@@ -671,7 +671,7 @@ command %i[done did] do |c|
|
|
671
671
|
end
|
672
672
|
|
673
673
|
input = wwid.fork_editor(input).strip
|
674
|
-
raise
|
674
|
+
raise EmptyInput, 'No content' unless input && !input.empty?
|
675
675
|
|
676
676
|
title, note = wwid.format_input(input)
|
677
677
|
new_entry = Doing::Item.new(date, title, section, note)
|
@@ -746,7 +746,7 @@ command %i[done did] do |c|
|
|
746
746
|
wwid.write(wwid.doing_file)
|
747
747
|
Doing.logger.info('Entry Added:', new_entry.title)
|
748
748
|
else
|
749
|
-
raise
|
749
|
+
raise EmptyInput, 'You must provide content when creating a new entry'
|
750
750
|
end
|
751
751
|
end
|
752
752
|
end
|
@@ -789,9 +789,9 @@ command :cancel do |c|
|
|
789
789
|
tags = options[:tag].to_tags
|
790
790
|
end
|
791
791
|
|
792
|
-
raise
|
792
|
+
raise InvalidArgument, 'Only one argument allowed' if args.length > 1
|
793
793
|
|
794
|
-
raise
|
794
|
+
raise InvalidArgument, 'Invalid argument (specify number of recent items to mark @done)' unless args.empty? || args[0] =~ /\d+/
|
795
795
|
|
796
796
|
if options[:interactive]
|
797
797
|
count = 0
|
@@ -873,22 +873,22 @@ command :finish do |c|
|
|
873
873
|
unless options[:auto]
|
874
874
|
if options[:took]
|
875
875
|
took = wwid.chronify_qty(options[:took])
|
876
|
-
raise
|
876
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --took' if took.nil?
|
877
877
|
end
|
878
878
|
|
879
|
-
raise
|
879
|
+
raise InvalidArgument, '--back and --took can not be used together' if options[:back] && options[:took]
|
880
880
|
|
881
|
-
raise
|
881
|
+
raise InvalidArgument, '--search and --tag can not be used together' if options[:search] && options[:tag]
|
882
882
|
|
883
883
|
if options[:at]
|
884
884
|
finish_date = wwid.chronify(options[:at], guess: :begin)
|
885
|
-
raise
|
885
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --at' if finish_date.nil?
|
886
886
|
|
887
887
|
date = options[:took] ? finish_date - took : finish_date
|
888
888
|
elsif options[:back]
|
889
889
|
date = wwid.chronify(options[:back])
|
890
890
|
|
891
|
-
raise
|
891
|
+
raise InvalidTimeExpression, 'Unable to parse date string' if date.nil?
|
892
892
|
elsif options[:took]
|
893
893
|
date = wwid.chronify_qty(options[:took])
|
894
894
|
else
|
@@ -902,9 +902,9 @@ command :finish do |c|
|
|
902
902
|
tags = options[:tag].to_tags
|
903
903
|
end
|
904
904
|
|
905
|
-
raise
|
905
|
+
raise InvalidArgument, 'Only one argument allowed' if args.length > 1
|
906
906
|
|
907
|
-
raise
|
907
|
+
raise InvalidArgument, 'Invalid argument (specify number of recent items to mark @done)' unless args.length == 0 || args[0] =~ /\d+/
|
908
908
|
|
909
909
|
if options[:interactive]
|
910
910
|
count = 0
|
@@ -1045,9 +1045,9 @@ command :tag do |c|
|
|
1045
1045
|
c.switch %i[i interactive], negatable: false, default_value: false
|
1046
1046
|
|
1047
1047
|
c.action do |_global_options, options, args|
|
1048
|
-
raise
|
1048
|
+
raise MissingArgument, 'You must specify at least one tag' if args.empty? && !options[:autotag]
|
1049
1049
|
|
1050
|
-
raise
|
1050
|
+
raise InvalidArgument, '--search and --tag can not be used together' if options[:search] && options[:tag]
|
1051
1051
|
|
1052
1052
|
section = 'All'
|
1053
1053
|
|
@@ -1117,19 +1117,6 @@ command :tag do |c|
|
|
1117
1117
|
end
|
1118
1118
|
end
|
1119
1119
|
|
1120
|
-
# desc 'Autotag last X entries'
|
1121
|
-
# arg_name 'COUNT'
|
1122
|
-
# command :autotag do |c|
|
1123
|
-
# c.action do |global_options, options, args|
|
1124
|
-
# options = {
|
1125
|
-
# autotag: true,
|
1126
|
-
# count: args[0].to_i
|
1127
|
-
# }
|
1128
|
-
# cmd = commands[:tag]
|
1129
|
-
# cmd.action.(global_options, options, [])
|
1130
|
-
# end
|
1131
|
-
# end
|
1132
|
-
|
1133
1120
|
desc 'Mark last entry as flagged'
|
1134
1121
|
command [:mark, :flag] do |c|
|
1135
1122
|
c.example 'doing flag', desc: 'Add @flagged to the last entry created'
|
@@ -1175,7 +1162,7 @@ command [:mark, :flag] do |c|
|
|
1175
1162
|
c.action do |_global_options, options, _args|
|
1176
1163
|
mark = settings['marker_tag'] || 'flagged'
|
1177
1164
|
|
1178
|
-
raise
|
1165
|
+
raise InvalidArgument, '--search and --tag can not be used together' if options[:search] && options[:tag]
|
1179
1166
|
|
1180
1167
|
section = 'All'
|
1181
1168
|
|
@@ -1307,8 +1294,8 @@ command :show do |c|
|
|
1307
1294
|
c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
|
1308
1295
|
c.arg_name 'FORMAT'
|
1309
1296
|
c.flag %i[o output]
|
1310
|
-
c.action do |
|
1311
|
-
raise
|
1297
|
+
c.action do |global_options, options, args|
|
1298
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1312
1299
|
|
1313
1300
|
tag_filter = false
|
1314
1301
|
tags = []
|
@@ -1323,8 +1310,15 @@ command :show do |c|
|
|
1323
1310
|
when /^@/
|
1324
1311
|
section = 'All'
|
1325
1312
|
else
|
1326
|
-
|
1327
|
-
|
1313
|
+
begin
|
1314
|
+
section = wwid.guess_section(args[0])
|
1315
|
+
rescue WrongCommand => exception
|
1316
|
+
cmd = commands[:view]
|
1317
|
+
action = cmd.send(:get_action, nil)
|
1318
|
+
return action.call(global_options, options, args)
|
1319
|
+
end
|
1320
|
+
|
1321
|
+
raise InvalidSection, "No such section: #{args[0]}" unless section
|
1328
1322
|
|
1329
1323
|
args.shift
|
1330
1324
|
end
|
@@ -1359,7 +1353,7 @@ command :show do |c|
|
|
1359
1353
|
start = wwid.chronify(date_string, guess: :begin)
|
1360
1354
|
finish = false
|
1361
1355
|
end
|
1362
|
-
raise
|
1356
|
+
raise InvalidTimeExpression, 'Unrecognized date string' unless start
|
1363
1357
|
dates = [start, finish]
|
1364
1358
|
end
|
1365
1359
|
|
@@ -1433,7 +1427,7 @@ command %i[grep search] do |c|
|
|
1433
1427
|
c.switch %i[i interactive], default_value: false, negatable: false
|
1434
1428
|
|
1435
1429
|
c.action do |_global_options, options, args|
|
1436
|
-
raise
|
1430
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1437
1431
|
|
1438
1432
|
tags_color = settings.key?('tags_color') ? settings['tags_color'] : nil
|
1439
1433
|
|
@@ -1548,7 +1542,7 @@ command :today do |c|
|
|
1548
1542
|
c.flag [:after]
|
1549
1543
|
|
1550
1544
|
c.action do |_global_options, options, _args|
|
1551
|
-
raise
|
1545
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1552
1546
|
|
1553
1547
|
options[:t] = true if options[:totals]
|
1554
1548
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
@@ -1595,9 +1589,9 @@ command :on do |c|
|
|
1595
1589
|
c.flag %i[o output]
|
1596
1590
|
|
1597
1591
|
c.action do |_global_options, options, args|
|
1598
|
-
raise
|
1592
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1599
1593
|
|
1600
|
-
raise
|
1594
|
+
raise MissingArgument, 'Missing date argument' if args.empty?
|
1601
1595
|
|
1602
1596
|
date_string = args.join(' ')
|
1603
1597
|
|
@@ -1610,7 +1604,7 @@ command :on do |c|
|
|
1610
1604
|
finish = false
|
1611
1605
|
end
|
1612
1606
|
|
1613
|
-
raise
|
1607
|
+
raise InvalidTimeExpression, 'Unrecognized date string' unless start
|
1614
1608
|
|
1615
1609
|
message = "Date interpreted as #{start}"
|
1616
1610
|
message += " to #{finish}" if finish
|
@@ -1653,9 +1647,9 @@ command :since do |c|
|
|
1653
1647
|
c.flag %i[o output]
|
1654
1648
|
|
1655
1649
|
c.action do |_global_options, options, args|
|
1656
|
-
raise
|
1650
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1657
1651
|
|
1658
|
-
raise
|
1652
|
+
raise MissingArgument, 'Missing date argument' if args.empty?
|
1659
1653
|
|
1660
1654
|
date_string = args.join(' ')
|
1661
1655
|
|
@@ -1665,7 +1659,7 @@ command :since do |c|
|
|
1665
1659
|
start = wwid.chronify(date_string, guess: :begin)
|
1666
1660
|
finish = Time.now
|
1667
1661
|
|
1668
|
-
raise
|
1662
|
+
raise InvalidTimeExpression, 'Unrecognized date string' unless start
|
1669
1663
|
|
1670
1664
|
Doing.logger.debug("Date interpreted as #{start} through the current time")
|
1671
1665
|
|
@@ -1698,7 +1692,6 @@ command :yesterday do |c|
|
|
1698
1692
|
c.switch [:totals], default_value: false, negatable: false
|
1699
1693
|
|
1700
1694
|
c.desc 'Sort tags by (name|time)'
|
1701
|
-
default = 'time'
|
1702
1695
|
default = settings['tag_sort'] || 'name'
|
1703
1696
|
c.arg_name 'KEY'
|
1704
1697
|
c.flag [:tag_sort], must_match: /^(?:name|time)$/i, default_value: default
|
@@ -1716,7 +1709,7 @@ command :yesterday do |c|
|
|
1716
1709
|
c.flag [:tag_order], must_match: REGEX_SORT_ORDER, default_value: 'asc'
|
1717
1710
|
|
1718
1711
|
c.action do |_global_options, options, _args|
|
1719
|
-
raise
|
1712
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1720
1713
|
|
1721
1714
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
1722
1715
|
|
@@ -1762,7 +1755,7 @@ command :last do |c|
|
|
1762
1755
|
c.flag [:search]
|
1763
1756
|
|
1764
1757
|
c.action do |global_options, options, _args|
|
1765
|
-
raise
|
1758
|
+
raise InvalidArgument, '--tag and --search can not be used together' if options[:tag] && options[:search]
|
1766
1759
|
|
1767
1760
|
if options[:tag].nil?
|
1768
1761
|
tags = []
|
@@ -1791,7 +1784,7 @@ end
|
|
1791
1784
|
desc 'List sections'
|
1792
1785
|
command :sections do |c|
|
1793
1786
|
c.desc 'List in single column'
|
1794
|
-
c.switch %i[c column], default_value: false
|
1787
|
+
c.switch %i[c column], negatable: false, default_value: false
|
1795
1788
|
|
1796
1789
|
c.action do |_global_options, options, _args|
|
1797
1790
|
joiner = options[:c] ? "\n" : "\t"
|
@@ -1814,7 +1807,7 @@ command :add_section do |c|
|
|
1814
1807
|
c.example 'doing add_section Ideas', desc: 'Add a section called Ideas to the doing file'
|
1815
1808
|
|
1816
1809
|
c.action do |_global_options, _options, args|
|
1817
|
-
raise
|
1810
|
+
raise InvalidArgument, "Section #{args[0]} already exists" if wwid.sections.include?(args[0])
|
1818
1811
|
|
1819
1812
|
wwid.add_section(args.join(' ').cap_first)
|
1820
1813
|
wwid.write(wwid.doing_file)
|
@@ -1853,16 +1846,54 @@ command :plugins do |c|
|
|
1853
1846
|
|
1854
1847
|
c.desc 'List plugins of type (import, export)'
|
1855
1848
|
c.arg_name 'TYPE'
|
1856
|
-
c.flag %i[t type], must_match: /^[iea]
|
1849
|
+
c.flag %i[t type], must_match: /^(?:[iea].*)$/i, default_value: 'all'
|
1857
1850
|
|
1858
1851
|
c.desc 'List in single column for completion'
|
1859
|
-
c.switch %i[c column], default_value: false
|
1852
|
+
c.switch %i[c column], negatable: false, default_value: false
|
1860
1853
|
|
1861
1854
|
c.action do |_global_options, options, _args|
|
1862
1855
|
Doing::Plugins.list_plugins(options)
|
1863
1856
|
end
|
1864
1857
|
end
|
1865
1858
|
|
1859
|
+
desc 'Generate shell completion scripts'
|
1860
|
+
command :completion do |c|
|
1861
|
+
c.example 'doing completion', desc: 'Output zsh (default) to STDOUT'
|
1862
|
+
c.example 'doing completion --type zsh --file ~/.zsh-completions/_doing.zsh', desc: 'Output zsh completions to file'
|
1863
|
+
c.example 'doing completion --type fish --file ~/.config/fish/completions/doing.fish', desc: 'Output fish completions to file'
|
1864
|
+
c.example 'doing completion --type bash --file ~/.bash_it/completion/enabled/doing.bash', desc: 'Output bash completions to file'
|
1865
|
+
|
1866
|
+
c.desc 'Shell to generate for (bash, zsh, fish)'
|
1867
|
+
c.arg_name 'SHELL'
|
1868
|
+
c.flag %i[t type], must_match: /^[bzf](?:[ai]?sh)?$/i, default_value: 'zsh'
|
1869
|
+
|
1870
|
+
c.desc 'File to write output to'
|
1871
|
+
c.arg_name 'PATH'
|
1872
|
+
c.flag %i[f file], default_value: 'stdout'
|
1873
|
+
|
1874
|
+
c.action do |_global_options, options, _args|
|
1875
|
+
script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
|
1876
|
+
|
1877
|
+
case options[:type]
|
1878
|
+
when /^b/
|
1879
|
+
result = `ruby #{File.join(script_dir, 'generate_bash_completions.rb')}`
|
1880
|
+
when /^z/
|
1881
|
+
result = `ruby #{File.join(script_dir, 'generate_zsh_completions.rb')}`
|
1882
|
+
when /^f/
|
1883
|
+
result = `ruby #{File.join(script_dir, 'generate_fish_completions.rb')}`
|
1884
|
+
end
|
1885
|
+
|
1886
|
+
if options[:file] =~ /^stdout$/i
|
1887
|
+
$stdout.puts result
|
1888
|
+
else
|
1889
|
+
File.open(File.expand_path(options[:file]), 'w') do |f|
|
1890
|
+
f.puts result
|
1891
|
+
end
|
1892
|
+
Doing.logger.warn('File written:', "#{options[:type]} completions written to #{options[:file]}")
|
1893
|
+
end
|
1894
|
+
end
|
1895
|
+
end
|
1896
|
+
|
1866
1897
|
desc 'Display a user-created view'
|
1867
1898
|
long_desc 'Command line options override view configuration'
|
1868
1899
|
arg_name 'VIEW_NAME'
|
@@ -1925,15 +1956,22 @@ command :view do |c|
|
|
1925
1956
|
c.desc 'Select from a menu of matching entries to perform additional operations'
|
1926
1957
|
c.switch %i[i interactive], negatable: false, default_value: false
|
1927
1958
|
|
1928
|
-
c.action do |
|
1929
|
-
raise
|
1959
|
+
c.action do |global_options, options, args|
|
1960
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1930
1961
|
|
1931
|
-
raise
|
1962
|
+
raise InvalidArgument, '--tag and --search can not be used together' if options[:tag] && options[:search]
|
1932
1963
|
|
1933
1964
|
title = if args.empty?
|
1934
1965
|
wwid.choose_view
|
1935
1966
|
else
|
1936
|
-
|
1967
|
+
begin
|
1968
|
+
wwid.guess_view(args[0])
|
1969
|
+
rescue WrongCommand => exception
|
1970
|
+
cmd = commands[:show]
|
1971
|
+
options[:sort] = 'asc'
|
1972
|
+
action = cmd.send(:get_action, nil)
|
1973
|
+
return action.call(global_options, options, args)
|
1974
|
+
end
|
1937
1975
|
end
|
1938
1976
|
|
1939
1977
|
if options[:section]
|
@@ -2023,7 +2061,7 @@ command :view do |c|
|
|
2023
2061
|
start = wwid.chronify(date_string, guess: :begin)
|
2024
2062
|
finish = false
|
2025
2063
|
end
|
2026
|
-
raise
|
2064
|
+
raise InvalidTimeExpression, 'Unrecognized date string' unless start
|
2027
2065
|
dates = [start, finish]
|
2028
2066
|
end
|
2029
2067
|
|
@@ -2046,9 +2084,9 @@ command :view do |c|
|
|
2046
2084
|
|
2047
2085
|
Doing::Pager.page wwid.list_section(opts)
|
2048
2086
|
elsif title.instance_of?(FalseClass)
|
2049
|
-
|
2087
|
+
raise UserCancelled, 'Cancelled' unless res
|
2050
2088
|
else
|
2051
|
-
raise
|
2089
|
+
raise InvalidView, "View #{title} not found in config"
|
2052
2090
|
end
|
2053
2091
|
end
|
2054
2092
|
end
|
@@ -2119,7 +2157,7 @@ command %i[archive move] do |c|
|
|
2119
2157
|
tags = args.length > 1 ? args[1..].map { |t| t.sub(/^@/, '').strip } : []
|
2120
2158
|
end
|
2121
2159
|
|
2122
|
-
raise
|
2160
|
+
raise InvalidArgument, '--keep and --count can not be used together' if options[:keep] && options[:count]
|
2123
2161
|
|
2124
2162
|
tags.concat(options[:tag].to_tags) if options[:tag]
|
2125
2163
|
|
@@ -2208,7 +2246,7 @@ command :open do |c|
|
|
2208
2246
|
system %(open "#{File.expand_path(wwid.doing_file)}")
|
2209
2247
|
end
|
2210
2248
|
else
|
2211
|
-
raise
|
2249
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
2212
2250
|
|
2213
2251
|
system %(#{Doing::Util.default_editor} "#{File.expand_path(wwid.doing_file)}")
|
2214
2252
|
end
|
@@ -2236,7 +2274,7 @@ command :config do |c|
|
|
2236
2274
|
c.flag %i[e editor], default_value: nil
|
2237
2275
|
|
2238
2276
|
c.desc 'Show a config key value based on arguments. Separate key paths with colons or dots, e.g. "export_templates.html". Empty arguments outputs the entire config.'
|
2239
|
-
c.switch %i[d dump]
|
2277
|
+
c.switch %i[d dump], negatable: false
|
2240
2278
|
|
2241
2279
|
c.desc 'Format for --dump (json|yaml|raw)'
|
2242
2280
|
c.arg_name 'FORMAT'
|
@@ -2261,7 +2299,6 @@ command :config do |c|
|
|
2261
2299
|
c.action do |_global_options, options, args|
|
2262
2300
|
if options[:update]
|
2263
2301
|
config.configure({rewrite: true, ignore_local: true})
|
2264
|
-
# Doing.logger.warn("Config file rewritten: #{config.config_file}")
|
2265
2302
|
return
|
2266
2303
|
end
|
2267
2304
|
|
@@ -2276,7 +2313,6 @@ command :config do |c|
|
|
2276
2313
|
when /^r/
|
2277
2314
|
cfg
|
2278
2315
|
else
|
2279
|
-
# cfg = { last_key => cfg } unless last_key.nil?
|
2280
2316
|
YAML.dump(cfg)
|
2281
2317
|
end
|
2282
2318
|
else
|
@@ -2291,7 +2327,7 @@ command :config do |c|
|
|
2291
2327
|
choices.concat(config.additional_configs)
|
2292
2328
|
res = wwid.choose_from(choices.uniq.sort.reverse, sorted: false, prompt: 'Local configs found, select which to edit > ')
|
2293
2329
|
|
2294
|
-
raise
|
2330
|
+
raise UserCancelled, 'Cancelled' unless res
|
2295
2331
|
|
2296
2332
|
config_file = res.strip || config.config_file
|
2297
2333
|
else
|
@@ -2308,7 +2344,7 @@ command :config do |c|
|
|
2308
2344
|
`open -a "#{editor}" "#{config_file}"`
|
2309
2345
|
end
|
2310
2346
|
else
|
2311
|
-
raise
|
2347
|
+
raise InvalidArgument, 'No viable editor found in config or environment.'
|
2312
2348
|
end
|
2313
2349
|
elsif options[:a] || options[:b]
|
2314
2350
|
if options[:a]
|
@@ -2319,7 +2355,7 @@ command :config do |c|
|
|
2319
2355
|
else
|
2320
2356
|
editor = options[:e] || Doing::Util.find_default_editor('config')
|
2321
2357
|
|
2322
|
-
raise
|
2358
|
+
raise MissingEditor, 'No viable editor defined in config or environment' unless editor
|
2323
2359
|
|
2324
2360
|
if Doing::Util.exec_available(editor)
|
2325
2361
|
system %(#{editor} "#{config_file}")
|
@@ -2329,7 +2365,7 @@ command :config do |c|
|
|
2329
2365
|
end
|
2330
2366
|
else
|
2331
2367
|
editor = options[:e] || Doing::Util.default_editor
|
2332
|
-
raise
|
2368
|
+
raise MissingEditor, 'No EDITOR variable defined in environment' unless editor && Doing::Util.exec_available(editor)
|
2333
2369
|
|
2334
2370
|
system %(#{editor} "#{config_file}")
|
2335
2371
|
end
|
@@ -2413,7 +2449,7 @@ command :import do |c|
|
|
2413
2449
|
start = wwid.chronify(date_string, guess: :begin)
|
2414
2450
|
finish = false
|
2415
2451
|
end
|
2416
|
-
raise
|
2452
|
+
raise InvalidTimeExpression, 'Unrecognized date string' unless start
|
2417
2453
|
dates = [start, finish]
|
2418
2454
|
end
|
2419
2455
|
|
@@ -2423,7 +2459,7 @@ command :import do |c|
|
|
2423
2459
|
wwid.import(args, options)
|
2424
2460
|
wwid.write(wwid.doing_file)
|
2425
2461
|
else
|
2426
|
-
raise
|
2462
|
+
raise InvalidPluginType, "Invalid import type: #{options[:type]}"
|
2427
2463
|
end
|
2428
2464
|
end
|
2429
2465
|
end
|
@@ -2448,14 +2484,13 @@ pre do |global, _command, _options, _args|
|
|
2448
2484
|
end
|
2449
2485
|
|
2450
2486
|
on_error do |exception|
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
false
|
2487
|
+
if exception.kind_of?(SystemExit)
|
2488
|
+
false
|
2489
|
+
else
|
2490
|
+
# Doing.logger.error('Fatal:', exception)
|
2491
|
+
Doing.logger.output_results
|
2492
|
+
true
|
2493
|
+
end
|
2459
2494
|
end
|
2460
2495
|
|
2461
2496
|
post do |global, _command, _options, _args|
|