84 lines
2.7 KiB
Ruby
Executable File
84 lines
2.7 KiB
Ruby
Executable File
#!/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
|
|
# 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['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
|