diff --git a/Makefile b/Makefile index d823757..daae2c6 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,29 @@ find := $(shell { command -v gfind || command -v find; } 2>&-) all: install mkdir: - mkdir -p $(path) + @mkdir -p $(path) rmdir: - rmdir $(path) 2>&-; : + @rmdir $(path) 2>&-; : install: mkdir - $(find) . -maxdepth 1 -type f -executable -exec basename {} \; | while read -r line; do ln -s $$(realpath -- $$line) $(path)/$$line 2>&-; done; true - -rmlinks: - $(find) . -maxdepth 1 -type f -executable -exec basename {} \; | xargs -IF rm -fv $(path)/F + @$(find) . \ + -maxdepth 1 \ + -type f \ + -executable \ + -exec basename {} \; \ + | while read -r line; do \ + ln -s $$(realpath -- $$line) $(path)/$$line 2>&-; \ + done; \ + true + +rmlinks: + @$(find) . \ + -maxdepth 1 \ + -type f \ + -executable \ + -exec basename {} \; \ + | xargs -IF rm -fv $(path)/F uninstall: rmlinks rmdir diff --git a/README.md b/README.md index ae7877f..fb44a07 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ will create the symbolic link for each script in the \ directory. ## Development tools - [doctools2man](doctools2man) converts doctool to man pages. +- [gitea-mirror](gitea-mirror) mirrors Gitea repositories. - [gitlab-ci-graph](gitlab-ci-graph) draws a graph of the GitLab CI Pipeline file. - [gitlab-ci-linter](gitlab-ci-linter) checks Gitlab CI Pipeline syntax via GitLab API. - [how](how) shows dev cheat sheets using [cheat.sh](https://cheat.sh). diff --git a/gitea-mirror b/gitea-mirror new file mode 100755 index 0000000..53a49c9 --- /dev/null +++ b/gitea-mirror @@ -0,0 +1,92 @@ +#!/bin/bash + +# Gitea repositories mirrorer + +rstc="\033[00m" +yellow="\033[1;33m" +blue="\033[1;36m" +red="\033[1;31m" + +show_help() { + echo -e "$(basename "$0") can be used to mirror all git repositories hosted on Gitea.\n" + echo -e "USAGE: $(basename "$0") -u USER -g GIT_URL ?-d DIR?\n" + + echo -e "Command line arguments:" + echo -e " -h --help show this help" + echo -e " -f --force drop all existing local changes" + echo -e " -u --user user name" + echo -e " -g --git git url" + echo -e " -p --private comma separated private repositories" + echo -e " -d --dir directory for storing files (current working directory by default)" + + echo + exit "${1:-0}" +} + +die() { + echo -e "${red}ERROR:${rstc} $*\n" + + show_help 1 +} + +git_update() { + pushd "$1" >/dev/null + + [ -n "$FORCE" ] && git checkout . 2>&- + + git fetch + git pull --all + + popd >/dev/null +} + +#------------------------------------------------------------------------------- + +UNKNOWN_ARGS=() + +[ $# -eq 0 ] && show_help + +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + -h|--help) show_help;; + -d|--dir) DIRECTORY="$2"; shift; shift;; + -u|--user) USERNAME="$2"; shift; shift;; + -g|--git) GIT_URL="$2"; shift; shift;; + -p|--private) PRIVATE="$2"; shift; shift;; + -f|--force) FORCE="true"; shift;; + *) UNKNOWN_ARGS+=("$1"); shift;; + esac +done + +[ ${#UNKNOWN_ARGS} -gt 0 ] && die "Unknown parameters: ${UNKNOWN_ARGS[*]}" +[ -z "${GIT_URL+x}" ] && die "Unknown gitea URL. Use the --git cli parameter to specify it." +[ -z "${USERNAME+x}" ] && die "Unknown gitea user. Use the --user cli parameter to specify it." + +#------------------------------------------------------------------------------- + +[ -n "$DIRECTORY" ] && mkdir -p "$DIRECTORY" && cd "$DIRECTORY" + +mapfile -t REPOSITORIES < <(curl -sq -L "$GIT_URL/api/v1/users/$USERNAME/repos" | jq -r '.[].clone_url') + +if [ -n "$PRIVATE" ]; then + for repository in $(tr ',' ' ' <<<"$PRIVATE"); do + REPOSITORIES+=("https://${GIT_URL}/${USERNAME}/${repository}.git") + done +fi + +r=0 + +for repository in ${REPOSITORIES[*]}; do + repo_name=$(sed 's/\.git.*$//' <<<"${repository##*/}") + + printf "\n${yellow}#### [%02d/%02d] ${blue}%s${rstc}\n" $((++r)) "${#REPOSITORIES[@]}" "$repo_name" + + if [ ! -d "$repo_name" ]; then + git clone --progress "$repository" + fi + + git_update "$repo_name" +done +