dsu 2.0.7 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/Gemfile.lock +18 -18
  4. data/README.md +78 -17
  5. data/lib/core/ruby/color_theme_mode.rb +1 -1
  6. data/lib/dsu/base_cli.rb +2 -16
  7. data/lib/dsu/cli.rb +29 -56
  8. data/lib/dsu/command_services/add_entry_service.rb +1 -1
  9. data/lib/dsu/env.rb +4 -0
  10. data/lib/dsu/models/color_theme.rb +2 -2
  11. data/lib/dsu/models/configuration.rb +3 -1
  12. data/lib/dsu/models/entry_group.rb +1 -1
  13. data/lib/dsu/presenters/color_theme_presenter.rb +4 -2
  14. data/lib/dsu/presenters/color_theme_show_presenter.rb +9 -3
  15. data/lib/dsu/presenters/configuration_presenter.rb +2 -2
  16. data/lib/dsu/presenters/entry_group_presenter.rb +2 -2
  17. data/lib/dsu/services/entry_group/counter_service.rb +32 -0
  18. data/lib/dsu/services/entry_group/deleter_service.rb +35 -0
  19. data/lib/dsu/services/entry_group/editor_service.rb +7 -11
  20. data/lib/dsu/subcommands/config.rb +17 -74
  21. data/lib/dsu/subcommands/delete.rb +107 -0
  22. data/lib/dsu/subcommands/edit.rb +16 -30
  23. data/lib/dsu/subcommands/list.rb +20 -90
  24. data/lib/dsu/subcommands/theme.rb +50 -79
  25. data/lib/dsu/support/ask.rb +1 -1
  26. data/lib/dsu/support/command_hookable.rb +2 -0
  27. data/lib/dsu/support/command_options/dsu_times.rb +2 -2
  28. data/lib/dsu/support/command_options/time.rb +1 -0
  29. data/lib/dsu/support/command_options/time_mneumonics.rb +1 -0
  30. data/lib/dsu/support/time_formatable.rb +13 -0
  31. data/lib/dsu/validators/description_validator.rb +2 -0
  32. data/lib/dsu/validators/entries_validator.rb +1 -0
  33. data/lib/dsu/version.rb +1 -1
  34. data/lib/dsu/views/color_theme/show.rb +1 -0
  35. data/lib/dsu/views/entry_group/edit.rb +2 -1
  36. data/lib/dsu/views/entry_group/shared/no_entries_to_display.rb +4 -1
  37. data/lib/dsu/views/shared/model_errors.rb +1 -0
  38. data/lib/dsu.rb +5 -1
  39. data/lib/locales/en/active_record.yml +8 -0
  40. data/lib/locales/en/commands.yml +90 -0
  41. data/lib/locales/en/miscellaneous.yml +23 -0
  42. data/lib/locales/en/presenters.yml +19 -0
  43. data/lib/locales/en/services.yml +10 -0
  44. data/lib/locales/en/subcommands.yml +348 -0
  45. metadata +45 -30
  46. data/exe/dsu_migrate.rb +0 -43
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../models/entry_group'
4
+
5
+ module Dsu
6
+ module Services
7
+ module EntryGroup
8
+ class DeleterService
9
+ def initialize(times:, options: {})
10
+ raise ArgumentError, 'Argument times is nil' if times.nil?
11
+
12
+ @times = times
13
+ @options = options
14
+ end
15
+
16
+ def call
17
+ deleted_entry_groups = 0
18
+
19
+ times.each do |time|
20
+ next unless Models::EntryGroup.exist?(time: time)
21
+
22
+ Models::EntryGroup.delete(time: time)
23
+ deleted_entry_groups += 1
24
+ end
25
+
26
+ deleted_entry_groups
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :times, :options
32
+ end
33
+ end
34
+ end
35
+ end
@@ -40,8 +40,9 @@ module Dsu
40
40
  # Renders the edit view to a string so we can write it to a temporary file
41
41
  # and edit it. The edits will be used to update the entry group.
42
42
  def render_edit_view
43
- puts apply_theme("Editing entry group #{formatted_time(time: entry_group.time)}...",
44
- theme_color: color_theme.header)
43
+ message = I18n.t('services.editor_service.messages.editing',
44
+ formatted_time: formatted_time(time: entry_group.time))
45
+ puts apply_theme(message, theme_color: color_theme.header)
45
46
  # TODO: Call #render_as_string directly below?
46
47
  StdoutRedirectorService.call { Views::EntryGroup::Edit.new(entry_group: entry_group).render }
47
48
  # Views::EntryGroup::Edit.new(entry_group: entry_group).render_as_string
@@ -63,15 +64,10 @@ module Dsu
63
64
 
64
65
  process_entry_group!(entry_group_with_edits)
65
66
  else
66
- puts apply_theme(
67
- [
68
- "Failed to open temporary file in editor '#{configuration.editor}'; " \
69
- "the system error returned was: '#{$CHILD_STATUS}'.",
70
- 'Either set the EDITOR environment variable ' \
71
- 'or set the dsu editor configuration option (`$ dsu config info`).',
72
- 'Run `$ dsu help config` for more information.'
73
- ], theme_color: color_theme.error
74
- )
67
+ message_array = I18n.t('services.editor_service.errors.temp_file_error',
68
+ editor: configuration.editor,
69
+ status: $CHILD_STATUS).split("\n")
70
+ puts apply_theme(message_array, theme_color: color_theme.error)
75
71
  end
76
72
  end
77
73
  end
@@ -18,99 +18,40 @@ module Dsu
18
18
  end
19
19
  end
20
20
 
21
- desc 'info', 'Displays information about this gem configuration'
22
- long_desc <<-LONG_DESC
23
- NAME
24
-
25
- `dsu config info` -- Displays information about this gem configuration.
26
-
27
- SYNOPSIS
28
-
29
- dsu config info
30
- LONG_DESC
21
+ desc I18n.t('subcommands.config.info.desc'), I18n.t('subcommands.config.info.usage')
22
+ long_desc I18n.t('subcommands.config.info.long_desc')
31
23
  def info
32
24
  configuration = Models::Configuration.new
33
25
  Views::Configuration::Show.new(config: configuration).call
34
26
  end
35
27
 
36
- if ENV['DEV_ENV']
37
- desc 'init', 'Creates and initializes a .dsu file in your home folder'
38
- long_desc <<-LONG_DESC
39
- NAME
40
-
41
- `dsu config init` -- will create and initialize a .dsu file ("#{Dsu::Support::Fileable.root_folder}/.dsu") that you may edit. Otherwise, the default configuration will be used.
42
-
43
- SYNOPSIS
44
-
45
- dsu config init
46
-
47
- CONFIGURATION FILE OPTIONS
48
-
49
- The following configuration file options are available:
50
-
51
- version:
52
-
53
- The configuration version - DO NOT ALTER THIS VALUE!
54
-
55
- editor:
56
-
57
- The default editor to use when editing entry groups if the EDITOR environment variable on your system is not set. The default is 'nano'. You'll need to change the default editor on Windows systems.
58
-
59
- entries_display_order:
60
-
61
- The order by which entries will be displayed, :asc or :desc (ascending or descending, respectively).
62
-
63
- Default: :desc
64
-
65
- entries_file_name:
66
-
67
- The entries file name format. It is recommended that you do not change this. The file name must include `%Y`, `%m` and `%d` `Time` formatting specifiers to make sure the file name is unique and able to be located by `dsu` functions. For example, the default file name is `%Y-%m-%d.json`; however, something like `%m-%d-%Y.json` or `entry-group-%m-%d-%Y.json` would work as well.
68
-
69
- ATTENTION: Please keep in mind that if you change this value `dsu` will not recognize entry files using a different format. You would (at this time), have to manually rename any existing entry file names to the new format.
70
-
71
- Default: '%Y-%m-%d.json'
72
-
73
- entries_folder:
74
-
75
- This is the folder where `dsu` stores entry files. You may change this to anything you want. `dsu` will create this folder for you, as long as your system's write permissions allow this.
76
-
77
- ATTENTION: Please keep in mind that if you change this value `dsu` will not be able to find entry files in any previous folder. You would (at this time), have to manually mode any existing entry files to this new folder.
78
-
79
- Default: "'#{Dsu::Support::Fileable.root_folder}/dsu/entries'"
80
- LONG_DESC
28
+ if Dsu.env.development?
29
+ desc I18n.t('subcommands.config.init.desc'), I18n.t('subcommands.config.init.usage')
30
+ long_desc I18n.t('subcommands.config.init.long_desc', home_folder: Dsu::Support::Fileable.root_folder)
81
31
  def init
82
32
  exit 1 if configuration_errors_or_wanings?
83
33
 
84
34
  Models::Configuration.default.tap do |configuration|
85
35
  configuration.save!
86
- messages = ["Configuration file (#{Models::Configuration.config_file}) created."]
36
+ messages = [I18n.t('messages.configuration_file.created',
37
+ configuration_file: Models::Configuration.config_file)]
87
38
  Views::Shared::Success.new(messages: messages).render
88
39
  Views::Configuration::Show.new(config: configuration).render
89
40
  end
90
41
  end
91
42
 
92
- desc 'delete', 'Deletes the configuration file'
93
- long_desc <<-LONG_DESC
94
- NAME
95
-
96
- `dsu config delete` -- Deletes the configuration.
97
-
98
- SYNOPSIS
99
-
100
- dsu config delete
101
-
102
- NOTES
103
-
104
- Deleting the dsu configuration file will simply cause dsu to use the default configuration options (`Dsu::Models::Configuration::DEFAULT_CONFIGURATION`).
105
- LONG_DESC
43
+ desc I18n.t('subcommands.config.delete.desc'), I18n.t('subcommands.config.delete.usage')
44
+ long_desc I18n.t('subcommands.config.delete.long_desc')
106
45
  def delete
107
46
  unless Models::Configuration.exist?
108
- messages = ["Configuration file (#{Models::Configuration.config_file}) does not exist."]
47
+ messages = [I18n.t('messages.configuration_file.does_not_exist',
48
+ configuration_file: Models::Configuration.config_file)]
109
49
  Views::Shared::Warning.new(messages: messages).render
110
50
  exit 1
111
51
  end
112
52
  Models::Configuration.delete!
113
- messages = ["Configuration file (#{Models::Configuration.config_file}) deleted."]
53
+ messages = [I18n.t('messages.configuration_file.deleted',
54
+ configuration_file: Models::Configuration.config_file)]
114
55
  Views::Shared::Success.new(messages: messages).render
115
56
  end
116
57
  end
@@ -119,10 +60,12 @@ module Dsu
119
60
 
120
61
  def configuration_errors_or_wanings?
121
62
  if Models::Configuration.exist?
122
- messages = ["Configuration file (#{Models::Configuration.config_file}) already exists"]
63
+ messages = [I18n.t('messages.configuration_file.already_exists',
64
+ configuration_file: Models::Configuration.config_file)]
123
65
  Views::Shared::Warning.new(messages: messages).render
124
66
  elsif !Dir.exist?(Models::Configuration.config_folder)
125
- messages = ["Destination folder for configuration file (#{Models::Configuration.config_folder}) does not exist"] # rubocop:disable Layout/LineLength
67
+ messages = [I18n.t('messages.configuration_file.destination_folder_does_not_exist',
68
+ configuration_file: Models::Configuration.config_file)]
126
69
  Views::Shared::Error.new(messages: messages).render
127
70
  else
128
71
  configuration = Models::Configuration.default
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../services/entry_group/counter_service'
4
+ require_relative '../services/entry_group/deleter_service'
5
+ require_relative '../support/command_options/dsu_times'
6
+ require_relative '../support/command_options/time_mneumonic'
7
+ require_relative '../support/time_formatable'
8
+ require_relative '../views/entry_group/shared/no_entries_to_display'
9
+ require_relative '../views/shared/error'
10
+ require_relative 'base_subcommand'
11
+
12
+ module Dsu
13
+ module Subcommands
14
+ class Delete < BaseSubcommand
15
+ include Support::CommandOptions::TimeMneumonic
16
+ include Support::TimeFormatable
17
+
18
+ map %w[d] => :date
19
+ map %w[dd] => :dates
20
+ map %w[n] => :today
21
+ map %w[t] => :tomorrow
22
+ map %w[y] => :yesterday
23
+
24
+ desc I18n.t('subcommands.delete.today.desc'), I18n.t('subcommands.delete.today.usage')
25
+ long_desc I18n.t('subcommands.delete.today.long_desc')
26
+ option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
27
+ def today
28
+ delete_entry_groups_if times: [Time.now], options: options
29
+ end
30
+
31
+ desc I18n.t('subcommands.delete.tomorrow.desc'), I18n.t('subcommands.delete.tomorrow.usage')
32
+ long_desc I18n.t('subcommands.delete.tomorrow.long_desc')
33
+ option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
34
+ def tomorrow
35
+ delete_entry_groups_if times: [Time.now.tomorrow], options: options
36
+ end
37
+
38
+ desc I18n.t('subcommands.delete.yesterday.desc'), I18n.t('subcommands.delete.yesterday.usage')
39
+ long_desc I18n.t('subcommands.delete.yesterday.long_desc')
40
+ option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
41
+ def yesterday
42
+ delete_entry_groups_if times: [Time.now.yesterday], options: options
43
+ end
44
+
45
+ desc I18n.t('subcommands.delete.date.desc'), I18n.t('subcommands.delete.date.usage')
46
+ long_desc I18n.t('subcommands.delete.date.long_desc',
47
+ date_option_description: date_option_description,
48
+ mneumonic_option_description: mneumonic_option_description)
49
+ option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
50
+ def date(date_or_mneumonic)
51
+ time = if time_mneumonic?(date_or_mneumonic)
52
+ time_from_mneumonic(command_option: date_or_mneumonic)
53
+ else
54
+ Time.parse(date_or_mneumonic)
55
+ end
56
+ delete_entry_groups_if times: [time], options: options
57
+ rescue ArgumentError => e
58
+ Views::Shared::Error.new(messages: e.message).render
59
+ end
60
+
61
+ desc I18n.t('subcommands.delete.dates.desc'), I18n.t('subcommands.delete.dates.usage')
62
+ long_desc I18n.t('subcommands.delete.dates.long_desc',
63
+ date_option_description: date_option_description,
64
+ mneumonic_option_description: mneumonic_option_description)
65
+ option :from, type: :string, required: true, aliases: '-f', banner: 'DATE|MNEMONIC'
66
+ option :to, type: :string, required: true, aliases: '-t', banner: 'DATE|MNEMONIC'
67
+ option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
68
+ def dates
69
+ options = configuration.to_h.merge(self.options).with_indifferent_access
70
+ times, errors = Support::CommandOptions::DsuTimes.dsu_times_for(from_option: options[:from], to_option: options[:to]) # rubocop:disable Layout/LineLength
71
+ if errors.any?
72
+ Views::Shared::Error.new(messages: errors).render
73
+ return
74
+ end
75
+
76
+ times = times_sort(times: times, entries_display_order: options[:entries_display_order])
77
+ delete_entry_groups_if times: times, options: options
78
+ rescue ArgumentError => e
79
+ Views::Shared::Error.new(messages: e.message).render
80
+ end
81
+
82
+ private
83
+
84
+ def delete_entry_groups_if(times:, options:)
85
+ prompt_string = I18n.t('subcommands.delete.prompts.are_you_sure',
86
+ dates: yyyy_mm_dd_or_through_for(times: times), count: total_entry_groups_for(times: times))
87
+ prompt = color_theme.prompt_with_options(prompt: prompt_string, options: %w[y N])
88
+ if yes?(prompt, options: options)
89
+ deleted_count = delete_entry_groups_for(times: times)
90
+ message = I18n.t('subcommands.delete.messages.deleted', count: deleted_count)
91
+ Views::Shared::Success.new(messages: message).render
92
+ else
93
+ message = I18n.t('subcommands.delete.messages.canceled')
94
+ Views::Shared::Info.new(messages: message).render
95
+ end
96
+ end
97
+
98
+ def delete_entry_groups_for(times:)
99
+ Services::EntryGroup::DeleterService.new(times: times).call
100
+ end
101
+
102
+ def total_entry_groups_for(times:)
103
+ Services::EntryGroup::CounterService.new(times: times).call
104
+ end
105
+ end
106
+ end
107
+ end
@@ -12,50 +12,36 @@ module Dsu
12
12
  map %w[t] => :tomorrow
13
13
  map %w[y] => :yesterday
14
14
 
15
- desc 'today, n',
16
- 'Edits the DSU entries for today.'
17
- long_desc <<-LONG_DESC
18
- Edits the DSU entries for today.
19
- LONG_DESC
15
+ desc I18n.t('subcommands.edit.date.desc'), I18n.t('subcommands.edit.date.usage')
16
+ long_desc I18n.t('subcommands.edit.date.long_desc', date_option_description: date_option_description)
17
+ def date(date)
18
+ entry_group = Models::EntryGroup.edit(time: Time.parse(date))
19
+ Views::EntryGroup::Show.new(entry_group: entry_group).render
20
+ rescue ArgumentError => e
21
+ puts apply_theme(I18n.t('errors.error', message: e.message), theme_color: color_theme.error)
22
+ exit 1
23
+ end
24
+
25
+ desc I18n.t('subcommands.edit.today.desc'), I18n.t('subcommands.edit.today.usage')
26
+ long_desc I18n.t('subcommands.edit.today.long_desc')
20
27
  def today
21
28
  entry_group = Models::EntryGroup.edit(time: Time.now)
22
29
  Views::EntryGroup::Show.new(entry_group: entry_group).render
23
30
  end
24
31
 
25
- desc 'tomorrow, t',
26
- 'Edits the DSU entries for tomorrow.'
27
- long_desc <<-LONG_DESC
28
- Edits the DSU entries for tomorrow.
29
- LONG_DESC
32
+ desc I18n.t('subcommands.edit.tomorrow.desc'), I18n.t('subcommands.edit.tomorrow.usage')
33
+ long_desc I18n.t('subcommands.edit.tomorrow.long_desc')
30
34
  def tomorrow
31
35
  entry_group = Models::EntryGroup.edit(time: Time.now.tomorrow)
32
36
  Views::EntryGroup::Show.new(entry_group: entry_group).render
33
37
  end
34
38
 
35
- desc 'yesterday, y',
36
- 'Edits the DSU entries for yesterday.'
37
- long_desc <<-LONG_DESC
38
- Edits the DSU entries for yesterday.
39
- LONG_DESC
39
+ desc I18n.t('subcommands.edit.yesterday.desc'), I18n.t('subcommands.edit.yesterday.usage')
40
+ long_desc I18n.t('subcommands.edit.yesterday.long_desc')
40
41
  def yesterday
41
42
  entry_group = Models::EntryGroup.edit(time: Time.now.yesterday)
42
43
  Views::EntryGroup::Show.new(entry_group: entry_group).render
43
44
  end
44
-
45
- desc 'date, d DATE',
46
- 'Edits the DSU entries for DATE.'
47
- long_desc <<-LONG_DESC
48
- Edits the DSU entries for DATE.
49
-
50
- \x5 #{date_option_description}
51
- LONG_DESC
52
- def date(date)
53
- entry_group = Models::EntryGroup.edit(time: Time.parse(date))
54
- Views::EntryGroup::Show.new(entry_group: entry_group).render
55
- rescue ArgumentError => e
56
- puts apply_theme("Error: #{e.message}", theme_color: color_theme.error)
57
- exit 1
58
- end
59
45
  end
60
46
  end
61
47
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../services/entry_group/counter_service'
3
4
  require_relative '../support/command_options/dsu_times'
4
5
  require_relative '../support/command_options/time_mneumonic'
5
6
  require_relative '../support/time_formatable'
@@ -19,52 +20,34 @@ module Dsu
19
20
  map %w[t] => :tomorrow
20
21
  map %w[y] => :yesterday
21
22
 
22
- desc 'today, n',
23
- 'Displays the DSU entries for today'
24
- long_desc <<-LONG_DESC
25
- Displays the DSU entries for today. This command has no options.
26
- LONG_DESC
27
- option :include_all, type: :boolean, aliases: '-a', desc: 'Include dates that have no DSU entries'
23
+ desc I18n.t('subcommands.list.today.desc'), I18n.t('subcommands.list.today.usage')
24
+ long_desc I18n.t('subcommands.list.today.long_desc')
28
25
  def today
29
26
  time = Time.now
30
27
  times = sorted_dsu_times_for(times: [time.yesterday, time])
31
28
  view_list_for(times: times, options: options)
32
29
  end
33
30
 
34
- desc 'tomorrow, t',
35
- 'Displays the DSU entries for tomorrow'
36
- long_desc <<-LONG_DESC
37
- Displays the DSU entries for tomorrow. This command has no options.
38
- LONG_DESC
39
- option :include_all, type: :boolean, aliases: '-a', desc: 'Include dates that have no DSU entries'
31
+ desc I18n.t('subcommands.list.tomorrow.desc'), I18n.t('subcommands.list.tomorrow.usage')
32
+ long_desc I18n.t('subcommands.list.tomorrow.long_desc')
40
33
  def tomorrow
41
34
  time = Time.now
42
35
  times = sorted_dsu_times_for(times: [time, time.tomorrow])
43
36
  view_list_for(times: times, options: options)
44
37
  end
45
38
 
46
- desc 'yesterday, y',
47
- 'Displays the DSU entries for yesterday'
48
- long_desc <<-LONG_DESC
49
- Displays the DSU entries for yesterday. This command has no options.
50
- LONG_DESC
51
- option :include_all, type: :boolean, aliases: '-a', desc: 'Include dates that have no DSU entries'
39
+ desc I18n.t('subcommands.list.yesterday.desc'), I18n.t('subcommands.list.yesterday.usage')
40
+ long_desc I18n.t('subcommands.list.yesterday.long_desc')
52
41
  def yesterday
53
42
  time = Time.now
54
43
  times = sorted_dsu_times_for(times: [time.yesterday, time.yesterday.yesterday])
55
44
  view_list_for(times: times, options: options)
56
45
  end
57
46
 
58
- desc 'date, d DATE|MNEUMONIC',
59
- 'Displays the DSU entries for the DATE or MNEUMONIC provided'
60
- long_desc <<-LONG_DESC
61
- Displays the DSU entries for the DATE or MNEUMONIC provided.
62
-
63
- #{date_option_description}
64
-
65
- #{mneumonic_option_description}
66
- LONG_DESC
67
- option :include_all, type: :boolean, aliases: '-a', desc: 'Include dates that have no DSU entries'
47
+ desc I18n.t('subcommands.list.date.desc'), I18n.t('subcommands.list.date.usage')
48
+ long_desc I18n.t('subcommands.list.date.long_desc',
49
+ date_option_description: date_option_description,
50
+ mneumonic_option_description: mneumonic_option_description)
68
51
  def date(date_or_mneumonic)
69
52
  time = if time_mneumonic?(date_or_mneumonic)
70
53
  time_from_mneumonic(command_option: date_or_mneumonic)
@@ -77,67 +60,13 @@ module Dsu
77
60
  Views::Shared::Error.new(messages: e.message).render
78
61
  end
79
62
 
80
- desc 'dates|dd OPTIONS',
81
- 'Displays the DSU entries for the OPTIONS provided'
82
- long_desc <<~LONG_DESC
83
- NAME
84
-
85
- $ dsu dates|dd OPTIONS -- will display the DSU entries for the OPTIONS provided.
86
-
87
- SYNOPSIS
88
-
89
- $ dsu dates|dd OPTIONS
90
-
91
- OPTIONS
92
-
93
- -a|--include-all true|false: If true, all DSU dates within the specified range will be displayed. If false, DSU dates between the first and last DSU dates that have NO entries will NOT be displayed.. The default is taken from the dsu configuration setting :include_all, see `dsu config info`.
94
-
95
- -f|--from DATE|MNEMONIC: The DATE or MNEUMONIC that represents the start of the range of DSU dates to display. If a relative mneumonic is used (+/-n, e.g +1, -1, etc.), the date calculated will be relative to the current date (e.g. `<MNEUMONIC>.to_i.days.from_now(Time.now)`).
96
-
97
- -t|--to DATE|MNEMONIC: The DATE or MNEUMONIC that represents the end of the range of DSU dates to display. If a relative mneumonic is used (+/-n, e.g +1, -1, etc.), the date calculated will be relative to the date that resulting from the `--from` option date calculation.
98
-
99
- #{date_option_description}
100
-
101
- #{mneumonic_option_description}
102
-
103
- EXAMPLES
104
-
105
- NOTE: All examples are subject to the `--include-all` option.
106
-
107
- The below will display the DSU entries for the range of dates from 1/1 to 1/4:
108
-
109
- $ dsu list dates --from 1/1 --to +3
110
-
111
- This will display the DSU entries for the range of dates from 1/2 to 1/5:
112
-
113
- $ dsu list dates --from 1/5 --to -3
114
-
115
- This (assuming "today" is 1/10) will display the DSU entries for the last week 1/10 to 1/3:
116
-
117
- $ dsu list dates --from today --to -7
118
-
119
- This (assuming "today" is 5/23) will display the DSU entries for the last week 5/16 to 5/22.
120
- This example simply illustrates the fact that you can use relative mneumonics for
121
- both `--from` and `--to` options; this doesn't mean you should do so...
122
-
123
- While you can use relative mneumonics for both `--from` and `--to` options,
124
- there is always a more intuitive way. The below example basically lists one week
125
- of DSU entries back 1 week from yesterday's date:
126
-
127
- $ dsu list dates --from -7 --to +6
128
-
129
- The above can be accomplished MUCH easier by simply using the `yesterday` mneumonic...
130
-
131
- This (assuming "today" is 5/23) will display the DSU entries back 1 week from yesterday's date 5/16 to 5/22:
132
-
133
- $ dsu list dates --from yesterday --to -6
134
- LONG_DESC
135
- # -f, --from FROM [DATE|MNEMONIC] (e.g. -f, --from 1/1[/yyy]|n|t|y|today|tomorrow|yesterday)
63
+ desc I18n.t('subcommands.list.dates.desc'), I18n.t('subcommands.list.dates.usage')
64
+ long_desc I18n.t('subcommands.list.dates.long_desc',
65
+ date_option_description: date_option_description,
66
+ mneumonic_option_description: mneumonic_option_description)
136
67
  option :from, type: :string, required: true, aliases: '-f', banner: 'DATE|MNEMONIC'
137
- # -t, --to TO [DATE|MNEMONIC] (e.g. -t, --to 1/1[/yyy]|n|t|y|today|tomorrow|yesterday)
138
68
  option :to, type: :string, required: true, aliases: '-t', banner: 'DATE|MNEMONIC'
139
- # Include dates that have no DSU entries.
140
- option :include_all, type: :boolean, aliases: '-a', desc: 'Include dates that have no DSU entries'
69
+ option :include_all, default: false, type: :boolean, aliases: '-a', desc: I18n.t('cli.options.include_all')
141
70
  def dates
142
71
  options = configuration.to_h.merge(self.options).with_indifferent_access
143
72
  times, errors = Support::CommandOptions::DsuTimes.dsu_times_for(from_option: options[:from], to_option: options[:to]) # rubocop:disable Layout/LineLength
@@ -149,9 +78,10 @@ module Dsu
149
78
  # NOTE: special sort here, unlike the other commands where rules for
150
79
  # displaying DSU entries are applied; this is more of a list command.
151
80
  times = times_sort(times: times, entries_display_order: options[:entries_display_order])
152
- view_entry_groups(times: times, options: options) do |total_entry_groups, _total_entry_groups_not_shown|
153
- # nothing_to_display_banner_for(times) if total_entry_groups.zero?
154
- Views::EntryGroup::Shared::NoEntriesToDisplay.new(times: times, options: options) if total_entry_groups.zero?
81
+ view_entry_groups(times: times, options: options) do |_total_entry_groups, _total_entry_groups_not_shown|
82
+ if Services::EntryGroup::CounterService.new(times: times).call.zero?
83
+ Views::EntryGroup::Shared::NoEntriesToDisplay.new(times: times, options: options).render
84
+ end
155
85
  end
156
86
  rescue ArgumentError => e
157
87
  Views::Shared::Error.new(messages: e.message).render