165 lines
5.8 KiB
Bash
165 lines
5.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Common utilities for gitlink-cli workflow scripts
|
|
|
|
set -euo pipefail
|
|
# Trap SIGPIPE to prevent premature exit when piping through head/truncate
|
|
trap '' PIPE
|
|
|
|
# Ensure jq is available (WinGet installs to non-default PATH on Windows)
|
|
if ! command -v jq &>/dev/null; then
|
|
for d in "$LOCALAPPDATA/Microsoft/WinGet/Links" "$HOME/AppData/Local/Microsoft/WinGet/Links"; do
|
|
[[ -d "$d" ]] && export PATH="$d:$PATH"
|
|
done
|
|
fi
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m'
|
|
|
|
# ── Logging ──────────────────────────────────────────────────────────
|
|
log_step() { echo -e "${BLUE}[STEP]${NC} $*"; }
|
|
log_ok() { echo -e "${GREEN}[ OK]${NC} $*"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
log_err() { echo -e "${RED}[ ERR]${NC} $*" >&2; }
|
|
log_info() { echo -e "${CYAN}[INFO]${NC} $*"; }
|
|
log_title(){ echo -e "\n${BOLD}══════ $* ══════${NC}\n"; }
|
|
|
|
# ── Auth Check ───────────────────────────────────────────────────────
|
|
check_auth() {
|
|
# Check env var first, then try CLI auth status
|
|
if [[ -n "${GITLINK_TOKEN:-}" ]]; then
|
|
log_ok "GITLINK_TOKEN is set"
|
|
return 0
|
|
fi
|
|
local status
|
|
status=$(gitlink-cli auth status 2>&1)
|
|
if echo "$status" | grep -qi "logged in\|✓"; then
|
|
log_ok "Authenticated: $(echo "$status" | sed -n 's/.*as //p' | tr -d '[:space:]')"
|
|
return 0
|
|
fi
|
|
log_err "Not authenticated. Please login first:"
|
|
log_info " gitlink-cli auth login"
|
|
log_info " export GITLINK_TOKEN=\"your-private-token\""
|
|
exit 1
|
|
}
|
|
|
|
# ── JSON Helpers ─────────────────────────────────────────────────────
|
|
# Extract a field from CLI JSON output (Envelope: {ok, data, ...})
|
|
json_ok() {
|
|
echo "$1" | jq -r '.ok // false' 2>/dev/null
|
|
}
|
|
|
|
json_data() {
|
|
echo "$1" | jq -r '.data' 2>/dev/null
|
|
}
|
|
|
|
json_get() {
|
|
echo "$1" | jq -r "$2" 2>/dev/null
|
|
}
|
|
|
|
json_error() {
|
|
echo "$1" | jq -r '.error.message // "unknown error"' 2>/dev/null
|
|
}
|
|
|
|
# ── CLI Wrapper ──────────────────────────────────────────────────────
|
|
GL="gitlink-cli"
|
|
|
|
gl_run() {
|
|
local output
|
|
# Always use JSON format for scripting
|
|
output=$("$GL" "$@" --format json 2>&1) || true
|
|
echo "$output"
|
|
}
|
|
|
|
gl_check() {
|
|
local output
|
|
output=$(gl_run "$@")
|
|
# Check if output is valid JSON (use here-string to avoid SIGPIPE)
|
|
if ! jq empty <<< "$output" 2>/dev/null; then
|
|
log_err "Command failed (non-JSON response): $GL $*"
|
|
log_err "$output"
|
|
return 1
|
|
fi
|
|
if [[ "$(json_ok "$output")" != "true" ]]; then
|
|
log_err "Command failed: $GL $*"
|
|
log_err "$(json_error "$output")"
|
|
return 1
|
|
fi
|
|
echo "$output"
|
|
}
|
|
|
|
# ── Owner/Repo Detection ────────────────────────────────────────────
|
|
detect_owner_repo() {
|
|
local remote_url
|
|
remote_url=$(git remote get-url origin 2>/dev/null || echo "")
|
|
if [[ -z "$remote_url" ]]; then
|
|
log_err "No git remote 'origin' found. Use --owner and --repo flags."
|
|
exit 1
|
|
fi
|
|
# Parse gitlink URL patterns
|
|
# https://gitlink.org.cn/owner/repo.git or git@gitlink.org.cn:owner/repo.git
|
|
if [[ "$remote_url" =~ gitlink\.org\.cn[:/]([^/]+)/([^/.]+) ]]; then
|
|
DETECTED_OWNER="${BASH_REMATCH[1]}"
|
|
DETECTED_REPO="${BASH_REMATCH[2]}"
|
|
else
|
|
log_err "Cannot parse owner/repo from remote: $remote_url"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
require_owner_repo() {
|
|
if [[ -z "${OWNER:-}" || -z "${REPO:-}" ]]; then
|
|
detect_owner_repo
|
|
OWNER="${OWNER:-$DETECTED_OWNER}"
|
|
REPO="${REPO:-$DETECTED_REPO}"
|
|
fi
|
|
log_info "Using: ${OWNER}/${REPO}"
|
|
}
|
|
|
|
# ── Confirmation ─────────────────────────────────────────────────────
|
|
confirm() {
|
|
local msg="${1:-Proceed?}"
|
|
if [[ "${DRY_RUN:-false}" == "true" ]]; then
|
|
log_warn "[DRY RUN] Would execute: $msg"
|
|
return 1
|
|
fi
|
|
read -rp "$(echo -e "${YELLOW}$msg [y/N]${NC} ")" answer
|
|
[[ "$answer" =~ ^[Yy] ]]
|
|
}
|
|
|
|
# ── Date Helpers ─────────────────────────────────────────────────────
|
|
date_today() {
|
|
date +%Y-%m-%d
|
|
}
|
|
|
|
date_week_ago() {
|
|
date -d "7 days ago" +%Y-%m-%d 2>/dev/null || date -v-7d +%Y-%m-%d 2>/dev/null
|
|
}
|
|
|
|
date_month_ago() {
|
|
date -d "30 days ago" +%Y-%m-%d 2>/dev/null || date -v-30d +%Y-%m-%d 2>/dev/null
|
|
}
|
|
|
|
# ── Parameter Parsing ────────────────────────────────────────────────
|
|
parse_common_args() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--owner) OWNER="$2"; shift 2 ;;
|
|
--repo) REPO="$2"; shift 2 ;;
|
|
--dry-run) DRY_RUN="true"; shift ;;
|
|
--help|-h) usage; exit 0 ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# ── Section Divider ──────────────────────────────────────────────────
|
|
divider() {
|
|
echo -e "${CYAN}────────────────────────────────────────────────${NC}"
|
|
}
|