Kieran's opinionated (and probably slightly dumb) nix config

feat: update ghrpc command

dunkirk.sh a46b9342 80fd0496

verified
+114 -129
+114 -129
modules/home/system/shell.nix
··· 374 374 ''; 375 375 376 376 ghrpc = pkgs.writeShellScriptBin "ghrpc" '' 377 - # Create GitHub and Tangled repos 378 - default_plc_id="did:plc:krxbvxvis5skq7jj6eot23ul" 379 - default_knot_host="knot.dunkirk.sh" 380 - default_tangled_domain="knot.dunkirk.sh" 381 - default_branch="main" 377 + set -euo pipefail 382 378 383 - # Check if we're in a git repository 384 - if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 385 - repo_name=$(basename "$(${pkgs.git}/bin/git rev-parse --show-toplevel)") 386 - ${pkgs.gum}/bin/gum style --foreground 214 "Already in a git repository: $repo_name" 387 - ${pkgs.gum}/bin/gum style --foreground 214 "This will add remotes to the existing repository." 388 - echo 389 - else 390 - # Get repository name 391 - repo_name=$(${pkgs.gum}/bin/gum input --placeholder "my-awesome-project" --prompt "Repository name: ") 392 - if [[ -z "$repo_name" ]]; then 393 - ${pkgs.gum}/bin/gum style --foreground 196 "No repository name provided" 394 - exit 1 395 - fi 396 - fi 379 + # Defaults (configured by Nix) 380 + PLC_ID="did:plc:krxbvxvis5skq7jj6eot23ul" 381 + KNOT_HOST="knot.dunkirk.sh" 382 + TANGLED_DOMAIN="knot.dunkirk.sh" 383 + BRANCH="main" 384 + VISIBILITY="public" 385 + DESCRIPTION="" 386 + GITHUB=true 387 + TANGLED=true 388 + NAME="" 397 389 398 - ${pkgs.gum}/bin/gum style --bold --foreground 212 "Creating repository: $repo_name" 399 - echo 390 + usage() { 391 + cat <<EOF 392 + Usage: ghrpc [OPTIONS] [NAME] 400 393 401 - # Get description 402 - description=$(${pkgs.gum}/bin/gum input --placeholder "A cool project" --prompt "Description: ") 403 - description=''${description:-""} 394 + Create repositories on GitHub and/or Tangled. 404 395 405 - # Get visibility 406 - if ${pkgs.gum}/bin/gum confirm "Make repository public?"; then 407 - visibility="public" 408 - else 409 - visibility="private" 410 - fi 396 + Arguments: 397 + NAME Repository name (defaults to current directory name if in a git repo) 411 398 412 - # Create on Tangled 413 - if ${pkgs.gum}/bin/gum confirm "Create on Tangled?"; then 414 - ${pkgs.gum}/bin/gum style --foreground 117 "Tangled configuration:" 415 - 416 - # Check for tangled session cookie 417 - tangled_cookie="" 418 - if [[ -f "/run/agenix/tangled-session" ]]; then 419 - tangled_cookie=$(cat /run/agenix/tangled-session) 420 - fi 399 + Options: 400 + -d, --description STR Repository description 401 + -p, --public Make repository public (default) 402 + --private Make repository private 403 + -g, --github-only Only create on GitHub 404 + -t, --tangled-only Only create on Tangled 405 + --no-github Skip GitHub 406 + --no-tangled Skip Tangled 407 + --plc ID PLC ID for Tangled (default: $PLC_ID) 408 + --domain DOMAIN Tangled domain (default: $TANGLED_DOMAIN) 409 + -h, --help Show this help 410 + EOF 411 + exit 0 412 + } 421 413 422 - if [[ -z "$tangled_cookie" ]]; then 423 - ${pkgs.gum}/bin/gum style --foreground 214 "⚠ No tangled session cookie found" 424 - ${pkgs.gum}/bin/gum style --foreground 214 " Please copy your appview-session-v2 cookie from tangled.org" 425 - tangled_cookie=$(${pkgs.gum}/bin/gum input --password --placeholder "appview-session-v2=..." --prompt "Cookie: ") 426 - 427 - if [[ -z "$tangled_cookie" ]]; then 428 - ${pkgs.gum}/bin/gum style --foreground 196 "No cookie provided, skipping Tangled" 429 - fi 430 - fi 414 + while [[ $# -gt 0 ]]; do 415 + case "$1" in 416 + -h|--help) usage ;; 417 + -d|--description) DESCRIPTION="$2"; shift 2 ;; 418 + -p|--public) VISIBILITY="public"; shift ;; 419 + --private) VISIBILITY="private"; shift ;; 420 + -g|--github-only) TANGLED=false; shift ;; 421 + -t|--tangled-only) GITHUB=false; shift ;; 422 + --no-github) GITHUB=false; shift ;; 423 + --no-tangled) TANGLED=false; shift ;; 424 + --plc) PLC_ID="$2"; shift 2 ;; 425 + --domain) TANGLED_DOMAIN="$2"; shift 2 ;; 426 + -*) echo "Unknown option: $1" >&2; exit 1 ;; 427 + *) NAME="$1"; shift ;; 428 + esac 429 + done 430 + 431 + # Determine repo name 432 + if [[ -z "$NAME" ]]; then 433 + if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 434 + NAME=$(basename "$(${pkgs.git}/bin/git rev-parse --show-toplevel)") 435 + else 436 + echo "Error: No repository name provided and not in a git repository" >&2 437 + exit 1 438 + fi 439 + fi 431 440 432 - if [[ -n "$tangled_cookie" ]]; then 433 - tangled_domain=$(${pkgs.gum}/bin/gum input --placeholder "$default_tangled_domain" --prompt "Domain: " --value "$default_tangled_domain") 434 - tangled_domain=''${tangled_domain:-$default_tangled_domain} 441 + echo "Creating repository: $NAME" 435 442 436 - # URL encode the description 437 - encoded_desc=$(echo -n "$description" | ${pkgs.gnused}/bin/sed 's/ /%20/g; s/!/%21/g; s/"/%22/g; s/#/%23/g; s/\$/%24/g; s/&/%26/g; s/'"'"'/%27/g; s/(/%28/g; s/)/%29/g; s/\*/%2A/g; s/+/%2B/g; s/,/%2C/g; s/\//%2F/g; s/:/%3A/g; s/;/%3B/g; s/=/%3D/g; s/?/%3F/g; s/@/%40/g; s/\[/%5B/g; s/\]/%5D/g') 443 + # Create on Tangled 444 + if [[ "$TANGLED" == true ]]; then 445 + tangled_cookie="" 446 + if [[ -f "/run/agenix/tangled-session" ]]; then 447 + tangled_cookie=$(cat /run/agenix/tangled-session) 448 + fi 438 449 439 - ${pkgs.gum}/bin/gum spin --spinner dot --title "Creating repository on Tangled..." -- \ 440 - ${pkgs.curl}/bin/curl -s 'https://tangled.org/repo/new' \ 441 - -H 'Accept: */*' \ 442 - -H 'Content-Type: application/x-www-form-urlencoded' \ 443 - -b "appview-session-v2=$tangled_cookie" \ 444 - -H 'HX-Current-URL: https://tangled.org/repo/new' \ 445 - -H 'HX-Request: true' \ 446 - -H 'Origin: https://tangled.org' \ 447 - -H 'Referer: https://tangled.org/repo/new' \ 448 - --data-raw "name=''${repo_name}&description=''${encoded_desc}&branch=''${default_branch}&domain=''${tangled_domain}" \ 449 - > /tmp/tangled-response-$$.html 450 + if [[ -z "$tangled_cookie" ]]; then 451 + echo "Warning: No tangled session cookie found at /run/agenix/tangled-session" >&2 452 + else 453 + encoded_desc=$(printf '%s' "$DESCRIPTION" | ${pkgs.gnused}/bin/sed 's/ /%20/g; s/!/%21/g; s/"/%22/g; s/#/%23/g; s/\$/%24/g; s/&/%26/g; s/'"'"'/%27/g; s/(/%28/g; s/)/%29/g; s/\*/%2A/g; s/+/%2B/g; s/,/%2C/g; s/\//%2F/g; s/:/%3A/g; s/;/%3B/g; s/=/%3D/g; s/?/%3F/g; s/@/%40/g; s/\[/%5B/g; s/\]/%5D/g') 450 454 451 - if grep -q "error\|Error\|failed\|Failed" /tmp/tangled-response-$$.html 2>/dev/null; then 452 - ${pkgs.gum}/bin/gum style --foreground 196 "✗ Failed to create Tangled repository" 453 - ${pkgs.gum}/bin/gum style --foreground 196 " Check /tmp/tangled-response-$$.html for details" 454 - else 455 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Created on Tangled: https://tangled.org/$tangled_domain/$repo_name" 456 - 457 - # Add tangled remote 458 - plc_id=$(${pkgs.gum}/bin/gum input --placeholder "$default_plc_id" --prompt "PLC ID: " --value "$default_plc_id") 459 - plc_id=''${plc_id:-$default_plc_id} 460 - 461 - if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 462 - if ${pkgs.git}/bin/git remote get-url origin &>/dev/null; then 463 - ${pkgs.gum}/bin/gum style --foreground 214 "Origin already exists, adding as 'tangled' remote" 464 - ${pkgs.git}/bin/git remote add tangled "git@$default_knot_host:''${plc_id}/''${repo_name}" 2>/dev/null || \ 465 - ${pkgs.git}/bin/git remote set-url tangled "git@$default_knot_host:''${plc_id}/''${repo_name}" 466 - else 467 - ${pkgs.git}/bin/git remote add origin "git@$default_knot_host:''${plc_id}/''${repo_name}" 468 - fi 469 - fi 470 - 471 - rm -f /tmp/tangled-response-$$.html 472 - fi 473 - fi 474 - fi 455 + response=$(${pkgs.curl}/bin/curl -s 'https://tangled.org/repo/new' \ 456 + -H 'Accept: */*' \ 457 + -H 'Content-Type: application/x-www-form-urlencoded' \ 458 + -b "appview-session-v2=$tangled_cookie" \ 459 + -H 'HX-Request: true' \ 460 + -H 'Origin: https://tangled.org' \ 461 + --data-raw "name=$NAME&description=$encoded_desc&branch=$BRANCH&domain=$TANGLED_DOMAIN") 475 462 476 - # Create on GitHub 477 - if ${pkgs.gum}/bin/gum confirm "Create on GitHub?"; then 478 - gh_flags="" 479 - [[ "$visibility" == "public" ]] && gh_flags="--public" || gh_flags="--private" 480 - [[ -n "$description" ]] && gh_flags="$gh_flags --description \"$description\"" 463 + if echo "$response" | grep -qi "error\|failed"; then 464 + echo "✗ Failed to create Tangled repository" >&2 465 + else 466 + echo "✓ Tangled: https://tangled.org/$TANGLED_DOMAIN/$NAME" 467 + 468 + if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 469 + tangled_url="git@$KNOT_HOST:$PLC_ID/$NAME" 470 + if ${pkgs.git}/bin/git remote get-url origin &>/dev/null; then 471 + ${pkgs.git}/bin/git remote add tangled "$tangled_url" 2>/dev/null || \ 472 + ${pkgs.git}/bin/git remote set-url tangled "$tangled_url" 473 + else 474 + ${pkgs.git}/bin/git remote add origin "$tangled_url" 475 + fi 476 + fi 477 + fi 478 + fi 479 + fi 481 480 482 - ${pkgs.gum}/bin/gum spin --spinner dot --title "Creating repository on GitHub..." -- \ 483 - bash -c "${pkgs.gh}/bin/gh repo create \"$repo_name\" $gh_flags --clone 2>&1" > /tmp/gh-response-$$.txt 481 + # Create on GitHub 482 + if [[ "$GITHUB" == true ]]; then 483 + gh_flags="--$VISIBILITY" 484 + [[ -n "$DESCRIPTION" ]] && gh_flags="$gh_flags --description \"$DESCRIPTION\"" 484 485 485 - if [[ $? -eq 0 ]]; then 486 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Created on GitHub" 487 - 488 - # If we weren't in a git repo before, cd into the new one 489 - if ! ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null && [[ -d "$repo_name" ]]; then 490 - cd "$repo_name" 491 - ${pkgs.gum}/bin/gum style --foreground 117 "Changed to directory: $repo_name" 492 - fi 493 - 494 - # Add github remote if it doesn't exist 495 - if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 496 - if ! ${pkgs.git}/bin/git remote get-url github &>/dev/null; then 497 - github_url=$(${pkgs.git}/bin/git remote get-url origin 2>/dev/null | ${pkgs.gnused}/bin/sed 's/origin/github/') 498 - if [[ -n "$github_url" && "$github_url" == *"github.com"* ]]; then 499 - ${pkgs.git}/bin/git remote add github "$github_url" 2>/dev/null || true 500 - fi 501 - fi 502 - fi 503 - else 504 - ${pkgs.gum}/bin/gum style --foreground 196 "✗ Failed to create GitHub repository" 505 - cat /tmp/gh-response-$$.txt 506 - fi 507 - 508 - rm -f /tmp/gh-response-$$.txt 509 - fi 486 + if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 487 + if eval "${pkgs.gh}/bin/gh repo create \"$NAME\" $gh_flags --source=. --remote=github 2>/dev/null"; then 488 + echo "✓ GitHub: https://github.com/$(${pkgs.gh}/bin/gh api user -q .login)/$NAME" 489 + else 490 + echo "✗ Failed to create GitHub repository" >&2 491 + fi 492 + else 493 + if eval "${pkgs.gh}/bin/gh repo create \"$NAME\" $gh_flags --clone 2>/dev/null"; then 494 + echo "✓ GitHub: created and cloned $NAME" 495 + else 496 + echo "✗ Failed to create GitHub repository" >&2 497 + fi 498 + fi 499 + fi 510 500 511 - echo 512 - ${pkgs.gum}/bin/gum style --bold --foreground 35 "Done!" 513 - 514 - # Show remotes 515 - if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 516 - echo 517 - ${pkgs.gum}/bin/gum style --bold "Git remotes:" 518 - ${pkgs.git}/bin/git remote -v 519 - fi 501 + if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 502 + echo 503 + ${pkgs.git}/bin/git remote -v 504 + fi 520 505 ''; 521 506 522 507 in