Module: Doing::Util

Extended by:
Util
Included in:
Util
Defined in:
lib/doing/util.rb

Overview

Utilities

Instance Method Summary collapse

Instance Method Details

#args_for_editor(editor) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/doing/util.rb', line 136

def args_for_editor(editor)
  return editor if editor =~ /-\S/

  args = case editor
         when /^(subl|code|mate)$/
           ['-w']
         when /^(vim|mvim)$/
           ['-f']
         else
           []
         end
  "#{editor} #{args.join(' ')}"
end

#deep_merge_hashes(master_hash, other_hash) ⇒ Object

Non-destructive version of deep_merge_hashes! See that method.

Parameters:

  • master_hash (Hash)

    The master hash

  • other_hash (Hash)

    The other hash

Returns:

  • the merged hashes.



51
52
53
# File 'lib/doing/util.rb', line 51

def deep_merge_hashes(master_hash, other_hash)
  deep_merge_hashes!(master_hash.dup, other_hash)
end

#deep_merge_hashes!(target, overwrite) ⇒ Object

Merges a master hash with another hash, recursively.

master_hash - the "parent" hash whose values will be overridden other_hash - the other hash whose values will be persisted after the merge

This code was lovingly stolen from some random gem: http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html

Thanks to whoever made it.



64
65
66
67
68
69
70
# File 'lib/doing/util.rb', line 64

def deep_merge_hashes!(target, overwrite)
  merge_values(target, overwrite)
  merge_default_proc(target, overwrite)
  duplicate_frozen_values(target)

  target
end

#default_editorObject



128
129
130
# File 'lib/doing/util.rb', line 128

def default_editor
  @default_editor = find_default_editor
end

#duplicable?(obj) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
# File 'lib/doing/util.rb', line 72

def duplicable?(obj)
  case obj
  when nil, false, true, Symbol, Numeric
    false
  else
    true
  end
end

#duplicate_frozen_values(target) ⇒ Object



37
38
39
40
41
# File 'lib/doing/util.rb', line 37

def duplicate_frozen_values(target)
  target.each do |key, val|
    target[key] = val.dup if val.frozen? && duplicable?(val)
  end
end

#editor_with_argsObject



132
133
134
# File 'lib/doing/util.rb', line 132

def editor_with_args
  args_for_editor(default_editor)
end

#exec_available(cli) ⇒ Object

Test if command line tool is available

Parameters:

  • cli (String)

    The name or path of the cli



21
22
23
24
25
26
27
28
29
# File 'lib/doing/util.rb', line 21

def exec_available(cli)
  return false if cli.nil?

  if File.exist?(File.expand_path(cli))
    File.executable?(File.expand_path(cli))
  else
    system "which #{cli}", out: File::NULL, err: File::NULL
  end
end

#find_default_editor(editor_for = 'default') ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/doing/util.rb', line 150

def find_default_editor(editor_for = 'default')
  # return nil unless $stdout.isatty || ENV['DOING_EDITOR_TEST']

  if ENV['DOING_EDITOR_TEST']
    return ENV['EDITOR']
  end

  editor_config = Doing.config.settings['editors']

  if editor_config.is_a?(String)
    Doing.logger.warn('Deprecated:', "Please update your configuration, 'editors' should be a mapping. Delete the key and run `doing config --update`.")
    return editor_config
  end

  if editor_config[editor_for]
    editor = editor_config[editor_for]
    # Doing.logger.debug('Editor:', "Using #{editor} from config 'editors->#{editor_for}'")
    return editor unless editor.nil? || editor.empty?
  end

  if editor_for != 'editor' && editor_config['default']
    editor = editor_config['default']
    # Doing.logger.debug('Editor:', "Using #{editor} from config: 'editors->default'")
    return editor unless editor.nil? || editor.empty?
  end

  editor ||= ENV['DOING_EDITOR'] || ENV['GIT_EDITOR'] || ENV['EDITOR']

  unless editor.nil? || editor.empty?
    # Doing.logger.debug('Editor:', "Found editor in environment variables: #{editor}")
    return editor
  end

  Doing.logger.debug('ENV:', 'No EDITOR environment variable, testing available editors')
  editors = %w[vim vi code subl mate mvim nano emacs]
  editors.each do |ed|
    return ed if exec_available(ed)
    Doing.logger.debug('ENV:', "#{ed} not available")
  end

  nil
end

#mergable?(value) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/doing/util.rb', line 81

def mergable?(value)
  value.is_a?(Hash)
end

#merge_default_proc(target, overwrite) ⇒ Object



31
32
33
34
35
# File 'lib/doing/util.rb', line 31

def merge_default_proc(target, overwrite)
  return unless target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?

  target.default_proc = overwrite.default_proc
end

#merge_values(target, overwrite) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/doing/util.rb', line 85

def merge_values(target, overwrite)
  target.merge!(overwrite) do |_key, old_val, new_val|
    if new_val.nil?
      old_val
    elsif mergable?(old_val) && mergable?(new_val)
      deep_merge_hashes(old_val, new_val)
    else
      new_val
    end
  end
end

#safe_load_file(filename) ⇒ Object



124
125
126
# File 'lib/doing/util.rb', line 124

def safe_load_file(filename)
  SafeYAML.load_file(filename) || {}
end

#user_homeObject



8
9
10
11
12
13
14
# File 'lib/doing/util.rb', line 8

def user_home
  if Dir.respond_to?('home')
    Dir.home
  else
    File.expand_path('~')
  end
end

#write_to_file(file, content, backup: true) ⇒ Object

Write content to a file

Parameters:

  • file (String)

    The path to the file to (over)write

  • content (String)

    The content to write to the file

  • backup (Boolean) (defaults to: true)

    create a ~ backup



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/doing/util.rb', line 104

def write_to_file(file, content, backup: true)
  unless file
    puts content
    return
  end

  file = File.expand_path(file)

  if File.exist?(file) && backup
    # Create a backup copy for the undo command
    FileUtils.cp(file, "#{file}~")
  end

  File.open(file, 'w+') do |f|
    f.puts content
  end

  Hooks.trigger :post_write, file
end