class TTY::File::CreateFile

Attributes

base[R]
content[R]
context[R]
prompt[R]
relative_path[R]

Public Class Methods

new(base, relative_path, content, context: nil, force: false, skip: false, verbose: true, noop: false, color: :green, quiet: true) click to toggle source
# File lib/tty/file/create_file.rb, line 11
def initialize(base, relative_path, content, context: nil, force: false,
               skip: false, verbose: true, noop: false, color: :green,
               quiet: true)
  @base    = base
  @content = content
  @context = context || @base
  @force   = force
  @skip    = skip
  @noop    = noop
  @verbose = verbose
  @color   = color
  @relative_path = convert_encoded_path(relative_path)
  @prompt  = TTY::Prompt.new(quiet: quiet)
end

Public Instance Methods

call() click to toggle source

Create a file

@api public

# File lib/tty/file/create_file.rb, line 37
def call
  detect_collision do
    FileUtils.mkdir_p(::File.dirname(relative_path))
    ::File.open(relative_path, "wb") { |f| f.write(content) }
  end
  relative_path
end
exist?() click to toggle source
# File lib/tty/file/create_file.rb, line 26
def exist?
  ::File.exist?(relative_path)
end
identical?() click to toggle source
# File lib/tty/file/create_file.rb, line 30
def identical?
  ::File.binread(relative_path) == content
end

Protected Instance Methods

convert_encoded_path(filename) click to toggle source
# File lib/tty/file/create_file.rb, line 47
def convert_encoded_path(filename)
  filename.gsub(/%(.*?)%/) do |match|
    method = $1.strip
    if context.respond_to?(method, true)
      context.public_send(method)
    else
      match
    end
  end
end
detect_collision() { || ... } click to toggle source

Check if file already exists and ask for user input on collision

@api private

# File lib/tty/file/create_file.rb, line 61
def detect_collision
  if exist?
    if identical?
      notify(:identical, :cyan)
    elsif @force
      notify(:force, :yellow)
      yield unless @noop
    elsif @skip
      notify(:skip, :yellow)
    else
      notify(:collision, :red)
      yield if file_collision(relative_path, content)
    end
  else
    notify(:create, :green)
    yield unless @noop
  end
end
file_collision(relative_path, content) click to toggle source

Display conflict resolution menu and gather answer

@api private

# File lib/tty/file/create_file.rb, line 91
def file_collision(relative_path, content)
  choices = [
    { key: "y", name: "yes, overwrite", value: :yes },
    { key: "d", name: "diff, compare files", value: :diff },
    { key: "n", name: "no, do not overwrite", value: :no },
    { key: "q", name: "quit, abort", value: :quit }
  ]
  while (answer = prompt.expand("Overwrite #{relative_path}?", choices)) == :diff do
    show_diff
  end
  interpret_answer(answer)
end
interpret_answer(answer) click to toggle source

@api private

# File lib/tty/file/create_file.rb, line 112
def interpret_answer(answer)
  case answer
  when :yes
    true
  when :no
    false
  when :quit
    abort
  end
end
notify(name, color) click to toggle source

Notify console about performed action

@api private

# File lib/tty/file/create_file.rb, line 83
def notify(name, color)
  base.__send__(:log_status, name, relative_path,
                verbose: @verbose, color: @color ? color : false)
end
show_diff() click to toggle source

Display difference between old and new file

@api private

# File lib/tty/file/create_file.rb, line 107
def show_diff
  print base.__send__(:diff_files, relative_path, content, verbose: @verbose)
end