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
@@ -11,142 +11,108 @@ require_relative 'base_subcommand'
11
11
  module Dsu
12
12
  module Subcommands
13
13
  class Theme < BaseSubcommand
14
- map %w[c] => :create if Dsu.env.test?
15
- map %w[d] => :delete if Dsu.env.test?
14
+ map %w[c] => :create if Dsu.env.local?
15
+ map %w[d] => :delete if Dsu.env.local?
16
16
  map %w[l] => :list
17
17
  map %w[s] => :show
18
18
  map %w[u] => :use
19
19
 
20
- if Dsu.env.test?
21
- desc 'create THEME_NAME [OPTIONS]',
22
- 'Creates a dsu color theme named THEME_NAME.'
23
- long_desc <<-LONG_DESC
24
- Create a dsu color theme named THEME_NAME in the #{Support::Fileable.themes_folder} folder.
25
-
26
- SYNOPSIS
27
-
28
- `dsu create THEME_NAME [-d|--description DESCRIPTION]`
29
-
30
- OPTIONS:
31
-
32
- -d|--description DESCRIPTION: Creates the dsu color theme with having DESCRIPTION as the color theme description.
33
-
34
- DESCRIPTION:
35
-
36
- Must be be between 2 and 256 characters (inclusive) in length.
37
- LONG_DESC
20
+ if Dsu.env.local?
21
+ desc I18n.t('subcommands.theme.create.desc'), I18n.t('subcommands.theme.create.usage')
22
+ long_desc I18n.t('subcommands.theme.create.long_desc', themes_folder: Support::Fileable.themes_folder)
38
23
  option :description, type: :string, aliases: '-d', banner: 'DESCRIPTION'
39
24
  option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
40
25
  def create(theme_name)
41
26
  if Models::ColorTheme.exist?(theme_name: theme_name)
42
- Views::Shared::Error.new(messages: "Color theme \"#{theme_name}\" already exists.").render
27
+ message = I18n.t('subcommands.theme.create.errors.already_exists', theme_name: theme_name)
28
+ Views::Shared::Error.new(messages: message).render
43
29
  return false
44
30
  end
45
- prompt = color_theme.prompt_with_options(prompt: "Create color theme \"#{theme_name}\"?", options: %w[y N])
31
+ prompt_string = I18n.t('subcommands.theme.create.prompts.create_theme', theme_name: theme_name)
32
+ prompt = color_theme.prompt_with_options(prompt: prompt_string, options: %w[y N])
46
33
  if yes?(prompt, options: options)
47
34
  theme_hash = Models::ColorTheme::DEFAULT_THEME.dup
48
- theme_hash[:description] = options[:description] || "#{theme_name.capitalize} color theme"
35
+ theme_hash[:description] = options[:description] || I18n.t('subcommands.theme.generic.color_theme',
36
+ theme_name: theme_name.capitalize)
49
37
  Models::ColorTheme.new(theme_name: theme_name, theme_hash: theme_hash).save!
50
- Views::Shared::Info.new(messages: "\nCreated color theme \"#{theme_name}\".").render
38
+ message = I18n.t('subcommands.theme.create.messages.created', theme_name: theme_name)
39
+ Views::Shared::Info.new(messages: "\n#{message}").render
51
40
  true
52
41
  else
53
- Views::Shared::Info.new(messages: "\nCanceled.").render
42
+ message = I18n.t('subcommands.theme.create.messages.canceled')
43
+ Views::Shared::Info.new(messages: "\n#{message}").render
54
44
  false
55
45
  end
56
46
  end
57
47
 
58
- desc 'delete THEME_NAME',
59
- 'Deletes the existing dsu color theme THEME_NAME.'
60
- long_desc <<-LONG_DESC
61
- NAME
62
-
63
- `dsu delete [THEME_NAME]` -- will delete the dsu color theme named THEME_NAME located in the #{Support::Fileable.themes_folder} folder.
64
- LONG_DESC
48
+ desc I18n.t('subcommands.theme.delete.desc'), I18n.t('subcommands.theme.delete.usage')
49
+ long_desc I18n.t('subcommands.theme.delete.long_desc', themes_folder: Support::Fileable.themes_folder)
65
50
  option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
66
- def delete(theme_name)
51
+ def delete(theme_name) # rubocop:disable Metrics/MethodLength
67
52
  display_dsu_header
68
53
 
69
54
  if theme_name == Models::ColorTheme::DEFAULT_THEME_NAME
70
- display_dsu_header
71
- Views::Shared::Error.new(messages: "Color theme \"#{theme_name}\" cannot be deleted.").render
55
+ message = I18n.t('subcommands.theme.delete.errors.cannot_delete', theme_name: theme_name)
56
+ Views::Shared::Error.new(messages: message).render
72
57
  return
73
58
  end
74
59
 
75
60
  unless Models::ColorTheme.exist?(theme_name: theme_name)
76
- Views::Shared::Error.new(messages: "Color theme \"#{theme_name}\" does not exist.").render
61
+ message = I18n.t('subcommands.theme.generic.errors.does_not_exist', theme_name: theme_name)
62
+ Views::Shared::Error.new(messages: message).render
77
63
  return
78
64
  end
79
65
 
80
- prompt = color_theme.prompt_with_options(prompt: "Delete color theme \"#{theme_name}\"?",
81
- options: %w[y N])
82
- if yes?(prompt, options: options)
66
+ prompt_string = I18n.t('subcommands.theme.delete.prompts.delete_theme', theme_name: theme_name)
67
+ prompt = color_theme.prompt_with_options(prompt: prompt_string, options: %w[y N])
68
+ message = if yes?(prompt, options: options)
83
69
  Models::ColorTheme.delete!(theme_name: theme_name)
84
- Views::Shared::Info.new(messages: "\nDeleted color theme \"#{theme_name}\".").render
70
+ change_theme
71
+ I18n.t('subcommands.theme.delete.messages.deleted', theme_name: theme_name)
85
72
  else
86
- Views::Shared::Info.new(messages: "\nCanceled.").render
73
+ I18n.t('subcommands.theme.delete.messages.canceled')
87
74
  end
75
+ Views::Shared::Info.new(messages: "\n#{message}").render
88
76
  end
89
77
  end
90
78
 
91
- desc 'list',
92
- 'Lists the available dsu color themes.'
93
- long_desc <<-LONG_DESC
94
- NAME
95
-
96
- `dsu list` -- lists the available dsu color themes located in the #{Support::Fileable.themes_folder} folder.
97
- LONG_DESC
79
+ desc I18n.t('subcommands.theme.list.desc'), I18n.t('subcommands.theme.list.usage')
80
+ long_desc I18n.t('subcommands.theme.list.long_desc', themes_folder: Support::Fileable.themes_folder)
98
81
  def list
99
82
  Views::ColorTheme::Index.new.render
100
83
  end
101
84
 
102
- desc 'use THEME_NAME',
103
- 'Sets THEME_NAME as the current DSU color theme.'
104
- long_desc <<-LONG_DESC
105
- NAME
106
-
107
- `dsu theme use [THEME_NAME]` -- sets the dsu color theme to THEME_NAME.
108
-
109
- SYNOPSIS
110
-
111
- If THEME_NAME is not provided, the default theme will be used.
112
- If THEME_NAME does not exist, you will be given the option to create a new theme.
113
-
114
- LONG_DESC
85
+ desc I18n.t('subcommands.theme.use.desc'), I18n.t('subcommands.theme.use.usage')
86
+ long_desc I18n.t('subcommands.theme.use.long_desc')
115
87
  option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
116
88
  def use(theme_name = Models::ColorTheme::DEFAULT_THEME_NAME)
117
- if Dsu.env.test? && !Models::ColorTheme.exist?(theme_name: theme_name)
118
- display_dsu_header
119
- return unless create(theme_name)
120
- end
89
+ display_dsu_header
90
+
91
+ return if Dsu.env.local? && !Models::ColorTheme.exist?(theme_name: theme_name) && !create(theme_name)
121
92
 
122
93
  unless Models::ColorTheme.exist?(theme_name: theme_name)
123
- display_dsu_header
124
- Views::Shared::Error.new(messages: "Color theme \"#{theme_name}\" does not exist.").render
94
+ message = I18n.t('subcommands.theme.generic.errors.does_not_exist', theme_name: theme_name)
95
+ Views::Shared::Error.new(messages: message).render
125
96
  return
126
97
  end
127
98
 
128
- configuration.theme_name = theme_name
129
- configuration.save!
99
+ change_theme theme_name: theme_name
130
100
  # We need to display the header after the theme is updated so that it is displayed in the
131
101
  # correct theme color.
132
- display_dsu_header
133
- Views::Shared::Info.new(messages: "Using color theme \"#{theme_name}\".").render
102
+ message = I18n.t('subcommands.theme.use.messages.using_color_theme', theme_name: theme_name)
103
+ Views::Shared::Info.new(messages: message).render
134
104
  end
135
105
 
136
- desc 'show THEME_NAME',
137
- 'Displays the dsu color theme.'
138
- long_desc <<-LONG_DESC
139
- NAME
140
-
141
- `dsu show THEME_NAME` -- displays the dsu color theme for THEME_NAME.
142
- LONG_DESC
106
+ desc I18n.t('subcommands.theme.show.desc'), I18n.t('subcommands.theme.show.usage')
107
+ long_desc I18n.t('subcommands.theme.show.long_desc')
143
108
  def show(theme_name = configuration.theme_name)
144
109
  if Dsu::Models::ColorTheme.exist?(theme_name: theme_name)
145
110
  Views::ColorTheme::Show.new(theme_name: theme_name).render
146
111
  return
147
112
  end
148
113
 
149
- Views::Shared::Error.new(messages: "Color theme \"#{theme_name}\" does not exist.").render
114
+ message = I18n.t('subcommands.theme.generic.errors.does_not_exist', theme_name: theme_name)
115
+ Views::Shared::Error.new(messages: message).render
150
116
  end
151
117
 
152
118
  private
@@ -154,6 +120,11 @@ module Dsu
154
120
  def display_dsu_header
155
121
  self.class.display_dsu_header
156
122
  end
123
+
124
+ def change_theme(theme_name: Models::ColorTheme::DEFAULT_THEME_NAME)
125
+ configuration.theme_name = theme_name
126
+ configuration.save!
127
+ end
157
128
  end
158
129
  end
159
130
  end
@@ -23,7 +23,7 @@ module Dsu
23
23
  def auto_prompt(prompt, options)
24
24
  prompt = Utils.strip_escapes(prompt)
25
25
  @auto_prompt ||= begin
26
- value = options.dig('prompts', prompt)
26
+ value = options.dig('prompts', prompt) || options.dig('prompts', 'any')
27
27
  value = (value == 'true' unless value.nil?)
28
28
  value
29
29
  end
@@ -35,11 +35,13 @@ module Dsu
35
35
  def suspend_header?(args, _options)
36
36
  return false unless args.count > 1
37
37
 
38
+ # TODO: I18n?
38
39
  true if args[0] == 'theme' && %w[use delete].include?(args[1])
39
40
  end
40
41
 
41
42
  def display_dsu_footer
42
43
  puts apply_theme('_' * 35, theme_color: color_theme.dsu_footer)
44
+ # TODO: I18n.
43
45
  footer = apply_theme("Theme: #{color_theme.theme_name}", theme_color: color_theme.dsu_footer)
44
46
  puts footer
45
47
  end
@@ -17,8 +17,8 @@ module Dsu
17
17
  to_time = dsu_to_time_for(to_option: to_option, from_time: from_time)
18
18
 
19
19
  errors = []
20
- errors << "Option -f, [--from=DATE|MNEMONIC] value is invalid [\"#{from_option}\"]" if from_time.nil?
21
- errors << "Option -t, [--to=DATE|MNEMONIC] value is invalid [\"#{to_option}\"]" if to_time.nil?
20
+ errors << I18n.t('errors.from_option_invalid', from_option: from_option) if from_time.nil?
21
+ errors << I18n.t('errors.to_option_invalid', to_option: to_option) if to_time.nil?
22
22
  return [[], errors] if errors.any?
23
23
 
24
24
  min_time, max_time = [from_time, to_time].sort
@@ -67,6 +67,7 @@ module Dsu
67
67
 
68
68
  def valid_time!(time_parts:)
69
69
  time_string = time_string_for(time_parts: time_parts)
70
+ # TODO: I18n.
70
71
  Date.strptime(time_string, '%Y/%m/%d').to_time
71
72
  end
72
73
 
@@ -4,6 +4,7 @@ module Dsu
4
4
  module Support
5
5
  module CommandOptions
6
6
  module TimeMneumonics
7
+ # TODO: I18n.
7
8
  TODAY = %w[n today].freeze
8
9
  TOMORROW = %w[t tomorrow].freeze
9
10
  YESERDAY = %w[y yesterday].freeze
@@ -10,6 +10,7 @@ module Dsu
10
10
  module TimeFormatable
11
11
  module_function
12
12
 
13
+ # TODO: I18n.
13
14
  def formatted_time(time:)
14
15
  time = time.localtime if time.utc?
15
16
 
@@ -28,10 +29,12 @@ module Dsu
28
29
  time.strftime("%A, (#{today_yesterday_or_tomorrow}) %Y-%m-%d #{time_zone}")
29
30
  end
30
31
 
32
+ # TODO: I18n.
31
33
  def mm_dd(time:, separator: '/')
32
34
  time.strftime("%m#{separator}%d")
33
35
  end
34
36
 
37
+ # TODO: I18n.
35
38
  def mm_dd_yyyy(time:, separator: '/')
36
39
  time.strftime("%m#{separator}%d#{separator}%Y")
37
40
  end
@@ -40,6 +43,16 @@ module Dsu
40
43
  time.zone
41
44
  end
42
45
 
46
+ # TODO: I18n.
47
+ def yyyy_mm_dd_or_through_for(times:)
48
+ return yyyy_mm_dd(time: times[0]) if times.one?
49
+
50
+ times = [yyyy_mm_dd(time: times.min), yyyy_mm_dd(time: times.max)]
51
+
52
+ I18n.t('information.dates.through', from: times[0], to: times[1])
53
+ end
54
+
55
+ # TODO: I18n.
43
56
  def yyyy_mm_dd(time:, separator: '-')
44
57
  time.strftime("%Y#{separator}%m#{separator}%d")
45
58
  end
@@ -28,8 +28,10 @@ module Dsu
28
28
  return if description.length.between?(2, 256)
29
29
 
30
30
  if description.length < 2
31
+ # TODO: I18n.
31
32
  record.errors.add(:description, "is too short: \"#{record.short_description}\" (minimum is 2 characters).")
32
33
  elsif description.length > 256
34
+ # TODO: I18n.
33
35
  record.errors.add(:description, "is too long: \"#{record.short_description}\" (maximum is 256 characters).")
34
36
  end
35
37
  end
@@ -46,6 +46,7 @@ module Dsu
46
46
 
47
47
  non_unique_descriptions = descriptions.select { |description| descriptions.count(description) > 1 }.uniq
48
48
  non_unique_descriptions.each do |non_unique_description|
49
+ # TODO: I18n.
49
50
  record.errors.add(:entries,
50
51
  "array contains duplicate entry: \"#{short_description(non_unique_description)}\".",
51
52
  type: Support::FieldErrors::FIELD_DUPLICATE_ERROR)
data/lib/dsu/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Dsu
4
4
  VERSION_REGEX = /\A\d+\.\d+\.\d+(\.alpha\.\d+)?\z/
5
- VERSION = '2.0.7'
5
+ VERSION = '2.1.1'
6
6
  end
@@ -11,6 +11,7 @@ require_relative '../shared/warning'
11
11
  module Dsu
12
12
  module Views
13
13
  module ColorTheme
14
+ # TODO: I18n this class.
14
15
  class Show
15
16
  include Support::ColorThemable
16
17
 
@@ -6,6 +6,7 @@ require_relative '../../models/entry_group'
6
6
  module Dsu
7
7
  module Views
8
8
  module EntryGroup
9
+ # TODO: I18n this class.
9
10
  class Edit
10
11
  def initialize(entry_group:, options: {})
11
12
  raise ArgumentError, 'entry_group is nil' if entry_group.nil?
@@ -98,7 +99,7 @@ module Dsu
98
99
  end
99
100
 
100
101
  def previous_entry_group?
101
- previous_entry_group.entries.present?
102
+ previous_entry_group&.entries&.present?
102
103
  end
103
104
 
104
105
  def previous_entry_group
@@ -21,8 +21,9 @@ module Dsu
21
21
  @options = options || {}
22
22
  end
23
23
 
24
+ # TODO: I18n.
24
25
  def render
25
- entry_group_times.sort!
26
+ times.sort!
26
27
  time_range = "#{formatted_time(time: times.first)} " \
27
28
  "through #{formatted_time(time: times.last)}"
28
29
  message = "(nothing to display for #{time_range})"
@@ -31,6 +32,8 @@ module Dsu
31
32
 
32
33
  private
33
34
 
35
+ attr_reader :times, :options
36
+
34
37
  def color_theme
35
38
  @color_theme ||= Models::ColorTheme.current_or_default
36
39
  end
@@ -10,6 +10,7 @@ module Dsu
10
10
  raise ArgumentError, 'model is nil' if model.nil?
11
11
  raise ArgumentError, "model is the wrong object type: \"#{model}\"" unless model.is_a?(ActiveModel::Model)
12
12
 
13
+ # TODO: I18n.
13
14
  header = options[:header] || 'The following ERRORS were encountered; changes could not be saved:'
14
15
  super(messages: model.errors.full_messages, header: header, options: options)
15
16
 
data/lib/dsu.rb CHANGED
@@ -2,9 +2,13 @@
2
2
 
3
3
  require 'active_support/core_ext/hash/indifferent_access'
4
4
  require 'active_support/core_ext/object/blank'
5
+ require 'i18n'
5
6
  require 'thor'
6
7
  require 'time'
7
8
 
9
+ I18n.load_path += Dir[File.join(__dir__, 'locales/**/*', '*.yml')]
10
+ # I18n.default_locale = :en # (note that `en` is already the default!)
11
+
8
12
  Dir.glob("#{__dir__}/core/**/*.rb").each do |file|
9
13
  require file
10
14
  end
@@ -24,7 +28,7 @@ if !(Dsu.env.test? || Dsu.env.development?) && Dsu::Migration::Service.run_migra
24
28
  begin
25
29
  Dsu::Migration::Service.new.call
26
30
  rescue StandardError => e
27
- puts "Error running migrations: #{e.message}"
31
+ puts I18n.t('errors.migration.error', message: e.message)
28
32
  exit 1
29
33
  end
30
34
  end
@@ -0,0 +1,8 @@
1
+ en:
2
+ activerecord:
3
+ errors:
4
+ models:
5
+ some_model:
6
+ attributes:
7
+ some_attribute:
8
+ some_error: Some error
@@ -0,0 +1,90 @@
1
+ # lib/dsu/cli.rb
2
+ en:
3
+ commands:
4
+ add:
5
+ desc: add|-a [OPTIONS] DESCRIPTION
6
+ usage: Adds a DSU entry having DESCRIPTION to the date associated with the given OPTION
7
+ long_desc: |
8
+ Will add a DSU entry having DESCRIPTION to the date associated with the given OPTION.
9
+
10
+ $ dsu add [-d DATE|-n|-t|-y] DESCRIPTION
11
+
12
+ $ dsu -a [-d DATE|-n|-t|-y] DESCRIPTION
13
+
14
+ OPTIONS:
15
+
16
+ -d DATE: Adds a DSU entry having DESCRIPTION to the DATE.
17
+
18
+ %{date_option_description}
19
+
20
+ -n: Adds a DSU entry having DESCRIPTION to today's date (`Time.now`).
21
+
22
+ -t: Adds a DSU entry having DESCRIPTION to tomorrow's date (`Time.new.tomorrow`).
23
+
24
+ -y: Adds a DSU entry having DESCRIPTION to yesterday's date (`Time.new.yesterday`).
25
+
26
+ DESCRIPTION
27
+
28
+ Must be be between 2 and 256 characters (inclusive) in length.
29
+ config:
30
+ desc: config|-c SUBCOMMAND
31
+ usage: Manage configuration file for this gem
32
+ delete:
33
+ desc: delete|-d SUBCOMMAND
34
+ usage: Delete DSU entries for the given SUBCOMMAND
35
+ edit:
36
+ desc: edit|-e SUBCOMMAND
37
+ usage: Edit DSU entries for the given SUBCOMMAND
38
+ info:
39
+ desc: info|-i
40
+ usage: Displays information about this DSU release
41
+ info: |
42
+ Dsu Info
43
+ --------------------------------------------------
44
+ Dsu version: %{dsu_version}
45
+ Configuration version: %{configuration_version}
46
+ Entry group version: %{entry_group_version}
47
+ Color theme version: %{color_theme_version}
48
+
49
+ Config folder: %{config_folder}
50
+ Root folder: %{root_folder}
51
+ Entries folder: %{entries_folder}
52
+ Themes folder: %{themes_folder}
53
+ Gem folder: %{gem_folder}
54
+ Temp folder: %{temp_folder}
55
+
56
+ Migration version folder: %{migration_version_folder}
57
+ Migration file folder: %{migration_file_folder}
58
+ list:
59
+ desc: list|-l SUBCOMMAND
60
+ usage: Displays DSU entries for the given SUBCOMMAND
61
+ theme:
62
+ desc: theme|-t SUBCOMMAND
63
+ usage: Manage DSU themes
64
+ version:
65
+ desc: version|-v
66
+ usage: Displays the DSU version for this gem
67
+ options:
68
+ include_all: Include dates that have no DSU entries
69
+ date_option_description: |
70
+ DATE
71
+
72
+ This may be any date string that can be parsed using `Time.parse`.
73
+ Consequently, you may use also use '/' as date separators,
74
+ as well as omit the year if the date you want to display is the
75
+ current year (e.g. <month>/<day>, or 1/31). For example: `require 'time';
76
+ Time.parse('01/02/2023'); Time.parse('1/2') # etc.`
77
+ mneumonic_option_description: |
78
+ MNEUMONIC
79
+
80
+ This may be any of the following: n|today|t|tomorrow|y|yesterday|+n|-n.
81
+
82
+ Where n, t, y are aliases for today, tomorrow, and yesterday, respectively.
83
+
84
+ Where +n, -n are relative date mneumonics (RDNs). Generally speaking,
85
+ RDNs are relative to the current date. For example, a RDN of +1 would be
86
+ equal to `Time.now + 1.day` (tomorrow), and a RDN of -1 would be equal to
87
+ `Time.now - 1.day` (yesterday).
88
+
89
+ In some cases the behavior RDNs have on some commands are context dependent;
90
+ in such cases the behavior will be noted.
@@ -0,0 +1,23 @@
1
+ en:
2
+ configuration:
3
+ errors:
4
+ theme_file_missing: Theme file "%{theme_path}" does not exist.
5
+ errors:
6
+ error: "Error: %{message}"
7
+ from_option_invalid: Option -f, [--from=DATE|MNEMONIC] value is invalid ["%{from_option}"]
8
+ to_option_invalid: Option -t, [--to=DATE|MNEMONIC] value is invalid ["%{to_option}"]
9
+ migration:
10
+ error: "Error running migrations: %{message}"
11
+ headers:
12
+ entry:
13
+ could_not_be_added: "An error was encountered; the entry could not be added:"
14
+ messages:
15
+ configuration_file:
16
+ already_exists: Configuration file (%{configuration_file}) already exists.
17
+ created: Configuration file (%{configuration_file}) created.
18
+ deleted: Configuration file (%{configuration_file}) deleted.
19
+ destination_folder_does_not_exist: "Destination folder for configuration file (%{configuration_folder}) does not exist."
20
+ does_not_exist: "Configuration file (%{configuration_file}) does not exist."
21
+ information:
22
+ dates:
23
+ through: "%{from} thru %{to}"
@@ -0,0 +1,19 @@
1
+ en:
2
+ presenters:
3
+ color_theme_presenter:
4
+ headers:
5
+ color_themes: Color Themes
6
+ current_theme: "* current theme"
7
+ color_theme_show_presenter:
8
+ headers:
9
+ number: No.
10
+ color: Color
11
+ values: Values
12
+ viewing_color_theme: "Viewing color theme: %{theme_name}"
13
+ footer_example: Footer example
14
+ configuration_presenter:
15
+ headers:
16
+ file_contents: "Configuration file contents (%{config_path})"
17
+ entry_group_presenter:
18
+ headers:
19
+ no_entries_available: (no entries available for this day)
@@ -0,0 +1,10 @@
1
+ en:
2
+ services:
3
+ editor_service:
4
+ errors:
5
+ temp_file_error: |
6
+ Failed to open temporary file in editor '%{editor}'; the system error returned was: '%{status}'.
7
+ Either set the EDITOR environment variable or set the dsu editor configuration option (`$ dsu config info`).
8
+ Run `$ dsu help config` for more information.
9
+ messages:
10
+ editing: "Editing entry group %{formatted_time}..."