#!/usr/bin/env bash #___Config_____________________________________________________________________________________________# default_branch_name="master" default_repo_visibility="PRIVATE" #___Helpers____________________________________________________________________________________________# function print_help() { printDivider echo -e "Usage: sourcehut-push \e[1;31m-y \e[1;35m~/path/to/git/repo\e[0m" echo -e " sourcehut-push \e[1;31m-h \e[0m| \e[1;31m--help\e[0m" echo -e "" echo -e "Before use set your personal sourcehut access token ( https://meta.sr.ht/oauth2 )" echo -e "The minimal grant string is: '\e[1;32mgit.sr.ht/REPOSITORIES:RW git.sr.ht/PROFILE\e[0m'" echo -e "\e[1;34mexport SRHT_ACCESS_TOKEN=\"\e[1;35myour_personal_access_token\e[1;34m\"\e[0m" echo -e "" echo -e "Options:" echo -e " \e[1;31m-y\e[0m \e[1;30m# Skip interaction and use default values.\e[0m" echo -e " \e[1;31m-h\e[0m, \e[1;31m--help\e[0m \e[1;30m# Display this help message and exit.\e[0m" echo -e "" echo -e "Description:" echo -e " This script automates the process of creating a new repository on Sourcehut and pushing the code from a local Git repository." printDivider } function printDivider() { local columns i columns=$(tput cols) for i in $(seq 1 "$columns"); do echo -n '─'; done echo '' } #___Check_inputs_and_flags_____________________________________________________________________________# function check_SRHT_access_token() { if [ -z "$SRHT_ACCESS_TOKEN" ]; then echo "Error: SRHT_ACCESS_TOKEN environment variable is not set." echo "Please set the variable with your personal access token." echo "The minimal grant string is 'git.sr.ht/REPOSITORIES:RW git.sr.ht/PROFILE'." echo "export SRHT_ACCESS_TOKEN=\"your_personal_access_token\"" exit 1 fi } function check_and_set_repo_path() { if [ -z "$1" ]; then print_help exit 1 fi repo_path="$1" } #___Functions__________________________________________________________________________________________# function check_valid_git_repository() { if [ ! -d "${repo_path}/.git" ]; then echo "The provided path is not a valid git repository." exit 1 fi } function get_and_set_current_branch() { current_branch=$(git -C "$repo_path" symbolic-ref --short HEAD) } function rename_primary_branch() { if ! $skip_interactions; then read -p "Do you want to rename the primary branch '$current_branch'? (Y/n): " confirm_rename if [ -z "$confirm_rename" ] || [ "$confirm_rename" == "Y" ] || [ "$confirm_rename" == "y" ]; then read -p "Enter a new branch name (default is '$default_branch_name'): " new_branch_name new_branch_name=${new_branch_name:-$default_branch_name} git -C "$repo_path" branch -m "$current_branch" "$new_branch_name" current_branch="$new_branch_name" echo "Renamed the primary branch to '$current_branch'." else echo "The current primary branch is '$current_branch'." fi fi } function set_sanitized_repo_name() { default_repo_name="$(basename "${repo_path}" | tr -cs '[:alnum:]' '_' | sed 's/_*$//')" } function ask_for_repo_name() { if [ "$skip_interactions" = false ]; then read -p "Enter the repository name [default: ${default_repo_name}]: " repo_name fi } function set_repo_name() { if [ -z "$repo_name" ] || [ "$skip_interactions" = true ]; then repo_name="$default_repo_name" fi } function set_repo_description() { repo_description="Your repository description" } function ask_for_repo_description() { if [ "$skip_interactions" = false ]; then read -p "Enter the repository description [default: ${repo_description}]: " input_repo_description fi } function update_repo_description() { if [ -n "$input_repo_description" ]; then repo_description="$input_repo_description" fi } function set_repository_visibility() { options=("PUBLIC" "UNLISTED" "PRIVATE") if [ "$skip_interactions" = false ]; then PS3="Please select a repository visibility (default is $default_repo_visibility): " select opt in "${options[@]}"; do if [ -z "$opt" ]; then repo_visibility="$default_repo_visibility" break fi case $opt in "PUBLIC" | "UNLISTED" | "PRIVATE") repo_visibility=$opt break ;; *) echo "Invalid option. Please try again." ;; esac done else repo_visibility="$default_repo_visibility" fi } function create_repository_and_push_code() { api_endpoint="https://git.sr.ht/query" tempfile=$(mktemp) response_header=$(curl --silent --oauth2-bearer "$SRHT_ACCESS_TOKEN" \ -H 'Content-Type: application/json' \ -d "{\"query\": \"mutation { createRepository(name: \\\"$repo_name\\\", visibility: $repo_visibility, description: \\\"$repo_description\\\") { id, name, owner { canonicalName } } }\"}" \ -w "%{http_code}" \ -o "$tempfile" \ $api_endpoint) http_status_code="${response_header}" response="$(cat "$tempfile")" if [ "$http_status_code" -ne 200 ]; then echo "Error: HTTP status code $http_status_code" error_reason=$(echo "$response" | jq -r '.errors[0].message // empty') if [ -n "$error_reason" ]; then echo "Error: $error_reason" else echo "$response" fi exit 1 fi response_name=$(echo "$response" | jq -r '.data.createRepository.name // empty') response_canonicalName=$(echo "$response" | jq -r '.data.createRepository.owner.canonicalName // empty') if [ -n "$response_name" ] && [ -n "$response_canonicalName" ]; then printDivider echo "Repository created successfully." ssh_url="git@git.sr.ht:$response_canonicalName/$response_name" echo "SSH URL: $ssh_url" printDivider cd "${repo_path}" || exit if git remote get-url origin >/dev/null 2>&1; then git remote set-url origin "$ssh_url" else git remote add origin "$ssh_url" fi sleep 1 # Just in case the server needs some time git push -u origin "$current_branch" else echo "Failed to create repository. Reason: $response" exit 1 fi } #___Main_control_flow_______________________________________________________________________________# if [ "$1" == "-y" ]; then skip_interactions=true shift else skip_interactions=false fi if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then print_help exit 0 fi check_and_set_repo_path "$@" check_SRHT_access_token check_valid_git_repository get_and_set_current_branch rename_primary_branch set_sanitized_repo_name ask_for_repo_name set_repo_name set_repo_description ask_for_repo_description update_repo_description set_repository_visibility create_repository_and_push_code