doing 2.0.24 → 2.0.25

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.
@@ -90,21 +90,56 @@ module Doing
90
90
  }
91
91
 
92
92
  def initialize(file = nil, options: {})
93
- if file
94
- cf = File.expand_path(file)
95
- # raise MissingConfigFile, "Config not found (#{cf})" unless File.exist?(cf)
93
+ @config_file = file.nil? ? default_config_file : File.expand_path(file)
96
94
 
97
- @config_file = cf
95
+ @settings = configure(options)
96
+ end
97
+
98
+ def config_file
99
+ @config_file ||= default_config_file
100
+ end
101
+
102
+ def config_dir
103
+ @config_dir ||= File.join(Util.user_home, '.config', 'doing')
104
+ # @config_dir ||= Util.user_home
105
+ end
106
+
107
+ def default_config_file
108
+ raise DoingRuntimeError, "#{config_dir} exists but is not a directory" if File.exist?(config_dir) && !File.directory?(config_dir)
109
+
110
+ unless File.exist?(config_dir)
111
+ FileUtils.mkdir_p(config_dir)
112
+ Doing.logger.log_now(:warn, "Config directory created at #{config_dir}")
98
113
  end
99
114
 
100
- @settings = configure(options)
115
+ # File.join(config_dir, 'config.yml')
116
+ File.join(config_dir, 'config.yml')
101
117
  end
102
118
 
119
+ def config_file=(file)
120
+ @config_file = file
121
+ end
122
+
123
+
103
124
  def additional_configs
104
125
  @additional_configs ||= find_local_config
105
126
  end
106
127
 
107
- def value_for_key(keypath = '')
128
+ def choose_config
129
+ if @additional_configs.count.positive?
130
+ choices = [@config_file]
131
+ choices.concat(@additional_configs)
132
+ res = Doing::WWID.new.choose_from(choices.uniq.sort.reverse, sorted: false, prompt: 'Local configs found, select which to update > ')
133
+
134
+ raise UserCancelled, 'Cancelled' unless res
135
+
136
+ res.strip || @config_file
137
+ else
138
+ @config_file
139
+ end
140
+ end
141
+
142
+ def resolve_key_path(keypath)
108
143
  cfg = @settings
109
144
  real_path = []
110
145
  unless keypath =~ /^[.*]?$/
@@ -113,7 +148,8 @@ module Doing
113
148
  path = paths.shift
114
149
  new_cfg = nil
115
150
  cfg.each do |key, val|
116
- next unless key =~ path.to_rx(distance: 2)
151
+ next unless key =~ path.to_rx(distance: 4)
152
+
117
153
  real_path << key
118
154
  new_cfg = val
119
155
  break
@@ -127,9 +163,20 @@ module Doing
127
163
  end
128
164
  end
129
165
  Doing.logger.debug('Config:', "translated key path #{keypath} to #{real_path.join('.')}")
130
- result = {}
131
- result[real_path[-1]] = cfg
132
- result
166
+ real_path
167
+ end
168
+
169
+ def value_for_key(keypath = '')
170
+ cfg = @settings
171
+ real_path = ['config']
172
+ unless keypath =~ /^[.*]?$/
173
+ real_path = resolve_key_path(keypath)
174
+ return nil unless real_path && real_path.count.positive?
175
+
176
+ cfg = cfg.dig(*real_path)
177
+ end
178
+
179
+ cfg.nil? ? nil : { real_path[-1] => cfg }
133
180
  end
134
181
 
135
182
  # It takes the input, fills in the defaults where values do not exist.
@@ -141,12 +188,33 @@ module Doing
141
188
  Util.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
142
189
  end
143
190
 
144
- def config_file
145
- @config_file ||= File.join(Util.user_home, '.doingrc')
146
- end
191
+ def update_deprecated_config
192
+ # return # Until further notice
193
+ return if File.exist?(default_config_file)
147
194
 
148
- def config_file=(file)
149
- @config_file = file
195
+ old_file = File.join(Util.user_home, '.doingrc')
196
+ return unless File.exist?(old_file)
197
+
198
+ wwid = Doing::WWID.new
199
+ Doing.logger.log_now(:warn, 'Deprecated:', "main config file location has changed to #{config_file}")
200
+ res = wwid.yn("Move #{old_file} to new location, preserving settings?", default_response: true)
201
+
202
+ if res
203
+ if File.exist?(default_config_file)
204
+ res = wwid.yn("#{default_config_file} already exists, overwrite it?", default_response: false)
205
+
206
+ unless res
207
+ @config_file = old_file
208
+ return
209
+ end
210
+ end
211
+
212
+ FileUtils.mv old_file, default_config_file, force: true
213
+ Doing.logger.log_now(:warn, 'Config:', "Config file moved to #{default_config_file}")
214
+ Doing.logger.log_now(:warn, 'Config:', %(If ~/.config/doing/config.yml exists in the future, it will be considered a local
215
+ config and its values will override the default configuration.))
216
+ Process.exit 0
217
+ end
150
218
  end
151
219
 
152
220
  ##
@@ -155,6 +223,8 @@ module Doing
155
223
  ## @param opt [Hash] Additional Options
156
224
  ##
157
225
  def configure(opt = {})
226
+ update_deprecated_config if config_file == default_config_file
227
+
158
228
  @ignore_local = opt[:ignore_local] if opt[:ignore_local]
159
229
 
160
230
  config = read_config.dup
data/lib/doing/string.rb CHANGED
@@ -392,36 +392,50 @@ module Doing
392
392
 
393
393
  def link_urls(opt = {})
394
394
  opt[:format] ||= :html
395
- str = self.dup
396
-
397
- if :format == :markdown
398
- # Remove <self-linked> formatting
399
- str.gsub!(/<(.*?)>/) do |match|
400
- m = Regexp.last_match
401
- if m[1] =~ /^https?:/
402
- m[1]
403
- else
404
- match
405
- end
395
+ str = dup
396
+
397
+ str = str.remove_self_links if opt[:format] == :markdown
398
+
399
+ str.replace_qualified_urls(format: opt[:format]).clean_unlinked_urls
400
+ end
401
+
402
+ # Remove <self-linked> formatting
403
+ def remove_self_links
404
+ gsub(/<(.*?)>/) do |match|
405
+ m = Regexp.last_match
406
+ if m[1] =~ /^https?:/
407
+ m[1]
408
+ else
409
+ match
406
410
  end
407
411
  end
412
+ end
408
413
 
409
- # Replace qualified urls
410
- str.gsub!(%r{(?mi)(?<!["'\[(\\])((http|https)://)([\w\-_]+(\.[\w\-_]+)+)([\w\-.,@?^=%&amp;:/~+#]*[\w\-@^=%&amp;/~+#])?}) do |_match|
414
+ # Replace qualified urls
415
+ def replace_qualified_urls(opt = {})
416
+ opt[:format] ||= :html
417
+ gsub(%r{(?mi)(?x:
418
+ (?<!["'\[(\\])
419
+ ((http|https)://)
420
+ ([\w\-]+(\.[\w\-]+)+)
421
+ ([\w\-.,@?^=%&;:/~+#]*[\w\-@^=%&;/~+#])?
422
+ )}) do |_match|
411
423
  m = Regexp.last_match
412
424
  proto = m[1].nil? ? 'http://' : ''
413
425
  case opt[:format]
414
426
  when :html
415
- %(<a href="#{proto}#{m[0]}" title="Link to #{m[0].sub(/^https?:\/\//, '')}">[#{m[3]}]</a>)
427
+ %(<a href="#{proto}#{m[0]}" title="Link to #{m[0].sub(%r{^https?://}, '')}">[#{m[3]}]</a>)
416
428
  when :markdown
417
429
  "[#{m[0]}](#{proto}#{m[0]})"
418
430
  else
419
431
  m[0]
420
432
  end
421
433
  end
434
+ end
422
435
 
423
- # Clean up unlinked <urls>
424
- str.gsub!(/<(\w+:.*?)>/) do |match|
436
+ # Clean up unlinked <urls>
437
+ def clean_unlinked_urls
438
+ gsub(/<(\w+:.*?)>/) do |match|
425
439
  m = Regexp.last_match
426
440
  if m[1] =~ /<a href/
427
441
  match
@@ -429,8 +443,6 @@ module Doing
429
443
  %(<a href="#{m[1]}" title="Link to #{m[1]}">[link]</a>)
430
444
  end
431
445
  end
432
-
433
- str
434
446
  end
435
447
  end
436
448
  end
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '2.0.24'
2
+ VERSION = '2.0.25'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -25,10 +25,7 @@ module Doing
25
25
  @timers = {}
26
26
  @recorded_items = []
27
27
  @content = {}
28
- @doingrc_needs_update = false
29
- @default_config_file = '.doingrc'
30
28
  @auto_tag = true
31
- @user_home = Util.user_home
32
29
  end
33
30
 
34
31
  ##
@@ -626,7 +623,7 @@ module Doing
626
623
  Doing.logger.log_now(:warn, 'Compiling and installing fzf -- this will only happen once')
627
624
  Doing.logger.log_now(:warn, 'fzf is copyright Junegunn Choi, MIT License <https://github.com/junegunn/fzf/blob/master/LICENSE>')
628
625
 
629
- res = system("'#{fzf_dir}/install' --bin --no-key-bindings --no-completion --no-update-rc --no-bash --no-zsh --no-fish &> /dev/null")
626
+ system("'#{fzf_dir}/install' --bin --no-key-bindings --no-completion --no-update-rc --no-bash --no-zsh --no-fish &> /dev/null")
630
627
  unless File.exist?(fzf_bin)
631
628
  Doing.logger.log_now(:warn, 'Error installing, trying again as root')
632
629
  system("sudo '#{fzf_dir}/install' --bin --no-key-bindings --no-completion --no-update-rc --no-bash --no-zsh --no-fish &> /dev/null")
@@ -1524,7 +1521,7 @@ module Doing
1524
1521
  def restore_backup(file)
1525
1522
  if File.exist?("#{file}~")
1526
1523
  FileUtils.cp("#{file}~", file)
1527
- logger.warn('File update:', "Restored #{file.sub(/^#{@user_home}/, '~')}")
1524
+ logger.warn('File update:', "Restored #{file.sub(/^#{Util.user_home}/, '~')}")
1528
1525
  else
1529
1526
  logger.error('Restore error:', 'No backup file found')
1530
1527
  end
data/rdoc_to_mmd.rb CHANGED
@@ -3,18 +3,24 @@
3
3
 
4
4
  input = IO.read('doing.rdoc')
5
5
 
6
+ input.gsub!(/^======= Options/, "###### Options\n\n")
6
7
  input.gsub!(/^===== Options/, "##### Options\n\n")
8
+ input.gsub!(/^===== Commands/, "### Commands\n")
7
9
  input.gsub!(/^=== Commands/, "## Commands\n")
8
- input.gsub!(/(?<=\n)===== (.*?)\n+((.|\n)+?)(?=\n=|$)/s) do
10
+
11
+ input.gsub!(/^(?<pre>={4,6}) Command: <tt>(?<cmd>.*?) (?<arg> .*?)?<\/tt>\n(?<after>.*?)$/) do
9
12
  m = Regexp.last_match
10
- "`#{m[1]}`\n: #{m[2].gsub(/\|/, '\\|')}"
13
+ level = m['pre'].length == 6 ? '####' : '###'
14
+ r = "#{level} #{m['cmd'].sub(/\|(.*?)$/, ' (*or* \1)')}"
15
+ r += " #{m['arg']}" if m['arg']
16
+ r += " {##{m['cmd'].gsub(/\|.*?$/, '')}}" if m['pre'].length == 4
17
+ r += "\n\n"
18
+ "#{r}**#{m['after']}**{:.description}\n"
11
19
  end
12
- input.gsub!(/^==== Command: <tt>(.*?) ( .*?)?<\/tt>\n(.*?)$/) do
20
+
21
+ input.gsub!(/(?<=\n)={5,7} (.*?)\n+((.|\n)+?)(?=\n=|$)/s) do
13
22
  m = Regexp.last_match
14
- r = "### #{m[1].sub(/\|(.*?)$/, ' (*or* \1)')}"
15
- r += " #{m[2]}" if m[2]
16
- r += " {##{m[1].gsub(/\|.*?$/, '')}}\n\n"
17
- "#{r}**#{m[3]}**{:.description}\n"
23
+ "`#{m[1]}`\n: #{m[2].gsub(/\|/, '\\|')}"
18
24
  end
19
25
 
20
26
  input.gsub!(/^=== Global Options/, "## Global Options\n")
@@ -28,7 +34,7 @@ input.gsub!(/\n (?=\S)/, ' ')
28
34
  input.gsub!(/^([^:`\n#*](.*?))$/, "\\1\n")
29
35
  input.gsub!(/\n{3,}/, "\n\n")
30
36
  input.gsub!(/^(: .*?)\n\n(:.*?)$/, "\\1\n\\2")
31
- input.gsub!(/^\[Default Command\] (.*?)$/, '## Default Command: [`\1`](#\1)')
37
+ input.gsub!(/^\[Default Command\] (.*?)$/, '> **Default Command:** [`\1`](#\1)')
32
38
  input.gsub!(/\/Users\/ttscoff\/scripts\/editor.sh/, '$EDITOR')
33
39
  input.gsub!(/\/Users\/ttscoff/, '~')
34
40
  puts %(---
@@ -155,7 +155,7 @@ class BashCompletions
155
155
  end
156
156
 
157
157
  def parse_option(option)
158
- res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
158
+ res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>w+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
159
159
  return nil unless res
160
160
  {
161
161
  short: res['short'],
@@ -100,7 +100,7 @@ class FishCompletions
100
100
  end
101
101
 
102
102
  def parse_option(option)
103
- res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
103
+ res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>w+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
104
104
  return nil unless res
105
105
  {
106
106
  short: res['short'],
@@ -71,7 +71,7 @@ class ZshCompletions
71
71
  end
72
72
 
73
73
  def parse_option(option)
74
- res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
74
+ res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>w+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
75
75
  return nil unless res
76
76
 
77
77
  {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.24
4
+ version: 2.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra