TheRepoClub-DotFiles/localbin/.local/bin/lmgr
2022-02-13 17:55:53 +00:00

338 lines
9.7 KiB
Bash
Executable File

#!/usr/bin/env sh
# Licensed under ArArv2 license: https://files.ari-web.xyz/files/ArAr.ari-archer.LICENSE
# Description: manage, switch and template licenses
# DEPENDS ON:
# general utilities: coreutils [head, awk, ...]
# license picker: fzf (optional)
# automatic config generation: git (optional)
# colours: ncurses (optional) [tput]
set -e
VERSION='0.8'
# Init
[ -z "$HOME" ] && HOME="$(eval echo '~')"
depend() { command -v -- "$1" >/dev/null || (echo "FATAL: depend(): Dependency '$1' broken" 1>&2 && exit 11); }
# Colours (requires ncurses)
if [ "$LMGR_COLOURS" != 0 ]; then
depend 'tput'
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BRIGHT=$(tput bold)
RESET=$(tput sgr0)
fi
# Aliases
alias lless='less -NrIMJ --use-color --incsearch --line-num-width=2'
alias ffind='find -L'
# Constants
LICENSE_DIR="$HOME/.config/licenses"
LICENSE_SED='s/^@//'
# Utility functions
error() { printf " ${RED}*${RESET} %s\n" "$1" 1>&2; }
warn() { printf " ${YELLOW}*${RESET} %s\n" "$1" 1>&2; }
info() { printf " ${GREEN}*${RESET} %s\n" "$1"; }
einfo() { printf " ${BRIGHT}*${RESET} %s\n" "$1"; }
check_valid_license() {
lic="$(echo "$1" | sed "$LICENSE_SED")"
echo "$1" | grep -qi '^@' || (error "License '$lic' is not valid" && exit 9)
[ ! -f "$LICENSE_DIR"/"$lic" ] && (error "License '$lic' does not exist" && exit 10)
return 0
}
sed_escape() { echo "$1" | sed -e 's/[\/&]/\\&/g'; }
# Functions
list_licenses() { ffind "$LICENSE_DIR" -maxdepth 1 -type f -printf " ${BRIGHT}*${RESET} @%f\n"; }
usage() {
echo " License manager v$VERSION"
echo ' manage, switch and template licenses'
echo ''
echo " \$AUTHOR_NAME -- '$AUTHOR_NAME'"
echo " \$AUTHOR_EMAIL -- '$AUTHOR_EMAIL'"
echo " \$AUTHOR_WEBSITE -- '$AUTHOR_WEBSITE'"
echo " \$LICENSE_DIR -- '$LICENSE_DIR'"
echo ''
echo " [ENV=VAL ...] $(basename "$0") <flag | @license>"
echo ''
echo ' -help --help -h show usage'
echo ' -list-licenses -l list awailable licenses'
echo ' -current-license -c show current active project license'
echo ' -pick-license -p pick a license in a FZF menu'
echo ' -preview-license -P @license_name preview a license template'
echo ' -remove-license -r remove all licenses from the current project'
echo " -search-license -s '<query | patten>' search for license"
echo ' -template-help -T print help for templating'
echo ' -new-template -t create a new license template'
echo ' -delete-license -R @license_name ... delete a license from templates'
echo ' -new-config -C create a default config overwriting current one'
echo ' -check-conflict -k check if current licene(s) are conflicting'
echo ''
echo " LMGR_COLOURS=0|[1] turn colour on (1) or off (0) [${LMGR_COLOURS:-1}]"
}
make_new_config() {
mkdir -p "$HOME"/.config
{
echo '#!/usr/bin/env sh'
echo "export AUTHOR_NAME='$(git config user.name || echo "${USER}")'"
echo "export AUTHOR_EMAIL='$(git config user.email || echo "${USER}@gmail.com")'"
echo "export AUTHOR_WEBSITE='https://example.com/'"
echo "export LICENSE_DIR='$LICENSE_DIR'"
} >"$HOME"/.config/license.conf
}
show_license() {
depend 'head'
l_name='LICENSE'
[ -f UNLICENSE ] && l_name='UNLICENSE'
if [ -f "$l_name" ]; then
head -n1 "$l_name" | sed 's/^\s*//; s/\s*$//'
else
echo 'strong copyright (no license)'
fi
}
check_license_conflict() {
if [ -f ./LICENSE ] && [ -f ./UNLICENSE ]; then
error 'Licensing conflict: UNLICENSE and LICENSE both found'
printf ' Do you either (1) Remove LICENSE or (2) Remove UNLICENSE? [1/2] '
read -r lr
case "$lr" in
1) rm LICENSE ;;
2) rm UNLICENSE ;;
*) error "'$lr' is not an option" && exit 1 ;;
esac || (error 'Could not resolve licensing conflict' && exit 6)
fi
}
get_license() {
depend 'cp'
check_valid_license "$1"
check_license_conflict
user_license="$(echo "$1" | sed "$LICENSE_SED")"
if [ ! -f "$LICENSE_DIR"/"$user_license" ]; then
error "No licence by the name of '$1'"
list_licenses
error 'Use of of the above'
exit 5
elif [ -f ./LICENSE ] || [ -f ./UNLICENSE ]; then
info "Found license: $(show_license)"
printf ' Switch licenses? [y/n] '
read -r yn
[ ! "$yn" = "y" ] && exit
fi
l_name='LICENSE'
[ "$(head -n1 "$LICENSE_DIR"/"$user_license")" = 'UNLICENSE' ] && l_name='UNLICENSE'
cp -fiL "$LICENSE_DIR"/"$user_license" "$l_name"
sed -i "$l_name" \
-e "s/{{PROJECT_NAME}}/$(sed_escape "$(basename "$PWD")")/g" \
-e "s/{{CURRENT_YEAR}}/$(sed_escape "$(date '+%Y')")/g" \
-e "s/{{AUTHOR_NAME}}/$(sed_escape "$AUTHOR_NAME")/g" \
-e "s/{{AUTHOR_EMAIL}}/$(sed_escape "$AUTHOR_EMAIL")/g" \
-e "s/{{AUTHOR_WEBSITE}}/$(sed_escape "$AUTHOR_WEBSITE")/g"
check_license_conflict
info "Current license now is set to $(show_license)"
}
license_picker() {
depend 'awk'
depend 'fzf'
license="$(list_licenses |
awk '{ print $2 }' |
sed "$LICENSE_SED" |
FZF_DEFAULT_OPTS='' fzf --layout=reverse --height=20 --no-mouse -i --preview "cat $LICENSE_DIR/{}" || echo '')"
if [ -z "$license" ]; then
license_picker
return
fi
get_license "@$license"
}
search_license() {
for lic in $(list_licenses | awk '{ print $2 }' | sed "$LICENSE_SED"); do
if echo "$lic $(head -n8 "$LICENSE_DIR"/"$lic")" | grep -iq "$1"; then
einfo "@$lic"
fi
done
}
remove_license() {
rm -f UNLICENSE LICENSE 2>/dev/null || true
info "Current license now is set to $(show_license)"
}
templating_help() {
{
echo 'Templating'
echo ''
echo 'To template a license you need to create a file named'
echo "the same like you want to refer to your license, let's say \`hello\` in this example"
echo "so now create a file called hello in '$LICENSE_DIR/hello'"
echo ''
echo 'Now you can make your license there, now onto templating'
echo ''
echo 'The templating "language" is pretty simple, all syntax goes in {{...}}'
echo 'So the variables are:'
echo ' * {{PROJECT_NAME}} -- The current project name (basename of current directory)'
echo ' * {{CURRENT_YEAR}} -- The current year'
echo " * {{AUTHOR_NAME}} -- The author's full name"
echo " * {{AUTHOR_EMAIL}} -- The author's email"
echo " * {{AUTHOR_WEBSITE}} -- The author's website"
echo ''
echo 'Example of a template: https://raw.githubusercontent.com/TruncatedDinosour/dotfiles-cleaned/gentoo/dotfiles/config/licenses/ArAr2'
} | lless
}
new_template() {
printf 'License name/alias (spaces will be removed) -- '
read -r ln
[ -z "$ln" ] && (
error 'Cannot leave license name empty'
exit 7
)
ln="$LICENSE_DIR/$(echo "$ln" | tr -d ' ' | head -c250)"
if [ -f "$ln" ]; then
printf 'This license already exists, do you want to overwrite it? [y/n] '
read -r yn
[ "$yn" != 'y' ] && exit
fi
editor="${EDITOR:-}"
if [ -z "$editor" ]; then
printf 'Editor to open file in -- '
read -r editor
fi
[ -z "$editor" ] && (
error 'Cannot leave editor empty'
exit 8
)
depend "$(basename "$editor" | awk '{print $1}')"
set -x
$editor "$ln"
set +x
[ -f "$ln" ] && einfo "License '$(basename "$ln")' saved"
}
delete_license() {
check_valid_license "$1"
rm -vi "$LICENSE_DIR"/"$(echo "$1" | sed "$LICENSE_SED")"
}
new_config() {
einfo "This will overwite your config, are you sure you want do do that?"
printf ' [y/n] '
read -r yn
[ "$yn" != 'y' ] && exit
make_new_config
info 'New config made and saved'
}
main() {
if [ -f "$HOME/.config/license.conf" ]; then
# shellcheck disable=1091
. "$HOME/.config/license.conf"
else
warn 'No configuration file found. Creating it.'
make_new_config
exit 4
fi
if [ ! -d "$LICENSE_DIR" ]; then
# shellcheck disable=2088
warn "'$LICENSE_DIR' does not exist. Creating it."
mkdir -p "$LICENSE_DIR"
fi
[ -z "$1" ] && (
usage
exit 1
)
ffind "$LICENSE_DIR" -not -name . -not -path "$LICENSE_DIR" -prune -not -type f -exec rm -R {} +
check_license_conflict
case "$1" in
-help | --help | -h) usage ;;
-list-licenses | -l) list_licenses ;;
-current-license | -c) einfo "$(show_license)" ;;
-pick-license | -p) license_picker ;;
-preview-license | -P)
check_valid_license "$2"
lless "$LICENSE_DIR"/"$(echo "$2" | sed "$LICENSE_SED")" 2>/dev/null || einfo "License $2 not found"
;;
-remove-license | -r) remove_license ;;
-search-license | -s) search_license "$2" ;;
-template-help | -T) templating_help ;;
-new-template | -t) new_template ;;
-delete-license | -R)
tmp_l=0
for lic in "$@"; do
if [ "$tmp_l" = 0 ]; then
tmp_l=1
continue
fi
delete_license "$lic"
done
;;
-new-config | -C) new_config ;;
-check-conflict | -k) check_license_conflict ;;
@*) check_valid_license "$1" && get_license "$1" ;;
*) error "Flag $1 is not known." && usage && exit 2 ;;
esac
}
main "$@"