Skip to content

Instantly share code, notes, and snippets.

@criztovyl
Last active July 13, 2018 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save criztovyl/248d4c61b8873fa884df to your computer and use it in GitHub Desktop.
Save criztovyl/248d4c61b8873fa884df to your computer and use it in GitHub Desktop.
Clones a GitHub Gist into an directory with the Gist's name.
#!/bin/bash
# Clones a GitHub Gist into an directory with the Gist's name.
# Copyright (C) 2016 Christoph "criztovyl" Schulz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if [[ "$1" =~ ^-{0,2}h(elp)?$ ]]; then
echo "Usage: $0 URL|ID [HTTPS-Clone]"
echo " URL|ID: Gist URL or ID"
echo " HTTPS-Clone: Set to non-empty value to clone via HTTPS, default is ssh."
exit 0
fi
# Constants
GHH="gist.github.com" # Gist Host
GHU="https://$GHH" # Gist base URL
UNRE='[a-zA-Z0-9_-]+' # Username RegEx; would also match an invalid username that starts or ends with a dash.
IDRE='[[:xdigit:]]+' # Gist ID, assuming it's a hex-only-string
CURL="curl -Ls" # curl command, -L is required, -s can be removed.
# The Algorithm is really easy:
# If you gave me a Gist URL, I'll extract the ID from it and fetch the page behind the URL.
# If you gave me a Gits ID, I'll fetch https://gist.github.com/[ID].
# When I received the page, I'll extract the Gist name from it and clone the Gist Git Repo into a directory with the Gist's name :)
# You can specify whether you want to use ssh or https for cloning.
gist-clone()
{
# Args: link httpsClone
local link=$1
local httpsClone=$2
local href
local method
[ ! "$httpsClone" ] && method="git@$GHH:" || method="$GHU/"
if [[ "$link" =~ ^($GHU/($UNRE/($IDRE))|($IDRE))$ ]]; then # Match on link for Gist URL or ID.
# Match Groups: 1 - the "or", 2 - relative Gist URL, 3 - ID (if got URL), 4 - ID (if got ID)
href="${BASH_REMATCH[2]}"
gistid=${BASH_REMATCH[@]:3:2} # No quotes to drop space empty index 3 would produce
[ "$href" ] || href=$gistid # We can use the Gist ID as relative URL, GitHub will redirect us to Gist page <3
# Debugging :)
#for ((i=0; i < ${#BASH_REMATCH[@]}; i++)); do echo $i ${BASH_REMATCH[$i]}; done
else
echo "Not URL nor ID: $link" >&2
exit 1
fi
regex='<a href="/'$UNRE/$IDRE'">([^<]+)</a>' # RegEx for Gist name
if [[ $($CURL $GHU/${sublink:-$href}) =~ $regex ]]; then # Match for Gist name.
git clone $method$gistid.git ${BASH_REMATCH[1]} # Clone it!
else
echo "Something went wrong :(" >&2
exit 2
# Debugging :)
#for name in link href method gistid sublink; do echo $name ${!name}; done
fi
}
# Call
gist-clone $1 $2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment