diff options
Diffstat (limited to 'src/git-permalink.in')
-rwxr-xr-x | src/git-permalink.in | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/src/git-permalink.in b/src/git-permalink.in new file mode 100755 index 0000000..6c83787 --- /dev/null +++ b/src/git-permalink.in @@ -0,0 +1,273 @@ +#!/bin/sh +# shellcheck disable=2034 +set -eu + +MSG_USAGE_EN='Usage: git permalink [-phV] FILE [LINENO]' +MSG_USAGE_PT='Uso: git permalink [-phV] ARQUIVO [NOLINHA]' +MSG_USAGE_FR='Usage: git permalink [-phV] FICHIER [LINENO]' +MSG_USAGE_EO='Uzmaniero: git permalink [-phV] DOSIERO [LINIONO]' + +MSG_HELP_EN='Options: + -p only print the link, don'"'"'t try to open it + -h, --help show this help message + -V, --version print the version number' +MSG_HELP_PT='Opções: + -p somemente imprime o link, não tenta abrí-lo + -h, --help mostra esta mensagem de ajuda + -V, --version imprime o número de versão' +MSG_HELP_FR='Options: + -p seulement imprimez le lien, n'"'"'essayez pas de l'"'"'ouvrir + -h, --help afficher ce message d'"'"'aide + -V, --version imprime le numeró de version' +MSG_HELP_EO='Ebloj: + -p nur presas la ligon, ne provas malfermi ĝin + -h, --help montras ĉi tiun helpmesaĝon + -V, --version presas la versian numeron' + +MSG_MISSING_FILE_EN="Missing FILE argument." +MSG_MISSING_FILE_PT="Faltando argumento ARQUIVO." +MSG_MISSING_FILE_FR="L'argument FICHIER manque." +MSG_MISSING_FILE_EO="La argumento DOSIERO mankas." + +MSG_UNSUPPORTED_ORIGIN_EN='Unsupported origin: %s. + +Add an template override to use git-permalink (see "man git-permalink.1" for instructions).' +MSG_UNSUPPORTED_ORIGIN_PT='Origem sem suporte: %s. + +Adicione um modelo de substituição para usar o git-permalink (veja "man git-permalink.1" para mais instruções).' +MSG_UNSUPPORTED_ORIGIN_FR='Origine n'"'"'es pas supporté: %s. + +Ajouter un modèle de remplacement pour utilisér git-permalink (regarde "man git-permalink.1" pour les instructions).' +MSG_UNSUPPORTED_ORIGIN_EO='Origo ne estas subtenata: %s. + +Aldoni anstataŭan ŝablonon por uzi git-permalink (vidu "man git-permalink.1" por instrukcioj).' + +MSG_OPEN_EN='Opening %s' +MSG_OPEN_PT='Abrindo %s' +MSG_OPEN_FR='Ouverture de %s' +MSG_OPEN_EO='Malfermado de %s' + +set_lang() { + lang="$1" + eval " +MSG_USAGE=\$MSG_USAGE_$lang +MSG_HELP=\$MSG_HELP_$lang +MSG_MISSING_FILE=\$MSG_MISSING_FILE_$lang +MSG_UNSUPPORTED_ORIGIN=\$MSG_UNSUPPORTED_ORIGIN_$lang +MSG_OPEN=\$MSG_OPEN_$lang +" +} + +get_lang() { + # LC_MESSAGES="ll_CC.CODESET@modifier" -> ll_CC, where quotes are optional + locale 2>/dev/null | \ + grep LC_MESSAGES | \ + cut -d. -f1 | \ + cut -d\" -f2 | \ + cut -d= -f2 +} + +case "$(get_lang)" in + pt*) + set_lang PT + ;; + fr*) + set_lang FR + ;; + eo*) + set_lang EO + ;; + *) + set_lang EN + ;; +esac + +usage() { + printf '%s\n' "$MSG_USAGE" +} + +help() { + printf '\n%s\n' "$MSG_HELP" +} + +version() { + printf 'git-permalink-@VERSION@ @DATE@\n' +} + +# shellcheck disable=2068 +for flag in $@; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + --version) + version + exit + ;; + *) + ;; + esac +done + +PRINTONLY=false +while getopts 'phV' flag; do + case "$flag" in + p) + PRINTONLY=true + ;; + h) + usage + help + exit + ;; + V) + version + exit + ;; + *) + ;; + esac +done + +shift $((OPTIND - 1)) + +if [ -z "${1:-}" ]; then + printf '%s\n\n' "$MSG_MISSING_FILE" >&2 + usage >&2 + exit 2 +fi + +FILE="$1" +MYLINENO="${2:-}" +COMMIT="$(git rev-parse HEAD)" +ORIGIN="$(git config remote.origin.url)" +OVERRIDE_CF="$(git config git-permalink.template-commit-file ||:)" +OVERRIDE_FC="$(git config git-permalink.template-file-commit ||:)" +REPOSITORY="$(basename "$PWD")" + +normalize_origin() { + if echo "$ORIGIN" | grep -q '^git@'; then + NAME="$(echo "$ORIGIN" | cut -d: -f2 | cut -d/ -f1)" + URL="$(echo "$ORIGIN" | cut -d@ -f2 | cut -d: -f1)" + ORIGIN="https://$URL/$NAME/$REPOSITORY" + fi +} + +lineno_with_l() { + if echo "$MYLINENO" | grep -q -- -; then + P1="$(echo "$MYLINENO" | cut -d- -f1)" + P2="$(echo "$MYLINENO" | cut -d- -f2)" + printf '#L%s-L%s' "$P1" "$P2" + elif [ -n "$MYLINENO" ]; then + printf '#L%s' "${MYLINENO}" + else + printf '' + fi +} + +euandreh() { + printf 'https://git.euandreh.xyz/%s/tree/%s?id=%s%s\n' "$REPOSITORY" "$FILE" "$COMMIT" "${MYLINENO:+#n$MYLINENO}" +} + +sourcehut() { + printf '%s/tree/%s/item/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "${MYLINENO:+#L$MYLINENO}" +} + +kernel() { + printf '%s/tree/%s?id=%s%s\n' "$ORIGIN" "$FILE" "$COMMIT" "${MYLINENO:+#n$MYLINENO}" +} + +savannah() { + printf '%s/tree/%s?id=%s%s\n' "$(echo "$ORIGIN" | sed 's|gnu.org/git|gnu.org/cgit|')" "$FILE" "$COMMIT" "${MYLINENO:+#n$MYLINENO}" +} + +notabug() { + normalize_origin + printf '%s/src/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "$(lineno_with_l)" +} + +codeberg() { + normalize_origin + printf '%s/src/commit/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "$(lineno_with_l)" +} + +bitbucket() { + normalize_origin + printf '%s/src/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "${MYLINENO:+#lines-$(echo "$MYLINENO" | tr '-' ':')}" +} + +pagure() { + printf '%s/blob/%s/f/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "${MYLINENO:+#_$MYLINENO}" +} + +gitlab() { + normalize_origin + printf '%s/-/blob/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "${MYLINENO:+#L$MYLINENO}" +} + +github() { + normalize_origin + printf '%s/blob/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "$(lineno_with_l)" +} + +guess_permalink() { + if [ -n "$OVERRIDE_CF" ]; then + # shellcheck disable=2059 + printf "$OVERRIDE_CF\n" "$COMMIT" "$FILE" + elif [ -n "$OVERRIDE_FC" ]; then + # shellcheck disable=2059 + printf "$OVERRIDE_FC\n" "$FILE" "$COMMIT" + else + case "$ORIGIN" in + *euandreh.xyz*) + euandreh + ;; + *git.sr.ht*) + sourcehut + ;; + *git.kernel.org*) + kernel + ;; + *git.savannah.gnu.org*) + savannah + ;; + *notabug.org*) + notabug + ;; + *codeberg.org*) + codeberg + ;; + *bitbucket.org*) + bitbucket + ;; + *pagure.io*) + pagure + ;; + *gitlab.com*) + gitlab + ;; + *github.com*) + github + ;; + *) + # shellcheck disable=2059 + printf "$MSG_UNSUPPORTED_ORIGIN\n" "$ORIGIN" >&2 + exit 1 + ;; + esac + fi +} + +LINK="$(guess_permalink)" +if [ "$PRINTONLY" = true ]; then + echo "$LINK" +else + # shellcheck disable=2059 + printf "$MSG_OPEN\n" "$LINK" >&2 + xdg-open "$LINK" +fi |