Skip to content

feat: add Nix package output for installable u7#42

Merged
vitali87 merged 5 commits intomainfrom
feat/nix-package
Mar 27, 2026
Merged

feat: add Nix package output for installable u7#42
vitali87 merged 5 commits intomainfrom
feat/nix-package

Conversation

@vitali87
Copy link
Owner

Summary

  • Adds packages.default output to flake.nix so users can install u7 system-wide
  • nix profile install github:vitali87/u7 — installs u7 as a standalone command
  • u7-init helper prints the path to source for shell function mode
  • Runtime deps extracted into shared list (used by both package and devShell)
  • wrapProgram ensures all deps are on PATH when running standalone
  • devShell unchanged in functionality

Test plan

  • nix build succeeds
  • ./result/bin/u7 --help works
  • nix develop still works as before
  • Run full test suite

@vitali87
Copy link
Owner Author

@greptile

@vitali87
Copy link
Owner Author

/gemini review

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the usability and packaging of the "u7" utility by introducing a Nix package output. This allows for easy system-wide installation and standalone execution, streamlining dependency management by centralizing runtime requirements for both the package and the development environment.

Highlights

  • Nix Package Output: Added a "packages.default" output to "flake.nix", enabling system-wide installation of the "u7" utility.
  • Standalone Installation: Users can now install "u7" as a standalone command using "nix profile install github:vitali87/u7".
  • u7-init Helper: Introduced a "u7-init" helper script to print the path for sourcing "u7" in shell function mode.
  • Dependency Management: Extracted common runtime dependencies into a shared list, used by both the new package and the existing "devShell".
  • Path Wrapping: Utilized "wrapProgram" to ensure all necessary runtime dependencies are correctly on the PATH when "u7" is run standalone.
  • devShell Consistency: The functionality of the "devShell" remains unchanged, now leveraging the shared dependency list.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a Nix package output for u7, allowing system-wide installation, and refactors runtime dependencies into a shared list. The installPhase correctly sets up the u7 and u7-init scripts, ensuring u7 functions as a standalone command with its dependencies. The devShell is updated to use the shared dependency list, maintaining its functionality. Overall, the changes are well-structured and achieve the stated goals.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a Nix package output for u7, allowing for system-wide installation. The changes are well-implemented, particularly the extraction of runtime dependencies into a shared list, which significantly improves maintainability and reduces duplication between the package and development shell definitions. The installPhase correctly sets up the u7 and u7-init scripts, utilizing wrapProgram to ensure all dependencies are on the PATH. Overall, this is a clean and effective enhancement to the project's Nix flake.

@greptile-apps
Copy link

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR adds a packages.default Nix flake output so u7 can be installed system-wide via nix profile install github:vitali87/u7. The implementation uses a hand-written bash wrapper heredoc (rather than wrapProgram) that hard-codes the Nix store paths for bash, the runtime dependency PATH, and utility.sh at derivation evaluation time — a clean and idiomatic approach for a pure-shell package. A shared runtimeDeps list is introduced to keep the package and devShell in sync, and a u7-init helper is added for users who prefer the shell-function sourcing mode.\n\nKey changes:\n- packages.default: stdenv.mkDerivation with dontBuild = true, a custom installPhase that writes two wrapper scripts via heredocs, and a meta block\n- runtimeDeps: shared list used by both packages.default and devShells.default (note: this silently adds pkgs.bash to the devShell's PATH, which may affect macOS developers — flagged in a previous thread)\n- u7-init: simple helper that prints the path to utility.sh for shell-function mode\n\nIssues found:\n- meta.platforms = platforms.all should be platforms.unix — the package is bash-only and cannot work on Windows targets\n- The $out/bin/u7 wrapper calls u7 \"$@\" after source utility.sh without checking whether the source succeeded; a failed source leaves u7 undefined and bash would resolve u7 as the same binary, causing infinite recursive forking

Confidence Score: 5/5

Safe to merge; both remaining findings are P2 style/hardening suggestions that do not block correct operation under normal conditions.

All P1 concerns from prior review rounds have been addressed (dontBuild, explicit bash shebang, cleanSource, no wrapProgram issues). The two new findings are P2: platforms.all is a metadata inaccuracy without runtime impact, and the source-failure recursion guard is a defensive hardening suggestion for an extremely unlikely scenario in a Nix store package. No blocking issues remain.

flake.nix — minor: platforms.all and missing source guard in wrapper script

Important Files Changed

Filename Overview
flake.nix Adds packages.default derivation using a hand-written bash wrapper heredoc, extracts shared runtimeDeps list. Two minor issues: platforms.all should be platforms.unix, and the wrapper lacks a guard against infinite recursion if source silently fails.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[nix build / nix profile install] --> B[stdenv.mkDerivation]
    B --> C[unpackPhase: cleanSource copied to sandbox]
    C --> D[dontBuild=true: skip buildPhase]
    D --> E[installPhase]
    E --> F[cp utility.sh to out/share/u7/]
    E --> G[write out/bin/u7 via heredoc]
    E --> H[write out/bin/u7-init via heredoc]
    G --> G1[shebang: pkgs.bash, PATH=runtimePath, source utility.sh, u7 args]
    H --> H1[shebang: pkgs.bash, echo path to utility.sh]
    subgraph Runtime
        R1[user: u7 show ip] --> R2[out/bin/u7 wrapper]
        R2 --> R3[export PATH with runtimeDeps]
        R3 --> R4[source utility.sh defines u7 function]
        R4 --> R5[call u7 function with args]
    end
    subgraph ShellMode
        S1[user: source dollar-paren u7-init] --> S2[u7-init prints path]
        S2 --> S3[source utility.sh into shell]
    end
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: flake.nix
Line: 83

Comment:
**`platforms.all` includes non-Unix targets**

`platforms.all` covers every Nix-aware platform including `x86_64-windows` and `i686-windows`. Since `u7` is a bash script, it cannot work on Windows. Using `platforms.unix` (or the more conservative `platforms.linux ++ platforms.darwin`) would correctly signal to Nix evaluators which systems are supported and suppress spurious "broken" warnings on unsupported platforms.

```suggestion
                            platforms = platforms.unix;
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: flake.nix
Line: 67-68

Comment:
**Silent `source` failure can cause infinite recursion**

If `source` on line 67 fails (e.g., unexpected permission change or a future regression in the store path), the `u7` shell function is never defined. Bash then searches `PATH` for a `u7` executable — which resolves to this same wrapper — causing unbounded recursive forking until the process limit is hit.

A simple guard prevents this:

```bash
source "$out/share/u7/utility.sh" || { echo "u7: failed to load utility.sh" >&2; exit 1; }
u7 "$@"
```

This gives a clear error message instead of a fork-bomb in the unlikely-but-possible failure scenario.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (6): Last reviewed commit: "fix: address Greptile review feedback on..." | Re-trigger Greptile

@vitali87
Copy link
Owner Author

@greptile

@vitali87
Copy link
Owner Author

@greptile

@vitali87
Copy link
Owner Author

@greptile


pkgs.rsync

pkgs.bash
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 pkgs.bash silently added to devShells.default

Since devShells.default is built from runtimeDeps ++ [ pkgs.bash-completion ] (line 84), pkgs.bash is now part of devShells.default.buildInputs. This changes the devShell's PATH compared to the previous behaviour (where Nix's bash was not in the shell's packages). On macOS in particular, having Nix's bash prepended to PATH ahead of the system bash can subtly change shell behaviour for developers who rely on the system bash.

Consider separating pkgs.bash into the packages.default-specific list rather than the shared runtimeDeps, or at least call this out in the PR description.

Prompt To Fix With AI
This is a comment left during a code review.
Path: flake.nix
Line: 40

Comment:
**`pkgs.bash` silently added to `devShells.default`**

Since `devShells.default` is built from `runtimeDeps ++ [ pkgs.bash-completion ]` (line 84), `pkgs.bash` is now part of `devShells.default.buildInputs`. This changes the devShell's PATH compared to the previous behaviour (where Nix's bash was not in the shell's packages). On macOS in particular, having Nix's bash prepended to PATH ahead of the system bash can subtly change shell behaviour for developers who rely on the system bash.

Consider separating `pkgs.bash` into the `packages.default`-specific list rather than the shared `runtimeDeps`, or at least call this out in the PR description.

How can I resolve this? If you propose a fix, please make it concise.

@vitali87
Copy link
Owner Author

@greptile

@vitali87
Copy link
Owner Author

@greptile

@vitali87 vitali87 merged commit d4cae03 into main Mar 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant