#!/usr/bin/env ruby ## fcl: Fantastic CLoner # # Clones git repos into a predictable directory structure, according to local # customs (HTTPS instead of SSH for Buildkite repos, for example) # # Makes educated guesses about incomplete repo identifiers. # # Also with some CLI pretty thanks to `gum`. # # TODO LIST # # [ ] Make a way to turn off the pretty, in case it's getting in the way # ConfigPath = File.join(File.expand_path(File.dirname(__FILE__)), 'config.bash') ConfigValues = `env -i bash --noprofile --norc -c 'source #{ConfigPath}; env'`.lines.map(&:chomp) ConfigPairs = ConfigValues.map {|v| v.split('=',2) }.to_h Config = ConfigPairs.reject {|k,v| ['_','SHLVL','PWD'].include?(k) } def clone(repo_url, destination) spinner_command = %Q[gum spin --show-output --spinner dot] git_command = ['git', 'clone', repo_url, destination].join(' ') system("#{spinner_command} -- #{git_command}") end def log_error(message) system(%Q[gum style --bold --border=double --padding='0 1' --foreground 212 "#{message}"]) end # Transform SSH URLs for GitHub into HTTPS, so we can do the recommended auth # things. # # Also, make some assumptions when info is missing, so I can provide stuff like # `buildkite-plugins/ecr-buildkite-plugin` and have this puppy still work. # def repo_url(repo_str) case repo_str # GitHub HTTPS. We like these, use it as-is. when /^(git|https)\:\/\/github\.com\// repo_str # Some other HTTPS. This is probably fine too, as long as it ends with '.git' when /^(git|https)\:\/\/.+\.git$/ repo_str # GitHub SSH. Let's convert this to HTTPS. when /^git@github\.com\:.+\.git$/ repo_str.sub(/^git@github\.com:/, 'https://github.com/') # Host, user/org and repo. Assume it's HTTPS. when /^[^\/\s]+\/[^\/\s]+\/[^\/\s]+/ "https://#{repo_str}#{repo_str.end_with?('.git') ? '' : '.git'}" # Just a user/org name and repo name. Assume it's on GitHub and make an HTTPS URL. when /^[\w\-_]+\/[\w\-_\.]+$/ "https://github.com/#{repo_str}.git" # Just a repo name. Assume it's a FCL_DEFAULT_ORG repo on GitHub and make an HTTPS URL. when /^[\w\-_\.]+$/ "https://github.com/#{Config['FCL_DEFAULT_ORG']}/#{repo_str}.git" else raise "I can't make a repo URL out of '#{repo_str}'." end end def destination_path(repo_str) repo_elms = repo_str.split('/') repo = repo_elms.pop.sub(/\.git$/, '') org = repo_elms.pop || Config.fetch('FCL_DEFAULT_ORG') forge = repo_elms.pop || 'github.com' File.join(forge, org, repo) end repo_str = ARGV.empty? ? `gum input --header="Enter a repo name" --placeholder=""`.chomp : ARGV[0] destination = ARGV[1] || destination_path(repo_str) full_dest = File.join(Config['REPOSITORY_BASE'], destination) clone_url = repo_url(repo_str) if Dir.exist?(full_dest) log_error "#{destination} already exists. Doing nothing." else clone(clone_url, full_dest) end