doing 2.1.40 → 2.1.41

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.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/CHANGELOG.md +22 -0
  4. data/Gemfile.lock +1 -1
  5. data/Rakefile +4 -4
  6. data/bin/commands/changes.rb +1 -1
  7. data/bin/commands/tag_dir.rb +49 -15
  8. data/{Dockerfile → docker/Dockerfile} +3 -1
  9. data/{Dockerfile-2.6 → docker/Dockerfile-2.6} +2 -2
  10. data/{Dockerfile-2.7 → docker/Dockerfile-2.7} +2 -2
  11. data/{Dockerfile-3.0 → docker/Dockerfile-3.0} +2 -2
  12. data/{bash_profile → docker/bash_profile} +0 -0
  13. data/{inputrc → docker/inputrc} +0 -0
  14. data/docs/doc/Array.html +84 -2
  15. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  16. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  17. data/docs/doc/BooleanTermParser/Query.html +1 -1
  18. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  19. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  20. data/docs/doc/BooleanTermParser.html +1 -1
  21. data/docs/doc/Doing/ArrayNestedHash.html +198 -0
  22. data/docs/doc/Doing/ArrayTags.html +424 -0
  23. data/docs/doc/Doing/CSVExport.html +266 -0
  24. data/docs/doc/Doing/CalendarImport.html +232 -0
  25. data/docs/doc/Doing/Change.html +617 -0
  26. data/docs/doc/Doing/Changes.html +468 -0
  27. data/docs/doc/Doing/ChronifyArray.html +347 -0
  28. data/docs/doc/Doing/ChronifyNumeric.html +271 -0
  29. data/docs/doc/Doing/ChronifyString.html +682 -0
  30. data/docs/doc/Doing/Color.html +2 -2
  31. data/docs/doc/Doing/Completion/BashCompletions.html +445 -0
  32. data/docs/doc/Doing/Completion/FishCompletions.html +445 -0
  33. data/docs/doc/Doing/Completion/StringUtils.html +229 -0
  34. data/docs/doc/Doing/Completion/ZshCompletions.html +445 -0
  35. data/docs/doc/Doing/Completion.html +17 -3
  36. data/docs/doc/Doing/Configuration.html +1 -1
  37. data/docs/doc/Doing/DayOneRenderer.html +383 -0
  38. data/docs/doc/Doing/DayoneExport.html +290 -0
  39. data/docs/doc/Doing/DoingImport.html +391 -0
  40. data/docs/doc/Doing/Entry.html +381 -0
  41. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  42. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  43. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  44. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  45. data/docs/doc/Doing/Errors/HistoryLimitError.html +1 -1
  46. data/docs/doc/Doing/Errors/InvalidPlugin.html +1 -1
  47. data/docs/doc/Doing/Errors/MissingBackupFile.html +1 -1
  48. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  49. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  50. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  51. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  52. data/docs/doc/Doing/Errors.html +1 -1
  53. data/docs/doc/Doing/HTMLExport.html +256 -0
  54. data/docs/doc/Doing/Hooks.html +1 -1
  55. data/docs/doc/Doing/Item.html +47 -3
  56. data/docs/doc/Doing/ItemDates.html +564 -0
  57. data/docs/doc/Doing/ItemQuery.html +614 -0
  58. data/docs/doc/Doing/ItemState.html +387 -0
  59. data/docs/doc/Doing/ItemTags.html +498 -0
  60. data/docs/doc/Doing/Items.html +460 -11
  61. data/docs/doc/Doing/JSONExport.html +222 -0
  62. data/docs/doc/Doing/Logger.html +1 -1
  63. data/docs/doc/Doing/MarkdownExport.html +266 -0
  64. data/docs/doc/Doing/MarkdownRenderer.html +383 -0
  65. data/docs/doc/Doing/Note.html +16 -3
  66. data/docs/doc/Doing/Pager.html +1 -1
  67. data/docs/doc/Doing/Plugins.html +1 -1
  68. data/docs/doc/Doing/Prompt.html +31 -682
  69. data/docs/doc/Doing/PromptChoose.html +484 -0
  70. data/docs/doc/Doing/PromptFZF.html +391 -0
  71. data/docs/doc/Doing/PromptInput.html +572 -0
  72. data/docs/doc/Doing/PromptSTD.html +293 -0
  73. data/docs/doc/Doing/PromptYN.html +237 -0
  74. data/docs/doc/Doing/Section.html +58 -2
  75. data/docs/doc/Doing/StringHighlight.html +533 -0
  76. data/docs/doc/Doing/StringNormalize.html +929 -0
  77. data/docs/doc/Doing/StringQuery.html +725 -0
  78. data/docs/doc/Doing/StringTags.html +884 -0
  79. data/docs/doc/Doing/StringTransform.html +565 -0
  80. data/docs/doc/Doing/StringTruncate.html +448 -0
  81. data/docs/doc/Doing/StringURL.html +409 -0
  82. data/docs/doc/Doing/SymbolNormalize.html +341 -0
  83. data/docs/doc/Doing/TaskPaperExport.html +222 -0
  84. data/docs/doc/Doing/TemplateExport.html +249 -0
  85. data/docs/doc/Doing/TemplateString.html +101 -2
  86. data/docs/doc/Doing/TimingImport.html +285 -0
  87. data/docs/doc/Doing/Types.html +1 -1
  88. data/docs/doc/Doing/Util/Backup.html +9 -7
  89. data/docs/doc/Doing/Util.html +2 -2
  90. data/docs/doc/Doing/Version.html +523 -0
  91. data/docs/doc/Doing/WWID/WWIDUtil.html +510 -0
  92. data/docs/doc/Doing/WWID.html +4377 -217
  93. data/docs/doc/Doing/WWIDDisplay.html +865 -0
  94. data/docs/doc/Doing/WWIDEditor.html +466 -0
  95. data/docs/doc/Doing/WWIDFileTools.html +359 -0
  96. data/docs/doc/Doing/WWIDFilter.html +466 -0
  97. data/docs/doc/Doing/WWIDGuess.html +299 -0
  98. data/docs/doc/Doing/WWIDInteractive.html +752 -0
  99. data/docs/doc/Doing/WWIDModify.html +1078 -0
  100. data/docs/doc/Doing/WWIDTags.html +302 -0
  101. data/docs/doc/Doing/WWIDTimers.html +359 -0
  102. data/docs/doc/Doing/WWIDUtil.html +510 -0
  103. data/docs/doc/Doing.html +9 -6
  104. data/docs/doc/FalseClass.html +1 -1
  105. data/docs/doc/GLI/Commands/Help.html +1 -1
  106. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  107. data/docs/doc/GLI/Commands.html +1 -1
  108. data/docs/doc/GLI.html +1 -1
  109. data/docs/doc/Hash.html +1 -1
  110. data/docs/doc/Numeric.html +23 -78
  111. data/docs/doc/Object.html +1 -1
  112. data/docs/doc/PhraseParser/Operator.html +1 -1
  113. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  114. data/docs/doc/PhraseParser/Query.html +1 -1
  115. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  116. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  117. data/docs/doc/PhraseParser/TermClause.html +1 -1
  118. data/docs/doc/PhraseParser.html +1 -1
  119. data/docs/doc/Status.html +1 -1
  120. data/docs/doc/String.html +58 -633
  121. data/docs/doc/Symbol.html +9 -224
  122. data/docs/doc/Time.html +119 -13
  123. data/docs/doc/TrueClass.html +1 -1
  124. data/docs/doc/_index.html +324 -8
  125. data/docs/doc/class_list.html +1 -1
  126. data/docs/doc/file.README.html +1 -1
  127. data/docs/doc/index.html +1 -1
  128. data/docs/doc/method_list.html +2326 -542
  129. data/docs/doc/top-level-namespace.html +2 -2
  130. data/doing.rdoc +13 -3
  131. data/lib/completion/_doing.zsh +1 -1
  132. data/lib/completion/doing.bash +2 -2
  133. data/lib/completion/doing.fish +3 -1
  134. data/lib/doing/array/array.rb +16 -12
  135. data/lib/doing/array/nested_hash.rb +1 -1
  136. data/lib/doing/array/tags.rb +6 -5
  137. data/lib/doing/changelog/changelog.rb +6 -0
  138. data/lib/doing/chronify/array.rb +1 -3
  139. data/lib/doing/chronify/chronify.rb +12 -0
  140. data/lib/doing/chronify/numeric.rb +3 -2
  141. data/lib/doing/chronify/string.rb +1 -1
  142. data/lib/doing/completion/completion_string.rb +25 -0
  143. data/lib/doing/completion.rb +1 -1
  144. data/lib/doing/good.rb +8 -0
  145. data/lib/doing/item/dates.rb +1 -1
  146. data/lib/doing/{item.rb → item/item.rb} +10 -5
  147. data/lib/doing/item/query.rb +1 -1
  148. data/lib/doing/item/state.rb +1 -1
  149. data/lib/doing/item/tags.rb +1 -1
  150. data/lib/doing/items/filter.rb +67 -0
  151. data/lib/doing/items/items.rb +57 -0
  152. data/lib/doing/items/modify.rb +36 -0
  153. data/lib/doing/items/sections.rb +83 -0
  154. data/lib/doing/items/util.rb +74 -0
  155. data/lib/doing/normalize.rb +10 -2
  156. data/lib/doing/plugins/export/markdown_export.rb +4 -2
  157. data/lib/doing/plugins/import/doing_import.rb +1 -1
  158. data/lib/doing/prompt/choose.rb +118 -0
  159. data/lib/doing/prompt/fzf.rb +84 -0
  160. data/lib/doing/prompt/input.rb +129 -0
  161. data/lib/doing/prompt/prompt.rb +41 -0
  162. data/lib/doing/prompt/std.rb +32 -0
  163. data/lib/doing/prompt/yn.rb +64 -0
  164. data/lib/doing/section.rb +4 -0
  165. data/lib/doing/string/highlight.rb +1 -1
  166. data/lib/doing/string/query.rb +1 -1
  167. data/lib/doing/string/string.rb +18 -7
  168. data/lib/doing/string/tags.rb +14 -3
  169. data/lib/doing/string/transform.rb +1 -1
  170. data/lib/doing/string/truncate.rb +1 -1
  171. data/lib/doing/string/url.rb +1 -1
  172. data/lib/doing/time.rb +19 -1
  173. data/lib/doing/util_backup.rb +2 -2
  174. data/lib/doing/version.rb +1 -1
  175. data/lib/doing/wwid/display.rb +357 -360
  176. data/lib/doing/wwid/editor.rb +173 -176
  177. data/lib/doing/wwid/filetools.rb +156 -159
  178. data/lib/doing/wwid/filter.rb +191 -183
  179. data/lib/doing/wwid/guess.rb +58 -60
  180. data/lib/doing/wwid/interactive.rb +332 -330
  181. data/lib/doing/wwid/modify.rb +509 -512
  182. data/lib/doing/wwid/tags.rb +38 -41
  183. data/lib/doing/wwid/timers.rb +293 -296
  184. data/lib/doing/{wwid.rb → wwid/wwid.rb} +32 -23
  185. data/lib/doing/wwid/wwidutil.rb +79 -82
  186. data/lib/doing.rb +5 -5
  187. data/lib/helpers/threaded_tests.rb +1 -0
  188. metadata +76 -14
  189. data/lib/doing/changelog.rb +0 -6
  190. data/lib/doing/completion/string.rb +0 -17
  191. data/lib/doing/items.rb +0 -221
  192. data/lib/doing/prompt.rb +0 -330
@@ -1,186 +1,183 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Doing
4
- # File methods for WWID class
5
4
  class WWID
6
- module FileTools
7
- ##
8
- ## Initializes the doing file.
9
- ##
10
- ## @param path [String] Override path to a doing file, optional
11
- ##
12
- def init_doing_file(path = nil)
13
- @doing_file = File.expand_path(Doing.setting('doing_file'))
14
-
15
- if path.nil?
16
- create(@doing_file) unless File.exist?(@doing_file)
17
- input = IO.read(@doing_file)
18
- input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
19
- logger.debug('Read:', "read file #{@doing_file}")
20
- elsif File.exist?(File.expand_path(path)) && File.file?(File.expand_path(path)) && File.stat(File.expand_path(path)).size.positive?
21
- @doing_file = File.expand_path(path)
22
- input = IO.read(File.expand_path(path))
23
- input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
24
- logger.debug('Read:', "read file #{File.expand_path(path)}")
25
- elsif path.length < 256
26
- @doing_file = File.expand_path(path)
27
- create(path)
28
- input = IO.read(File.expand_path(path))
29
- input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
30
- logger.debug('Read:', "read file #{File.expand_path(path)}")
31
- end
32
-
33
- @other_content_top = []
34
- @other_content_bottom = []
35
-
36
- section = nil
37
- lines = input.split(/[\n\r]/)
38
-
39
- lines.each do |line|
40
- next if line =~ /^\s*$/
41
-
42
- if line =~ /^(\S[\S ]+):\s*(@\S+\s*)*$/
43
- section = Regexp.last_match(1)
44
- @content.add_section(Section.new(section, original: line), log: false)
45
- elsif line =~ /^\s*- (\d{4}-\d\d-\d\d \d\d:\d\d) \| (.*)/
46
- if section.nil?
47
- section = 'Uncategorized'
48
- @content.add_section(Section.new(section, original: 'Uncategorized:'), log: false)
49
- end
50
-
51
- date = Regexp.last_match(1).strip
52
- title = Regexp.last_match(2).strip
53
- item = Item.new(date, title, section)
54
- @content.push(item)
55
- elsif @content.count.zero?
56
- # if content[section].items.length - 1 == current
57
- @other_content_top.push(line)
58
- elsif line =~ /^\S/
59
- @other_content_bottom.push(line)
60
- else
61
- prev_item = @content.last
62
- prev_item.note = Note.new unless prev_item.note
63
-
64
- prev_item.note.add(line)
65
- # end
66
- end
67
- end
68
-
69
- Hooks.trigger :post_read, self
70
- @initial_content = @content.clone
5
+ ##
6
+ ## Initializes the doing file.
7
+ ##
8
+ ## @param path [String] Override path to a doing file, optional
9
+ ##
10
+ def init_doing_file(path = nil)
11
+ @doing_file = File.expand_path(Doing.setting('doing_file'))
12
+
13
+ if path.nil?
14
+ create(@doing_file) unless File.exist?(@doing_file)
15
+ input = IO.read(@doing_file)
16
+ input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
17
+ logger.debug('Read:', "read file #{@doing_file}")
18
+ elsif File.exist?(File.expand_path(path)) && File.file?(File.expand_path(path)) && File.stat(File.expand_path(path)).size.positive?
19
+ @doing_file = File.expand_path(path)
20
+ input = IO.read(File.expand_path(path))
21
+ input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
22
+ logger.debug('Read:', "read file #{File.expand_path(path)}")
23
+ elsif path.length < 256
24
+ @doing_file = File.expand_path(path)
25
+ create(path)
26
+ input = IO.read(File.expand_path(path))
27
+ input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
28
+ logger.debug('Read:', "read file #{File.expand_path(path)}")
71
29
  end
72
30
 
73
- ##
74
- ## Create a new doing file
75
- ##
76
- def create(filename = nil)
77
- filename = @doing_file if filename.nil?
78
- return if File.exist?(filename) && File.stat(filename).size.positive?
31
+ @other_content_top = []
32
+ @other_content_bottom = []
79
33
 
80
- FileUtils.mkdir_p(File.dirname(filename)) unless File.directory?(File.dirname(filename))
34
+ section = nil
35
+ lines = input.split(/[\n\r]/)
81
36
 
82
- File.open(filename, 'w+') do |f|
83
- f.puts "#{Doing.setting('current_section')}:"
84
- end
85
- end
37
+ lines.each do |line|
38
+ next if line =~ /^\s*$/
86
39
 
87
- ##
88
- ## Write content to file or STDOUT
89
- ##
90
- ## @param file [String] The filepath to write to
91
- ##
92
- def write(file = nil, backup: true)
93
- Hooks.trigger :pre_write, self, file
94
- output = combined_content
95
- if file.nil?
96
- $stdout.puts output
40
+ if line =~ /^(\S[\S ]+):\s*(@[\w\-_.]+\s*)*$/
41
+ section = Regexp.last_match(1)
42
+ @content.add_section(Section.new(section, original: line), log: false)
43
+ elsif line =~ /^\s*- (\d{4}-\d\d-\d\d \d\d:\d\d) \| (.*)/
44
+ if section.nil?
45
+ section = 'Uncategorized'
46
+ @content.add_section(Section.new(section, original: 'Uncategorized:'), log: false)
47
+ end
48
+
49
+ date = Regexp.last_match(1).strip
50
+ title = Regexp.last_match(2).strip
51
+ item = Item.new(date, title, section)
52
+ @content.push(item)
53
+ elsif @content.count.zero?
54
+ # if content[section].items.length - 1 == current
55
+ @other_content_top.push(line)
56
+ elsif line =~ /^\S/
57
+ @other_content_bottom.push(line)
97
58
  else
98
- Util.write_to_file(file, output, backup: backup)
99
- run_after if Doing.setting('run_after')
59
+ prev_item = @content.last
60
+ prev_item.note = Note.new unless prev_item.note
61
+
62
+ prev_item.note.add(line)
63
+ # end
100
64
  end
101
65
  end
102
66
 
103
- ##
104
- ## Rename doing file with date and start fresh one
105
- ##
106
- def rotate(opt)
107
- opt ||= {}
108
- keep = opt[:keep] || 0
109
- tags = []
110
- tags.concat(opt[:tag].split(/ *, */).map { |t| t.sub(/^@/, '').strip }) if opt[:tag]
111
- bool = opt[:bool] || :and
112
- sect = opt[:section] !~ /^all$/i ? guess_section(opt[:section]) : 'all'
113
-
114
- section = guess_section(sect)
115
-
116
- section_items = @content.in_section(section)
117
- max = section_items.count - keep.to_i
118
-
119
- counter = 0
120
- new_content = Items.new
121
-
122
- section_items.each do |item|
123
- break if counter >= max
124
- if opt[:before]
125
- time_string = opt[:before]
126
- cutoff = time_string.chronify(guess: :begin)
127
- end
67
+ Hooks.trigger :post_read, self
68
+ @initial_content = @content.clone
69
+ end
128
70
 
129
- unless ((!tags.empty? && !item.tags?(tags, bool)) || (opt[:search] && !item.search(opt[:search].to_s)) || (opt[:before] && item.date >= cutoff))
130
- new_item = @content.delete(item)
131
- Hooks.trigger :post_entry_removed, self, item.clone
132
- raise DoingRuntimeError, "Error deleting item: #{item}" if new_item.nil?
71
+ ##
72
+ ## Create a new doing file
73
+ ##
74
+ def create(filename = nil)
75
+ filename = @doing_file if filename.nil?
76
+ return if File.exist?(filename) && File.stat(filename).size.positive?
133
77
 
134
- new_content.add_section(new_item.section, log: false)
135
- new_content.push(new_item)
136
- counter += 1
137
- end
138
- end
78
+ FileUtils.mkdir_p(File.dirname(filename)) unless File.directory?(File.dirname(filename))
139
79
 
140
- if counter.positive?
141
- logger.count(:rotated,
142
- level: :info,
143
- count: counter,
144
- message: "Rotated %count %items")
145
- else
146
- logger.info('Skipped:', 'No items were rotated')
80
+ File.open(filename, 'w+') do |f|
81
+ f.puts "#{Doing.setting('current_section')}:"
82
+ end
83
+ end
84
+
85
+ ##
86
+ ## Write content to file or STDOUT
87
+ ##
88
+ ## @param file [String] The filepath to write to
89
+ ##
90
+ def write(file = nil, backup: true)
91
+ Hooks.trigger :pre_write, self, file
92
+ output = combined_content
93
+ if file.nil?
94
+ $stdout.puts output
95
+ else
96
+ Util.write_to_file(file, output, backup: backup)
97
+ run_after if Doing.setting('run_after')
98
+ end
99
+ end
100
+
101
+ ##
102
+ ## Rename doing file with date and start fresh one
103
+ ##
104
+ def rotate(opt)
105
+ opt ||= {}
106
+ keep = opt[:keep] || 0
107
+ tags = []
108
+ tags.concat(opt[:tag].split(/ *, */).map { |t| t.sub(/^@/, '').strip }) if opt[:tag]
109
+ bool = opt[:bool] || :and
110
+ sect = opt[:section] !~ /^all$/i ? guess_section(opt[:section]) : 'all'
111
+
112
+ section = guess_section(sect)
113
+
114
+ section_items = @content.in_section(section)
115
+ max = section_items.count - keep.to_i
116
+
117
+ counter = 0
118
+ new_content = Items.new
119
+
120
+ section_items.each do |item|
121
+ break if counter >= max
122
+ if opt[:before]
123
+ time_string = opt[:before]
124
+ cutoff = time_string.chronify(guess: :begin)
147
125
  end
148
126
 
149
- write(@doing_file)
127
+ unless ((!tags.empty? && !item.tags?(tags, bool)) || (opt[:search] && !item.search(opt[:search].to_s)) || (opt[:before] && item.date >= cutoff))
128
+ new_item = @content.delete(item)
129
+ Hooks.trigger :post_entry_removed, self, item.clone
130
+ raise DoingRuntimeError, "Error deleting item: #{item}" if new_item.nil?
150
131
 
151
- file = @doing_file.sub(/(\.\w+)$/, "_#{Time.now.strftime('%Y-%m-%d')}\\1")
152
- if File.exist?(file)
153
- init_doing_file(file)
154
- @content.concat(new_content).uniq!
155
- logger.warn('File update:', "added entries to existing file: #{file}")
156
- else
157
- @content = new_content
158
- logger.warn('File update:', "created new file: #{file}")
132
+ new_content.add_section(new_item.section, log: false)
133
+ new_content.push(new_item)
134
+ counter += 1
159
135
  end
136
+ end
160
137
 
161
- write(file, backup: false)
138
+ if counter.positive?
139
+ logger.count(:rotated,
140
+ level: :info,
141
+ count: counter,
142
+ message: "Rotated %count %items")
143
+ else
144
+ logger.info('Skipped:', 'No items were rotated')
162
145
  end
163
146
 
164
- private
165
-
166
- ##
167
- ## Wraps doing file content with additional
168
- ## header/footer content
169
- ##
170
- ## @return [String] concatenated content
171
- ## @api private
172
- def combined_content
173
- output = @other_content_top ? "#{@other_content_top.join("\n")}\n" : ''
174
- was_color = Color.coloring?
175
- Color.coloring = false
176
- @content.dedup!(match_section: true)
177
- output += @content.to_s
178
- output += @other_content_bottom.join("\n") unless @other_content_bottom.nil?
179
- # Just strip all ANSI colors from the content before writing to doing file
180
- Color.coloring = was_color
181
-
182
- output.uncolor
147
+ write(@doing_file)
148
+
149
+ file = @doing_file.sub(/(\.\w+)$/, "_#{Time.now.strftime('%Y-%m-%d')}\\1")
150
+ if File.exist?(file)
151
+ init_doing_file(file)
152
+ @content.concat(new_content).uniq!
153
+ logger.warn('File update:', "added entries to existing file: #{file}")
154
+ else
155
+ @content = new_content
156
+ logger.warn('File update:', "created new file: #{file}")
183
157
  end
158
+
159
+ write(file, backup: false)
160
+ end
161
+
162
+ private
163
+
164
+ ##
165
+ ## Wraps doing file content with additional
166
+ ## header/footer content
167
+ ##
168
+ ## @return [String] concatenated content
169
+ ## @api private
170
+ def combined_content
171
+ output = @other_content_top ? "#{@other_content_top.join("\n")}\n" : ''
172
+ was_color = Color.coloring?
173
+ Color.coloring = false
174
+ @content.dedup!(match_section: true)
175
+ output += @content.to_s
176
+ output += @other_content_bottom.join("\n") unless @other_content_bottom.nil?
177
+ # Just strip all ANSI colors from the content before writing to doing file
178
+ Color.coloring = was_color
179
+
180
+ output.uncolor
184
181
  end
185
182
  end
186
183
  end