Skip to content

Instantly share code, notes, and snippets.

@unleashed
Last active April 25, 2019 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unleashed/bea72d4907affd178ae9a7bd5465ac8e to your computer and use it in GitHub Desktop.
Save unleashed/bea72d4907affd178ae9a7bd5465ac8e to your computer and use it in GitHub Desktop.
Get GitHub Gist
#!/bin/bash
#
# gist-go - Get a Github Gist
# Copyright (c) 2019 Alejandro Martinez Ruiz <alex flawedcode org>
#
# Downloads latest version of files in a Github gist, optionally outputting them to stdout.
# Files will by default be written to the current working directory, unless you
# specify --stdout (or -o) as first parameter.
#
# Usage:
#
# gist-go [--stdout|-o] <gist url> [<file_regexp>]
#
# 1st param: gist URL (where all files in the gist are listed)
# 2nd param (optional): Perl regexp that urls should match to be fetched, typically used for "globs".
#
# Example:
#
# * Show all Markdown (*.md) files from a gist in the terminal
# gist-go --stdout https://gist.github.com/unleashed/123abc \\.md$
#
# * Use gist-go with curl to execute a specific script
# curl -sSfL https://bit.ly/gist-go https://gist.github.com/unleashed/123abc script\\.sh$ | bash -s -- some-param
#
# TODO: (maybe?) sanitize file names to be included in grep as literals instead of grep expressions
GIST_BASE_URL="https://gist.github.com"
fetch_gist_paths()
{
local gist_url="${1}"
curl -sSfL "${gist_url}" | grep "<a .*>Raw</a>" | sed -E -e "s/.*\bhref=\"([^\"]*)\".*/\1/"
}
file_match_re()
{
local path_re="${1}"
local path="${2}"
echo "${path}" | grep -P "${path_re}"
}
file_match()
{
local file_re="${1}"
local paths="${2}"
for p in ${paths}; do
file_match_re "${file_re}" "${p}"
done
}
file_urls()
{
local gist_url="${1}"
local paths="${2}"
local urls
for p in ${paths}; do
urls="${urls:+${urls} }${GIST_BASE_URL}${p}"
done
echo "${urls}"
}
gist_urls_for()
{
local gist_url="${1}"
local files="${@:2}"
local paths="$(fetch_gist_paths "${gist_url}")"
local urls="$(file_urls "${gist_url}" "${paths}")"
local result
if test "x${files}" = "x"; then
result=${urls}
else
for f in ${files}; do
for u in ${urls}; do
thismatch="$(file_match "${f}" ${u})"
if test "x${thismatch}" != "x"; then
result="${result:+${result} }${thismatch}"
fi
done
done
fi
echo ${result}
}
go_gist()
{
local stdout="${1}"
if test "x${stdout}" != "x--stdout" -a "x${stdout}" != "x-o"; then
curl_out="-O "
else
curl_opts="sf"
shift
fi
local urls=$(gist_urls_for "${@}")
local cmdline
for u in ${urls}; do
cmdline="${cmdline:+${cmdline} }${curl_out}${u}"
done
curl -${curl_opts}SL ${cmdline}
}
if test "x${BASH_SOURCE[0]}" = "x" -o "${BASH_SOURCE[0]}" = "${0}"; then
set -eo pipefail
shopt -s failglob
go_gist "${@}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment