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

feat: improve ghrpc and tangled setup commands

dunkirk.sh 2870e4df 66f03542

verified
+157 -102
+157 -102
modules/home/system/shell.nix
··· 6 6 ... 7 7 }: 8 8 let 9 + cfg = config.atelier.shell; 10 + tangled = cfg.tangled; 11 + 9 12 tangled-setup = pkgs.writeShellScriptBin "tangled-setup" '' 10 - # Configuration 11 - default_plc_id="did:plc:krxbvxvis5skq7jj6eot23ul" 12 - default_github_username="taciturnaxolotl" 13 - default_knot_host="knot.dunkirk.sh" 13 + set -euo pipefail 14 14 15 - # Verify git repository 15 + # Defaults (configured by Nix) 16 + PLC_ID="${tangled.plcId}" 17 + GITHUB_USER="${tangled.githubUser}" 18 + KNOT_HOST="${tangled.knotHost}" 19 + BRANCH="${tangled.defaultBranch}" 20 + FORCE=false 21 + 22 + usage() { 23 + cat <<EOF 24 + Usage: tangled-setup [OPTIONS] 25 + 26 + Configure git remotes for tangled workflow. 27 + Sets: origin → knot, github → GitHub 28 + 29 + Options: 30 + --plc ID PLC ID (default: $PLC_ID) 31 + --github-user USER GitHub username (default: $GITHUB_USER) 32 + --knot HOST Knot host (default: $KNOT_HOST) 33 + --branch BRANCH Default branch (default: $BRANCH) 34 + -f, --force Overwrite existing remotes without checking 35 + -h, --help Show this help 36 + EOF 37 + exit 0 38 + } 39 + 40 + while [[ $# -gt 0 ]]; do 41 + case "$1" in 42 + -h|--help) usage ;; 43 + --plc) PLC_ID="$2"; shift 2 ;; 44 + --github-user) GITHUB_USER="$2"; shift 2 ;; 45 + --knot) KNOT_HOST="$2"; shift 2 ;; 46 + --branch) BRANCH="$2"; shift 2 ;; 47 + -f|--force) FORCE=true; shift ;; 48 + -*) echo "Unknown option: $1" >&2; exit 1 ;; 49 + *) shift ;; 50 + esac 51 + done 52 + 16 53 if ! ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 17 - ${pkgs.gum}/bin/gum style --foreground 196 "Not a git repository" 54 + echo "Error: Not a git repository" >&2 18 55 exit 1 19 56 fi 20 57 21 58 repo_name=$(basename "$(${pkgs.git}/bin/git rev-parse --show-toplevel)") 22 - ${pkgs.gum}/bin/gum style --bold --foreground 212 "Configuring tangled remotes for: $repo_name" 23 - echo 24 - 25 - # Check current remotes 26 - origin_url=$(${pkgs.git}/bin/git remote get-url origin 2>/dev/null) 27 - github_url=$(${pkgs.git}/bin/git remote get-url github 2>/dev/null) 28 - origin_is_knot=false 29 - github_username="$default_github_username" 59 + knot_url="git@$KNOT_HOST:$PLC_ID/$repo_name" 60 + github_url="git@github.com:$GITHUB_USER/$repo_name.git" 30 61 31 - # Extract GitHub username from existing origin if it's GitHub 32 - if [[ "$origin_url" == *"github.com"* ]]; then 33 - github_username=$(echo "$origin_url" | ${pkgs.gnused}/bin/sed -E 's/.*github\.com[:/]([^/]+)\/.*$/\1/') 34 - fi 62 + echo "Configuring remotes for: $repo_name" 35 63 36 - # Check if origin points to knot 37 - if [[ "$origin_url" == *"$default_knot_host"* ]]; then 38 - origin_is_knot=true 39 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Origin → knot ($origin_url)" 40 - elif [[ -n "$origin_url" ]]; then 41 - ${pkgs.gum}/bin/gum style --foreground 214 "! Origin → $origin_url (not knot)" 64 + # Configure origin → knot 65 + current_origin=$(${pkgs.git}/bin/git remote get-url origin 2>/dev/null || true) 66 + if [[ -z "$current_origin" ]]; then 67 + ${pkgs.git}/bin/git remote add origin "$knot_url" 68 + echo "✓ origin → $knot_url" 69 + elif [[ "$current_origin" == *"$KNOT_HOST"* ]]; then 70 + echo "✓ origin → $current_origin (already knot)" 71 + elif [[ "$FORCE" == true ]]; then 72 + ${pkgs.git}/bin/git remote set-url origin "$knot_url" 73 + echo "✓ origin → $knot_url (was: $current_origin)" 42 74 else 43 - ${pkgs.gum}/bin/gum style --foreground 214 "! Origin not configured" 75 + echo "! origin → $current_origin (use -f to override)" 44 76 fi 45 77 46 - # Check github remote 47 - if [[ -n "$github_url" ]]; then 48 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ GitHub → $github_url" 78 + # Configure github remote 79 + current_github=$(${pkgs.git}/bin/git remote get-url github 2>/dev/null || true) 80 + if [[ -z "$current_github" ]]; then 81 + ${pkgs.git}/bin/git remote add github "$github_url" 82 + echo "✓ github → $github_url" 83 + elif [[ "$FORCE" == true ]]; then 84 + ${pkgs.git}/bin/git remote set-url github "$github_url" 85 + echo "✓ github → $github_url (was: $current_github)" 49 86 else 50 - ${pkgs.gum}/bin/gum style --foreground 214 "! GitHub remote not configured" 51 - fi 52 - 53 - echo 54 - 55 - # Configure origin remote if needed 56 - if [[ "$origin_is_knot" = false ]]; then 57 - should_migrate=true 58 - if [[ -n "$origin_url" ]]; then 59 - ${pkgs.gum}/bin/gum confirm "Migrate origin from $origin_url to knot?" || should_migrate=false 60 - fi 61 - 62 - if [[ "$should_migrate" = true ]]; then 63 - plc_id=$(${pkgs.gum}/bin/gum input --placeholder "$default_plc_id" --prompt "PLC ID: " --value "$default_plc_id") 64 - plc_id=''${plc_id:-$default_plc_id} 65 - 66 - if ${pkgs.git}/bin/git remote get-url origin &>/dev/null; then 67 - ${pkgs.git}/bin/git remote remove origin 68 - fi 69 - ${pkgs.git}/bin/git remote add origin "git@$default_knot_host:''${plc_id}/''${repo_name}" 70 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Configured origin → git@$default_knot_host:''${plc_id}/''${repo_name}" 71 - fi 87 + echo "✓ github → $current_github" 72 88 fi 73 89 74 - # Configure github remote if needed 75 - if [[ -z "$github_url" ]]; then 76 - username=$(${pkgs.gum}/bin/gum input --placeholder "$github_username" --prompt "GitHub username: " --value "$github_username") 77 - username=''${username:-$github_username} 78 - 79 - ${pkgs.git}/bin/git remote add github "git@github.com:''${username}/''${repo_name}.git" 80 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Configured github → git@github.com:''${username}/''${repo_name}.git" 81 - fi 90 + # Set default push to origin 91 + ${pkgs.git}/bin/git config branch.$BRANCH.remote origin 2>/dev/null || true 82 92 83 93 echo 84 - 85 - # Configure default push remote 86 - current_remote=$(${pkgs.git}/bin/git config --get branch.main.remote 2>/dev/null) 87 - if [[ -z "$current_remote" ]]; then 88 - if ${pkgs.gum}/bin/gum confirm "Set origin (knot) as default push remote?"; then 89 - ${pkgs.git}/bin/git config branch.main.remote origin 90 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Default push remote → origin" 91 - fi 92 - elif [[ "$current_remote" != "origin" ]]; then 93 - ${pkgs.gum}/bin/gum style --foreground 117 "Current default: $current_remote" 94 - if ${pkgs.gum}/bin/gum confirm "Change default push remote to origin (knot)?"; then 95 - ${pkgs.git}/bin/git config branch.main.remote origin 96 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Default push remote → origin" 97 - fi 98 - else 99 - ${pkgs.gum}/bin/gum style --foreground 35 "✓ Default push remote is origin" 100 - fi 94 + ${pkgs.git}/bin/git remote -v 101 95 ''; 102 96 103 97 assh = pkgs.writeShellScriptBin "assh" '' ··· 377 371 set -euo pipefail 378 372 379 373 # 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" 374 + PLC_ID="${tangled.plcId}" 375 + GITHUB_USER="${tangled.githubUser}" 376 + KNOT_HOST="${tangled.knotHost}" 377 + TANGLED_DOMAIN="${tangled.domain}" 378 + BRANCH="${tangled.defaultBranch}" 384 379 VISIBILITY="public" 385 380 DESCRIPTION="" 386 381 GITHUB=true ··· 389 384 390 385 usage() { 391 386 cat <<EOF 392 - Usage: ghrpc [OPTIONS] [NAME] 387 + Usage: ghrpc [OPTIONS] [NAME] 393 388 394 - Create repositories on GitHub and/or Tangled. 389 + Create repositories on GitHub and/or Tangled. 390 + Remotes: origin → knot (tangled), github → GitHub 395 391 396 - Arguments: 397 - NAME Repository name (defaults to current directory name if in a git repo) 392 + Arguments: 393 + NAME Repository name (defaults to current directory name) 398 394 399 - Options: 395 + Options: 400 396 -d, --description STR Repository description 401 397 -p, --public Make repository public (default) 402 398 --private Make repository private ··· 404 400 -t, --tangled-only Only create on Tangled 405 401 --no-github Skip GitHub 406 402 --no-tangled Skip Tangled 407 - --plc ID PLC ID for Tangled (default: $PLC_ID) 403 + --plc ID PLC ID (default: $PLC_ID) 408 404 --domain DOMAIN Tangled domain (default: $TANGLED_DOMAIN) 409 405 -h, --help Show this help 410 - EOF 406 + EOF 411 407 exit 0 412 408 } 413 409 ··· 433 429 if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 434 430 NAME=$(basename "$(${pkgs.git}/bin/git rev-parse --show-toplevel)") 435 431 else 436 - echo "Error: No repository name provided and not in a git repository" >&2 437 - exit 1 432 + read -p "Repository name: " NAME 433 + if [[ -z "$NAME" ]]; then 434 + echo "Error: Repository name is required" >&2 435 + exit 1 436 + fi 438 437 fi 438 + fi 439 + 440 + # Prompt for description if not provided 441 + if [[ -z "$DESCRIPTION" ]]; then 442 + read -p "Description (optional): " DESCRIPTION 439 443 fi 440 444 441 445 echo "Creating repository: $NAME" ··· 464 468 echo "✗ Failed to create Tangled repository" >&2 465 469 else 466 470 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 471 fi 478 472 fi 479 473 fi ··· 484 478 [[ -n "$DESCRIPTION" ]] && gh_flags="$gh_flags --description \"$DESCRIPTION\"" 485 479 486 480 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" 481 + if eval "${pkgs.gh}/bin/gh repo create \"$NAME\" $gh_flags --source=. --push --remote=github 2>/dev/null"; then 482 + echo "✓ GitHub: https://github.com/$GITHUB_USER/$NAME" 489 483 else 490 484 echo "✗ Failed to create GitHub repository" >&2 491 485 fi 492 486 else 493 487 if eval "${pkgs.gh}/bin/gh repo create \"$NAME\" $gh_flags --clone 2>/dev/null"; then 494 488 echo "✓ GitHub: created and cloned $NAME" 489 + cd "$NAME" 495 490 else 496 491 echo "✗ Failed to create GitHub repository" >&2 497 492 fi 498 493 fi 499 494 fi 500 495 496 + # Configure remotes: origin → knot, github → GitHub 501 497 if ${pkgs.git}/bin/git rev-parse --is-inside-work-tree &>/dev/null; then 498 + knot_url="git@$KNOT_HOST:$PLC_ID/$NAME" 499 + github_url="git@github.com:$GITHUB_USER/$NAME.git" 500 + 501 + # Set origin to knot 502 + if [[ "$TANGLED" == true ]]; then 503 + if ${pkgs.git}/bin/git remote get-url origin &>/dev/null; then 504 + current_origin=$(${pkgs.git}/bin/git remote get-url origin) 505 + if [[ "$current_origin" != *"$KNOT_HOST"* ]]; then 506 + ${pkgs.git}/bin/git remote set-url origin "$knot_url" 507 + fi 508 + else 509 + ${pkgs.git}/bin/git remote add origin "$knot_url" 510 + fi 511 + fi 512 + 513 + # Set github remote 514 + if [[ "$GITHUB" == true ]]; then 515 + ${pkgs.git}/bin/git remote add github "$github_url" 2>/dev/null || \ 516 + ${pkgs.git}/bin/git remote set-url github "$github_url" 517 + fi 518 + 519 + # Set default push to origin (knot) 520 + ${pkgs.git}/bin/git config branch.$BRANCH.remote origin 2>/dev/null || true 521 + 502 522 echo 503 523 ${pkgs.git}/bin/git remote -v 504 524 fi ··· 506 526 507 527 in 508 528 { 509 - options.atelier.shell.enable = lib.mkEnableOption "Custom shell config"; 510 - config = lib.mkIf config.atelier.shell.enable { 529 + options.atelier.shell = { 530 + enable = lib.mkEnableOption "Custom shell config"; 531 + 532 + tangled = { 533 + plcId = lib.mkOption { 534 + type = lib.types.str; 535 + default = "did:plc:krxbvxvis5skq7jj6eot23ul"; 536 + description = "PLC ID for Tangled"; 537 + }; 538 + 539 + githubUser = lib.mkOption { 540 + type = lib.types.str; 541 + default = "taciturnaxolotl"; 542 + description = "GitHub username"; 543 + }; 544 + 545 + knotHost = lib.mkOption { 546 + type = lib.types.str; 547 + default = "knot.dunkirk.sh"; 548 + description = "Knot host for git remotes"; 549 + }; 550 + 551 + domain = lib.mkOption { 552 + type = lib.types.str; 553 + default = "knot.dunkirk.sh"; 554 + description = "Tangled domain for repo creation"; 555 + }; 556 + 557 + defaultBranch = lib.mkOption { 558 + type = lib.types.str; 559 + default = "main"; 560 + description = "Default git branch"; 561 + }; 562 + }; 563 + }; 564 + 565 + config = lib.mkIf cfg.enable { 511 566 programs.oh-my-posh = { 512 567 enable = true; 513 568 enableZshIntegration = true;