summaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/gh/ghui/package.nix
blob: 418b8253b7a689ee23e2c85361d585e02ed76080 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{
  lib,
  buildNpmPackage,
  fetchFromGitHub,
  bun,
  gh,
  git,
  nix-update-script,
  runtimeShell,
  versionCheckHook,
}:

buildNpmPackage (finalAttrs: {
  pname = "ghui";
  version = "0.4.6";

  __structuredAttrs = true;

  src = fetchFromGitHub {
    owner = "kitlangton";
    repo = "ghui";
    tag = "v${finalAttrs.version}";
    hash = "sha256-jMi2Pc2VTpj0cZ2zXqtunG0FxcglCNEt9WzWnwxq+Js=";
  };

  # Upstream ghui is a Bun project and ships only `bun.lock`. We vendor an
  # npm `package-lock.json` next to this file so `buildNpmPackage` has a
  # deterministic, cross-OS-stable FOD input; `passthru.updateScript` below
  # keeps it in sync via `nix-update --generate-lockfile`.
  postPatch = ''
    cp ${./package-lock.json} package-lock.json
  '';

  npmDepsHash = "sha256-JxyG7qMJS7zchxLIxYCmsFajUVW4fONnqgeq2iKlt4A=";
  npmDepsFetcherVersion = 2;

  nativeBuildInputs = [ bun ];

  npmFlags = [
    "--no-audit"
    "--no-fund"
  ];

  npmBuildScript = "build:cli";

  nativeInstallCheckInputs = [ versionCheckHook ];
  doInstallCheck = true;

  postInstallCheck = ''
    cd $out/lib/ghui
    ${lib.getExe bun} -e '
      await import("@effect/atom-react")
      await import("@ghui/keymap")
      await import("@opentui/core")
      await import("@opentui/react")
      await import("effect")
      await import("react")
      await import("scheduler")
    '
  '';

  # The bundled CLI runs on Bun and resolves runtime dependencies from the
  # installed node_modules tree. gh is kept on PATH for GitHub API operations.
  installPhase = ''
    runHook preInstall

    npm prune --omit=dev --no-save --no-audit --no-fund
    # `@ghui/keymap` is declared as a `workspace:*` devDependency upstream but
    # imported at runtime (see postInstallCheck). `npm prune --omit=dev` may
    # strip the `node_modules/@ghui/keymap` workspace symlink; restore it
    # idempotently so the Bun runtime can resolve it after install. `ln -sf`
    # is safe whether or not prune actually removed the link.
    ln -sf ../../packages/keymap node_modules/@ghui/keymap

    mkdir -p $out/lib/ghui $out/bin
    cp -r dist node_modules packages package.json README.md LICENSE .env.example $out/lib/ghui/
    rm -f $out/lib/ghui/node_modules/.bin/ghui

    cat > $out/bin/ghui <<'EOF'
    #!@runtimeShell@
    case "''${1-}" in
      -v|--version|version)
        echo @version@
        exit 0
        ;;
      -h|--help|help)
        printf '%s\n' \
          "ghui @version@" \
          "" \
          "Terminal UI for GitHub pull requests." \
          "" \
          "Usage:" \
          "  ghui              Start the TUI" \
          "  ghui -v, --version" \
          "                    Print the installed version" \
          "  ghui -h, --help   Show this help message"
        exit 0
        ;;
    esac

    export PATH=@path@:$PATH
    exec @bun@ "@out@/lib/ghui/dist/index.js" "$@"
    EOF
    substituteInPlace $out/bin/ghui \
      --replace-fail @runtimeShell@ ${runtimeShell} \
      --replace-fail @version@ ${finalAttrs.version} \
      --replace-fail @path@ ${
        lib.makeBinPath [
          gh
          git
        ]
      } \
      --replace-fail @bun@ ${lib.getExe bun} \
      --replace-fail @out@ $out
    chmod +x $out/bin/ghui

    runHook postInstall
  '';

  passthru.updateScript = nix-update-script {
    extraArgs = [ "--generate-lockfile" ];
  };

  meta = {
    description = "Terminal UI for GitHub pull requests";
    homepage = "https://github.com/kitlangton/ghui";
    changelog = "https://github.com/kitlangton/ghui/releases/tag/v${finalAttrs.version}";
    license = lib.licenses.mit;
    maintainers = with lib.maintainers; [ kitlangton ];
    mainProgram = "ghui";
    platforms = bun.meta.platforms;
    sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
  };
})