Skip to content

Instantly share code, notes, and snippets.

@jolros
Last active May 30, 2021 14:13
Show Gist options
  • Save jolros/8360779 to your computer and use it in GitHub Desktop.
Save jolros/8360779 to your computer and use it in GitHub Desktop.
Script that clones a github repository into a nested githubuser/repositoryname directory within the current working directory or directory specified by the GITHUB_CLONE_HOME environment variable. Also works for gists. This allows your github clones to be organized cleanly and consistently. http://blog.jolros.com/consistent-github-cloning
#!/usr/bin/env perl
use File::Path qw(make_path);
use File::Spec;
use strict;
use warnings;
@ARGV || die 'Must provide repository information as an argument';
my $raw = $ARGV[0];
my $ENV_VAR = 'GITHUB_CLONE_HOME';
my @dirs;
if ($ENV{$ENV_VAR}) {
if (! -d $ENV{$ENV_VAR} || ! -w $ENV{$ENV_VAR}) {
die "Environment variable $ENV_VAR was set but was not a directory or writable";
}
push @dirs, $ENV{$ENV_VAR};
}
my ($path, $url);
if ($raw =~ /gist\.github\.com/) {
# Gist Repositories
my $gistid;
if ($raw =~ /^(https?:\/\/|git\@)gist\.github\.com[:\/](?:[^\/]+\/)?(\d+)(?:\.git)?$/) {
my $scheme = $1;
$gistid = $2;
if ($scheme =~ /^http/) {
$url = "${scheme}gist.github.com/${gistid}.git"
} else {
$url = "${scheme}gist.github.com:${gistid}.git"
}
}
($gistid && $url) || die 'Could not determine repository information';
push @dirs, 'gists', $gistid;
} else {
# Normal GitHub Repositories
my ($user, $repo);
if ($raw =~ /^(https?:\/\/|git\@)github\.com[:\/]([^\/]+)\/([^\/]+?)(?:\.git)?$/) {
my $scheme = $1;
$user = $2;
$repo = $3;
if ($scheme =~ /^http/) {
$url = "${scheme}github.com/${user}/${repo}.git"
} else {
$url = "${scheme}github.com:${user}/${repo}.git"
}
} elsif( $raw =~ /^([^\/]+)\/([^\/]+)$/) {
($user, $repo, $url) = ($1, $2, "git\@github.com:$1/$2.git");
}
($user && $repo && $url) || die 'Could not determine repository information';
push @dirs, lc($user), lc($repo);
}
$path = File::Spec->catdir( @dirs );
#print "Clone URL: $url, Clone path: $path\n";
make_path( $path );
# TODO: Use to Git::Repository (if available) for non-Unix users, fall back
# to system call
system( 'git', 'clone', "$url", $path );
=head1 NAME
gclone - clones a github repository or gist into a nested $user/$repo directory
=head1 USAGE
> gclone git@github.com:ttscoff/Slogger.git
Cloning into 'ttscoff/slogger'...
remote: Reusing existing pack: 2203, done.
remote: Total 2203 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (2203/2203), 797.84 KiB | 408.00 KiB/s, done.
Resolving deltas: 100% (1014/1014), done.
Checking connectivity... done.
> GITHUB_CLONE_HOME=~/Documents/code/github gclone ttscoff/Slogger
Cloning into '/Users/joel/Documents/code/github/ttscoff/slogger'...
remote: Reusing existing pack: 2203, done.
remote: Total 2203 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (2203/2203), 797.84 KiB | 490.00 KiB/s, done.
Resolving deltas: 100% (1014/1014), done.
Checking connectivity... done.
> export GITHUB_CLONE_HOME=~/Documents/code/github
> gclone https://gist.github.com/jolros/8191941
Cloning into '/Users/joel/Documents/code/github/gists/8191941'...
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
Checking connectivity... done.
=head1 DESCRIPTION
This command takes a github repository string in a variety of formats and
clones it to $user/$repo.
It will clone to $user/$repo within the current working directory. if
$GITHUB_CLONE_HOME is set, it will clone to that directory. Gists will
be cloned into gist/$gistid.
Here are some allowed GitHub repository argument examples:
git@github.com:ttscoff/Slogger.git
https://github.com/ttscoff/Slogger.git
https://github.com/ttscoff/Slogger
ttscoff/Slogger
ttscoff/Slogger.git
https://gist.github.com/jolros/8191941
git@gist.github.com:8360779
git@gist.github.com:jolros/8360779.git
=head1 AUTHOR
Joel Rosenberg https://github.com/jolros
=head1 LICENSE
This library is free software. You can redistribute it
and/or modify it under the same terms as Perl itself.
=head1 DISCLAIMER OF WARRANTY
The author assumes no warranty for the software. Use at your own risk.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment