class Raykit::Console

The implementation for the raykit console application

def add

def add
  if @opts.arguments.length < 2
    puts "add requires a url"
    return 1
  end
  url = @opts.arguments[1]
  if REPOSITORIES.include?(url)
    puts "url #{url} already exists."
  else
    REPOSITORIES << url
    REPOSITORIES.save(REPOSITORIES.filename)
    puts "url #{url} added."
  end
end

def clean

def clean
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  REPOSITORIES.matches(pattern).each do |url|
    repo = Raykit::Git::Repository.new(url)
    work = Raykit::Git::Directory.new(repo.get_dev_dir("work"))
    next unless Dir.exist?(work.directory)
    puts "removing #{work.directory}"
    begin
      FileUtils.rm_rf(work.directory, secure: true)
    rescue StandardError
      puts "error removing #{work.directory}"
    end
  end
end

def copy

def copy
  if @opts.arguments.length < 3
    puts "source and destination arguments are required for copy"
    return 1
  end
  source = @opts.arguments[1]
  dest = @opts.arguments[2]
  FileUtils.cp(source, dest)
  puts "copied #{source} to #{dest}"
end

def import

def import
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  puts "scanning..."
  count = REPOSITORIES.length
  REPOSITORIES.import(pattern)
  new_count = REPOSITORIES.length - count
  puts "imported #{new_count} git repositories"
end

def initialize

def initialize
  @opts = Slop.parse do |o|
    o.string "-t", "--task", "rake task", default: "default"
    o.bool "-v", "--verbose", "print detailed output", default: false
    o.bool "-q", "--quiet", "minimal output", default: false
    o.bool "-s", "--stop", "stop on error", default: true
  end
  if opts.verbose?
    puts "options: #{Rainbow(@opts.to_hash).yellow.bright}"
    puts "arguments:#{Rainbow(@opts.arguments).yellow.bright}"
  end
end

def pull

def pull
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  REPOSITORIES.matches(pattern).each do |url|
    repo = Raykit::Git::Repository.new(url)
    work = Raykit::Git::Directory.new(repo.get_dev_dir("work"))
    if Dir.exist?(work.directory) && !work.directory == ".git"
      Dir.chdir(work.directory) do
        diff = `git diff`.strip
        status = `git status`.strip
        if diff.length.zero? && status.include?("nothing to commit")
          cmd = Command.new("git pull")
          cmd.summary if @opts.verbose?
          if cmd.exitstatus != 0
            cmd.details
            abort Rainbow(cmd.summary).blue.bright if @opts.quit?
          end
        end
      end
    end
  rescue StandardError => e
    issue = "error occurred for pull of #{url} #{e}"
    if @opts.quit?
      abort Rainbow(issue).blue.bright
    else
      puts Rainbow(issue).blue.bright
    end
  end
end

def rake(hash)

def rake(hash)
  REPOSITORIES.each do |remote|
    next unless remote.include?(hash[:pattern])
    begin
      puts "remote: #{remote}"
      cmd = Raykit::Rake.run(remote, "master")
      elapsed_str = Timer.get_elapsed_str(cmd.elapsed)
      if cmd.exitstatus.zero?
        puts "#{elapsed_str} #{Rainbow(SECRETS.hide(cmd.command)).yellow.bright} (#{cmd.directory})"
      else
        puts "\r\n#{cmd.command}\r\n"
        puts "\r\n#{cmd.output}\r\n"
        puts "\r\n#{cmd.error}\r\n"
        puts ""
        puts "#{Rainbow(elapsed_str).red.bright} #{Rainbow(cmd.command).white}"
      end
    rescue StandardError
      puts "rescued..."
    end
  end
end

def remove

def remove
  if @opts.arguments.length < 2
    puts "remove requires a url or pattern"
    return 1
  end
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  remove_urls = REPOSITORIES.matches(pattern)
  if remove_urls.length.zero?
    puts "no matching urls found."
  else
    remove_urls.each do |url|
      REPOSITORIES.delete(url)
      puts "url #{url} removed."
    end
    REPOSITORIES.save(REPOSITORIES.filename)
  end
end

def run

def run
  verb = "usage"
  verb = @opts.arguments[0] if @opts.arguments.length.positive?
  case verb
  when "usage"
    usage
  when "add"
    add
  when "remove"
    remove
  when "show"
    show
  when "work"
    work
  when "import"
    import
  when "clean"
    clean
  when "sync_version"
    sync_version
  when "copy"
    copy
  when "pull"
    pull
  else
    puts "unrecognized command #{verb}"
    1
  end
end

def show

def show
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  REPOSITORIES.matches(pattern).each do |url|
    puts url
  end
end

def usage

def usage
  puts "Usage: raykit VERB [GIT_URL|PATTERN] [OPTIONS]"
  verb_descriptions.each do |k, v|
    puts "#{k.ljust(15, " ")} - #{v}"
  end
  # puts @opts

  # puts "verbs: " + verbs.to_s

  0
end

def verb_descriptions

def verb_descriptions
  { "add" => "add a git url",
    "remove" => "remove one or more git urls",
    "show" => "show git urls matching a specific pattern",
    "work" => "clone and rake a git repository",
    "import" => "import git urls matching a specific pattern",
    "clean" => "clean one or more working directories",
    "pull" => "preform git pull on one or more working directories",
    "sync_version" => "synchronize the version number between two files",
    "copy" => "copy a file" }
end

def verb_usage

def verb_usage
  { "add" => "add GIT_URL",
    "remove" => "remove URL_PATTERN",
    "show" => "show URL_PATTERN",
    "work" => "work URL_PATTERN [--task RAKE_TASK]",
    "import" => "import URL_PATTERN",
    "clean" => "clean URL_PATTERN",
    "pull" => "pull URL_PATTERN",
    "sync_version" => "sync_version SOURCE_FILENAME DESTINATION_FILENAME",
    "copy" => "copy SOURCE DESTINATION" }
end

def work

def work
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  work_repositories = REPOSITORIES.matches(pattern)
  errors = []
  puts "work: found #{work_repositories.length} matching urls"
  work_repositories.each do |url|
    exitstatus = work_url(url)
    puts " " if @opts.verbose?
    return exitstatus if @opts[:stop] && exitstatus != 0
  end
  0
end

def work_url(url)

def work_url(url)
  return 0 if url == "https://gitlab.com/lou-parslow/raykit.git"
  puts Rainbow(url).yellow.bright if @opts.verbose?
  repo = Raykit::Git::Repository.new(url)
  work = Raykit::Git::Directory.new(repo.get_dev_dir("work"))
  unless Dir.exist?(work.directory)
    clone = Command.new("git clone #{url} #{work.directory} --recursive")
    puts clone.summary unless @opts.quiet?
    if clone.exitstatus != 0
      clone.details
      return clone.exitstatus
    end
  end
  if Dir.exist?(work.directory)
    Dir.chdir(work.directory) do
      if File.exist?("rakefile.rb")
        rake = Raykit::Command.new("rake #{@opts[:task]}")
        rake.summary(true) if !@opts.quiet? || rake.exitstatus != 0
        if rake.exitstatus != 0
          rake.details
          rake.summary true
          return rake.exitstatus
        end
      else
        puts("rakefile.rb not found in #{work.directory}") if @opts.verbose?
        return 0
      end
    end
  end
  0
end