aboutsummaryrefslogtreecommitdiff
#!/bin/sh
set -eu

usage() {
	printf 'Usage:  %s [-p] FILE [LINENO]\n' "$0"
}

help() {
	cat <<EOF

Options:
  -p             only print the link, don't try to open it
  -h, --help     show this help
  -V, --version  print the version number
EOF
}

version() {
	echo 'git-permalink-@VERSION@ @DATE@'
}

PRINTONLY=false
if [ "${1:-}" = '-p' ]; then
	PRINTONLY=true
	shift
fi
if [ -z "${1:-}" ]; then
	printf "Missing \$FILE argument\n\n" >&2
	usage >&2
	exit 2
fi
FILE="$1"

# shellcheck disable=2068
for flag in $@; do
	case "$flag" in
		-h|--help)
			usage
			help
			exit
			;;
		-V|--version)
			version
			exit
			;;
		*)
			;;
	esac
done

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")"

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}"
}

savannah() {
	printf '%s/tree/%s?id=%s%s\n' "$(echo "$ORIGIN" | sed 's|gnu.org/git|gnu.org/cgit|')" "$FILE" "$COMMIT" "${MYLINENO:+#n$MYLINENO}"
}

gitlab() {
	if echo "$ORIGIN" | grep -q '^git@gitlab.com:'; then
		NAME="$(echo "$ORIGIN" | cut -d: -f2 | cut -d/ -f1)"
		ORIGIN="https://gitlab.com/$NAME/$REPOSITORY"
	fi
	printf '%s/-/blob/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "${MYLINENO:+#L$MYLINENO}"
}

damnyou_github() {
	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
}

github() {
	if echo "$ORIGIN" | grep -q '^git@github.com:'; then
		NAME="$(echo "$ORIGIN" | cut -d: -f2 | cut -d/ -f1)"
		ORIGIN="https://github.com/$NAME/$REPOSITORY"
	fi
	printf '%s/blob/%s/%s%s\n' "$ORIGIN" "$COMMIT" "$FILE" "$(damnyou_github)"
}

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.savannah.gnu.org*)
				savannah
				;;
			*gitlab.com*)
				gitlab
				;;
			*github.com*)
				github
				;;
			*)
				printf "Unsupported origin: %s.\n\n" "$ORIGIN" >&2
				printf 'Add an template override to use git-permalink (see "man git-permalink.1" for instructions).\n' >&2
				exit 1
				;;
		esac
	fi
}

LINK="$(guess_permalink)"
if [ "$PRINTONLY" = true ]; then
	echo "$LINK"
else
	echo "Opening $LINK" >&2
	xdg-open "$LINK"
fi