standup_md 0.2.1 → 0.3.0

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.
@@ -1,29 +1,50 @@
1
- require 'json'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'optparse'
3
- require_relative '../standup_md'
4
+ require_relative 'cli/helpers'
5
+
6
+ module StandupMD
4
7
 
5
- class StandupMD
6
8
  ##
7
9
  # Class for handing the command-line interface.
8
10
  class Cli
11
+ include Helpers
12
+
13
+ ##
14
+ # Access to the class's configuration.
15
+ #
16
+ # @return [StandupMD::Config::Cli]
17
+ def self.config
18
+ @config ||= StandupMD.config.cli
19
+ end
9
20
 
10
21
  ##
11
- # The user's preference file.
12
- PREFERENCE_FILE =
13
- File.expand_path(File.join(ENV['HOME'], '.standup_md.yml')).freeze
22
+ # Prints output if +verbose+ is true.
23
+ #
24
+ # @return [nil]
25
+ def self.echo(msg)
26
+ puts msg if config.verbose
27
+ end
14
28
 
15
29
  ##
16
30
  # Creates an instance of +StandupMD+ and runs what the user requested.
17
31
  def self.execute(options = [])
18
32
  exe = new(options)
19
- exe.append_to_previous_entry_tasks if exe.should_append?
20
33
 
21
- exe.print_current_entry if exe.print_current_entry?
22
- exe.print_all_entries if exe.print_all_entries?
23
- exe.write_file if exe.write?
24
- exe.edit if exe.edit?
34
+ exe.write_file if config.write
35
+ if config.print
36
+ exe.print(exe.entry)
37
+ elsif config.edit
38
+ exe.edit
39
+ end
25
40
  end
26
41
 
42
+ ##
43
+ # The entry searched for, usually today.
44
+ #
45
+ # @return [StandupMD::Entry]
46
+ attr_reader :entry
47
+
27
48
  ##
28
49
  # Arguments passed at runtime.
29
50
  #
@@ -31,115 +52,54 @@ class StandupMD
31
52
  attr_reader :options
32
53
 
33
54
  ##
34
- # Preferences after reading config file and parsing ARGV.
55
+ # The file loaded.
35
56
  #
36
- # @return [Array]
37
- attr_reader :preferences
57
+ # @return [StandupMD::File]
58
+ attr_reader :file
38
59
 
39
60
  ##
40
61
  # Constructor. Sets defaults.
41
62
  #
42
63
  # @param [Array] options
43
- def initialize(options)
44
- @edit = true
45
- @write = true
46
- @append_previous = true
47
- @print_current_entry = false
48
- @json = false
49
- @verbose = false
50
- @print_all_entries = false
51
- @options = options
52
- @preferences = get_preferences
64
+ def initialize(options = [], load_config = true)
65
+ @config = self.class.config
66
+ @preference_file_loaded = false
67
+ @options = options
68
+ load_preferences if load_config
69
+ set_preferences(options)
70
+ @file = StandupMD::File.find_by_date(@config.date)
71
+ @file.load
72
+ @entry = set_entry(@file)
53
73
  end
54
74
 
55
75
  ##
56
- # Sets up an instance of +StandupMD+ and passes all user preferences.
57
- #
58
- # @return [StandupMD]
59
- def standup
60
- cf = File.file?(PREFERENCE_FILE) ? PREFERENCE_FILE : nil
61
- @standup ||= ::StandupMD.new(cf) do |s|
62
- if s.config.any?
63
- echo 'Config options:'
64
- s.config.each { |k, v| echo " #{k} = #{v}" }
65
- end
66
- echo 'Runtime options:' if preferences.any?
67
- preferences.each do |k, v|
68
- echo " #{k} = #{v}"
69
- s.send("#{k}=", v)
70
- end
71
- end.load
72
- end
73
-
74
- ##
75
- # Tries to determine the editor, first by checking if the user has one set
76
- # in their preferences. If not, the +VISUAL+ and +EDITOR+ environmental
77
- # variables are checked. If none of the above are set, defaults to +vim+.
78
- #
79
- # @return [String] The editor
80
- def editor
81
- @editor ||=
82
- if standup.config.key?('editor')
83
- echo "Editor set to [#{standup.config['editor']}] via preferences"
84
- standup.config['editor']
85
- elsif ENV['VISUAL']
86
- echo "Editor set to [#{ENV['VISUAL']}] (ENV['VISUAL'])"
87
- ENV['VISUAL']
88
- elsif ENV['EDITOR']
89
- echo "Editor set to [#{ENV['EDITOR']}] (ENV['EDITOR'])"
90
- ENV['EDITOR']
91
- else
92
- echo "Editor set to [vim] (default)"
93
- 'vim'
94
- end
95
- end
96
-
97
- ##
98
- # Prints all entries to the command line.
99
- #
100
- # @return [nil]
101
- def print_all_entries
102
- echo 'Display all entries'
103
- unless json?
104
- standup.all_entries.keys.reverse.each do |head|
105
- print_entry(head, standup.all_entries[head])
106
- end
107
- return
108
- end
109
- echo ' ...as json'
110
- puts standup.all_entries.to_json
111
- end
112
-
113
- ##
114
- # Prints the current entry to the command line.
76
+ # Load the preference file.
115
77
  #
116
78
  # @return [nil]
117
- def print_current_entry
118
- echo 'Print current entry'
119
- unless json?
120
- print_entry(standup.header, standup.current_entry)
121
- return
79
+ def load_preferences
80
+ if ::File.exist?(@config.preference_file)
81
+ ::StandupMD.load_config_file(@config.preference_file)
82
+ @preference_file_loaded = true
83
+ else
84
+ echo "Preference file #{@config.preference_file} does not exist."
122
85
  end
123
- echo ' ...as json'
124
- entry = {standup.header => standup.current_entry}.to_json
125
- puts entry
126
86
  end
127
87
 
128
88
  ##
129
- # Appends entries passed at runtime to existing previous entries.
89
+ # Has the preference file been loaded?
130
90
  #
131
- # @return [Hash]
132
- def append_to_previous_entry_tasks
133
- echo 'Appending previous entry tasks'
134
- additions = preferences.delete('previous_entry_tasks')
135
- standup.previous_entry_tasks.concat(additions)
91
+ # @return boolean
92
+ def preference_file_loaded?
93
+ @preference_file_loaded
136
94
  end
137
95
 
138
96
  ##
139
97
  # Opens the file in an editor. Abandons the script.
98
+ #
99
+ # @return [nil]
140
100
  def edit
141
- echo "Opening file in #{editor}"
142
- exec("#{editor} #{standup.file}")
101
+ echo "Opening file in #{@config.editor}"
102
+ exec("#{@config.editor} #{file.name}")
143
103
  end
144
104
 
145
105
  ##
@@ -147,159 +107,16 @@ class StandupMD
147
107
  #
148
108
  # @return [Boolean] true if file was written
149
109
  def write_file
150
- echo 'Writing file'
151
- standup.write
152
- end
153
-
154
- ##
155
- # Should current entry be printed? If true, disables editing.
156
- #
157
- # @return [Boolean] Default is false
158
- def print_current_entry?
159
- @print_current_entry
160
- end
161
-
162
- ##
163
- # If printing an entry, should it be printed as json?
164
- #
165
- # @return [Boolean] Default is false
166
- def json?
167
- @json
168
- end
169
-
170
- ##
171
- # Should all entries be printed? If true, disables editing.
172
- #
173
- # @return [Boolean] Default is false
174
- def print_all_entries?
175
- @print_all_entries
110
+ echo "Writing file #{file.name}"
111
+ file.write
176
112
  end
177
113
 
178
114
  ##
179
- # Should debug info be printed?
180
- #
181
- # @return [Boolean] Default is false
182
- def verbose?
183
- @verbose
184
- end
185
-
186
- ##
187
- # Should the file be written?
188
- #
189
- # @return [Boolean] Default is true
190
- def write?
191
- @write
192
- end
193
-
194
- ##
195
- # Should the standup file be opened in the editor?
196
- #
197
- # @return [Boolean] Default is true
198
- def edit?
199
- @edit
200
- end
201
-
202
- ##
203
- # Should `previous_entry_tasks` be appended? If false,
204
- # +previous_entry_tasks+ will be overwritten.
205
- #
206
- # @return [Boolean] Default is true
207
- def append_previous?
208
- @append_previous
209
- end
210
-
211
- ##
212
- # Did the user pass +previous_entry_tasks+, and should we append?
213
- #
214
- # @return [Boolean]
215
- def should_append?
216
- preferences.key?('previous_entry_tasks') && append_previous?
217
- end
218
-
219
- ##
220
- # Prints output if +verbose+ is true.
115
+ # Quick access to Cli.echo.
221
116
  #
222
117
  # @return [nil]
223
118
  def echo(msg)
224
- puts msg if verbose?
225
- end
226
-
227
- private
228
-
229
- ##
230
- # Prints entries to the command line as markdown.
231
- def print_entry(head, s_heads) # :nodoc:
232
- puts '#' * standup.header_depth + ' ' + head
233
- s_heads.each do |s_head, tasks|
234
- puts '#' * standup.sub_header_depth + ' ' + s_head
235
- tasks.each { |task| puts standup.bullet_character + ' ' + task }
236
- end
237
- puts
238
- end
239
-
240
- ##
241
- # Parses options passed at runtime and concatenates them with the options in
242
- # the user's preferences file. Reveal source to see options.
243
- #
244
- # @return [Hash]
245
- def get_preferences # :nodoc:
246
- prefs = {}
247
-
248
- OptionParser.new do |opts|
249
- opts.banner = 'The Standup Doctor'
250
- opts.version = ::StandupMD::VERSION
251
- opts.on('--current-entry-tasks=ARRAY', Array, "List of current entry's tasks") do |v|
252
- prefs['current_entry_tasks'] = v
253
- end
254
- opts.on('--previous-entry-tasks=ARRAY', Array, "List of precious entry's tasks") do |v|
255
- prefs['previous_entry_tasks'] = v
256
- end
257
- opts.on('--impediments=ARRAY', Array, 'List of impediments for current entry') do |v|
258
- prefs['impediments'] = v
259
- end
260
- opts.on('--notes=ARRAY', Array, 'List of notes for current entry') do |v|
261
- prefs['notes'] = v
262
- end
263
- opts.on('--sub-header-order=ARRAY', Array, 'The order of the sub-headers when writing the file') do |v|
264
- prefs['sub_header_order'] = v
265
- end
266
- opts.on('--[no-]append-previous', 'Append previous tasks? Default is true') do |v|
267
- @append_previous = v
268
- end
269
- opts.on('-f', '--file-name-format=STRING', 'Date-formattable string to use for standup file name') do |v|
270
- prefs['file_name_format'] = v
271
- end
272
- opts.on('-e', '--editor=EDITOR', 'Editor to use for opening standup files') do |v|
273
- @editor = v
274
- end
275
- opts.on('-d', '--directory=DIRECTORY', 'The directories where standup files are located') do |v|
276
- prefs['directory'] = v
277
- end
278
- opts.on('--[no-]write', "Write current entry if it doesn't exist. Default is true") do |v|
279
- @write = v
280
- end
281
- opts.on('--[no-]edit', 'Open the file in the editor. Default is true') do |v|
282
- @edit = v
283
- end
284
- opts.on('-j', '--[no-]json', 'Print output as formatted json. Default is false.') do |v|
285
- @json = v
286
- end
287
- opts.on('-v', '--[no-]verbose', 'Verbose output. Default is false.') do |v|
288
- @verbose = v
289
- end
290
- opts.on('-c', '--current', 'Print current entry. Disables editing and writing') do |v|
291
- @print_current_entry = v
292
- @edit = false
293
- @write = false
294
- end
295
- opts.on('-a', '--all', 'Print all previous entries. Disables editing and writing') do |v|
296
- @print_all_entries = v
297
- @edit = false
298
- @write = false
299
- end
300
- end.parse!(options)
301
-
302
- prefs
119
+ self.class.echo(msg)
303
120
  end
304
121
  end
305
122
  end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StandupMD
4
+ class Cli
5
+
6
+ ##
7
+ # Module responsible for reading and writing standup files.
8
+ module Helpers
9
+
10
+ ##
11
+ # Print an entry to the command line.
12
+ #
13
+ # @param [StandupMD::Entry] entry
14
+ #
15
+ # @return [nil]
16
+ def print(entry)
17
+ if entry.nil?
18
+ puts "No record found for #{StandupMD.config.cli.date}"
19
+ return
20
+ end
21
+ puts '#' * StandupMD.config.file.header_depth + ' ' + entry.date.strftime(StandupMD.config.file.header_date_format)
22
+ StandupMD.config.file.sub_header_order.each do |attr|
23
+ tasks = entry.send(attr)
24
+ next if !tasks || tasks.empty?
25
+ puts '#' * StandupMD.config.file.sub_header_depth + ' ' + StandupMD.config.file.send("#{attr}_header").capitalize
26
+ tasks.each { |task| puts StandupMD.config.file.bullet_character + ' ' + task }
27
+ end
28
+ puts
29
+ end
30
+
31
+ private
32
+
33
+ ##
34
+ # Parses options passed at runtime and concatenates them with the options
35
+ # in the user's preferences file. Reveal source to see options.
36
+ #
37
+ # @return [Hash]
38
+ def set_preferences(options)
39
+ OptionParser.new do |opts|
40
+ opts.banner = 'The Standup Doctor'
41
+ opts.version = "[StandupMD] #{::StandupMD::VERSION}"
42
+ opts.on(
43
+ '--current ARRAY', Array,
44
+ "List of current entry's tasks"
45
+ ) { |v| StandupMD.config.entry.current = v }
46
+
47
+ opts.on(
48
+ '--previous ARRAY', Array,
49
+ "List of precious entry's tasks"
50
+ ) { |v| StandupMD.config.entry.previous = v }
51
+
52
+ opts.on(
53
+ '--impediments ARRAY', Array,
54
+ 'List of impediments for current entry'
55
+ ) { |v| StandupMD.config.entry.impediments = v }
56
+
57
+ opts.on(
58
+ '--notes ARRAY', Array,
59
+ 'List of notes for current entry'
60
+ ) { |v| StandupMD.config.entry.notes = v }
61
+
62
+ opts.on(
63
+ '--sub-header-order ARRAY', Array,
64
+ 'The order of the sub-headers when writing the file'
65
+ ) { |v| StandupMD.config.file.sub_header_order = v }
66
+
67
+ opts.on(
68
+ '-f', '--file-name-format STRING',
69
+ 'Date-formattable string to use for standup file name'
70
+ ) { |v| StandupMD.config.file.name_format = v }
71
+
72
+ opts.on(
73
+ '-E', '--editor EDITOR',
74
+ 'Editor to use for opening standup files'
75
+ ) { |v| StandupMD.config.cli.editor = v }
76
+
77
+ opts.on(
78
+ '-d', '--directory DIRECTORY',
79
+ 'The directories where standup files are located'
80
+ ) { |v| StandupMD.config.file.directory = v }
81
+
82
+ opts.on(
83
+ '-w', '--[no-]write',
84
+ "Write current entry if it doesn't exist. Default is true"
85
+ ) { |v| StandupMD.config.cli.write = v }
86
+
87
+ opts.on(
88
+ '-a', '--[no-]auto-fill-previous',
89
+ "Auto-generate 'previous' tasks for new entries. Default is true"
90
+ ) { |v| StandupMD.config.cli.auto_fill_previous = v }
91
+
92
+ opts.on(
93
+ '-e', '--[no-]edit',
94
+ 'Open the file in the editor. Default is true'
95
+ ) { |v| StandupMD.config.cli.edit = v }
96
+
97
+ opts.on(
98
+ '-v', '--[no-]verbose',
99
+ 'Verbose output. Default is false.'
100
+ ) { |v| StandupMD.config.cli.verbose = v }
101
+
102
+ opts.on(
103
+ '-p', '--print [DATE]',
104
+ 'Print current entry.',
105
+ 'If DATE is passed, will print entry for DATE, if it exists.',
106
+ 'DATE must be in the same format as file-name-format',
107
+ ) do |v|
108
+ StandupMD.config.cli.print = true
109
+ StandupMD.config.cli.date =
110
+ v.nil? ? Date.today : Date.strptime(v, StandupMD.config.file.header_date_format)
111
+ end
112
+ end.parse!(options)
113
+ end
114
+
115
+ ##
116
+ # The entry for today.
117
+ #
118
+ # @return [StandupMD::Entry]
119
+ def set_entry(file)
120
+ entry = file.entries.find(StandupMD.config.cli.date)
121
+ if entry.nil? && StandupMD.config.cli.date == Date.today
122
+ previous_entry = set_previous_entry(file)
123
+ entry = StandupMD::Entry.new(
124
+ StandupMD.config.cli.date,
125
+ StandupMD.config.entry.current,
126
+ previous_entry,
127
+ StandupMD.config.entry.impediments,
128
+ StandupMD.config.entry.notes
129
+ )
130
+ file.entries << entry
131
+ end
132
+ entry
133
+ end
134
+
135
+ ##
136
+ # The "previous" entries.
137
+ #
138
+ # @return [Array]
139
+ def set_previous_entry(file)
140
+ return [] unless StandupMD.config.cli.auto_fill_previous
141
+ return prev_entry(prev_file.load.entries) if file.new? && prev_file
142
+ prev_entry(file.entries)
143
+ end
144
+
145
+ ##
146
+ # The previous entry.
147
+ #
148
+ # @param [StandupMD::EntryList] entries
149
+ #
150
+ # @return [StandupMD::Entry]
151
+ def prev_entry(entries)
152
+ return [] if entries.empty?
153
+ entries.last.current
154
+ end
155
+
156
+ ##
157
+ # The previous month's file.
158
+ #
159
+ # @return [StandupMD::File]
160
+ def prev_file
161
+ StandupMD::File.find_by_date(Date.today.prev_month)
162
+ end
163
+ end
164
+ end
165
+ end