diff --git a/gitea_push.sh b/gitea_push.sh index 0bca28e..27353fd 100755 --- a/gitea_push.sh +++ b/gitea_push.sh @@ -1,6 +1,6 @@ #!/bin/zsh -# Script Version: 1.5 -# Description: Pushes the current folder (e.g. /etc) to a nested Gitea repo using provided nesting arguments. Auto-creates the remote repo via Gitea API if missing. +# Script Version: 1.6 +# Description: Pushes the current folder (e.g. /etc) or a single file to a nested Gitea repo using provided nesting arguments. Auto-creates the remote repo via Gitea API if missing. # Set variables # ======== @@ -27,6 +27,8 @@ GITEA_API_URL="$GITEA_URL/api/v1" PRIVATE=false DEBUG=false COMMIT_MESSAGE="Update $(date +"%F_%T")" +SINGLE_FILE="" +TARGET_REPO="" # Logging function # ======== @@ -65,7 +67,11 @@ create_repo() { } prepare_commit() { - git add . + if [ -n "$SINGLE_FILE" ]; then + git add "$SINGLE_FILE" + else + git add . + fi if git diff --quiet HEAD && ! git rev-parse --verify HEAD >/dev/null 2>&1; then log INFO "Creating initial commit" git commit -m "$COMMIT_MESSAGE" @@ -96,16 +102,24 @@ push_changes() { # ======== if [ $# -eq 0 ]; then echo "GITEA_API_TOKEN=" - echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] " + echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] [--file ] [--repo ] " echo "Example: $0 server" echo " $0 --private workstation" echo " $0 --debug server" echo " $0 --message \"minor update\" server" + echo " $0 --file /path/to/script.sh server" + echo " $0 --file /path/to/script.sh --repo at1-workstation-scripts server" echo - echo "Note: You must cd into the target folder before running this script." + echo "Note: Without --file, you must cd into the target folder before running this script." echo "For example:" echo " cd /etc && $0 server" echo + echo "With --file, you can push a single file from any location:" + echo " $0 --file /home/user/scripts/myscript.sh server" + echo + echo "With --repo, you can specify an existing repository name instead of auto-generating:" + echo " $0 --file /path/to/script.sh --repo at1-workstation-scripts server" + echo echo "Authentication:" echo " Git operations (clone, push, pull) use ~/.netrc with your Git password:" echo " machine \$(echo \"$GITEA_URL\" | sed 's|https\?://||') login $GITEA_USER password \"\"" @@ -133,6 +147,14 @@ while [[ $# -gt 0 ]]; do COMMIT_MESSAGE="$2" shift 2 ;; + --file) + SINGLE_FILE="$2" + shift 2 + ;; + --repo) + TARGET_REPO="$2" + shift 2 + ;; *) POSITIONAL_ARGS+=("$1") shift @@ -143,22 +165,67 @@ done set -- "${POSITIONAL_ARGS[@]}" if [[ $# -ne 1 ]]; then - echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] " + echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] [--file ] [--repo ] " exit 1 fi HOST_GROUP=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-') HOST_NAME=$(hostname -s | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-') -FOLDER_NAME="${HOST_NAME}-${HOST_GROUP}-$(basename "$PWD")" -REPO_PATH="$PWD" -REMOTE_PATH="$FOLDER_NAME" -GIT_REMOTE="$GITEA_URL/$GITEA_USER/$FOLDER_NAME.git" + +if [ -n "$TARGET_REPO" ]; then + # Use specified repository name + FOLDER_NAME="$TARGET_REPO" + if [ -n "$SINGLE_FILE" ]; then + # Validate file exists + if [ ! -f "$SINGLE_FILE" ]; then + log ERROR "File not found: $SINGLE_FILE" + exit 1 + fi + FILE_DIR=$(dirname "$SINGLE_FILE") + REPO_PATH="$FILE_DIR" + log INFO "Using existing repo: $TARGET_REPO" + log INFO "Single file mode: $SINGLE_FILE" + else + REPO_PATH="$PWD" + log INFO "Using existing repo: $TARGET_REPO" + fi + REMOTE_PATH="$FOLDER_NAME" + GIT_REMOTE="$GITEA_URL/$GITEA_USER/$FOLDER_NAME.git" +elif [ -n "$SINGLE_FILE" ]; then + # Validate file exists + if [ ! -f "$SINGLE_FILE" ]; then + log ERROR "File not found: $SINGLE_FILE" + exit 1 + fi + # Get directory and filename + FILE_DIR=$(dirname "$SINGLE_FILE") + FILE_NAME=$(basename "$SINGLE_FILE") + # Sanitize filename for repo name + FILE_NAME_SANITIZED=$(echo "$FILE_NAME" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-') + FOLDER_NAME="${HOST_NAME}-${HOST_GROUP}-${FILE_NAME_SANITIZED}" + REPO_PATH="$FILE_DIR" + REMOTE_PATH="$FOLDER_NAME" + GIT_REMOTE="$GITEA_URL/$GITEA_USER/$FOLDER_NAME.git" + log INFO "Single file mode: $SINGLE_FILE" +else + FOLDER_NAME="${HOST_NAME}-${HOST_GROUP}-$(basename "$PWD")" + REPO_PATH="$PWD" + REMOTE_PATH="$FOLDER_NAME" + GIT_REMOTE="$GITEA_URL/$GITEA_USER/$FOLDER_NAME.git" +fi # Git authentication hint log DEBUG "Ensure ~/.netrc has: machine login $GITEA_USER password " # Check or create remote repo check_or_create_repo() { + if [ -n "$TARGET_REPO" ]; then + # Assume repo exists when --repo is specified + log INFO "Skipping repo creation (using --repo)" + HTTP_STATUS=200 + return + fi + if [ -z "$GITEA_API_TOKEN" ]; then log WARNING "GITEA_API_TOKEN is not set. Skipping API repo creation." return @@ -182,8 +249,8 @@ check_or_create_repo # ======== # Safety check against pushing from / or $HOME -if [[ "$PWD" == "$HOME" || "$PWD" == "/" ]]; then - log ERROR "Refusing to run inside \$PWD=$PWD" +if [[ "$REPO_PATH" == "$HOME" || "$REPO_PATH" == "/" ]]; then + log ERROR "Refusing to run inside \$REPO_PATH=$REPO_PATH" exit 1 fi log INFO "Pushing $REPO_PATH to $GIT_REMOTE" @@ -192,10 +259,22 @@ cd "$REPO_PATH" || { log ERROR "Directory $REPO_PATH not found"; exit 1; } # Initialize git if needed # Branch is fixed to 'main' for simplicity and consistency if [ ! -d .git ]; then - log INFO "Initializing Git repo" - git init - git config init.defaultBranch main - git checkout -b main + if [ -n "$TARGET_REPO" ]; then + # Clone existing repository when --repo is specified + log INFO "Cloning existing repository from $GIT_REMOTE" + TEMP_DIR=".gitea_push_clone_$$" + git clone "$GIT_REMOTE" "$TEMP_DIR" + # Move .git from temp dir to current dir + mv "$TEMP_DIR/.git" .git + rm -rf "$TEMP_DIR" + git config init.defaultBranch main + log INFO "Repository cloned successfully" + else + log INFO "Initializing Git repo" + git init + git config init.defaultBranch main + git checkout -b main + fi else log DEBUG ".git directory already present" fi