doing 2.0.5.pre → 2.0.6.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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|
|