class Raykit::Console

The implementation for the raykit console application

def self.get_opts

def self.get_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
end # def self.get_opts

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"))
    if Dir.exist?(work.directory)
      puts "cleaning #{work.directory}"
      Dir.chdir(work.directory) do
        #puts "git clean -xdf"
        #puts `git clean -xdf`
      end
    else
      puts "directory #{work.directory} does not exist"
    end
  end # REPOSITORIES.matches(pattern).each do |url|
  Dir::remove_empty_directories(Raykit::Environment.get_dev_dir("work"))
end

def clobber

def clobber
  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
  Dir::remove_empty_directories(Raykit::Environment.get_dev_dir("work"))
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(opts = nil)

def initialize(opts = nil)
  if opts.nil?
    @opts = Console.get_opts
  else
    @opts = opts
  end
end

def list

def list
  pattern = ""
  pattern = @opts.arguments[1] if @opts.arguments.length > 1
  REPOSITORIES.matches(pattern).each do |url|
    repo = Raykit::Git::Repository.new(url)
    puts repo.to_s
  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 "list"
    list
  when "show"
    show
  when "work"
    work
  when "import"
    import
  when "clean"
    clean
  when "clobber"
    clobber
  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",
    "list" => "list summaries of repositories",
    "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",
    "clobber" => "clobber 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",
    "clobber" => "clobber 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 = []
  work_repositories.each do |url|
    default_command = "rake default"
    repo = Raykit::Git::Repository.new(url)
    cmd = repo.work default_command
  end
  0
end

def work_url(url)

def work_url(url)
  return 0 if url == "https://gitlab.com/gems-rb/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