Repository navigation
Integrate dream2nix outputs into main flake #234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
bd0464a
639b27e
13421f2
917d9df
93c2e71
c19cc60
84c33fb
5a63fa4
3b5a80c
e1aee09
dc701f7
7ab43d2
adfcb32
ba8d9b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Example environment secrets consumed by home-manager/modules/secret | ||
| # Copy to home-manager/.env and provide real values. The .env file stays local. | ||
| MY_SECRET=replace-me | ||
| # GITHUB_TOKEN=ghp_your_token_here |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Nix + dream2nix setup | ||
|
|
||
| This repo can build and expose all CLI tools declared in `package.json` using the exact versions from the lockfile, via [dream2nix]. | ||
|
|
||
| ## Prerequisites | ||
| - Nix installed | ||
| - Flakes enabled (see Nix docs) | ||
|
|
||
| ## Typical usage | ||
|
|
||
| Build the tools as a package: | ||
| ```bash | ||
| nix build .#node-tools | ||
| # The result symlink contains bin/ with your CLI tools | ||
| ls -l result/bin | ||
| ``` | ||
|
|
||
| Open a dev shell with Node and tools on PATH: | ||
|
|
||
| ```bash | ||
| nix develop | ||
| # then run your tools, e.g. | ||
| tsc --version | ||
| prettier --version | ||
| eslint_d --version | ||
| ``` | ||
|
|
||
| Use in Home Manager (example): | ||
|
|
||
| ```nix | ||
| { pkgs, ... }: | ||
| { | ||
| home.packages = [ | ||
| (builtins.getFlake ".").packages.${builtins.currentSystem}.node-tools | ||
| ]; | ||
| } | ||
| ``` | ||
|
Comment on lines
+30
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Home Manager example uses I recommend updating the example to demonstrate this more common and robust pattern. For example: "To use these packages in your Home Manager configuration, first add this repository as an input to your # flake.nix
inputs.my-tools = {
url = "github:shunkakinoki/dotfiles"; # Or the path to this repo
};Then, you can add the package to # home-manager.nix
{ pkgs, inputs, ... }:
{
home.packages = [
inputs.my-tools.packages.${pkgs.system}.node-tools
];
}
```" |
||
|
|
||
| ## Notes | ||
|
|
||
| * Versions are pinned by the lockfile (`package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml`). | ||
| * If you change dependencies, update the lockfile, then rebuild. | ||
| * If your package has native deps, dream2nix will build them; ensure required system libs are available in nixpkgs. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| * **Missing lockfile**: generate one (`npm i`, `pnpm i`, or `yarn install`) before running `nix build`. | ||
|
shunkakinoki marked this conversation as resolved.
Resolved
|
||
| * **Postinstall script fails**: check logs from `nix build`; you may need to add system libraries or patch scripts. | ||
| * **Bins missing**: ensure the dependency actually exposes a `bin` entry in its `package.json`. | ||
|
|
||
| [dream2nix]: https://github.com/nix-community/dream2nix | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -124,7 +124,7 @@ | |||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| perSystem = | ||||||||||||||
| { ... }: | ||||||||||||||
| { system, pkgs, ... }: | ||||||||||||||
| { | ||||||||||||||
| treefmt = { | ||||||||||||||
| projectRootFile = "flake.nix"; | ||||||||||||||
|
|
@@ -139,6 +139,15 @@ | |||||||||||||
| yamlfmt.enable = true; | ||||||||||||||
| }; | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| devShells.default = pkgs.mkShell { | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For creating development shells that don't require a C/C++ compiler toolchain, it's better to use |
||||||||||||||
| packages = [ pkgs.nodejs_20 ]; | ||||||||||||||
| shellHook = '' | ||||||||||||||
| # Enable Corepack so Yarn/PNPM versions follow packageManager field | ||||||||||||||
| corepack enable || true | ||||||||||||||
|
||||||||||||||
| corepack enable || true | |
| if command -v corepack >/dev/null 2>&1; then | |
| corepack enable | |
| else | |
| echo "Warning: 'corepack' not found. Yarn/PNPM version management may not work as expected." | |
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
| ./crush | ||
| ./dust | ||
| ./ghostty | ||
| ./npm-globals | ||
| ./opencode | ||
| ./serena | ||
| ] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { config, lib, pkgs, ... }: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Install npm global packages from package.json using home-manager activation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export PATH=${pkgs.nodejs_20}/bin:${pkgs.corepack}/bin:$PATH | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export PNPM_HOME="$HOME/.local/share/pnpm" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Enable corepack for pnpm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ${pkgs.corepack}/bin/corepack enable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Install global packages from package.json if it exists | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$PACKAGE_JSON" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Installing npm global packages from package.json..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cd "${config.home.homeDirectory}/dotfiles" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+8
to
+17
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Install npm global packages from package.json using home-manager activation | |
| home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] '' | |
| export PATH=${pkgs.bun}/bin:$PATH | |
| export BUN_INSTALL="$HOME/.bun" | |
| # Install global packages from package.json if it exists | |
| PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json" | |
| if [ -f "$PACKAGE_JSON" ]; then | |
| echo "Installing npm global packages from package.json using bun..." | |
| cd "${config.home.homeDirectory}/dotfiles" | |
| # Optionally allow configuring the dotfiles directory location | |
| dotfilesDirectory = config.dotfilesDirectory or "${config.home.homeDirectory}/dotfiles"; | |
| # Install npm global packages from package.json using home-manager activation | |
| home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] '' | |
| export PATH=${pkgs.bun}/bin:$PATH | |
| export BUN_INSTALL="$HOME/.bun" | |
| # Install global packages from package.json if it exists | |
| PACKAGE_JSON="${dotfilesDirectory}/package.json" | |
| if [ -f "$PACKAGE_JSON" ]; then | |
| echo "Installing npm global packages from package.json using bun..." | |
| cd "${dotfilesDirectory}" |
Copilot
AI
Oct 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command silently ignores all errors with 2>/dev/null || true, which could hide legitimate installation failures. Consider logging errors or using more specific error handling.
| $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>/dev/null || true | |
| $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") | |
| if [ $? -ne 0 ]; then | |
| echo "Error: Failed to install npm global packages from package.json using bun." >&2 | |
| fi |
Copilot
AI
Oct 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command suppresses all errors with 2>/dev/null || true, which could hide important installation failures. Consider logging errors or providing more specific error handling.
| $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>/dev/null || true | |
| $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>>"$HOME/.bun-install-errors.log" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling and robustness in activation script.
The activation script has several concerns:
- Line 9:
corepack enableruns without checking if it succeeds - Line 17:
2>/dev/null || truesuppresses all errors, hiding:- Invalid JSON in package.json
- Failed pnpm installations
- Missing dependencies
- Line 15:
cdcould fail if dotfiles directory doesn't exist - Performance: Activation runs on every home-manager switch, potentially reinstalling packages unnecessarily
Consider these improvements:
home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
export PATH=${pkgs.nodejs_20}/bin:${pkgs.corepack}/bin:$PATH
export PNPM_HOME="$HOME/.local/share/pnpm"
# Enable corepack for pnpm
- ${pkgs.corepack}/bin/corepack enable
+ if ! ${pkgs.corepack}/bin/corepack enable; then
+ echo "Warning: Failed to enable corepack" >&2
+ fi
# Install global packages from package.json if it exists
PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json"
if [ -f "$PACKAGE_JSON" ]; then
echo "Installing npm global packages from package.json..."
- cd "${config.home.homeDirectory}/dotfiles"
- ${pkgs.corepack}/bin/pnpm install --global \
- $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>/dev/null || true
+ PACKAGES=$(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON" 2>&1)
+ if [ $? -ne 0 ]; then
+ echo "Warning: Failed to parse package.json: $PACKAGES" >&2
+ elif [ -n "$PACKAGES" ]; then
+ if ! ${pkgs.corepack}/bin/pnpm install --global $PACKAGES; then
+ echo "Warning: Some packages failed to install" >&2
+ fi
+ fi
fi
'';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] '' | |
| export PATH=${pkgs.nodejs_20}/bin:${pkgs.corepack}/bin:$PATH | |
| export PNPM_HOME="$HOME/.local/share/pnpm" | |
| # Enable corepack for pnpm | |
| ${pkgs.corepack}/bin/corepack enable | |
| # Install global packages from package.json if it exists | |
| PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json" | |
| if [ -f "$PACKAGE_JSON" ]; then | |
| echo "Installing npm global packages from package.json..." | |
| cd "${config.home.homeDirectory}/dotfiles" | |
| ${pkgs.corepack}/bin/pnpm install --global \ | |
| $(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>/dev/null || true | |
| fi | |
| ''; | |
| home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] '' | |
| export PATH=${pkgs.nodejs_20}/bin:${pkgs.corepack}/bin:$PATH | |
| export PNPM_HOME="$HOME/.local/share/pnpm" | |
| # Enable corepack for pnpm | |
| if ! ${pkgs.corepack}/bin/corepack enable; then | |
| echo "Warning: Failed to enable corepack" >&2 | |
| fi | |
| # Install global packages from package.json if it exists | |
| PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json" | |
| if [ -f "$PACKAGE_JSON" ]; then | |
| echo "Installing npm global packages from package.json..." | |
| PACKAGES=$(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON" 2>&1) | |
| if [ $? -ne 0 ]; then | |
| echo "Warning: Failed to parse package.json: $PACKAGES" >&2 | |
| elif [ -n "$PACKAGES" ]; then | |
| if ! ${pkgs.corepack}/bin/pnpm install --global $PACKAGES; then | |
| echo "Warning: Some packages failed to install" >&2 | |
| fi | |
| fi | |
| fi | |
| ''; |
🤖 Prompt for AI Agents
In home-manager/modules/npm-globals/default.nix around lines 4 to 19, the
activation script runs corepack without checking its exit status, blindly cds
into dotfiles, silences all errors from jq/pnpm (hiding invalid JSON and install
failures), and may re-run installs on every switch; update the script to (1)
check the exit code of `${pkgs.corepack}/bin/corepack enable` and log+exit on
failure, (2) verify the dotfiles directory exists before cd and skip with a
logged message if missing, (3) validate PACKAGE_JSON with `${pkgs.jq}` and fail
gracefully when JSON is invalid (log the jq error instead of redirecting to
/dev/null), (4) run `${pkgs.corepack}/bin/pnpm install --global` and capture its
exit code, logging any failures instead of using `|| true`, and (5) avoid
unnecessary reinstalls by adding a cheap guard (e.g., check for a
lockfile/marker or verify installed packages with `pnpm list -g` before running
install) so activation is idempotent and failures are visible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Add proper module structure with options and conditional configuration.
The module directly sets home.activation and home.sessionPath without declaring any options or providing an enable switch. Following Home Manager conventions and coding guidelines, modules should:
- Declare options (typically
options.modules.npm-globals.enablewithmkEnableOption) - Gate configuration with
mkIf cfg.enable - Document the module's purpose and options
Based on coding guidelines.
Apply this structure:
{ config, lib, pkgs, ... }:
+let
+ cfg = config.modules.npm-globals;
+in
{
+ options.modules.npm-globals = {
+ enable = lib.mkEnableOption "npm global package management via pnpm";
+
+ packageJsonPath = lib.mkOption {
+ type = lib.types.str;
+ default = "${config.home.homeDirectory}/dotfiles/package.json";
+ description = "Path to package.json containing global dependencies";
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
# Install npm global packages from package.json using home-manager activation
home.activation.installNpmGlobals = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
export PATH=${pkgs.nodejs_20}/bin:${pkgs.corepack}/bin:$PATH
export PNPM_HOME="$HOME/.local/share/pnpm"
# Enable corepack for pnpm
${pkgs.corepack}/bin/corepack enable
# Install global packages from package.json if it exists
- PACKAGE_JSON="${config.home.homeDirectory}/dotfiles/package.json"
+ PACKAGE_JSON="${cfg.packageJsonPath}"
if [ -f "$PACKAGE_JSON" ]; then
echo "Installing npm global packages from package.json..."
- cd "${config.home.homeDirectory}/dotfiles"
+ cd "$(dirname "$PACKAGE_JSON")"
${pkgs.corepack}/bin/pnpm install --global \
$(${pkgs.jq}/bin/jq -r '.dependencies | keys[]' "$PACKAGE_JSON") 2>/dev/null || true
fi
'';
# Add pnpm bin to PATH
home.sessionPath = [
"$HOME/.local/share/pnpm"
];
+ };
}🤖 Prompt for AI Agents
home-manager/modules/npm-globals/default.nix lines 1-25: the module currently
mutates home.activation and home.sessionPath unconditionally; add a proper
module structure by declaring an options attribute (e.g.,
options.modules.npm-globals.enable using lib.mkEnableOption with a helpful
description and default false), then wrap all configuration
(home.activation.installNpmGlobals and home.sessionPath additions) inside
lib.mkIf cfg.enable so they only apply when enabled; ensure the module returns a
config attribute (e.g., config = { ... } or use lib.mkIf to conditionally merge
into config.home.*) and include a short docstring in the option to explain the
purpose.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "name": "dotfiles", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "packageManager": "pnpm@10.15.1", | ||
| "dependencies": { | ||
| "@github/copilot": "^0.0.333", | ||
| "open-composer": "0.8.5" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
builtins.getFlakewith a relative path in Home Manager configuration is not recommended as it creates impure evaluations. Consider using a proper flake input or absolute path reference instead.