doing 2.0.24 → 2.0.25

Sign up to get free protection for your applications and to get access to all the features.
@@ -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