Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40e3b99d82 |
@@ -55,7 +55,3 @@ f2f1076c1f789595c2a2b18b76466fbd691025dd
|
||||
11ad9d2e42ebf6d00db4d7bae252f1c6b7dd36a4
|
||||
74b0e979375b0ed469e2394820aa50ba2114800b
|
||||
de90ee24082bb8dd44145f5c733b807467856820
|
||||
|
||||
# Deadnix cleanup
|
||||
71402c5df34df5ee7b6c10d738018f9f0c8bde2b
|
||||
a93d80bcec089abf80894c25ee3934b7e196bbd9
|
||||
|
||||
@@ -24,8 +24,8 @@ Also make sure to read the guidelines found at
|
||||
- [ ] Code formatted with `nix fmt` or
|
||||
`nix-shell -A dev --run treefmt`.
|
||||
|
||||
- [ ] Code tested through `nix build .#test-all`
|
||||
or a targeted `nix run .#tests -- <pattern>`.
|
||||
- [ ] Code tested through `nix run .#tests -- test-all` or
|
||||
`nix-shell --pure tests -A run.all`.
|
||||
|
||||
- [ ] Test cases updated/added. See [example](https://github.com/nix-community/home-manager/commit/f3fbb50b68df20da47f9b0def5607857fcc0d021#diff-b61a6d542f9036550ba9c401c80f00ef).
|
||||
|
||||
|
||||
+1
-15
@@ -9,22 +9,8 @@ updates:
|
||||
prefix: "ci:"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "release-26.05"
|
||||
target-branch: "release-25.11"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci:"
|
||||
- package-ecosystem: "nix"
|
||||
directory: "/"
|
||||
target-branch: "master"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "flake:"
|
||||
- package-ecosystem: "nix"
|
||||
directory: "/"
|
||||
target-branch: "release-26.05"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "flake:"
|
||||
|
||||
+2
-5
@@ -1,16 +1,13 @@
|
||||
"release":
|
||||
- base-branch:
|
||||
- '^release-.*'
|
||||
"ai":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- modules/programs/aiac.nix
|
||||
- modules/programs/aichat.nix
|
||||
- modules/programs/aider-chat.nix
|
||||
- modules/programs/claude-code/**/*
|
||||
- modules/programs/claude-code.nix
|
||||
- modules/programs/codex.nix
|
||||
- modules/programs/fabric-ai.nix
|
||||
- modules/programs/antigravity-cli.nix
|
||||
- modules/programs/gemini-cli.nix
|
||||
- modules/programs/mcp.nix
|
||||
- modules/programs/mistral-vibe.nix
|
||||
- modules/programs/mods.nix
|
||||
|
||||
@@ -31,10 +31,10 @@ jobs:
|
||||
with:
|
||||
app-id: ${{ vars.CI_APP_ID }}
|
||||
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Create backport PRs
|
||||
id: backport
|
||||
uses: korthout/backport-action@v4
|
||||
|
||||
@@ -12,10 +12,10 @@ jobs:
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v6
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixpkgs-unstable
|
||||
nix_path: nixpkgs=channel:nixos-unstable
|
||||
- uses: cachix/cachix-action@v17
|
||||
with:
|
||||
name: nix-community
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
run: |
|
||||
COUNT=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename' | grep -c '^modules/' || true)
|
||||
COUNT=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename' | grep '^modules/' | wc -l || echo 0)
|
||||
echo "Found $COUNT changed module files."
|
||||
echo "count=$COUNT" >> "$GITHUB_OUTPUT"
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
app-id: ${{ vars.CI_APP_ID }}
|
||||
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
- name: Get Nixpkgs revision from flake.lock
|
||||
@@ -42,12 +42,12 @@ jobs:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
run: |
|
||||
CHANGED_FILES=$(gh pr diff "$PR_NUMBER" --name-only | grep '^modules/' | grep -v '^modules/\(po\|.*\/news\)/' || true)
|
||||
CHANGED_FILES=$(gh pr diff $PR_NUMBER --name-only | grep '^modules/' | grep -v '^modules/\(po\|.*\/news\)/' || true)
|
||||
echo "Changed files:"
|
||||
echo "$CHANGED_FILES"
|
||||
echo "changed_files<<EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$CHANGED_FILES" >> "$GITHUB_OUTPUT"
|
||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$CHANGED_FILES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
- name: Extract Maintainers
|
||||
id: extract-maintainers
|
||||
env:
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
MAINTAINERS=$(lib/python/extract-maintainers.py \
|
||||
--changed-files "$CHANGED_FILES" \
|
||||
--pr-author "$PR_AUTHOR")
|
||||
echo "maintainers=$MAINTAINERS" >> "$GITHUB_OUTPUT"
|
||||
echo "maintainers=$MAINTAINERS" >> $GITHUB_OUTPUT
|
||||
echo "Found maintainers: $MAINTAINERS"
|
||||
- name: Manage Reviewers
|
||||
env:
|
||||
|
||||
+16
-38
@@ -6,19 +6,16 @@ on:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
permissions: {}
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
docs: ${{ steps.changes.outputs.docs }}
|
||||
format: ${{ steps.changes.outputs.format }}
|
||||
hm: ${{ steps.changes.outputs.hm }}
|
||||
parse: ${{ steps.changes.outputs.parse }}
|
||||
tests: ${{ steps.changes.outputs.tests }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dorny/paths-filter@v4
|
||||
id: changes
|
||||
with:
|
||||
@@ -42,41 +39,28 @@ jobs:
|
||||
- 'flake.lock'
|
||||
- 'flake.nix'
|
||||
- 'home-manager/**'
|
||||
parse:
|
||||
- '**/*.nix'
|
||||
- 'flake.lock'
|
||||
tests:
|
||||
needs: changes
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/checkout@v6
|
||||
- name: Get Nixpkgs revision from flake.lock
|
||||
id: get-nixpkgs
|
||||
run: |
|
||||
echo "rev=$(jq -r '.nodes.nixpkgs.locked.rev' flake.lock)" >> "$GITHUB_OUTPUT"
|
||||
- uses: cachix/install-nix-action@v31
|
||||
if: github.event_name == 'schedule' || needs.changes.outputs.docs == 'true' || needs.changes.outputs.tests == 'true' || needs.changes.outputs.hm == 'true' || needs.changes.outputs.parse == 'true' || needs.changes.outputs.format == 'true'
|
||||
if: github.event_name == 'schedule' || needs.changes.outputs.docs == 'true' || needs.changes.outputs.tests == 'true' || needs.changes.outputs.hm == 'true' || needs.changes.outputs.format == 'true'
|
||||
with:
|
||||
nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/${{ steps.get-nixpkgs.outputs.rev }}.tar.gz
|
||||
extra_nix_config: |
|
||||
sandbox = true
|
||||
- name: Build docs
|
||||
if: github.event_name == 'schedule' || needs.changes.outputs.docs == 'true'
|
||||
run: nix build --show-trace .#docs-jsonModuleMaintainers
|
||||
- name: Parse Nix files with nix and Lix
|
||||
if: >-
|
||||
matrix.os == 'ubuntu-latest' &&
|
||||
(github.event_name == 'schedule' || needs.changes.outputs.parse == 'true')
|
||||
run: nix build --show-trace --keep-going .#ci-parse .#ci-parse-lix
|
||||
- name: Format Check
|
||||
if: >-
|
||||
matrix.os == 'ubuntu-latest' &&
|
||||
(github.event_name == 'schedule' || needs.changes.outputs.format == 'true')
|
||||
if: github.event_name == 'schedule' || needs.changes.outputs.format == 'true'
|
||||
run: nix fmt -- --ci
|
||||
- name: Test init --switch with locked inputs
|
||||
if: github.event_name == 'schedule' || needs.changes.outputs.hm == 'true'
|
||||
@@ -92,37 +76,31 @@ jobs:
|
||||
if: github.event_name == 'pull_request'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "### Test Job Summary" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "A summary of tasks triggered by file changes in this PR:" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "### Test Job Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "A summary of tasks triggered by file changes in this PR:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [[ "${{ needs.changes.outputs.docs }}" == "true" ]]; then
|
||||
echo "- ✅ **Docs Build:** Triggered" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ✅ **Docs Build:** Triggered" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "- ☑️ **Docs Build:** Skipped (no relevant files changed)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ☑️ **Docs Build:** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [[ "${{ needs.changes.outputs.format }}" == "true" ]]; then
|
||||
echo "- ✅ **Format Check:** Triggered" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ✅ **Format Check:** Triggered" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "- ☑️ **Format Check:** Skipped (no relevant files changed)" >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
|
||||
if [[ "${{ needs.changes.outputs.parse }}" == "true" ]]; then
|
||||
echo "- ✅ **Nix Parse (nix + Lix):** Triggered" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "- ☑️ **Nix Parse (nix + Lix):** Skipped (no relevant files changed)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ☑️ **Format Check:** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [[ "${{ needs.changes.outputs.hm }}" == "true" ]]; then
|
||||
echo "- ✅ **Home Manager Tests:** Triggered" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ✅ **Home Manager Tests:** Triggered" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "- ☑️ **Home Manager Tests:** Skipped (no relevant files changed)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ☑️ **Home Manager Tests:** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [[ "${{ needs.changes.outputs.tests }}" == "true" ]]; then
|
||||
echo "- ✅ **General Tests:** Triggered" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ✅ **General Tests:** Triggered" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "- ☑️ **General Tests:** Skipped (no relevant files changed)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "- ☑️ **General Tests:** Skipped (no relevant files changed)" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
name: Update flake inputs
|
||||
on:
|
||||
schedule:
|
||||
# Update every Sunday and Wednesday
|
||||
- cron: "51 3 * * 0,3"
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'nix-community'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branch: [master, release-25.11]
|
||||
steps:
|
||||
- name: Create GitHub App token
|
||||
uses: actions/create-github-app-token@v3
|
||||
if: vars.CI_APP_ID
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.CI_APP_ID }}
|
||||
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
|
||||
- name: Get GitHub App user info
|
||||
if: vars.CI_APP_ID
|
||||
id: user-info
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token}}
|
||||
slug: ${{ steps.app-token.outputs.app-slug }}
|
||||
run: |
|
||||
name="$slug[bot]"
|
||||
id=$(gh api "/users/$name" --jq .id)
|
||||
{
|
||||
echo "id=$id"
|
||||
echo "name=$name"
|
||||
echo "email=$id+$name@users.noreply.github.com"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ matrix.branch }}
|
||||
token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v31
|
||||
- name: Update flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@v28
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
|
||||
git-committer-name: ${{ steps.user-info.outputs.name || 'github-actions[bot]' }}
|
||||
git-committer-email: ${{ steps.user-info.outputs.email || '41898282+github-actions[bot]@users.noreply.github.com' }}
|
||||
git-author-name: ${{ steps.user-info.outputs.name || 'github-actions[bot]' }}
|
||||
git-author-email: ${{ steps.user-info.outputs.email || '41898282+github-actions[bot]@users.noreply.github.com' }}
|
||||
pr-labels: dependencies
|
||||
pr-title: "[${{ matrix.branch }}] flake.lock: Update"
|
||||
pr-body: |
|
||||
Automated update by the [update-flake-lock] GitHub Action.
|
||||
|
||||
```
|
||||
{{ env.GIT_COMMIT_MESSAGE }}
|
||||
```
|
||||
|
||||
This PR was most recently updated by workflow run [${{ github.run_id }}].
|
||||
|
||||
[update-flake-lock]: https://github.com/DeterminateSystems/update-flake-lock
|
||||
[${{ github.run_id }}]: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
base: ${{ matrix.branch }}
|
||||
branch: update/${{ matrix.branch }}
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
echo "email=$id+$name@users.noreply.github.com"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token || github.token }}
|
||||
- name: Get Nixpkgs revision from flake.lock
|
||||
@@ -184,7 +184,7 @@ jobs:
|
||||
if [[ -n "$info" ]]; then
|
||||
echo "PR info:"
|
||||
echo "$info"
|
||||
echo "$info" >> "$GITHUB_OUTPUT"
|
||||
echo "$info" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "No PR is currently open"
|
||||
fi
|
||||
@@ -266,21 +266,21 @@ jobs:
|
||||
echo "✅ Successfully updated PR with new changes."
|
||||
echo "$changes"
|
||||
echo "🔗 PR URL: $pr_url"
|
||||
echo "### ✅ PR Updated" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "[$pr_url]($pr_url)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "### ✅ PR Updated" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[$pr_url]($pr_url)" >> $GITHUB_STEP_SUMMARY
|
||||
elif [[ -n "$pr_url" ]]; then
|
||||
echo "✅ Successfully created PR with maintainer updates."
|
||||
echo "$changes"
|
||||
echo "🔗 PR URL: $pr_url"
|
||||
echo "### ✅ PR Created" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "[$pr_url]($pr_url)" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "### ✅ PR Created" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[$pr_url]($pr_url)" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ Failed to create or update pull request."
|
||||
echo "### ❌ PR Operation Failed" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "A pull request was intended but the URL was not captured. Please check the logs." >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "### ❌ PR Operation Failed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "A pull request was intended but the URL was not captured. Please check the logs." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
else
|
||||
echo "ℹ️ No changes detected - maintainers list is up to date."
|
||||
echo "### ℹ️ No Changes" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "The maintainers list is up-to-date. No PR was created." >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "### ℹ️ No Changes" >> $GITHUB_STEP_SUMMARY
|
||||
echo "The maintainers list is up-to-date. No PR was created." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
if: github.repository_owner == 'nix-community'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
uses: actions/checkout@v6
|
||||
- name: Get Nixpkgs revision from flake.lock
|
||||
id: get-nixpkgs
|
||||
run: |
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Noah Biewesch <dev@noahbiewesch.com> <90870942+trueNAHO@users.noreply.github.com>
|
||||
@@ -1,8 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
Home Manager contribution guidelines live in the manual:
|
||||
|
||||
- [`docs/manual/contributing.md`](docs/manual/contributing.md)
|
||||
- <https://nix-community.github.io/home-manager/#ch-contributing>
|
||||
|
||||
Read those docs before changing modules, tests, news entries, or release notes.
|
||||
@@ -11,13 +11,9 @@ list *pattern:
|
||||
test *pattern:
|
||||
nix run .#tests -- {{pattern}}
|
||||
|
||||
# List integration tests
|
||||
list_integration_tests:
|
||||
nix run .#tests -- -t -l
|
||||
|
||||
# Run integration tests
|
||||
integration_tests:
|
||||
nix run .#tests -- -t integration-test-
|
||||
nix run .#tests -- -t -l
|
||||
|
||||
# Create a news entry
|
||||
create-news-entry:
|
||||
|
||||
+2
-2
@@ -125,7 +125,7 @@ Reference commits:
|
||||
- Update the nixpkgs input to track the corresponding stable branch
|
||||
- Example: For `release-25.11`, change from:
|
||||
```nix
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
```
|
||||
to:
|
||||
```nix
|
||||
@@ -135,7 +135,7 @@ Reference commits:
|
||||
- Commit the flake.nix and flake.lock changes
|
||||
|
||||
**Note**: The release branch should track the stable NixOS release channel
|
||||
(e.g., `nixos-25.11`), while master continues to track `nixpkgs-unstable`.
|
||||
(e.g., `nixos-25.11`), while master continues to track `nixos-unstable`.
|
||||
|
||||
#### Step 3.5: On master - Update CI for the New Release Branch
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.PHONY: all all-tests test test-install format
|
||||
NIXPKGS_REV := nixpkgs-unstable
|
||||
NIXPKGS_REV := nixos-unstable
|
||||
NIX_PATH := nixpkgs=https://github.com/NixOS/nixpkgs/archive/${NIXPKGS_REV}.tar.gz
|
||||
|
||||
all: all-tests test-install
|
||||
|
||||
@@ -25,11 +25,10 @@ If you would like to contribute to Home Manager, then please have a look at
|
||||
Releases
|
||||
--------
|
||||
|
||||
Home Manager is developed against the `nixpkgs-unstable` branch, which often
|
||||
causes it to contain tweaks for changes/packages not yet released in stable
|
||||
[NixOS][].
|
||||
Home Manager is developed against `nixos-unstable` branch, which often causes
|
||||
it to contain tweaks for changes/packages not yet released in stable [NixOS][].
|
||||
To avoid breaking users' configurations, Home Manager is released in branches
|
||||
corresponding to NixOS releases (e.g. `release-26.05`). These branches get
|
||||
corresponding to NixOS releases (e.g. `release-25.11`). These branches get
|
||||
fixes, but usually not new modules. If you need a module to be backported, then
|
||||
feel free to open an issue.
|
||||
|
||||
@@ -50,7 +49,7 @@ dconf store and cannot tell whether a configuration that is about to be
|
||||
overwritten was from a previous Home Manager generation or from manual
|
||||
configuration.
|
||||
|
||||
Home Manager targets `nixpkgs-unstable` and NixOS version 26.05 (the current
|
||||
Home Manager targets [NixOS][] unstable and NixOS version 25.11 (the current
|
||||
stable version), it may or may not work on other Linux distributions and NixOS
|
||||
versions.
|
||||
|
||||
|
||||
+61
-188
@@ -21,13 +21,6 @@
|
||||
name = "0xda157";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
"0xdsqr" = {
|
||||
email = "me@dsqr.dev";
|
||||
github = "0xdsqr";
|
||||
githubId = 99584622;
|
||||
name = "Dave Dennis";
|
||||
source = "home-manager";
|
||||
};
|
||||
"3ulalia" = {
|
||||
email = "3ulalia@proton.me";
|
||||
github = "3ulalia";
|
||||
@@ -39,14 +32,8 @@
|
||||
email = "git.t@betsumei.com";
|
||||
github = "74k1";
|
||||
githubId = 49000471;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "46F3 422F 63A3 1369 7EAB 83D5 1CF1 55F7 6F21 3503";
|
||||
}
|
||||
];
|
||||
matrix = "@74k1:matrix.org";
|
||||
name = "Tim";
|
||||
source = "nixpkgs";
|
||||
source = "home-manager";
|
||||
};
|
||||
"9p4" = {
|
||||
email = "vcs@ersei.net";
|
||||
@@ -81,14 +68,14 @@
|
||||
github = "AndreasMager";
|
||||
githubId = 5646732;
|
||||
name = "Andreas Mager";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
Austreelis = {
|
||||
email = "github@accounts.austreelis.net";
|
||||
github = "Austreelis";
|
||||
githubId = 56743515;
|
||||
name = "Morgane Austreelis";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
CarlosLoboxyz = {
|
||||
email = "86011416+CarlosLoboxyz@users.noreply.github.com";
|
||||
@@ -125,27 +112,12 @@
|
||||
name = "Denis Kaynar";
|
||||
source = "home-manager";
|
||||
};
|
||||
ErinaYip = {
|
||||
email = "erinayip@outlook.com";
|
||||
github = "ErinaYip";
|
||||
githubId = 227132255;
|
||||
name = "erina";
|
||||
source = "home-manager";
|
||||
};
|
||||
Eveeifyeve = {
|
||||
email = "eveeg1971@gmail.com";
|
||||
github = "Eveeifyeve";
|
||||
githubId = 88671402;
|
||||
matrix = "@eveeifyeve:matrix.org";
|
||||
name = "Eveeifyeve";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
Fendse = {
|
||||
email = "46252070+Fendse@users.noreply.github.com";
|
||||
github = "Fendse";
|
||||
githubId = 46252070;
|
||||
name = "Sara Johnsson";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
Flameopathic = {
|
||||
email = "flameopathic@gmail.com";
|
||||
@@ -208,7 +180,7 @@
|
||||
githubId = 80165193;
|
||||
matrix = "@janik0:matrix.org";
|
||||
name = "Janik";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
JasmineLowen = {
|
||||
email = "robwalter96@gmail.com";
|
||||
@@ -234,7 +206,7 @@
|
||||
github = "Joker9944";
|
||||
githubId = 9194199;
|
||||
name = "Felix von Arx";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
JustinLovinger = {
|
||||
email = "git@justinlovinger.com";
|
||||
@@ -311,7 +283,7 @@
|
||||
github = "MForster";
|
||||
githubId = 4067975;
|
||||
name = "Michael Forster";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
Misterio77 = {
|
||||
email = "eu@misterio.me";
|
||||
@@ -390,25 +362,12 @@
|
||||
name = "Philipp Mildenberger";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ReStranger = {
|
||||
github = "ReStranger";
|
||||
githubId = 69393944;
|
||||
name = "ReStranger";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ReeSilva = {
|
||||
email = "reesilva@proton.me";
|
||||
github = "ReeSilva";
|
||||
githubId = 3605032;
|
||||
name = "Renato da Silva";
|
||||
source = "home-manager";
|
||||
};
|
||||
Rosuavio = {
|
||||
email = "RosarioPulella@gmail.com";
|
||||
github = "Rosuavio";
|
||||
githubId = 7164552;
|
||||
name = "Rosario Pulella";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
S0AndS0 = {
|
||||
email = "S0AndS0@digital-mercenaries.com";
|
||||
@@ -431,6 +390,13 @@
|
||||
name = "Sefa Eyeoglu";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
SebTM = {
|
||||
email = "mail@sebastian-sellmeier.de";
|
||||
github = "SebTM";
|
||||
githubId = 17243347;
|
||||
name = "Sebastian Sellmeier";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ShamrockLee = {
|
||||
email = "shamrocklee@posteo.net";
|
||||
github = "ShamrockLee";
|
||||
@@ -451,12 +417,6 @@
|
||||
name = "Mel Bourgeois";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
SunOfLife1 = {
|
||||
github = "SunOfLife1";
|
||||
githubId = 30405063;
|
||||
name = "SunOfLife1";
|
||||
source = "home-manager";
|
||||
};
|
||||
Swarsel = {
|
||||
email = "leon@swarsel.win";
|
||||
github = "Swarsel";
|
||||
@@ -492,6 +452,13 @@
|
||||
name = "Vincent Breitmoser";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
Vortriz = {
|
||||
email = "vorarishi22+nix@gmail.com";
|
||||
github = "Vortriz";
|
||||
githubId = 97402159;
|
||||
name = "Rishi Vora";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
WGUNDERWOOD = {
|
||||
email = "wg.underwood13@gmail.com";
|
||||
github = "WGUNDERWOOD";
|
||||
@@ -548,6 +515,14 @@
|
||||
name = "David Chocholatý";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
adisbladis = {
|
||||
email = "adisbladis@gmail.com";
|
||||
github = "adisbladis";
|
||||
githubId = 63286;
|
||||
matrix = "@adis:blad.is";
|
||||
name = "Adam Hose";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
afresquet = {
|
||||
email = "alvarofresquet@gmail.com";
|
||||
github = "afresquet";
|
||||
@@ -597,13 +572,6 @@
|
||||
name = "Alin";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
amadejkastelic = {
|
||||
email = "amadejkastelic7@gmail.com";
|
||||
github = "amadejkastelic";
|
||||
githubId = 26391003;
|
||||
name = "Amadej Kastelic";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ambroisie = {
|
||||
email = "bruno.nixpkgs@belanyi.fr";
|
||||
github = "ambroisie";
|
||||
@@ -671,7 +639,7 @@
|
||||
github = "b1kku";
|
||||
githubId = 77858854;
|
||||
name = "Bikku";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
bamhm182 = {
|
||||
email = "bamhm182@gmail.com";
|
||||
@@ -711,13 +679,6 @@
|
||||
name = "Filippo Berto";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
bittner = {
|
||||
email = "peter@painless.software";
|
||||
github = "bittner";
|
||||
githubId = 665072;
|
||||
name = "Peter Bittner";
|
||||
source = "home-manager";
|
||||
};
|
||||
bjpbakker = {
|
||||
email = "bart@thesoftwarecraft.com";
|
||||
github = "bjpbakker";
|
||||
@@ -881,7 +842,7 @@
|
||||
github = "ckgxrg-salt";
|
||||
githubId = 165614491;
|
||||
name = "ckgxrg";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
cmacrae = {
|
||||
email = "hi@cmacr.ae";
|
||||
@@ -910,13 +871,6 @@
|
||||
name = "Phillip Cloud";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
csanthiago = {
|
||||
email = "git@csanthiago.dev";
|
||||
github = "csanthiago";
|
||||
githubId = 8346803;
|
||||
name = "csanthiago";
|
||||
source = "home-manager";
|
||||
};
|
||||
cwyc = {
|
||||
email = "hello@cwyc.page";
|
||||
github = "cwyc";
|
||||
@@ -997,6 +951,13 @@
|
||||
name = "Robin Stumm";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
diniamo = {
|
||||
email = "diniamo53@gmail.com";
|
||||
github = "diniamo";
|
||||
githubId = 55629891;
|
||||
name = "diniamo";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
donovanglover = {
|
||||
github = "donovanglover";
|
||||
githubId = 2374245;
|
||||
@@ -1176,13 +1137,6 @@
|
||||
name = "Fugi";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
garklein = {
|
||||
email = "garklein97@gmail.com";
|
||||
github = "garklein";
|
||||
githubId = 63201615;
|
||||
name = "Garklein";
|
||||
source = "home-manager";
|
||||
};
|
||||
gauthsvenkat = {
|
||||
email = "gauthsvenkat+home-manager@gmail.com";
|
||||
github = "gauthsvenkat";
|
||||
@@ -1284,18 +1238,6 @@
|
||||
name = "Bhe Hongtyu";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
iamanaws = {
|
||||
email = "iamanaws@httpd.dev";
|
||||
github = "iamanaws";
|
||||
githubId = 78835633;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "CF10 DCBB 9318 BE1D 6040 4222 272C 61AB 190D ED28";
|
||||
}
|
||||
];
|
||||
name = "Angel J";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ilaumjd = {
|
||||
email = "ilaumjd@gmail.com";
|
||||
github = "ilaumjd";
|
||||
@@ -1317,13 +1259,6 @@
|
||||
name = "Ilya Savitsky";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
isaacST08 = {
|
||||
email = "isaacst.nix@proton.me";
|
||||
github = "isaacST08";
|
||||
githubId = 106057977;
|
||||
name = "Isaac Shiells Thomas";
|
||||
source = "home-manager";
|
||||
};
|
||||
iynaix = {
|
||||
email = "iynaix@gmail.com";
|
||||
github = "iynaix";
|
||||
@@ -1471,7 +1406,7 @@
|
||||
github = "kaleocheng";
|
||||
githubId = 7939352;
|
||||
name = "Kaleo Cheng";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
kalhauge = {
|
||||
email = "kalhauge@users.noreply.github.com";
|
||||
@@ -1499,13 +1434,6 @@
|
||||
name = "Nikolaos Karaolidis";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
kayskayskays = {
|
||||
email = "115312476+kayskayskays@users.noreply.github.com";
|
||||
github = "kayskayskays";
|
||||
githubId = 115312476;
|
||||
name = "Kays";
|
||||
source = "home-manager";
|
||||
};
|
||||
khaneliman = {
|
||||
email = "khaneliman12@gmail.com";
|
||||
github = "khaneliman";
|
||||
@@ -1528,13 +1456,6 @@
|
||||
name = "Knut Magnus Aasrud";
|
||||
source = "home-manager";
|
||||
};
|
||||
kpbaks = {
|
||||
email = "kristoffer.pbs@gmail.com";
|
||||
github = "kpbaks";
|
||||
githubId = 57013304;
|
||||
name = "Kristoffer Plagborg Bak Sørensen";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
kubukoz = {
|
||||
email = "kubukoz@gmail.com";
|
||||
github = "kubukoz";
|
||||
@@ -1657,13 +1578,6 @@
|
||||
name = "Manaiki Laut";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
marijanp = {
|
||||
email = "marijan.petricevic94@gmail.com";
|
||||
github = "marijanp";
|
||||
githubId = 13599169;
|
||||
name = "Marijan Petričević";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
mateusauler = {
|
||||
email = "mateus@auler.dev";
|
||||
github = "mateusauler";
|
||||
@@ -1765,7 +1679,7 @@
|
||||
github = "miku4k";
|
||||
githubId = 89653242;
|
||||
name = "Miku B";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
minijackson = {
|
||||
email = "minijackson@riseup.net";
|
||||
@@ -1864,7 +1778,7 @@
|
||||
github = "natecox";
|
||||
githubId = 2782695;
|
||||
name = "Nate Cox";
|
||||
source = "home-manager";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
nbp = {
|
||||
email = "nixos@nbp.name";
|
||||
@@ -1911,9 +1825,21 @@
|
||||
email = "nukdokplex@nukdokplex.ru";
|
||||
github = "nukdokplex";
|
||||
githubId = 25458915;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "7CE2 4C42 942D 58EA 99F6 F00A A47E 7374 3EF6 FCC4";
|
||||
}
|
||||
];
|
||||
name = "Viktor Titov";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
nurelin = {
|
||||
email = "nurelin@users.noreply.github.com";
|
||||
github = "nurelin";
|
||||
githubId = 5276274;
|
||||
name = "nurelin";
|
||||
source = "home-manager";
|
||||
};
|
||||
nyarly = {
|
||||
email = "nyarly@gmail.com";
|
||||
github = "nyarly";
|
||||
@@ -1921,13 +1847,6 @@
|
||||
name = "Judson Lester";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ojsef39 = {
|
||||
email = "me+github@jhofer.de";
|
||||
github = "ojsef39";
|
||||
githubId = 43563019;
|
||||
name = "Josef Hofer";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
olmokramer = {
|
||||
email = "olmokramer@users.noreply.github.com";
|
||||
github = "olmokramer";
|
||||
@@ -2018,6 +1937,13 @@
|
||||
name = "Myles Wirth";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
pinage404 = {
|
||||
email = "pinage404+nixpkgs@gmail.com";
|
||||
github = "pinage404";
|
||||
githubId = 6325757;
|
||||
name = "pinage404";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
pjones = {
|
||||
email = "pjones@devalot.com";
|
||||
github = "pjones";
|
||||
@@ -2085,18 +2011,6 @@
|
||||
name = "Rasmus Kirk";
|
||||
source = "home-manager";
|
||||
};
|
||||
ratakor = {
|
||||
email = "ratakor@disroot.org";
|
||||
github = "ratakor";
|
||||
githubId = 45130910;
|
||||
keys = [
|
||||
{
|
||||
fingerprint = "B60F 8F80 D6CD C5D2 58CF 14C3 241B 1CBE 567B 287E";
|
||||
}
|
||||
];
|
||||
name = "Ratakor";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
ravenjoad = {
|
||||
email = "raven@hallsby.com";
|
||||
github = "ravenjoad";
|
||||
@@ -2203,13 +2117,6 @@
|
||||
name = "Robert Helgesson";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
s0racat = {
|
||||
email = "125882337+s0racat@users.noreply.github.com";
|
||||
github = "s0racat";
|
||||
githubId = 125882337;
|
||||
name = "soracat";
|
||||
source = "home-manager";
|
||||
};
|
||||
sableseyler = {
|
||||
email = "sable@seyleri.us";
|
||||
github = "sableseyler";
|
||||
@@ -2222,20 +2129,6 @@
|
||||
name = "Sable Seyler";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
sei40kr = {
|
||||
email = "sei40kr@gmail.com";
|
||||
github = "sei40kr";
|
||||
githubId = 11665236;
|
||||
name = "Seong Yong-ju";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
semi710 = {
|
||||
email = "nik.singh710@gmail.com";
|
||||
github = "semi710";
|
||||
githubId = 60490474;
|
||||
name = "Nikhil Singh";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
shikanime = {
|
||||
email = "william.phetsinorath@shikanime.studio";
|
||||
github = "shikanime";
|
||||
@@ -2315,13 +2208,6 @@
|
||||
name = "Sumner Evans";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
superflash41 = {
|
||||
email = "saymon.nicho@pucp.edu.pe";
|
||||
github = "superflash41";
|
||||
githubId = 102434258;
|
||||
name = "Saymon Nicho";
|
||||
source = "home-manager";
|
||||
};
|
||||
surfaceflinger = {
|
||||
email = "nat@nekopon.pl";
|
||||
github = "surfaceflinger";
|
||||
@@ -2496,13 +2382,6 @@
|
||||
name = "Xavier Lambein";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
yaaaarn = {
|
||||
email = "nix@yarncat.moe";
|
||||
github = "yaaaarn";
|
||||
githubId = 30006414;
|
||||
name = "yarncat";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
yethal = {
|
||||
github = "yethal";
|
||||
githubId = 26117918;
|
||||
@@ -2521,12 +2400,6 @@
|
||||
name = "Jona Abdinghoff";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
zh4ngx = {
|
||||
github = "zh4ngx";
|
||||
githubId = 1329212;
|
||||
name = "Andy Zhang";
|
||||
source = "nixpkgs";
|
||||
};
|
||||
zorrobert = {
|
||||
email = "118135271+zorrobert@users.noreply.github.com";
|
||||
github = "zorrobert";
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
nix,
|
||||
runCommand,
|
||||
}:
|
||||
let
|
||||
home-manager =
|
||||
with lib.fileset;
|
||||
toSource {
|
||||
root = ../.;
|
||||
fileset = (fileFilter (file: file.hasExt "nix") ../.);
|
||||
};
|
||||
parseLog = "$TMPDIR/nix-parse.log";
|
||||
in
|
||||
runCommand "nix-parse-${nix.name}"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
nix
|
||||
];
|
||||
}
|
||||
''
|
||||
export NIX_STORE_DIR=$TMPDIR/store
|
||||
export NIX_STATE_DIR=$TMPDIR/state
|
||||
nix-store --init
|
||||
|
||||
cd "${home-manager}"
|
||||
|
||||
# This will only show the first parse error, not all of them. That's fine, because
|
||||
# the other CI jobs will report in more detail. This job is about checking parsing
|
||||
# across different implementations / versions, not about providing the best DX.
|
||||
# Returning all parse errors requires significantly more resources.
|
||||
if ! find . -type f -iname '*.nix' | xargs -P $(nproc) nix-instantiate --parse 2> "${parseLog}" > /dev/null; then
|
||||
cat "${parseLog}" >&2
|
||||
echo "Parse failed in nix-instantiate." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep "warning" "${parseLog}"; then
|
||||
cat "${parseLog}" >&2
|
||||
echo "Failing due to warnings in stderr" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch $out
|
||||
''
|
||||
+3
-9
@@ -253,15 +253,9 @@ let
|
||||
# Generate the HTML manual pages
|
||||
home-manager-manual = pkgs.callPackage ./home-manager-manual.nix {
|
||||
home-manager-options = {
|
||||
home-manager = {
|
||||
json = hmOptionsDocs.optionsJSON;
|
||||
};
|
||||
nixos = {
|
||||
json = nixosOptionsDocs.optionsJSON;
|
||||
};
|
||||
nix-darwin = {
|
||||
json = nixDarwinOptionsDocs.optionsJSON;
|
||||
};
|
||||
home-manager = hmOptionsDocs.optionsJSON;
|
||||
nixos = nixosOptionsDocs.optionsJSON;
|
||||
nix-darwin = nixDarwinOptionsDocs.optionsJSON;
|
||||
};
|
||||
inherit revision;
|
||||
};
|
||||
|
||||
Generated
+4
-4
@@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1779877693,
|
||||
"narHash": "sha256-NOF9NAREhxr50bbBfVcVOq+ArCMSoe8dP79Pk2uyARk=",
|
||||
"lastModified": 1773821835,
|
||||
"narHash": "sha256-wvfdLLWJ2I9oEpDd9PfMA8osfIZicoQ5MT1jIwNs9Tk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4100e830e085863741bc69b156ec4ccd53ab5be0",
|
||||
"rev": "c06b4ae3d6599a672a6210b7021d699c351eebda",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
description = "Support developing Home Manager documentation";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
scss-reset = {
|
||||
url = "github:andreymatin/scss-reset/1.4.2";
|
||||
flake = false;
|
||||
|
||||
@@ -1,75 +1,63 @@
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
callPackage,
|
||||
mdbook,
|
||||
python3,
|
||||
documentation-highlighter,
|
||||
revision,
|
||||
home-manager-options,
|
||||
nixos-render-docs,
|
||||
}:
|
||||
let
|
||||
outputPath = "share/doc/home-manager";
|
||||
mdbookOptions = callPackage ./mdbook/options.nix {
|
||||
manpageUrls = ./manual/manpage-urls.json;
|
||||
inherit revision;
|
||||
optionDocs = {
|
||||
home-manager = {
|
||||
title = "Home Manager Configuration Options";
|
||||
path = "home-manager";
|
||||
prefix = "opt-";
|
||||
json = "${home-manager-options.home-manager.json}";
|
||||
};
|
||||
nixos = {
|
||||
title = "NixOS Configuration Options";
|
||||
path = "nixos";
|
||||
prefix = "nixos-opt-";
|
||||
json = "${home-manager-options.nixos.json}";
|
||||
};
|
||||
nix-darwin = {
|
||||
title = "nix-darwin Configuration Options";
|
||||
path = "nix-darwin";
|
||||
prefix = "nix-darwin-opt-";
|
||||
json = "${home-manager-options.nix-darwin.json}";
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "home-manager-manual";
|
||||
|
||||
nativeBuildInputs = [
|
||||
mdbook
|
||||
python3
|
||||
];
|
||||
nativeBuildInputs = [ nixos-render-docs ];
|
||||
|
||||
src = ./.;
|
||||
src = ./manual;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
mkdir -p out/{highlightjs,media}
|
||||
|
||||
mkdir -p source
|
||||
python3 ${./mdbook/convert-markup.py} "$src/manual" source
|
||||
python3 ${./mdbook/convert-markup.py} \
|
||||
--base-depth 1 \
|
||||
"$src/release-notes" \
|
||||
source/release-notes
|
||||
cp -t out/highlightjs \
|
||||
${documentation-highlighter}/highlight.pack.js \
|
||||
${documentation-highlighter}/LICENSE \
|
||||
${documentation-highlighter}/mono-blue.css \
|
||||
${documentation-highlighter}/loader.js
|
||||
|
||||
cp -r ${mdbookOptions}/options source/options
|
||||
substituteInPlace ./options.md \
|
||||
--subst-var-by \
|
||||
OPTIONS_JSON \
|
||||
${home-manager-options.home-manager}/share/doc/nixos/options.json
|
||||
|
||||
python3 ${./mdbook/substitute-summary.py} \
|
||||
source/SUMMARY.md \
|
||||
${mdbookOptions}/summary/home-manager.md \
|
||||
${mdbookOptions}/summary/nixos.md \
|
||||
${mdbookOptions}/summary/nix-darwin.md
|
||||
substituteInPlace ./nixos-options.md \
|
||||
--subst-var-by \
|
||||
OPTIONS_JSON \
|
||||
${home-manager-options.nixos}/share/doc/nixos/options.json
|
||||
|
||||
mdbook build source --dest-dir book
|
||||
substituteInPlace ./nix-darwin-options.md \
|
||||
--subst-var-by \
|
||||
OPTIONS_JSON \
|
||||
${home-manager-options.nix-darwin}/share/doc/nixos/options.json
|
||||
|
||||
mkdir -p out
|
||||
cp -r book/* out/
|
||||
cp ${./options.html} out/options.html
|
||||
|
||||
python3 ${./mdbook/legacy-redirects.py} source out
|
||||
cp ${./static/style.css} out/style.css
|
||||
cp ${./static/anchor-links.js} out/anchor-links.js
|
||||
|
||||
runHook postBuild
|
||||
cp -r ${./release-notes} release-notes
|
||||
|
||||
nixos-render-docs manual html \
|
||||
--manpage-urls ./manpage-urls.json \
|
||||
--revision ${lib.trivial.revisionWithDefault revision} \
|
||||
--stylesheet style.css \
|
||||
--script highlightjs/highlight.pack.js \
|
||||
--script highlightjs/loader.js \
|
||||
--script anchor-links.js \
|
||||
--toc-depth 1 \
|
||||
--section-toc-depth 1 \
|
||||
manual.md \
|
||||
out/index.xhtml
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
@@ -81,9 +69,7 @@ stdenv.mkDerivation {
|
||||
echo "doc manual $dest index.html" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit home-manager-options mdbookOptions;
|
||||
};
|
||||
passthru = { inherit home-manager-options; };
|
||||
|
||||
meta = {
|
||||
maintainers = [ lib.maintainers.considerate ];
|
||||
|
||||
@@ -25,14 +25,9 @@ let
|
||||
if [[ ! -v BROWSER || -z $BROWSER ]]; then
|
||||
echo "$0: unable to start a web browser; please set \$BROWSER"
|
||||
exit 1
|
||||
else
|
||||
exec "$BROWSER" "${html}/share/doc/${pathName}/index.xhtml"
|
||||
fi
|
||||
|
||||
manualPath="${html}/share/doc/${pathName}/index.html"
|
||||
if [[ ! -e $manualPath ]]; then
|
||||
manualPath="${html}/share/doc/${pathName}/index.xhtml"
|
||||
fi
|
||||
|
||||
exec "$BROWSER" "$manualPath"
|
||||
'';
|
||||
|
||||
desktopItem = makeDesktopItem {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# Summary
|
||||
|
||||
- [Preface](preface.md)
|
||||
- [Introduction to Home Manager](introduction.md)
|
||||
- [Installing Home Manager](installation.md)
|
||||
- [Standalone installation](installation/standalone.md)
|
||||
- [NixOS module](installation/nixos.md)
|
||||
- [nix-darwin module](installation/nix-darwin.md)
|
||||
- [Using Home Manager](usage.md)
|
||||
- [Configuration Example](usage/configuration.md)
|
||||
- [Rollbacks](usage/rollbacks.md)
|
||||
- [Keeping your ~ safe from harm](usage/dotfiles.md)
|
||||
- [Graphical services](usage/graphical.md)
|
||||
- [GPU on non-NixOS systems](usage/gpu-non-nixos.md)
|
||||
- [Modular Services](usage/modular-services.md)
|
||||
- [Updating](usage/updating.md)
|
||||
- [Upgrading to a new Home Manager release](usage/upgrading.md)
|
||||
- [Nix Flakes](nix-flakes.md)
|
||||
- [Prerequisites](nix-flakes/prerequisites.md)
|
||||
- [Standalone setup](nix-flakes/standalone.md)
|
||||
- [NixOS module](nix-flakes/nixos.md)
|
||||
- [nix-darwin module](nix-flakes/nix-darwin.md)
|
||||
- [flake-parts module](nix-flakes/flake-parts.md)
|
||||
- [Writing Home Manager Modules](writing-modules.md)
|
||||
- [Option Types](writing-modules/types.md)
|
||||
- [Contributing](contributing.md)
|
||||
- [Getting started](contributing/getting-started.md)
|
||||
- [Guidelines](contributing/guidelines.md)
|
||||
- [Release Notes](contributing/release-notes.md)
|
||||
- [News](contributing/news.md)
|
||||
- [Tests](contributing/tests.md)
|
||||
- [Home Manager Internals](internals.md)
|
||||
- [Activation](internals/activation.md)
|
||||
- [Third-Party Tools and Extensions](3rd-party.md)
|
||||
- [Module Collections](3rd-party/collections.md)
|
||||
- [Frequently Asked Questions (FAQ)](faq.md)
|
||||
- [Why is there a collision error when switching generation?](faq/collision.md)
|
||||
- [Why are the session variables not set?](faq/session-variables.md)
|
||||
- [How to set up a configuration for multiple users/machines?](faq/multiple-users-machines.md)
|
||||
- [Why do I get an error message about `ca.desrt.dconf` or `dconf.service`?](faq/ca-desrt-dconf.md)
|
||||
- [How do I install packages from Nixpkgs unstable?](faq/unstable.md)
|
||||
- [How do I change the package used by a module?](faq/change-package-module.md)
|
||||
- [Options](options.md)
|
||||
@HOME_MANAGER_OPTIONS@
|
||||
@NIXOS_OPTIONS@
|
||||
@NIX_DARWIN_OPTIONS@
|
||||
- [Release Notes](release-notes/release-notes.md)
|
||||
- [Release 26.11](release-notes/rl-2611.md)
|
||||
- [Release 26.05](release-notes/rl-2605.md)
|
||||
- [Release 25.11](release-notes/rl-2511.md)
|
||||
- [Release 25.05](release-notes/rl-2505.md)
|
||||
- [Release 24.11](release-notes/rl-2411.md)
|
||||
- [Release 24.05](release-notes/rl-2405.md)
|
||||
- [Release 23.11](release-notes/rl-2311.md)
|
||||
- [Release 23.05](release-notes/rl-2305.md)
|
||||
- [Release 22.11](release-notes/rl-2211.md)
|
||||
- [Release 22.05](release-notes/rl-2205.md)
|
||||
- [Release 21.11](release-notes/rl-2111.md)
|
||||
- [Release 21.05](release-notes/rl-2105.md)
|
||||
- [Release 20.09](release-notes/rl-2009.md)
|
||||
- [Release 20.03](release-notes/rl-2003.md)
|
||||
- [Release 19.09](release-notes/rl-1909.md)
|
||||
- [Release 19.03](release-notes/rl-1903.md)
|
||||
- [Release 18.09](release-notes/rl-1809.md)
|
||||
@@ -1,11 +0,0 @@
|
||||
[book]
|
||||
title = "Home Manager Manual"
|
||||
language = "en"
|
||||
src = "."
|
||||
|
||||
[output.html]
|
||||
git-repository-url = "https://github.com/nix-community/home-manager"
|
||||
|
||||
[output.html.fold]
|
||||
enable = true
|
||||
level = 0
|
||||
@@ -3,8 +3,8 @@
|
||||
Contributions to Home Manager are very welcome. To make the process as
|
||||
smooth as possible for both you and the Home Manager maintainers we
|
||||
provide some guidelines that we ask you to follow. See [Getting
|
||||
started](contributing/getting-started.md#sec-contrib-getting-started) for information on how to set up
|
||||
a suitable development environment and [Guidelines](contributing/guidelines.md#sec-guidelines) for
|
||||
started](#sec-contrib-getting-started) for information on how to set up
|
||||
a suitable development environment and [Guidelines](#sec-guidelines) for
|
||||
the actual guidelines.
|
||||
|
||||
This text is mainly directed at those who would like to make code
|
||||
@@ -22,7 +22,6 @@ configuration.
|
||||
```{=include=} sections
|
||||
contributing/getting-started.md
|
||||
contributing/guidelines.md
|
||||
contributing/release-notes.md
|
||||
contributing/news.md
|
||||
contributing/tests.md
|
||||
```
|
||||
|
||||
@@ -8,7 +8,7 @@ how to do this.
|
||||
Once you have a fork of Home Manager you should create a branch starting
|
||||
at the most recent `master` branch. Give your branch a reasonably
|
||||
descriptive name. Commit your changes to this branch and when you are
|
||||
happy with the result and it fulfills [Guidelines](guidelines.md#sec-guidelines) then
|
||||
happy with the result and it fulfills [Guidelines](#sec-guidelines) then
|
||||
push the branch to GitHub and [create a pull
|
||||
request](https://help.github.com/articles/creating-a-pull-request/).
|
||||
|
||||
@@ -21,7 +21,7 @@ the `home-manager` command use it by either
|
||||
$ home-manager -I home-manager=$HOME/devel/home-manager
|
||||
```
|
||||
|
||||
or, if using [flakes](../nix-flakes/standalone.md#sec-flakes-standalone):
|
||||
or, if using [flakes](#sec-flakes-standalone):
|
||||
|
||||
``` shell
|
||||
$ home-manager --override-input home-manager ~/devel/home-manager
|
||||
|
||||
@@ -58,38 +58,11 @@ YAML, INI, TOML, or even a plain list of key/value pairs then consider
|
||||
using a `settings` option as described in [Nix RFC
|
||||
42](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md).
|
||||
|
||||
These guidelines describe the minimum option design requirements. Before
|
||||
submitting a module, compare it against the upstream documentation or
|
||||
source code and verify that the generated files, services, environment
|
||||
variables, and command line arguments all match the upstream behavior
|
||||
you intend to expose.
|
||||
|
||||
If a module installs a package, try to make the package option nullable,
|
||||
for example
|
||||
|
||||
``` nix
|
||||
package = lib.mkPackageOption pkgs "xdg-terminal-exec" { nullable = true; };
|
||||
```
|
||||
|
||||
This lets users keep installation outside Home Manager, for example via
|
||||
`apt` or because the program is built into macOS, while still using the
|
||||
module for configuration. Keeping the package non-nullable is fine when
|
||||
the enabled behavior structurally requires the executable or when
|
||||
package-less support would make the module significantly more complex.
|
||||
|
||||
Avoid generating files for empty settings, null packages, or optional
|
||||
features that are not configured.
|
||||
|
||||
If upstream does not use XDG paths by default but supports changing the
|
||||
configuration location with an environment variable, for example
|
||||
`FOO_HOME`, expose a `configDir` option and use it to respect
|
||||
`home.preferXdgDirectories`.
|
||||
|
||||
## Add relevant tests {#sec-guidelines-add-tests}
|
||||
|
||||
If at all possible, make sure to add new tests and expand existing tests
|
||||
so that your change will keep working in the future. See
|
||||
[Tests](tests.md#sec-tests) for more information about the Home Manager test
|
||||
[Tests](#sec-tests) for more information about the Home Manager test
|
||||
suite.
|
||||
|
||||
All contributed code *must* pass the test suite.
|
||||
@@ -108,7 +81,7 @@ Manager Git repository:
|
||||
|
||||
``` shell
|
||||
$ nix-build -A docs.html
|
||||
$ xdg-open ./result/share/doc/home-manager/index.html
|
||||
$ xdg-open ./result/share/doc/home-manager/index.xhtml
|
||||
```
|
||||
|
||||
When you have made changes to a module, it is a good idea to check that
|
||||
@@ -116,7 +89,7 @@ the man page version of the module options looks good:
|
||||
|
||||
``` shell
|
||||
$ nix-build -A docs.manPages
|
||||
$ man ./result/share/man/man5/home-configuration.nix.5
|
||||
$ man ./result/share/man/man5/home-configuration.nix.5.gz
|
||||
```
|
||||
|
||||
## Module Auto-importing {#sec-module-auto-importing}
|
||||
@@ -182,17 +155,10 @@ consistent commit message format as described in
|
||||
|
||||
If your contribution includes a change that should be communicated to
|
||||
users of Home Manager then you can add a news entry. The entry must be
|
||||
formatted as described in [News](news.md#sec-news).
|
||||
formatted as described in [News](#sec-news).
|
||||
|
||||
When new modules are added a news entry should be included.
|
||||
|
||||
News entries and release notes serve different purposes. Release notes
|
||||
should be updated separately when a change affects users migrating
|
||||
between stable releases, such as state version default changes, required
|
||||
migration steps, or broad behavior changes. See
|
||||
[Release Notes](release-notes.md#sec-contributing-release-notes) and [News](news.md#sec-news)
|
||||
for more details.
|
||||
|
||||
## Use conditional modules and news {#sec-guidelines-conditional-modules}
|
||||
|
||||
Home Manager includes a number of modules that are only usable on some
|
||||
@@ -200,16 +166,12 @@ of the supported platforms. The most common example of platform specific
|
||||
modules are those that define systemd user services, which only works on
|
||||
Linux systems.
|
||||
|
||||
If you add a module that is platform specific then make sure the module
|
||||
guards platform-specific configuration with an appropriate condition, for
|
||||
example `pkgs.stdenv.hostPlatform.isLinux` or
|
||||
`pkgs.stdenv.hostPlatform.isDarwin`. Modules in `modules/programs/` and
|
||||
`modules/services/` are auto-imported, so the platform condition should live
|
||||
in the module behavior and in any platform-specific tests rather than in a
|
||||
separate module discovery call.
|
||||
If you add a module that is platform specific then make sure to include
|
||||
a condition in the `loadModule` function call. This will make the module
|
||||
accessible only on systems where the condition evaluates to `true`.
|
||||
|
||||
Similarly, if you are adding a news entry then it should be shown only
|
||||
to users that may find it relevant, see [News](news.md#sec-news) for a
|
||||
to users that may find it relevant, see [News](#sec-news) for a
|
||||
description of conditional news.
|
||||
|
||||
## Mind the license {#sec-guidelines-licensing}
|
||||
@@ -232,11 +194,6 @@ that is, each commit should make sense in isolation. In particular, you
|
||||
will be asked to amend any commit that introduces syntax errors or
|
||||
similar problems even if they are fixed in a later commit.
|
||||
|
||||
Keep commits atomic and separated by concern. For example, a new
|
||||
maintainer entry should be a separate first commit, and a shared module
|
||||
should be committed separately from integrations in existing modules.
|
||||
Pull requests should not include merge commits or fixup commits.
|
||||
|
||||
The commit messages should follow the [seven
|
||||
rules](https://chris.beams.io/posts/git-commit/#seven-rules), except for
|
||||
\"Capitalize the subject line\". We also ask you to include the affected
|
||||
|
||||
@@ -6,17 +6,8 @@ associated news entry. In general, a news entry should only be added for
|
||||
truly noteworthy news. For example, a bug fix or new option does
|
||||
generally not need a news entry.
|
||||
|
||||
Release notes and news entries serve different purposes. A news entry is
|
||||
shown during Home Manager activation and is useful for day-to-day
|
||||
communication about noteworthy changes, such as a new module, a new
|
||||
feature, or a specific deprecation. Release notes are read from the
|
||||
website documentation and should summarize what users need to know before
|
||||
or during a stable-release upgrade. See
|
||||
[Release Notes](release-notes.md#sec-contributing-release-notes) for guidance on changes
|
||||
that affect stable-release upgrades.
|
||||
|
||||
If you do have a change worthy of a news entry then please add one in
|
||||
[`news`](https://github.com/nix-community/home-manager/blob/master/modules/misc/news)
|
||||
[`news.nix`](https://github.com/nix-community/home-manager/blob/master/modules/misc/news.nix)
|
||||
but you should follow some basic guidelines:
|
||||
|
||||
- Use the included news entry generator to create a news entry file:
|
||||
@@ -34,12 +25,9 @@ but you should follow some basic guidelines:
|
||||
This will create a new file inside the `modules/misc/news` directory
|
||||
with some placeholder information that you can edit.
|
||||
|
||||
- The entry condition should be as specific as possible for changes
|
||||
affecting existing functionality. For example, if you are changing
|
||||
or deprecating a specific option then you could restrict the news to
|
||||
those users who actually use this option. Prefer a targeted
|
||||
condition over skipping useful news only to avoid notifying
|
||||
unaffected users.
|
||||
- The entry condition should be as specific as possible. For example,
|
||||
if you are changing or deprecating a specific option then you could
|
||||
restrict the news to those users who actually use this option.
|
||||
|
||||
- Wrap the news message so that it will fit in the typical terminal,
|
||||
that is, at most 80 characters wide. Ideally a bit less.
|
||||
@@ -65,10 +53,6 @@ but you should follow some basic guidelines:
|
||||
|
||||
A new module is available: 'services.foo'.
|
||||
|
||||
Since this news announces newly available functionality, its
|
||||
condition should not require `config.services.foo.enable`; otherwise
|
||||
users who may want the new module will not see the news.
|
||||
|
||||
If the module is platform specific, e.g., a service module using
|
||||
systemd, then a condition like
|
||||
|
||||
@@ -76,6 +60,5 @@ but you should follow some basic guidelines:
|
||||
condition = hostPlatform.isLinux;
|
||||
```
|
||||
|
||||
should be added to avoid showing the news on unsupported platforms.
|
||||
Use the `create-news-entry` generator described above to scaffold
|
||||
this entry as part of your contribution.
|
||||
should be added. If you contribute a module then you don't need to
|
||||
add this entry, the merger will create an entry for you.
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Release Notes {#sec-contributing-release-notes}
|
||||
|
||||
Home Manager release notes are published as part of the website documentation in
|
||||
`docs/release-notes/rl-*.md`. They are intended for users migrating from one
|
||||
stable release to another.
|
||||
|
||||
A change should be mentioned in the release notes when it affects migration
|
||||
between stable releases. This includes changes that require user action or
|
||||
awareness during an upgrade, such as:
|
||||
|
||||
- breaking changes;
|
||||
- default changes guarded by `home.stateVersion`;
|
||||
- required migration steps;
|
||||
- broad behavior changes across platform or integration boundaries;
|
||||
- compatibility changes that can affect existing configurations.
|
||||
|
||||
Do not use the presence or absence of a news entry to decide whether a change
|
||||
belongs in the release notes. A change can require a news entry, a release note,
|
||||
both, or neither.
|
||||
|
||||
When preparing a release, review the commits since the previous stable release
|
||||
and update the upcoming release note file with the migration impact. Prefer
|
||||
concise user-facing descriptions that name the affected option paths and explain
|
||||
required action.
|
||||
@@ -54,13 +54,6 @@ The `default.nix` file should list all test cases:
|
||||
}
|
||||
```
|
||||
|
||||
Prefer keeping related assertions in as few test files as practical.
|
||||
Exercising several cases in one evaluation keeps the test suite cheaper
|
||||
to evaluate and reduces maintenance burden. Split cases into separate
|
||||
files when they need incompatible module configuration, platform
|
||||
conditions, expected assertion failures, or otherwise cannot share one
|
||||
evaluation.
|
||||
|
||||
### Common NMT Assertions {#sec-tests-assertions}
|
||||
|
||||
NMT provides several assertion functions:
|
||||
@@ -169,12 +162,6 @@ For cross-platform modules that have packages which need to be stubbed on Darwin
|
||||
add the package names to `tests/darwinScrublist.nix` to prevent build failures
|
||||
during cross-platform test runs.
|
||||
|
||||
On Linux, packages are automatically scrubbed by the test infrastructure,
|
||||
so tests should normally use the module's default package. Use
|
||||
`test.stubs` or `config.lib.test.mkStubPackage` only when the automatic
|
||||
scrubbing does not model the behavior that the test needs, such as a
|
||||
package with additional files or a non-default executable layout.
|
||||
|
||||
## Using the tests command {#sec-tests-command}
|
||||
|
||||
Home Manager provides a convenient `tests` command for discovering and running tests:
|
||||
@@ -192,22 +179,16 @@ $ nix run .#tests -- alacritty
|
||||
# Run a specific test
|
||||
$ nix run .#tests -- test-alacritty-empty-settings
|
||||
|
||||
# List integration tests
|
||||
# Run integration tests
|
||||
$ nix run .#tests -- -t -l
|
||||
|
||||
# Run all integration tests
|
||||
$ nix run .#tests -- -t integration-test-
|
||||
|
||||
# Interactive test selection (requires fzf)
|
||||
$ nix run .#tests -- -i
|
||||
$ python3 tests/tests.py -i
|
||||
|
||||
# Pass additional nix build flags
|
||||
$ nix run .#tests -- alacritty -- --verbose
|
||||
```
|
||||
|
||||
Integration tests are only exposed on Linux. On other platforms, integration
|
||||
test discovery may report no matching tests.
|
||||
|
||||
## Manual test commands {#sec-tests-manual}
|
||||
|
||||
For advanced usage or CI environments, you can also run tests manually using nix build commands.
|
||||
@@ -221,7 +202,7 @@ $ nix-build --pure --option allow-import-from-derivation false tests -A build.al
|
||||
in the project root. List all test cases through
|
||||
|
||||
``` shell
|
||||
$ nix run .#tests -- -l
|
||||
$ nix-build --pure tests --option allow-import-from-derivation false -A list
|
||||
```
|
||||
|
||||
and run an individual test, for example `alacritty-empty-settings`,
|
||||
@@ -236,13 +217,13 @@ and may cause failures. To run against the Nixpkgs from the `flake.lock` file,
|
||||
use instead e.g.
|
||||
|
||||
``` shell
|
||||
$ nix build .#test-all
|
||||
$ nix build --option allow-import-from-derivation false .#test-all
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
``` shell
|
||||
$ nix build .#test-alacritty-empty-settings
|
||||
$ nix build --option allow-import-from-derivation false .#test-alacritty-empty-settings
|
||||
```
|
||||
|
||||
Some tests may be marked with `enableLegacyIfd`, those may be run by run with e.g.
|
||||
|
||||
@@ -20,22 +20,10 @@ this package. This can typically be done in two ways.
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
{
|
||||
programs.beets.package = pkgsUnstable.beets;
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
|
||||
should work OK. With flakes, pass the unstable package set as
|
||||
described in
|
||||
[How do I install packages from Nixpkgs unstable?](unstable.md#_how_do_i_install_packages_from_nixpkgs_unstable)
|
||||
and then use the extra module argument:
|
||||
|
||||
``` nix
|
||||
{ pkgsUnstable, ... }:
|
||||
|
||||
{
|
||||
programs.beets.package = pkgsUnstable.beets;
|
||||
@@ -44,7 +32,9 @@ this package. This can typically be done in two ways.
|
||||
}
|
||||
```
|
||||
|
||||
2. If no `package` option is available then you can typically change
|
||||
should work OK.
|
||||
|
||||
3. If no `package` option is available then you can typically change
|
||||
the relevant package using an
|
||||
[overlay](https://nixos.org/nixpkgs/manual/#chap-overlays).
|
||||
|
||||
@@ -55,14 +45,16 @@ this package. This can typically be done in two ways.
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
programs.skim.enable = true;
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(_final: _prev: {
|
||||
(self: super: {
|
||||
skim = pkgsUnstable.skim;
|
||||
})
|
||||
];
|
||||
@@ -72,46 +64,3 @@ this package. This can typically be done in two ways.
|
||||
```
|
||||
|
||||
should work OK.
|
||||
|
||||
The same Home Manager overlay works in a flake-based standalone
|
||||
configuration if `pkgsUnstable` is passed to the Home Manager
|
||||
module:
|
||||
|
||||
``` nix
|
||||
{ pkgsUnstable, ... }:
|
||||
|
||||
{
|
||||
programs.skim.enable = true;
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(_final: _prev: {
|
||||
skim = pkgsUnstable.skim;
|
||||
})
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
|
||||
This also works when Home Manager is used as a NixOS or nix-darwin
|
||||
module without `home-manager.useGlobalPkgs = true`. If
|
||||
`home-manager.useGlobalPkgs = true` is enabled, Home Manager uses
|
||||
the system package set and the `nixpkgs.*` options inside Home
|
||||
Manager are disabled. In that case, put the overlay in the system
|
||||
configuration instead, for example:
|
||||
|
||||
``` nix
|
||||
{ pkgsUnstable, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(_final: _prev: {
|
||||
skim = pkgsUnstable.skim;
|
||||
})
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
In a flake-based NixOS or nix-darwin configuration, pass
|
||||
`pkgsUnstable` to `nixosSystem` or `darwinSystem` with
|
||||
`specialArgs`.
|
||||
|
||||
@@ -3,20 +3,22 @@
|
||||
If you are using a stable version of Nixpkgs but would like to install
|
||||
some particular packages from Nixpkgs unstable -- or some other channel
|
||||
-- then you can import the unstable Nixpkgs and refer to its packages
|
||||
within your configuration.
|
||||
|
||||
With channels, something like
|
||||
within your configuration. Something like
|
||||
|
||||
``` nix
|
||||
{ pkgs, config, ... }:
|
||||
|
||||
let
|
||||
|
||||
pkgsUnstable = import <nixpkgs-unstable> {};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
home.packages = [
|
||||
pkgsUnstable.foo
|
||||
];
|
||||
|
||||
# …
|
||||
}
|
||||
```
|
||||
@@ -30,82 +32,5 @@ $ nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
With flakes, add another Nixpkgs input and pass its packages to your
|
||||
Home Manager modules. For example, a standalone Home Manager flake can
|
||||
define the following. Replace 25.11 with the release branch your
|
||||
configuration follows.
|
||||
|
||||
``` nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager/release-25.11";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ nixpkgs, nixpkgs-unstable, home-manager, ... }:
|
||||
let
|
||||
# Replace this with the system of your Home Manager configuration.
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
pkgsUnstable = nixpkgs-unstable.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
homeConfigurations.jdoe = home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
extraSpecialArgs = { inherit pkgsUnstable; };
|
||||
modules = [ ./home.nix ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
and then use the extra argument in `home.nix`:
|
||||
|
||||
``` nix
|
||||
{ pkgsUnstable, ... }:
|
||||
|
||||
{
|
||||
home.packages = [
|
||||
pkgsUnstable.foo
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
When Home Manager is used as a NixOS or nix-darwin module, pass the
|
||||
extra package set with `home-manager.extraSpecialArgs` in the system
|
||||
configuration:
|
||||
|
||||
``` nix
|
||||
outputs =
|
||||
{ nixpkgs, nixpkgs-unstable, home-manager, ... }:
|
||||
let
|
||||
# Replace this with the system of your NixOS or nix-darwin configuration.
|
||||
system = "x86_64-linux";
|
||||
in
|
||||
{
|
||||
nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
home-manager.nixosModules.home-manager
|
||||
({ config, ... }: {
|
||||
home-manager.extraSpecialArgs = {
|
||||
pkgsUnstable = import nixpkgs-unstable {
|
||||
inherit system;
|
||||
config = config.nixpkgs.config;
|
||||
overlays = config.nixpkgs.overlays;
|
||||
};
|
||||
|
||||
# If you use a stock Nixpkgs configuration, you can use:
|
||||
# pkgsUnstable = nixpkgs-unstable.legacyPackages.${system};
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
The nix-darwin setup is the same pattern with
|
||||
`darwin.lib.darwinSystem` and
|
||||
`home-manager.darwinModules.home-manager`.
|
||||
Note, the package will not be affected by any package overrides,
|
||||
overlays, etc.
|
||||
|
||||
@@ -6,26 +6,26 @@ Home Manager can be used in three primary ways:
|
||||
NixOS and Darwin, this is the only available choice. It is also
|
||||
recommended for people on NixOS or Darwin that want to manage their
|
||||
home directory independently of the system as a whole. See
|
||||
[Standalone installation](installation/standalone.md#sec-install-standalone) for instructions
|
||||
[Standalone installation](#sec-install-standalone) for instructions
|
||||
on how to perform this installation.
|
||||
|
||||
2. As a module within a NixOS system configuration. This allows the
|
||||
user profiles to be built together with the system when running
|
||||
`nixos-rebuild`. See [NixOS module](installation/nixos.md#sec-install-nixos-module) for a
|
||||
`nixos-rebuild`. See [NixOS module](#sec-install-nixos-module) for a
|
||||
description of this setup.
|
||||
|
||||
3. As a module within a
|
||||
[nix-darwin](https://github.com/nix-darwin/nix-darwin/) system
|
||||
configuration. This allows the user profiles to be built together
|
||||
with the system when running `darwin-rebuild`. See [nix-darwin
|
||||
module](installation/nix-darwin.md#sec-install-nix-darwin-module) for a description of this
|
||||
module](#sec-install-nix-darwin-module) for a description of this
|
||||
setup.
|
||||
|
||||
:::{.note}
|
||||
In this chapter we describe how to install Home Manager in the standard
|
||||
way using channels. If you prefer to use [Nix
|
||||
Flakes](https://wiki.nixos.org/wiki/Flakes) then please see the instructions
|
||||
in [nix flakes](nix-flakes.md#ch-nix-flakes).
|
||||
in [nix flakes](#ch-nix-flakes).
|
||||
:::
|
||||
|
||||
```{=include=} sections
|
||||
|
||||
@@ -5,9 +5,9 @@ environments directly from the
|
||||
[nix-darwin](https://github.com/nix-darwin/nix-darwin/) configuration file,
|
||||
which often is more convenient than using the `home-manager` tool.
|
||||
|
||||
To make the nix-darwin module available for use you must `import` it
|
||||
into your system configuration. This is most conveniently done by adding
|
||||
a Home Manager channel. For example, if you are following Nixpkgs master
|
||||
To make the NixOS module available for use you must `import` it into
|
||||
your system configuration. This is most conveniently done by adding a
|
||||
Home Manager channel. For example, if you are following Nixpkgs master
|
||||
or an unstable channel, you can run
|
||||
|
||||
``` shell
|
||||
@@ -15,10 +15,10 @@ $ nix-channel --add https://github.com/nix-community/home-manager/archive/master
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 26.05 channel, you can run
|
||||
and if you follow a Nixpkgs version 25.11 channel, you can run
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz home-manager
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
@@ -28,9 +28,9 @@ It is then possible to add
|
||||
imports = [ <home-manager/nix-darwin> ];
|
||||
```
|
||||
|
||||
to your nix-darwin `configuration.nix` file, which will introduce a
|
||||
`home-manager.users` option whose type is an attribute set that maps
|
||||
user names to Home Manager configurations.
|
||||
to your nix-darwin `configuration.nix` file, which will introduce a new
|
||||
NixOS option called `home-manager` whose type is an attribute set that
|
||||
maps user names to Home Manager configurations.
|
||||
|
||||
For example, a nix-darwin configuration may include the lines
|
||||
|
||||
@@ -45,16 +45,13 @@ home-manager.users.eve = { pkgs, ... }: {
|
||||
|
||||
# The state version is required and should stay at the version you
|
||||
# originally installed.
|
||||
home.stateVersion = "26.05";
|
||||
home.stateVersion = "25.11";
|
||||
};
|
||||
```
|
||||
|
||||
and after a `darwin-rebuild switch` the user eve's environment should
|
||||
include a basic Bash configuration and the packages atool and httpie.
|
||||
|
||||
Home Manager activation runs as part of nix-darwin activation for each
|
||||
configured user.
|
||||
|
||||
If you do not plan on having Home Manager manage your shell
|
||||
configuration then you must add either
|
||||
|
||||
@@ -106,23 +103,13 @@ Nixpkgs.
|
||||
:::
|
||||
|
||||
:::{.note}
|
||||
Home Manager passes extra module arguments to each
|
||||
`home-manager.users.<name>` module:
|
||||
Home Manager will pass `osConfig` as a module argument to any modules
|
||||
you create. This contains the system's nix-darwin configuration.
|
||||
|
||||
``` nix
|
||||
{ lib, pkgs, osConfig, darwinConfig, osClass, modulesPath, ... }:
|
||||
{ lib, pkgs, osConfig, ... }:
|
||||
```
|
||||
|
||||
Here `osConfig` contains the system's nix-darwin configuration and
|
||||
`darwinConfig` is a Darwin-specific alias for the same value. The `lib`
|
||||
argument is Home Manager's extended library. You can pass additional module
|
||||
arguments with `home-manager.extraSpecialArgs`.
|
||||
:::
|
||||
|
||||
:::{.note}
|
||||
Use `home-manager.sharedModules` to add Home Manager modules to every user
|
||||
declared under `home-manager.users`.
|
||||
:::
|
||||
|
||||
Once installed you can see [Using Home Manager](../usage.md#ch-usage) for a more detailed
|
||||
Once installed you can see [Using Home Manager](#ch-usage) for a more detailed
|
||||
description of Home Manager and how to use it.
|
||||
|
||||
@@ -17,10 +17,10 @@ $ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/m
|
||||
$ sudo nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 26.05 channel, you can run
|
||||
and if you follow a Nixpkgs version 25.11 channel, you can run
|
||||
|
||||
``` shell
|
||||
$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz home-manager
|
||||
$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ sudo nix-channel --update
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ Alternatively, home-manager installation can be done declaratively through confi
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
home-manager = builtins.fetchTarball https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz;
|
||||
home-manager = builtins.fetchTarball https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
@@ -54,7 +54,7 @@ in
|
||||
|
||||
# The state version is required and should stay at the version you
|
||||
# originally installed.
|
||||
home.stateVersion = "26.05";
|
||||
home.stateVersion = "25.11";
|
||||
};
|
||||
}
|
||||
```
|
||||
@@ -74,7 +74,7 @@ home-manager.users.eve = { pkgs, ... }: {
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
home.stateVersion = "26.05"; # Please read the comment before changing.
|
||||
home.stateVersion = "25.11"; # Please read the comment before changing.
|
||||
|
||||
};
|
||||
```
|
||||
@@ -85,21 +85,12 @@ httpie.
|
||||
|
||||
:::{.note}
|
||||
If `nixos-rebuild switch` does not result in the environment you expect,
|
||||
then the service to inspect depends on the activation mode.
|
||||
|
||||
By default, Home Manager activates each configured user during boot and
|
||||
system rebuilds through a NixOS system service:
|
||||
you can take a look at the output of the Home Manager activation script
|
||||
output using
|
||||
|
||||
``` shell
|
||||
$ systemctl status "home-manager-$USER.service"
|
||||
```
|
||||
|
||||
If `home-manager.startAsUserService = true` is set, Home Manager instead
|
||||
activates through the user's systemd service:
|
||||
|
||||
``` shell
|
||||
$ systemctl --user status home-manager.service
|
||||
```
|
||||
:::
|
||||
|
||||
If you do not plan on having Home Manager manage your shell
|
||||
@@ -153,23 +144,14 @@ Nixpkgs.
|
||||
:::
|
||||
|
||||
:::{.note}
|
||||
Home Manager passes extra module arguments to each
|
||||
`home-manager.users.<name>` module:
|
||||
Home Manager will pass `osConfig` as a module argument to any modules
|
||||
you create. This contains the system's NixOS configuration.
|
||||
|
||||
``` nix
|
||||
{ lib, pkgs, osConfig, nixosConfig, osClass, modulesPath, ... }:
|
||||
{ lib, pkgs, osConfig, ... }:
|
||||
```
|
||||
|
||||
Here `osConfig` contains the system's NixOS configuration and `nixosConfig`
|
||||
is a NixOS-specific alias for the same value. The `lib` argument is Home
|
||||
Manager's extended library. You can pass additional module arguments with
|
||||
`home-manager.extraSpecialArgs`.
|
||||
:::
|
||||
|
||||
:::{.note}
|
||||
Use `home-manager.sharedModules` to add Home Manager modules to every user
|
||||
declared under `home-manager.users`.
|
||||
:::
|
||||
|
||||
Once installed you can see [Using Home Manager](../usage.md#ch-usage) for a more detailed
|
||||
Once installed you can see [Using Home Manager](#ch-usage) for a more detailed
|
||||
description of Home Manager and how to use it.
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
and if you follow a Nixpkgs version 26.05 channel you can run
|
||||
and if you follow a Nixpkgs version 25.11 channel you can run
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-26.05.tar.gz home-manager
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
@@ -71,5 +71,5 @@ checkout of the repository then you can use the
|
||||
[home-manager.path](#opt-programs.home-manager.path) option to specify the absolute
|
||||
path to the repository.
|
||||
|
||||
Once installed you can see [Using Home Manager](../usage.md#ch-usage) for a more detailed
|
||||
Once installed you can see [Using Home Manager](#ch-usage) for a more detailed
|
||||
description of Home Manager and how to use it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Home Manager Manual {#home-manager-manual}
|
||||
|
||||
## Version 26.11 (unstable)
|
||||
## Version 26.05 (unstable)
|
||||
|
||||
|
||||
```{=include=} preface
|
||||
|
||||
@@ -12,40 +12,18 @@ flake in three ways:
|
||||
NixOS and Darwin, this is the only available choice. It is also
|
||||
recommended for people on NixOS or Darwin that want to manage their
|
||||
home directory independently of the system as a whole. See
|
||||
[Standalone setup](nix-flakes/standalone.md#sec-flakes-standalone) for instructions on how
|
||||
[Standalone setup](#sec-flakes-standalone) for instructions on how
|
||||
to perform this installation.
|
||||
|
||||
2. As a module within a NixOS system configuration. This allows the
|
||||
user profiles to be built together with the system when running
|
||||
`nixos-rebuild`. See [NixOS module](nix-flakes/nixos.md#sec-flakes-nixos-module) for a
|
||||
`nixos-rebuild`. See [NixOS module](#sec-flakes-nixos-module) for a
|
||||
description of this setup.
|
||||
|
||||
3. As a module within a [nix-darwin](https://github.com/nix-darwin/nix-darwin/)
|
||||
system configuration. This allows the user profiles to be built
|
||||
together with the system when running `darwin-rebuild`. See
|
||||
[nix-darwin module](nix-flakes/nix-darwin.md#sec-flakes-nix-darwin-module) for a
|
||||
description of this setup.
|
||||
|
||||
Advanced users may want Home Manager's `nixpkgs` input to follow the
|
||||
same Nixpkgs input as the rest of their flake. This avoids a second
|
||||
Nixpkgs input and makes Home Manager use the same pinned Nixpkgs source
|
||||
revision as the rest of the configuration:
|
||||
|
||||
``` nix
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
```
|
||||
|
||||
This removes the compatibility assumption between Home Manager and the
|
||||
Nixpkgs revision in Home Manager's own lock file, so use it carefully,
|
||||
especially when tracking unstable branches.
|
||||
|
||||
This does not by itself make Home Manager use the same `pkgs` value as
|
||||
your NixOS or nix-darwin system. In NixOS and nix-darwin module setups,
|
||||
`home-manager.useGlobalPkgs = true` controls that behavior by making
|
||||
Home Manager modules receive the system `pkgs` value. When
|
||||
`home-manager.useGlobalPkgs` is enabled, configure Nixpkgs overlays and
|
||||
configuration at the system level instead of through Home Manager
|
||||
`nixpkgs.*` options.
|
||||
3. This allows the user profiles to be built together with the system
|
||||
when running `darwin-rebuild`. See [nix-darwin
|
||||
module](#sec-flakes-nix-darwin-module) for a description of this
|
||||
setup.
|
||||
|
||||
```{=include=} sections
|
||||
nix-flakes/prerequisites.md
|
||||
@@ -54,3 +32,5 @@ nix-flakes/nixos.md
|
||||
nix-flakes/nix-darwin.md
|
||||
nix-flakes/flake-parts.md
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@ Manager's flake module, `flakeModules.home-manager`.
|
||||
description = "flake-parts configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@ to that of NixOS. The `flake.nix` would be:
|
||||
description = "Darwin configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
darwin.url = "github:nix-darwin/nix-darwin";
|
||||
darwin.inputs.nixpkgs.follows = "nixpkgs";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs@{ nixpkgs, home-manager, darwin, ... }: {
|
||||
@@ -24,8 +25,10 @@ to that of NixOS. The `flake.nix` would be:
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.extraSpecialArgs = { inherit inputs; };
|
||||
home-manager.users.jdoe = ./home.nix;
|
||||
|
||||
# Optionally, use home-manager.extraSpecialArgs to pass
|
||||
# arguments to home.nix
|
||||
}
|
||||
];
|
||||
};
|
||||
@@ -34,23 +37,8 @@ to that of NixOS. The `flake.nix` would be:
|
||||
}
|
||||
```
|
||||
|
||||
Use `home-manager.extraSpecialArgs` to pass arguments from your flake to
|
||||
`home.nix` and any imported Home Manager modules. For example, the
|
||||
configuration above makes the complete `inputs` attrset available to modules,
|
||||
so they can declare arguments such as `{ inputs, ... }:`.
|
||||
|
||||
The lower-level mechanism behind this is `_module.args`. Set
|
||||
`_module.args.<name>` from inside a module only when you need to provide a
|
||||
module argument from within the module graph itself. For values that originate
|
||||
outside the module graph, such as flake inputs, prefer
|
||||
`home-manager.extraSpecialArgs`.
|
||||
|
||||
Use `home-manager.sharedModules` for Home Manager modules or settings that
|
||||
should be imported by every user declared in `home-manager.users`.
|
||||
|
||||
The Home Manager configuration is also rebuilt with the nix-darwin
|
||||
generations. The rebuild command here may be
|
||||
`darwin-rebuild switch --flake ~/.config/darwin`.
|
||||
and it is also rebuilt with the nix-darwin generations. The rebuild
|
||||
command here may be `darwin-rebuild switch --flake <flake-uri>`.
|
||||
|
||||
You can use the above `flake.nix` as a template in `~/.config/darwin` by
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@ be as follows:
|
||||
description = "NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs@{ nixpkgs, home-manager, ... }: {
|
||||
@@ -22,8 +23,10 @@ be as follows:
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.extraSpecialArgs = { inherit inputs; };
|
||||
home-manager.users.jdoe = ./home.nix;
|
||||
|
||||
# Optionally, use home-manager.extraSpecialArgs to pass
|
||||
# arguments to home.nix
|
||||
}
|
||||
];
|
||||
};
|
||||
@@ -32,27 +35,10 @@ be as follows:
|
||||
}
|
||||
```
|
||||
|
||||
Use `home-manager.extraSpecialArgs` to pass arguments from your flake to
|
||||
`home.nix` and any imported Home Manager modules. For example, the
|
||||
configuration above makes the complete `inputs` attrset available to modules,
|
||||
so they can declare arguments such as `{ inputs, ... }:`.
|
||||
|
||||
The lower-level mechanism behind this is `_module.args`. Set
|
||||
`_module.args.<name>` from inside a module only when you need to provide a
|
||||
module argument from within the module graph itself. For values that originate
|
||||
outside the module graph, such as flake inputs, prefer
|
||||
`home-manager.extraSpecialArgs`.
|
||||
|
||||
Use `home-manager.sharedModules` for Home Manager modules or settings that
|
||||
should be imported by every user declared in `home-manager.users`.
|
||||
|
||||
The Home Manager configuration is then part of the NixOS configuration
|
||||
and is automatically rebuilt with the system when using the appropriate
|
||||
command for the system, such as
|
||||
|
||||
``` shell
|
||||
$ nixos-rebuild switch --flake /etc/nixos
|
||||
```
|
||||
`nixos-rebuild switch --flake <flake-uri>`.
|
||||
|
||||
You can use the above `flake.nix` as a template in `/etc/nixos` by
|
||||
|
||||
|
||||
@@ -33,5 +33,5 @@
|
||||
|
||||
Unlike the channel-based setup, `home.nix` will be evaluated when
|
||||
the flake is built, so it must be present before bootstrap of Home
|
||||
Manager from the flake. See [Configuration Example](../usage/configuration.md#sec-usage-configuration) for
|
||||
Manager from the flake. See [Configuration Example](#sec-usage-configuration) for
|
||||
introduction about writing a Home Manager configuration.
|
||||
|
||||
@@ -11,44 +11,15 @@ then to generate and activate a basic configuration run the command
|
||||
$ nix run home-manager/master -- init --switch
|
||||
```
|
||||
|
||||
For Nixpkgs or NixOS version 26.05 run
|
||||
For Nixpkgs or NixOS version 25.11 run
|
||||
|
||||
``` shell
|
||||
$ nix run home-manager/release-26.05 -- init --switch
|
||||
$ nix run home-manager/release-25.11 -- init --switch
|
||||
```
|
||||
|
||||
This will generate a `flake.nix` and a `home.nix` file in
|
||||
`~/.config/home-manager`, creating the directory if it does not exist.
|
||||
|
||||
If you need to pass additional values from your flake to `home.nix` or any
|
||||
imported Home Manager modules, use `extraSpecialArgs` in the call to
|
||||
`home-manager.lib.homeManagerConfiguration`:
|
||||
|
||||
``` nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
};
|
||||
|
||||
outputs = inputs@{ nixpkgs, home-manager, ... }: {
|
||||
homeConfigurations.jdoe = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs = { inherit inputs; };
|
||||
modules = [ ./home.nix ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Any attribute in `extraSpecialArgs` becomes a module argument, so `home.nix`
|
||||
or imported modules can declare arguments such as `{ inputs, ... }:`.
|
||||
|
||||
The lower-level mechanism behind this is `_module.args`. Set
|
||||
`_module.args.<name>` from inside a module only when you need to provide a
|
||||
module argument from within the module graph itself. For values that originate
|
||||
outside the module graph, such as flake inputs, prefer `extraSpecialArgs`.
|
||||
|
||||
If you omit the `--switch` option then the activation will not happen.
|
||||
This is useful if you want to inspect and edit the configuration before
|
||||
activating it.
|
||||
@@ -59,7 +30,7 @@ $ # Edit files in ~/.config/home-manager
|
||||
$ nix run home-manager/$branch -- init --switch
|
||||
```
|
||||
|
||||
Where `$branch` is one of `master` or `release-26.05`.
|
||||
Where `$branch` is one of `master` or `release-25.11`.
|
||||
|
||||
After the initial activation has completed successfully then building
|
||||
and activating your flake-based configuration is as simple as
|
||||
@@ -78,13 +49,14 @@ $ home-manager switch --flake ~/hmconf
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
The flake inputs are not automatically updated by Home Manager. Update
|
||||
the lock file with `nix flake update` before switching if you want to
|
||||
use newer input revisions.
|
||||
The flake inputs are not automatically updated by Home Manager. You need
|
||||
to use the standard `nix flake update` command for that.
|
||||
|
||||
If you only want to update specific flake inputs, name them explicitly,
|
||||
for example `nix flake update nixpkgs home-manager`.
|
||||
If you only want to update a single flake input, then the command
|
||||
`nix flake lock --update-input <input>` can be used.
|
||||
|
||||
These commands assume that your current directory is the flake. If not,
|
||||
pass the flake path or URI with `--flake <flake-uri>`.
|
||||
You can also pass flake-related options such as `--recreate-lock-file`
|
||||
or `--update-input <input>` to `home-manager` when building or
|
||||
switching, and these options will be forwarded to `nix build`. See the
|
||||
[NixOS Wiki page](https://wiki.nixos.org/wiki/Flakes) for details.
|
||||
:::
|
||||
|
||||
@@ -43,7 +43,7 @@ option will state the expected type, for
|
||||
[programs.emacs.enable](#opt-programs.emacs.enable) you will see "Type: boolean". You
|
||||
there also find information about the default value and a description of
|
||||
the option. You can find the complete option documentation in
|
||||
[Home Manager Configuration Options](options.md#ch-options) or directly in the terminal by running
|
||||
[Home Manager Configuration Options](#ch-options) or directly in the terminal by running
|
||||
|
||||
``` shell
|
||||
man home-configuration.nix
|
||||
@@ -60,7 +60,6 @@ usage/rollbacks.md
|
||||
usage/dotfiles.md
|
||||
usage/graphical.md
|
||||
usage/gpu-non-nixos.md
|
||||
usage/modular-services.md
|
||||
usage/updating.md
|
||||
usage/upgrading.md
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ A fresh install of Home Manager will generate a minimal
|
||||
# You can update Home Manager without changing this value. See
|
||||
# the Home Manager release notes for a list of state version
|
||||
# changes in each release.
|
||||
home.stateVersion = "26.05";
|
||||
home.stateVersion = "25.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
@@ -65,7 +65,7 @@ follows:
|
||||
# You can update Home Manager without changing this value. See
|
||||
# the Home Manager release notes for a list of state version
|
||||
# changes in each release.
|
||||
home.stateVersion = "26.05";
|
||||
home.stateVersion = "25.11";
|
||||
|
||||
# Let Home Manager install and manage itself.
|
||||
programs.home-manager.enable = true;
|
||||
|
||||
@@ -34,136 +34,3 @@ Activating checkLinkTargets
|
||||
Existing file '/home/jdoe/.config/git/config' is in the way
|
||||
Please move the above files and try again
|
||||
```
|
||||
|
||||
This error is about a file that Home Manager wants to manage as a
|
||||
symbolic link in your home directory. It is separate from package
|
||||
profile collisions, which usually mention `installPackages` or a
|
||||
`collision between .../bin/...` path. For package collisions, see
|
||||
[Why is there a collision error when switching generation?](../faq/collision.md#_why_is_there_a_collision_error_when_switching_generation).
|
||||
|
||||
## Resolving file collisions {#sec-usage-dotfiles-collisions}
|
||||
|
||||
The safest resolution is to inspect the existing path, move any
|
||||
settings you want Home Manager to manage into your configuration, and
|
||||
remove or move the unmanaged file before switching again.
|
||||
|
||||
For a standalone Home Manager installation, you can ask Home Manager to
|
||||
move unmanaged non-symlink paths out of the way during activation:
|
||||
|
||||
``` shell
|
||||
home-manager switch -b backup
|
||||
```
|
||||
|
||||
With the command above, a colliding `~/.config/git/config` is moved to
|
||||
`~/.config/git/config.backup` before Home Manager links the managed
|
||||
file. If the backup path already exists then activation still aborts, so
|
||||
choose an extension whose backup path does not already exist.
|
||||
|
||||
Standalone activation can also run a custom command for each collision:
|
||||
|
||||
``` shell
|
||||
home-manager switch -B trash-put
|
||||
```
|
||||
|
||||
The command receives the colliding path as an argument and must move or
|
||||
remove that path. If both `-B` and `-b` are set, the custom command takes
|
||||
precedence; the command may still use the
|
||||
`HOME_MANAGER_BACKUP_EXT` environment variable set by `-b`.
|
||||
|
||||
When Home Manager is used as a NixOS or nix-darwin module, configure the
|
||||
corresponding module options instead of passing standalone command line
|
||||
flags:
|
||||
|
||||
``` nix
|
||||
{
|
||||
home-manager.backupFileExtension = "backup";
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
``` nix
|
||||
{
|
||||
home-manager.backupCommand = "${pkgs.trash-cli}/bin/trash-put";
|
||||
}
|
||||
```
|
||||
|
||||
If both {option}`home-manager.backupCommand` and
|
||||
{option}`home-manager.backupFileExtension` are set, the command takes
|
||||
precedence. The extension is still exported to the command as
|
||||
`HOME_MANAGER_BACKUP_EXT`, so the command can use it when implementing
|
||||
its own backup naming. With
|
||||
{option}`home-manager.backupFileExtension`, Home Manager refuses to
|
||||
replace an existing backup path unless
|
||||
{option}`home-manager.overwriteBackup` is enabled:
|
||||
|
||||
``` nix
|
||||
{
|
||||
home-manager.backupFileExtension = "backup";
|
||||
home-manager.overwriteBackup = true;
|
||||
}
|
||||
```
|
||||
|
||||
::: {.warning}
|
||||
{option}`home-manager.overwriteBackup` allows activation to clobber
|
||||
existing backup files. Only enable it when those backup paths are
|
||||
disposable.
|
||||
:::
|
||||
|
||||
For individual files, many file options also support `force = true`:
|
||||
|
||||
``` nix
|
||||
{
|
||||
home.file.".config/example" = {
|
||||
source = ./example;
|
||||
force = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
This skips the collision check for the affected target and lets Home
|
||||
Manager replace the existing file or link. Use it sparingly; it can
|
||||
silently delete local changes.
|
||||
|
||||
Backup commands and backup extensions are intended for unmanaged
|
||||
non-symlink paths. If the colliding target is an unmanaged symbolic
|
||||
link, move it manually or use `force = true` after checking that the
|
||||
link target is safe to replace.
|
||||
|
||||
## Advanced file behavior {#sec-usage-dotfiles-advanced}
|
||||
|
||||
The notes below apply to {option}`home.file` and to options based on the
|
||||
same file type, such as {option}`xdg.configFile`.
|
||||
|
||||
When a file source is a directory, {option}`home.file.<name>.recursive`
|
||||
changes how the directory is linked. With the default `recursive =
|
||||
false`, the target is one symbolic link to the source directory. With
|
||||
`recursive = true`, Home Manager creates a matching directory tree and
|
||||
links each leaf file into it.
|
||||
|
||||
Recursive directory linking has special overlap behavior. A direct
|
||||
duplicate target, such as two managed files both targeting `foo`, is an
|
||||
error. If a recursively linked directory provides `foo/bar` and another
|
||||
managed file also targets `foo/bar`, Home Manager keeps the recursive
|
||||
file by default and ignores the overlapping regular file.
|
||||
|
||||
The {option}`home.file.<name>.onChange` hook runs after the new files
|
||||
are linked. For recursive file entries, the hook is always run, so it
|
||||
should be written to be safe even when no leaf file actually changed.
|
||||
|
||||
Normally a path assigned to {option}`home.file.<name>.source` is copied
|
||||
or linked through the Nix store. To make Home Manager create a link to a
|
||||
live path outside the store, use
|
||||
`config.lib.file.mkOutOfStoreSymlink`:
|
||||
|
||||
``` nix
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
home.file.".config/example".source =
|
||||
config.lib.file.mkOutOfStoreSymlink ./example;
|
||||
}
|
||||
```
|
||||
|
||||
This is useful when the target should follow changes to a mutable file
|
||||
or directory outside the store.
|
||||
|
||||
@@ -38,17 +38,16 @@ GPU drivers require an update, run
|
||||
|
||||
Because the `/run` directory is volatile and disappears on reboot, libraries
|
||||
cannot be simply copied or linked there. The `non-nixos-gpu-setup` script
|
||||
installs a
|
||||
[`tmpfiles.d`](https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html)
|
||||
config which ensures that the drivers are linked to `/run/opengl-driver` on
|
||||
boot. Home Manager will always check and warn you when this setup needs to be
|
||||
refreshed.
|
||||
installs a Systemd service which ensures that the drivers are linked to
|
||||
`/run/opengl-driver` on boot. Home Manager will always check and warn you when
|
||||
this setup needs to be refreshed.
|
||||
|
||||
If you ever wish to uninstall these drivers, all you need to do is
|
||||
|
||||
```sh
|
||||
sudo rm /run/opengl-driver
|
||||
sudo rm /etc/tmpfiles.d/non-nixos-gpu.conf
|
||||
sudo systemctl disable --now non-nixos-gpu.service
|
||||
sudo rm /etc/systemd/system/non-nixos-gpu.service
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
# Modular Services {#sec-usage-modular-services}
|
||||
|
||||
Home Manager supports nixpkgs
|
||||
[modular services](https://nixos.org/manual/nixos/unstable/#modular-services)
|
||||
under [](#opt-home.services). This is the Home Manager analog to the
|
||||
NixOS `system.services` namespace: each entry is an abstract service
|
||||
sourced from `<nixpkgs/lib/services/lib.nix>` with the upstream portable
|
||||
systemd module loaded into it, so service modules shipped with packages
|
||||
(e.g. `pkgs.<name>.passthru.services.default`) drop in unchanged --
|
||||
the same module evaluates on NixOS and on Home Manager.
|
||||
|
||||
A minimal example -- run mpd as a user service:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }: {
|
||||
home.services.mpd = {
|
||||
process.argv = [ "${pkgs.mpd}/bin/mpd" "--no-daemon" ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
This produces `~/.config/systemd/user/mpd.service` with `ExecStart` set
|
||||
to the mpd binary and `WantedBy=default.target`.
|
||||
|
||||
Each service exposes the upstream NixOS-style schema: [`process.argv`],
|
||||
`systemd.lib`, `systemd.mainExecStart`, `systemd.service`,
|
||||
`systemd.services`, `systemd.sockets`. Lifted units are translated from
|
||||
NixOS-style attrs (`wantedBy`, `serviceConfig`, `unitConfig`,
|
||||
`environment`, ...) into the section-based INI shape
|
||||
(`{ Unit; Service; Install; }`) that Home Manager's
|
||||
[](#opt-systemd.user.services) consumes. Only common keys are mapped
|
||||
explicitly; uncommon options remain reachable via `unitConfig`,
|
||||
`serviceConfig`, or `socketConfig`.
|
||||
|
||||
Sub-services (nested `services.<sub>` inside another service) and their
|
||||
units are dashed under the parent service name. The empty unit key
|
||||
`""` denotes the service's *primary* unit (lifted to a unit named
|
||||
after the service itself); [`process.argv`] becomes the default
|
||||
`ExecStart` for that unit, which defaults to `WantedBy=default.target`.
|
||||
|
||||
## Reusing upstream package modules {#sec-usage-modular-services-upstream}
|
||||
|
||||
Modular services exposed by packages under
|
||||
`pkgs.<name>.passthru.services.default` can be imported directly.
|
||||
For example, `pkgs.php`'s [`php-fpm`]:
|
||||
|
||||
```nix
|
||||
{ pkgs, ... }: {
|
||||
home.services."php-fpm" = {
|
||||
imports = [ pkgs.php.passthru.services.default ];
|
||||
configData."php-fpm.conf".source = builtins.elemAt config.home.services.php-fpm.process.argv 2;
|
||||
php-fpm.settings.mypool = {
|
||||
listen = "127.0.0.1:9000";
|
||||
# FIXME: required by upstream modular service, but ignored when run as user
|
||||
"user" = "";
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 75;
|
||||
"pm.min_spare_servers" = 5;
|
||||
"pm.max_spare_servers" = 20;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Some packages ship modules written for system services that include
|
||||
directives the user-session manager cannot honour (`DynamicUser`,
|
||||
`AmbientCapabilities`, ...). The unit is still generated with those
|
||||
directives -- user systemd silently ignores what it cannot apply.
|
||||
`WantedBy=multi-user.target` is automatically normalized to
|
||||
`WantedBy=default.target`. Other directives can be overridden per
|
||||
service:
|
||||
|
||||
```nix
|
||||
home.services."tunnel" = {
|
||||
imports = [ pkgs.ghostunnel.passthru.services.default ];
|
||||
# ...
|
||||
systemd.services."tunnel".serviceConfig.DynamicUser = lib.mkForce false;
|
||||
};
|
||||
```
|
||||
|
||||
## Configuration data {#sec-usage-modular-services-configdata}
|
||||
|
||||
Each service can declare configuration files via `configData.<name>`.
|
||||
These are materialized at `$XDG_CONFIG_HOME/home-services/<service>/<name>`
|
||||
(mirroring how NixOS lifts `configData` to `environment.etc`), with the
|
||||
absolute path injected back into `configData.<name>.path` so the service
|
||||
can refer to its files at a stable location:
|
||||
|
||||
```nix
|
||||
{ config, ... }:
|
||||
{
|
||||
home.services.demo = {
|
||||
process.argv = [ "/bin/myapp" "--config" config.home.services.demo.configData."app.toml".path ];
|
||||
configData."app.toml".text = ''
|
||||
port = 1234
|
||||
'';
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The store paths of all enabled `configData` entries are automatically
|
||||
added to the primary unit's `X-Reload-Triggers`, so `home-manager switch`
|
||||
restarts the service whenever any of its configuration files change. To
|
||||
reload instead of restart, override `X-SwitchMethod`:
|
||||
|
||||
```nix
|
||||
home.services.demo.systemd.services."".unitConfig.X-SwitchMethod = "reload";
|
||||
```
|
||||
|
||||
## Scope notes {#sec-usage-modular-services-scope}
|
||||
|
||||
Home Manager mirrors the surface of nixpkgs' portable systemd module:
|
||||
services and sockets only. Other unit kinds Home Manager supports
|
||||
natively under [](#opt-systemd.user.services) (timers, paths, mounts, ...)
|
||||
are intentionally not modeled on `home.services` until upstream grows them,
|
||||
to keep both surfaces aligned.
|
||||
|
||||
[`process.argv`]: https://nixos.org/manual/nixos/unstable/#service-opt-process.argv
|
||||
[`php-fpm`]: https://nixos.org/manual/nixos/stable/options#opt-_imports_=___pkgs.php.services.default___
|
||||
@@ -1,64 +1,8 @@
|
||||
# Updating {#sec-updating}
|
||||
|
||||
Updating means moving to a newer revision of the Home Manager branch
|
||||
that your configuration already follows. For example, a configuration
|
||||
using `release-25.11` can update to a newer revision of `release-25.11`
|
||||
without changing release branches.
|
||||
|
||||
If you want to move from one release branch to another, such as
|
||||
`release-25.05` to `release-25.11`, or between a release branch and
|
||||
`master`, see
|
||||
[Upgrading to a new Home Manager release](upgrading.md#sec-upgrade-release).
|
||||
|
||||
## Flake-Based Configurations {#sec-updating-flakes}
|
||||
|
||||
Flake inputs are pinned in `flake.lock`, and Home Manager will keep using
|
||||
the pinned revisions until you update that lock file.
|
||||
|
||||
To update all inputs in the flake:
|
||||
|
||||
``` shell
|
||||
$ nix flake update
|
||||
```
|
||||
|
||||
To update only specific inputs, name them explicitly:
|
||||
|
||||
``` shell
|
||||
$ nix flake update home-manager nixpkgs
|
||||
```
|
||||
|
||||
These commands assume that your current directory is the flake. If not,
|
||||
pass the flake path or URI with `--flake <flake-uri>`.
|
||||
|
||||
After updating the lock file, rebuild with the command for your
|
||||
installation method.
|
||||
|
||||
For a standalone Home Manager flake:
|
||||
|
||||
``` shell
|
||||
$ home-manager switch --flake .
|
||||
```
|
||||
|
||||
For Home Manager as a NixOS module:
|
||||
|
||||
``` shell
|
||||
$ sudo nixos-rebuild switch --flake .
|
||||
```
|
||||
|
||||
For Home Manager as a nix-darwin module:
|
||||
|
||||
``` shell
|
||||
$ darwin-rebuild switch --flake .
|
||||
```
|
||||
|
||||
## Channel-Based Configurations {#sec-updating-channels}
|
||||
|
||||
Channels are mutable references outside the Home Manager configuration
|
||||
itself. Updating a channel moves it to a newer revision of the same
|
||||
channel or branch.
|
||||
|
||||
For a standalone Home Manager channel installation, update the user's
|
||||
channels and then switch:
|
||||
If you have installed Home Manager using the Nix channel method then
|
||||
updating Home Manager is done by first updating the channel. You can
|
||||
then switch to the updated Home Manager environment.
|
||||
|
||||
``` shell
|
||||
$ nix-channel --update
|
||||
@@ -66,19 +10,3 @@ $ nix-channel --update
|
||||
unpacking channels...
|
||||
$ home-manager switch
|
||||
```
|
||||
|
||||
For Home Manager as a NixOS module, update the root user's Home Manager
|
||||
channel and rebuild the system:
|
||||
|
||||
``` shell
|
||||
$ sudo nix-channel --update home-manager
|
||||
$ sudo nixos-rebuild switch
|
||||
```
|
||||
|
||||
For Home Manager as a nix-darwin module, update the Home Manager channel
|
||||
used by your nix-darwin configuration and rebuild the system:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --update home-manager
|
||||
$ darwin-rebuild switch
|
||||
```
|
||||
|
||||
+60
-114
@@ -2,47 +2,66 @@
|
||||
|
||||
## Overview {#sec-upgrade-release-overview}
|
||||
|
||||
When moving your configuration to a new Nixpkgs release branch, you
|
||||
should also move Home Manager to the matching release branch. On NixOS
|
||||
this usually means upgrading Home Manager together with NixOS. On
|
||||
standalone and nix-darwin installations, match Home Manager to the
|
||||
Nixpkgs branch used by your configuration. The examples below use 25.11;
|
||||
replace this with the release branch you are upgrading to.
|
||||
|
||||
If your configuration follows `nixos-unstable` or `nixpkgs-unstable`,
|
||||
use Home Manager's `master` branch.
|
||||
When upgrading NixOS to a new major version (e.g., from 24.11 to
|
||||
25.05), you also need to upgrade your Home Manager channel to maintain
|
||||
compatibility. This guide covers the proper steps to upgrade Home
|
||||
Manager channels for NixOS 25.05.
|
||||
|
||||
## Understanding Home Manager Versioning {#sec-upgrade-release-understanding-versioning}
|
||||
|
||||
Home Manager follows NixOS release cycles and provides corresponding branches:
|
||||
|
||||
- **release-\<version\>**: Stable branch for the matching NixOS or
|
||||
Nixpkgs release, such as `release-25.11`.
|
||||
- **release-##.##**: Stable branch for NixOS ##.## (current stable)
|
||||
|
||||
- **master**: Development branch (tracks nixpkgs-unstable)
|
||||
- **master**: Development branch (tracks nixos-unstable)
|
||||
|
||||
:::{.note}
|
||||
Use the Home Manager branch that matches the Nixpkgs branch used to
|
||||
evaluate your Home Manager configuration. For stable NixOS
|
||||
configurations, this is normally the same as your NixOS version.
|
||||
Always use the Home Manager version that matches your NixOS version to
|
||||
avoid compatibility issues.
|
||||
:::
|
||||
|
||||
## Flake-Based Installation {#sec-upgrade-release-understanding-flake}
|
||||
## Channel-Based Installation (Traditional) {#sec-upgrade-release-understanding-channel}
|
||||
|
||||
If you are using Home Manager with Nix flakes, update your `nixpkgs` and
|
||||
`home-manager` inputs together:
|
||||
1. First, verify your current Home Manager channel:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --list
|
||||
```
|
||||
|
||||
You should see something like:
|
||||
|
||||
```
|
||||
home-manager https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz
|
||||
```
|
||||
|
||||
1. Update the Home Manager channel to a NixOS 25.05 compatible version:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.05.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
```
|
||||
|
||||
1. Apply the changes:
|
||||
|
||||
``` shell
|
||||
$ home-manager switch
|
||||
```
|
||||
|
||||
## Flake-Based Installation (Modern) {#sec-upgrade-release-understanding-flake}
|
||||
|
||||
If you're using Home Manager with Nix flakes, update your `flake.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "Home Manager configuration";
|
||||
|
||||
inputs = {
|
||||
# Match the Nixpkgs branch to the release you are using.
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
|
||||
# Increment release branch for NixOS
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
home-manager = {
|
||||
# Match the Home Manager branch to the Nixpkgs branch above.
|
||||
url = "github:nix-community/home-manager/release-25.11";
|
||||
# Follow corresponding `release` branch from Home Manager
|
||||
url = "github:nix-community/home-manager/release-25.05";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,126 +74,54 @@ If you are using Home Manager with Nix flakes, update your `nixpkgs` and
|
||||
}
|
||||
```
|
||||
|
||||
For `nixos-unstable` or `nixpkgs-unstable`, use the `master` branch
|
||||
instead:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then update the lock file and rebuild using the command for your
|
||||
installation method.
|
||||
|
||||
For a standalone Home Manager flake:
|
||||
Then update and rebuild. If you are using Home Manager standalone:
|
||||
|
||||
``` shell
|
||||
$ nix flake update
|
||||
$ home-manager switch --flake .
|
||||
```
|
||||
|
||||
For Home Manager as a NixOS module:
|
||||
And if you are using Home Manager as a NixOS module then you will need
|
||||
to update your system configuration instead and run
|
||||
|
||||
``` shell
|
||||
$ nix flake update
|
||||
$ sudo nixos-rebuild switch --flake .
|
||||
```
|
||||
|
||||
For Home Manager as a nix-darwin module:
|
||||
|
||||
``` shell
|
||||
$ nix flake update
|
||||
$ darwin-rebuild switch --flake .
|
||||
```
|
||||
|
||||
These commands assume that your current directory is the flake. If not,
|
||||
pass the flake path or URI with `--flake <flake-uri>`.
|
||||
|
||||
## Channel-Based Installation {#sec-upgrade-release-understanding-channel}
|
||||
|
||||
For a standalone channel-based installation, first verify your current
|
||||
Home Manager channel:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --list
|
||||
```
|
||||
|
||||
The entry identifies the Home Manager branch currently in use. For
|
||||
example:
|
||||
|
||||
```
|
||||
home-manager https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz
|
||||
```
|
||||
|
||||
Update the Home Manager channel to the branch matching your Nixpkgs
|
||||
release, then switch:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
$ home-manager switch
|
||||
```
|
||||
|
||||
When Home Manager is installed as a NixOS module with channels, update
|
||||
the root user's Home Manager channel and rebuild the system:
|
||||
|
||||
``` shell
|
||||
$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ sudo nix-channel --update
|
||||
$ sudo nixos-rebuild switch
|
||||
```
|
||||
|
||||
When Home Manager is installed as a nix-darwin module with channels,
|
||||
update the Home Manager channel used by your nix-darwin configuration
|
||||
and rebuild the system:
|
||||
|
||||
``` shell
|
||||
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz home-manager
|
||||
$ nix-channel --update
|
||||
$ darwin-rebuild switch
|
||||
```
|
||||
|
||||
## State Version Management {#sec-upgrade-release-state-version}
|
||||
|
||||
:::{.warning}
|
||||
Careful updating your `home.stateVersion` when upgrading Home Manager.
|
||||
:::
|
||||
|
||||
The `stateVersion` should remain set to the Home Manager release you
|
||||
first used for this home configuration.
|
||||
The `stateVersion` is best to remain set to the NixOS version you
|
||||
**first installed** Home Manager
|
||||
|
||||
```nix
|
||||
{
|
||||
# Example: if this home configuration was first created on 24.11.
|
||||
home.stateVersion = "24.11";
|
||||
home.stateVersion = "24.11"; # Example: if you first installed on 24.11
|
||||
}
|
||||
```
|
||||
|
||||
**Why?** The `stateVersion` ensures backward compatibility and
|
||||
prevents breaking changes from affecting your existing configuration.
|
||||
|
||||
**Remember:** Channel or flake input version is not the same as state
|
||||
version. Update Home Manager, keep `home.stateVersion` unchanged, and
|
||||
only change it after reading the release notes and migrating any
|
||||
affected configuration.
|
||||
**Remember:** Channel version is not the same as State version. Update
|
||||
the channel, keep the `stateVersion` unchanged. Advanced users can
|
||||
view the changes between releases and see if any of the `stateVersion`
|
||||
changes will affect them and increment, if they migrate their
|
||||
configurations to follow the changed evaluation.
|
||||
|
||||
## Troubleshooting {#sec-upgrade-release-state-troubleshooting}
|
||||
|
||||
### Common Issues {#sec-upgrade-release-state-troubleshooting-common-issues}
|
||||
|
||||
Check the [Home Manager Release Notes](../release-notes/release-notes.md#ch-release-notes) for breaking changes.
|
||||
Check the [Home Manager Release Notes](#ch-release-notes) for breaking changes.
|
||||
|
||||
1. **Version Mismatch Warning**: If you see warnings about version
|
||||
mismatches, ensure your Home Manager branch matches the Nixpkgs
|
||||
branch used by your configuration. For NixOS stable releases, this
|
||||
usually means matching your NixOS version.
|
||||
mismatches, ensure your Home Manager version matches your NixOS
|
||||
version.
|
||||
|
||||
1. **Module Changes**: Modules are constantly being updated with new
|
||||
features to keep up with changes in upstream packaging or to fix
|
||||
@@ -182,8 +129,8 @@ Check the [Home Manager Release Notes](../release-notes/release-notes.md#ch-rele
|
||||
there was something noted in the release notes or news entries.
|
||||
|
||||
1. **Channel Not Found**: If `nix-channel --list` shows no channels,
|
||||
you might be using a different installation method, such as flakes,
|
||||
or Home Manager may be imported through your system configuration.
|
||||
you might be using a different installation method (like flakes or
|
||||
NixOS module).
|
||||
|
||||
### Verification {#sec-upgrade-release-state-troubleshooting-verification}
|
||||
|
||||
@@ -193,10 +140,9 @@ After upgrading, verify the installation:
|
||||
$ home-manager --version
|
||||
```
|
||||
|
||||
This should show the Home Manager version or indicate that it is using
|
||||
the expected release branch.
|
||||
This should show version 25.05 or indicate it's using the release-25.05 branch.
|
||||
|
||||
## Additional Resources {#sec-upgrade-release-resources}
|
||||
|
||||
- [NixOS Stable Release Notes](https://nixos.org/manual/nixos/stable/release-notes)
|
||||
- [Home Manager Release Notes](../release-notes/release-notes.md#ch-release-notes)
|
||||
- [Home Manager Release Notes](#ch-release-notes)
|
||||
|
||||
@@ -4,7 +4,7 @@ Overall the basic option types are the same in Home Manager as NixOS. A
|
||||
few Home Manager options, however, make use of custom types that are
|
||||
worth describing in more detail. These are the option types `dagOf` and
|
||||
`gvariant` that are used, for example, by
|
||||
[programs.ssh.settings](#opt-programs.ssh.settings) and [dconf.settings](#opt-dconf.settings).
|
||||
[programs.ssh.matchBlocks](#opt-programs.ssh.matchBlocks) and [dconf.settings](#opt-dconf.settings).
|
||||
|
||||
[]{#sec-option-types-dag}`hm.types.dagOf`
|
||||
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import html
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SIMPLE_ROLES = (
|
||||
"command",
|
||||
"component",
|
||||
"description",
|
||||
"file",
|
||||
"index",
|
||||
"system",
|
||||
"type",
|
||||
)
|
||||
|
||||
HEADING_ANCHOR = re.compile(r"^(#{1,6}\s+)(.*)\s+\{#([^}]+)\}\s*$")
|
||||
INLINE_ANCHOR = re.compile(r"\[\]\{#([^}]+)\}")
|
||||
OPTION_ROLE = re.compile(r"(?<![$`])\{option\}`([^`]*)`")
|
||||
SIMPLE_ROLE = re.compile(r"(?<![$`])\{(" + "|".join(SIMPLE_ROLES) + r")\}`([^`]*)`")
|
||||
OPTION_LINK = re.compile(
|
||||
r"\[(?P<label>[^\]]*)\]\(#(?P<anchor>(?:opt|nixos-opt|nix-darwin-opt)-[^)]+)\)"
|
||||
)
|
||||
LEFTOVER_ROLE = re.compile(
|
||||
r"(?<![$`])\{(" + "|".join(("option", *SIMPLE_ROLES)) + r")\}`[^`]*`"
|
||||
)
|
||||
FENCE = re.compile(r"^\s*(`{3,})(.*)$")
|
||||
FENCE_CLOSE = re.compile(r"^\s*`{3,}\s*$")
|
||||
ADMONITION_OPEN = re.compile(r"^\s*:::\s*\{\.(note|warning|example)\}\s*$")
|
||||
ADMONITION_CLOSE = re.compile(r"^\s*:::\s*$")
|
||||
DEEP_SPLIT_NAMESPACES = {"programs", "services"}
|
||||
|
||||
|
||||
def option_target(anchor: str, current_file: Path, base_depth: int) -> str:
|
||||
if anchor.startswith("nix-darwin-opt-"):
|
||||
option = anchor.removeprefix("nix-darwin-opt-")
|
||||
option = option.replace("<", "_").replace(">", "_")
|
||||
anchor = f"nix-darwin-opt-{option}"
|
||||
base = "options/nix-darwin"
|
||||
elif anchor.startswith("nixos-opt-"):
|
||||
option = anchor.removeprefix("nixos-opt-")
|
||||
option = option.replace("<", "_").replace(">", "_")
|
||||
anchor = f"nixos-opt-{option}"
|
||||
base = "options/nixos"
|
||||
else:
|
||||
option = anchor.removeprefix("opt-")
|
||||
option = option.replace("<", "_").replace(">", "_")
|
||||
anchor = f"opt-{option}"
|
||||
base = "options/home-manager"
|
||||
|
||||
page_parts = option_page_parts(option)
|
||||
prefix = "../" * (base_depth + len(current_file.parent.parts))
|
||||
return f"{prefix}{base}/{'/'.join(page_parts)}.md#{anchor}"
|
||||
|
||||
|
||||
def option_page_parts(option_name: str) -> list[str]:
|
||||
parts = option_name.split(".")
|
||||
namespace = parts[0]
|
||||
if namespace in DEEP_SPLIT_NAMESPACES and len(parts) > 1:
|
||||
return parts[:2]
|
||||
return [namespace]
|
||||
|
||||
|
||||
def option_label(anchor: str) -> str:
|
||||
if anchor.startswith("nix-darwin-opt-"):
|
||||
return anchor.removeprefix("nix-darwin-opt-")
|
||||
if anchor.startswith("nixos-opt-"):
|
||||
return anchor.removeprefix("nixos-opt-")
|
||||
return anchor.removeprefix("opt-")
|
||||
|
||||
|
||||
def markdown_label(value: str) -> str:
|
||||
return value.replace("<", "<").replace(">", ">")
|
||||
|
||||
|
||||
def convert_inline(line: str, current_file: Path, base_depth: int) -> str:
|
||||
line = line.replace("index.xhtml", "index.html")
|
||||
line = INLINE_ANCHOR.sub(
|
||||
lambda match: f'<a id="{html.escape(match.group(1), quote=True)}"></a>',
|
||||
line,
|
||||
)
|
||||
line = OPTION_ROLE.sub(
|
||||
lambda match: (
|
||||
f"[{markdown_label(match.group(1))}]"
|
||||
f"({option_target(f'opt-{match.group(1)}', current_file, base_depth)})"
|
||||
),
|
||||
line,
|
||||
)
|
||||
line = OPTION_LINK.sub(
|
||||
lambda match: (
|
||||
f"[{markdown_label(match.group('label') or option_label(match.group('anchor')))}]"
|
||||
f"({option_target(match.group('anchor'), current_file, base_depth)})"
|
||||
),
|
||||
line,
|
||||
)
|
||||
return SIMPLE_ROLE.sub(lambda match: f"`{match.group(2)}`", line)
|
||||
|
||||
|
||||
def convert_heading(line: str, current_file: Path, base_depth: int) -> str:
|
||||
match = HEADING_ANCHOR.match(line)
|
||||
if match is None:
|
||||
return convert_inline(line, current_file, base_depth)
|
||||
|
||||
prefix, title, anchor = match.groups()
|
||||
return (
|
||||
f'<a id="{html.escape(anchor, quote=True)}"></a>\n'
|
||||
f"{prefix}{convert_inline(title, current_file, base_depth)}"
|
||||
)
|
||||
|
||||
|
||||
def is_include_fence(line: str) -> tuple[bool, str]:
|
||||
match = FENCE.match(line)
|
||||
if match is None:
|
||||
return False, ""
|
||||
|
||||
info = match.group(2).strip()
|
||||
return info.startswith(("{=include=}", "include")), match.group(1)
|
||||
|
||||
|
||||
def convert_markdown(
|
||||
text: str,
|
||||
source: Path,
|
||||
current_file: Path,
|
||||
base_depth: int,
|
||||
) -> str:
|
||||
output: list[str] = []
|
||||
in_code_fence = False
|
||||
code_fence = ""
|
||||
in_include = False
|
||||
include_fence = ""
|
||||
in_admonition = False
|
||||
|
||||
for raw_line in text.splitlines(keepends=True):
|
||||
line = raw_line[:-1] if raw_line.endswith("\n") else raw_line
|
||||
newline = "\n" if raw_line.endswith("\n") else ""
|
||||
|
||||
if in_include:
|
||||
if FENCE_CLOSE.match(line) and len(line.strip()) >= len(include_fence):
|
||||
in_include = False
|
||||
include_fence = ""
|
||||
continue
|
||||
|
||||
if in_code_fence:
|
||||
output.append(raw_line)
|
||||
if FENCE_CLOSE.match(line) and len(line.strip()) >= len(code_fence):
|
||||
in_code_fence = False
|
||||
code_fence = ""
|
||||
continue
|
||||
|
||||
include, fence = is_include_fence(line)
|
||||
if include:
|
||||
in_include = True
|
||||
include_fence = fence
|
||||
continue
|
||||
|
||||
fence_match = FENCE.match(line)
|
||||
if fence_match is not None:
|
||||
in_code_fence = True
|
||||
code_fence = fence_match.group(1)
|
||||
output.append(raw_line)
|
||||
continue
|
||||
|
||||
if in_admonition:
|
||||
if ADMONITION_CLOSE.match(line):
|
||||
in_admonition = False
|
||||
continue
|
||||
converted = convert_inline(line, current_file, base_depth)
|
||||
output.append(f"> {converted}{newline}" if converted else ">\n")
|
||||
continue
|
||||
|
||||
admonition = ADMONITION_OPEN.match(line)
|
||||
if admonition is not None:
|
||||
in_admonition = True
|
||||
output.append(f"> **{admonition.group(1).title()}**\n")
|
||||
continue
|
||||
|
||||
output.append(convert_heading(line, current_file, base_depth) + newline)
|
||||
|
||||
if in_include:
|
||||
raise ValueError(f"{source}: unterminated include block")
|
||||
|
||||
converted = "".join(output)
|
||||
if LEFTOVER_ROLE.search(converted):
|
||||
raise ValueError(f"{source}: unconverted NixOS-render-docs role remains")
|
||||
if "```{=include=}" in converted:
|
||||
raise ValueError(f"{source}: unconverted include block remains")
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
def convert_tree(source: Path, destination: Path, base_depth: int) -> None:
|
||||
for path in source.rglob("*"):
|
||||
if not path.is_file():
|
||||
continue
|
||||
|
||||
target = destination / path.relative_to(source)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if path.suffix == ".md":
|
||||
text = path.read_text(encoding="utf-8")
|
||||
target.write_text(
|
||||
convert_markdown(text, path, path.relative_to(source), base_depth),
|
||||
encoding="utf-8",
|
||||
)
|
||||
else:
|
||||
shutil.copy2(path, target)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--base-depth", type=int, default=0)
|
||||
parser.add_argument("source", type=Path)
|
||||
parser.add_argument("destination", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.source.is_dir():
|
||||
print(f"missing source directory: {args.source}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
args.destination.mkdir(parents=True, exist_ok=True)
|
||||
convert_tree(args.source, args.destination, args.base_depth)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,132 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import html
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ANCHOR = re.compile(r'<a id="([^"]+)"></a>')
|
||||
SPECIAL_PAGES = {
|
||||
Path("manual.md"): "index.html",
|
||||
Path("preface.md"): "index.html",
|
||||
Path("options.md"): "options/home-manager/index.html",
|
||||
Path("nixos-options.md"): "options/nixos/index.html",
|
||||
Path("nix-darwin-options.md"): "options/nix-darwin/index.html",
|
||||
}
|
||||
OPTION_PREFIXES = {
|
||||
"opt-": "options/home-manager",
|
||||
"nixos-opt-": "options/nixos",
|
||||
"nix-darwin-opt-": "options/nix-darwin",
|
||||
}
|
||||
|
||||
ROUTER = """
|
||||
(function () {
|
||||
var h = location.hash || "", a = h.slice(1), t = __DEFAULT__;
|
||||
var m = __ANCHORS__, p = __PREFIXES__;
|
||||
function o(a) {
|
||||
for (var k in p) {
|
||||
if (a.indexOf(k) !== 0) continue;
|
||||
var s = a.slice(k.length).replace(/[<>]/g, "_").split("."), q = s[0];
|
||||
if ((q === "programs" || q === "services") && s.length > 1) q += "/" + s[1];
|
||||
return p[k] + "/" + q + ".html";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (a) t = Object.prototype.hasOwnProperty.call(m, a) ? m[a] : o(a) || t;
|
||||
if (t === null) return;
|
||||
var n = t + (location.search || "") + h;
|
||||
var c = location.pathname.split("/").pop() + location.search + h;
|
||||
if (n !== c) location.replace(n);
|
||||
}());
|
||||
""".strip()
|
||||
|
||||
|
||||
def page_for(source, path):
|
||||
relative = path.relative_to(source)
|
||||
return SPECIAL_PAGES.get(relative, relative.with_suffix(".html").as_posix())
|
||||
|
||||
|
||||
def anchors_for(source, roots):
|
||||
anchors = {}
|
||||
for root in roots:
|
||||
files = [root] if root.is_file() else sorted(root.rglob("*.md"))
|
||||
for path in files:
|
||||
page = page_for(source, path)
|
||||
for anchor in ANCHOR.findall(path.read_text(encoding="utf-8")):
|
||||
anchors.setdefault(anchor, page)
|
||||
return anchors
|
||||
|
||||
|
||||
def script(default, anchors):
|
||||
js = (
|
||||
ROUTER.replace("__DEFAULT__", json.dumps(default))
|
||||
.replace(
|
||||
"__ANCHORS__", json.dumps(anchors, sort_keys=True, separators=(",", ":"))
|
||||
)
|
||||
.replace("__PREFIXES__", json.dumps(OPTION_PREFIXES, separators=(",", ":")))
|
||||
)
|
||||
return "\n".join(
|
||||
[
|
||||
" <script>",
|
||||
" //<![CDATA[",
|
||||
*[f" {line}" for line in js.splitlines()],
|
||||
" //]]>",
|
||||
" </script>",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def write_redirect(output, name, destination, anchors=None):
|
||||
escaped = html.escape(destination, quote=True)
|
||||
(output / name).write_text(
|
||||
f"""<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
{script(destination, anchors or {})}
|
||||
<meta http-equiv="refresh" content="0; url={escaped}" />
|
||||
<link rel="canonical" href="{escaped}" />
|
||||
<title>Redirecting...</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="{escaped}">{escaped}</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def inject_root_router(output, anchors):
|
||||
index = output / "index.html"
|
||||
text = index.read_text(encoding="utf-8")
|
||||
index.write_text(text.replace("<head>", f"<head>\n{script(None, anchors)}", 1))
|
||||
|
||||
|
||||
def main():
|
||||
source, output = map(Path, sys.argv[1:])
|
||||
|
||||
manual_roots = [
|
||||
path
|
||||
for path in source.iterdir()
|
||||
if path.name != "options" and (path.is_dir() or path.suffix == ".md")
|
||||
]
|
||||
manual_anchors = anchors_for(source, manual_roots)
|
||||
release_anchors = anchors_for(source, [source / "release-notes"])
|
||||
|
||||
inject_root_router(output, manual_anchors)
|
||||
for name, destination, anchors in [
|
||||
("index.xhtml", "index.html", manual_anchors),
|
||||
("options.html", "options/home-manager/index.html", {}),
|
||||
("options.xhtml", "options/home-manager/index.html", {}),
|
||||
("nixos-options.xhtml", "options/nixos/index.html", {}),
|
||||
("nix-darwin-options.xhtml", "options/nix-darwin/index.html", {}),
|
||||
("release-notes.xhtml", "release-notes/release-notes.html", release_anchors),
|
||||
]:
|
||||
write_redirect(output, name, destination, anchors)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
optionDocs,
|
||||
manpageUrls,
|
||||
revision,
|
||||
}:
|
||||
|
||||
pkgs.runCommand "home-manager-mdbook-options"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
pkgs.buildPackages.nixos-render-docs
|
||||
pkgs.buildPackages.python3
|
||||
];
|
||||
optionDocsJson = builtins.toJSON optionDocs;
|
||||
passAsFile = [ "optionDocsJson" ];
|
||||
}
|
||||
''
|
||||
python3 ${./render-options.py} \
|
||||
"$optionDocsJsonPath" \
|
||||
${manpageUrls} \
|
||||
${revision} \
|
||||
"$out"
|
||||
''
|
||||
@@ -1,221 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
OPTION_LINK = re.compile(
|
||||
r"\[(?P<label>[^\]]*)\]\(#(?P<anchor>(?:opt|nixos-opt|nix-darwin-opt)-[^)]+)\)"
|
||||
)
|
||||
OPTION_HREF = re.compile(r'href="#(?P<anchor>(?:opt|nixos-opt|nix-darwin-opt)-[^"]+)"')
|
||||
DEEP_SPLIT_NAMESPACES = {"programs", "services"}
|
||||
|
||||
|
||||
def option_label(anchor: str) -> str:
|
||||
if anchor.startswith("nix-darwin-opt-"):
|
||||
return anchor.removeprefix("nix-darwin-opt-")
|
||||
if anchor.startswith("nixos-opt-"):
|
||||
return anchor.removeprefix("nixos-opt-")
|
||||
return anchor.removeprefix("opt-")
|
||||
|
||||
|
||||
def option_target(anchor: str, current_file: Path) -> str:
|
||||
if anchor.startswith("nix-darwin-opt-"):
|
||||
option = anchor.removeprefix("nix-darwin-opt-")
|
||||
base = "options/nix-darwin"
|
||||
elif anchor.startswith("nixos-opt-"):
|
||||
option = anchor.removeprefix("nixos-opt-")
|
||||
base = "options/nixos"
|
||||
else:
|
||||
option = anchor.removeprefix("opt-")
|
||||
base = "options/home-manager"
|
||||
|
||||
page_parts = option_page_parts(option)
|
||||
prefix = "../" * len(current_file.parent.parts)
|
||||
return f"{prefix}{base}/{'/'.join(page_parts)}.md#{anchor}"
|
||||
|
||||
|
||||
def rewrite_option_links(text: str, current_file: Path) -> str:
|
||||
text = OPTION_LINK.sub(
|
||||
lambda match: (
|
||||
f"[{match.group('label') or option_label(match.group('anchor'))}]"
|
||||
f"({option_target(match.group('anchor'), current_file)})"
|
||||
),
|
||||
text,
|
||||
)
|
||||
return OPTION_HREF.sub(
|
||||
lambda match: f'href="{option_target(match.group("anchor"), current_file)}"',
|
||||
text,
|
||||
)
|
||||
|
||||
|
||||
def namespace_for(option_name: str) -> str:
|
||||
return option_name.split(".", 1)[0]
|
||||
|
||||
|
||||
def option_page_parts(option_name: str) -> list[str]:
|
||||
parts = option_name.split(".")
|
||||
namespace = parts[0]
|
||||
if namespace in DEEP_SPLIT_NAMESPACES and len(parts) > 1:
|
||||
return parts[:2]
|
||||
return [namespace]
|
||||
|
||||
|
||||
def option_group_for(option_name: str) -> str:
|
||||
return "/".join(option_page_parts(option_name))
|
||||
|
||||
|
||||
def render_namespace(
|
||||
options: dict[str, object],
|
||||
destination: Path,
|
||||
manpage_urls: Path,
|
||||
revision: str,
|
||||
anchor_prefix: str,
|
||||
current_file: Path,
|
||||
) -> None:
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
source = destination.with_suffix(".json")
|
||||
source.write_text(json.dumps(options, sort_keys=True), encoding="utf-8")
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
"nixos-render-docs",
|
||||
"options",
|
||||
"commonmark",
|
||||
"--manpage-urls",
|
||||
str(manpage_urls),
|
||||
"--revision",
|
||||
revision,
|
||||
"--anchor-style",
|
||||
"legacy",
|
||||
"--anchor-prefix",
|
||||
anchor_prefix,
|
||||
str(source),
|
||||
str(destination),
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
source.unlink()
|
||||
destination.write_text(
|
||||
rewrite_option_links(destination.read_text(encoding="utf-8"), current_file),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def write_doc(
|
||||
name: str,
|
||||
doc: dict[str, str],
|
||||
manpage_urls: Path,
|
||||
revision: str,
|
||||
output: Path,
|
||||
) -> None:
|
||||
options_json = Path(doc["json"]) / "share/doc/nixos/options.json"
|
||||
options = json.loads(options_json.read_text(encoding="utf-8"))
|
||||
|
||||
grouped: dict[str, dict[str, object]] = {}
|
||||
for option_name, option in options.items():
|
||||
group = option_group_for(option_name)
|
||||
grouped.setdefault(group, {})[option_name] = option
|
||||
|
||||
doc_dir = output / "options" / doc["path"]
|
||||
doc_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
groups = sorted(grouped)
|
||||
namespaces = sorted({group.split("/", 1)[0] for group in groups})
|
||||
nested = {
|
||||
namespace: sorted(
|
||||
group for group in groups if group.startswith(f"{namespace}/")
|
||||
)
|
||||
for namespace in namespaces
|
||||
}
|
||||
index = [
|
||||
f"# {doc['title']}\n",
|
||||
"\n",
|
||||
"Generated from Home Manager option definitions.\n",
|
||||
"\n",
|
||||
"## Namespaces\n",
|
||||
"\n",
|
||||
]
|
||||
for namespace in namespaces:
|
||||
if nested[namespace]:
|
||||
index.append(f"- [{namespace}]({namespace}/index.md)\n")
|
||||
else:
|
||||
index.append(f"- [{namespace}]({namespace}.md)\n")
|
||||
(doc_dir / "index.md").write_text("".join(index), encoding="utf-8")
|
||||
|
||||
summary_dir = output / "summary"
|
||||
summary_dir.mkdir(parents=True, exist_ok=True)
|
||||
summary = [f" - [{doc['title']}](options/{doc['path']}/index.md)\n"]
|
||||
|
||||
for namespace in namespaces:
|
||||
if nested[namespace]:
|
||||
namespace_index = doc_dir / namespace / "index.md"
|
||||
namespace_index.parent.mkdir(parents=True, exist_ok=True)
|
||||
namespace_index.write_text(
|
||||
"".join(
|
||||
[
|
||||
f"# {namespace}\n",
|
||||
"\n",
|
||||
"## Modules\n",
|
||||
"\n",
|
||||
*(
|
||||
f"- [{group.split('/', 1)[1]}]({group.split('/', 1)[1]}.md)\n"
|
||||
for group in nested[namespace]
|
||||
),
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
summary.append(
|
||||
f" - [{namespace}](options/{doc['path']}/{namespace}/index.md)\n"
|
||||
)
|
||||
for group in nested[namespace]:
|
||||
module_name = group.split("/", 1)[1]
|
||||
summary.append(
|
||||
f" - [{module_name}](options/{doc['path']}/{namespace}/{module_name}.md)\n"
|
||||
)
|
||||
else:
|
||||
summary.append(
|
||||
f" - [{namespace}](options/{doc['path']}/{namespace}.md)\n"
|
||||
)
|
||||
|
||||
for group in groups:
|
||||
page = doc_dir / f"{group}.md"
|
||||
current_file = Path("options") / doc["path"] / f"{group}.md"
|
||||
render_namespace(
|
||||
grouped[group],
|
||||
page,
|
||||
manpage_urls,
|
||||
revision,
|
||||
doc["prefix"],
|
||||
current_file,
|
||||
)
|
||||
|
||||
(summary_dir / f"{name}.md").write_text("".join(summary), encoding="utf-8")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) != 5:
|
||||
print(
|
||||
"usage: render-options.py OPTION_DOCS MANPAGE_URLS REVISION OUT",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
option_docs = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
||||
manpage_urls = Path(sys.argv[2])
|
||||
revision = sys.argv[3]
|
||||
output = Path(sys.argv[4])
|
||||
|
||||
for name, doc in option_docs.items():
|
||||
write_doc(name, doc, manpage_urls, revision, output)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) != 5:
|
||||
print(
|
||||
"usage: substitute-summary.py SUMMARY HM_SUMMARY NIXOS_SUMMARY DARWIN_SUMMARY",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
summary = Path(sys.argv[1])
|
||||
replacements = {
|
||||
"@HOME_MANAGER_OPTIONS@": Path(sys.argv[2]).read_text(encoding="utf-8"),
|
||||
"@NIXOS_OPTIONS@": Path(sys.argv[3]).read_text(encoding="utf-8"),
|
||||
"@NIX_DARWIN_OPTIONS@": Path(sys.argv[4]).read_text(encoding="utf-8"),
|
||||
}
|
||||
|
||||
text = summary.read_text(encoding="utf-8")
|
||||
for needle, replacement in replacements.items():
|
||||
text = text.replace(needle, replacement.rstrip())
|
||||
|
||||
summary.write_text(text, encoding="utf-8")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,10 +1,9 @@
|
||||
# Release Notes {#ch-release-notes}
|
||||
|
||||
This section lists the release notes for stable versions of Home Manager and the
|
||||
current unstable version.
|
||||
This section lists the release notes for stable versions of Home Manager
|
||||
and the current unstable version.
|
||||
|
||||
```{=include=} chapters
|
||||
rl-2611.md
|
||||
rl-2605.md
|
||||
rl-2511.md
|
||||
rl-2505.md
|
||||
|
||||
@@ -71,7 +71,7 @@ This release has the following notable changes:
|
||||
no longer packages compton, and instead packages the (mostly)
|
||||
compatible fork called picom.
|
||||
|
||||
- The list form of the `programs.ssh.matchBlocks` option has
|
||||
- The list form of the [programs.ssh.matchBlocks](#opt-programs.ssh.matchBlocks) option has
|
||||
been deprecated and configurations requiring match blocks in a
|
||||
defined order should switch to using DAG entries instead. For
|
||||
example, a configuration
|
||||
|
||||
@@ -36,7 +36,7 @@ This release has the following notable changes:
|
||||
optionally also activate it. The recommended installation method for
|
||||
a standalone Home Manager setup with Nix flakes uses this new
|
||||
command. The standard installation method remains the same but uses
|
||||
the new command internally. See [sec-flakes-standalone](../nix-flakes/standalone.md#sec-flakes-standalone) for
|
||||
the new command internally. See [sec-flakes-standalone](#sec-flakes-standalone) for
|
||||
more.
|
||||
|
||||
## State Version Changes {#sec-release-23.05-state-version-changes}
|
||||
|
||||
@@ -19,7 +19,7 @@ This release has the following notable changes:
|
||||
- The Home Manager test suite has been removed from the main Nix Flake
|
||||
since it caused unnecessary evaluations and downloads. Instead the
|
||||
tests are available through a Nix Flake file inside the `tests`
|
||||
directory. See [Tests](../contributing/tests.md#sec-tests) for example commands.
|
||||
directory. See [](#sec-tests) for example commands.
|
||||
|
||||
## State Version Changes {#sec-release-25.05-state-version-changes}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This release has the following notable changes:
|
||||
term removed all together. If you have developed tooling that
|
||||
directly call the generated activation script, then you are
|
||||
encouraged to adapt to the new behavior. See the
|
||||
[Activation](../internals/activation.md#sec-internals-activation) section in the manual for
|
||||
[Activation](#sec-internals-activation) section in the manual for
|
||||
details on how to call the activation script.
|
||||
|
||||
- The `home-manager switch` command now offers a `--rollback` option.
|
||||
@@ -25,7 +25,7 @@ This release has the following notable changes:
|
||||
previously possible to accomplish this by manually activating an old
|
||||
generation, it always created a new profile generation. The new
|
||||
behavior mirrors the behavior of `nixos-rebuild switch --rollback`.
|
||||
See the [Rollbacks](../usage/rollbacks.md#sec-usage-rollbacks) section for more.
|
||||
See the [Rollbacks](#sec-usage-rollbacks) section for more.
|
||||
|
||||
- The `home-manager switch` command now offers a
|
||||
`--specialisation NAME` option. When given, the switch activates the
|
||||
|
||||
+27
-161
@@ -1,146 +1,40 @@
|
||||
# Release 26.05 {#sec-release-26.05}
|
||||
|
||||
The 26.05 release branch became stable in May, 2026.
|
||||
This is the current unstable branch and the information in this
|
||||
section is therefore not final.
|
||||
|
||||
## Highlights {#sec-release-26.05-highlights}
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
- Home Manager now supports RFC 42-style SSH configuration through
|
||||
[](#opt-programs.ssh.settings). The legacy `programs.ssh.matchBlocks` format
|
||||
is deprecated and migrated automatically.
|
||||
|
||||
- The new `home-manager.startAsUserService` option runs user activation on
|
||||
demand at login instead of doing all setup during system boot, which helps on
|
||||
systems where home directories are mounted later (for example, pam_mount).
|
||||
|
||||
- New options were added for `services.podman.useDefaultMachine` and podman
|
||||
machine management on Darwin.
|
||||
|
||||
- The [](#opt-programs.rclone.enable) module now supports launchd-backed config,
|
||||
mount, and serve agents on Darwin. The new
|
||||
`programs.rclone.remotes.<name>.serve` option can manage `rclone serve`
|
||||
sidecar services on both Linux and Darwin. On non-systemd platforms,
|
||||
`programs.rclone.requiresUnit` is read-only and always `null` because there is
|
||||
no systemd ordering unit to depend on.
|
||||
|
||||
- The Syncthing credentials flow now uses `services.syncthing.guiCredentials`
|
||||
instead of the removed `services.syncthing.passwordFile` option.
|
||||
|
||||
- Firefox extensions are now managed per-profile through the
|
||||
`programs.firefox.profiles.<name>.extensions.packages` and
|
||||
`programs.firefox.profiles.<name>.extensions.settings` options. The top-level
|
||||
`programs.firefox.extensions = [ ... ]` list was removed; migrate it to
|
||||
`programs.firefox.profiles.<name>.extensions.packages`.
|
||||
|
||||
- Thunderbird now supports `accounts.email.accounts.<name>.ews`, the
|
||||
`outlook.office365.com-ews` account flavor, declarative language packs, and
|
||||
enterprise policies. Thunderbird accounts using the `outlook.office365.com`
|
||||
flavor now default IMAP and SMTP authentication to OAuth2 when the account
|
||||
does not set an authentication method explicitly.
|
||||
|
||||
- A new `systemd.user.packages` option provides a user-level equivalent of
|
||||
`systemd.packages` for installing unit files from packages.
|
||||
|
||||
- WezTerm now supports declarative configuration via
|
||||
[](#opt-programs.wezterm.settings). Settings are expressed as a Nix attribute
|
||||
set and serialized to Lua using `lib.generators.toLua`. Raw Lua expressions
|
||||
such as `wezterm.font` and `wezterm.action.*` can be embedded using
|
||||
`lib.generators.mkLuaInline`. The existing
|
||||
[](#opt-programs.wezterm.extraConfig) option remains fully supported and can
|
||||
be combined with [](#opt-programs.wezterm.settings).
|
||||
[](#opt-programs.wezterm.settings). Settings are expressed as a Nix
|
||||
attribute set and serialized to Lua using `lib.generators.toLua`.
|
||||
Raw Lua expressions such as `wezterm.font` and `wezterm.action.*`
|
||||
can be embedded using `lib.generators.mkLuaInline`. The existing
|
||||
[](#opt-programs.wezterm.extraConfig) option remains fully supported
|
||||
and can be combined with [](#opt-programs.wezterm.settings).
|
||||
|
||||
- The [](#opt-programs.anki.uiScale) option now expects a value in the range
|
||||
1.0–2.0, previously it erroneously expected values in the range `0.0–1.0`.
|
||||
Anki sync options moved from `programs.anki.sync.*` to
|
||||
`programs.anki.profiles."User 1".sync.*`, and
|
||||
`programs.anki.sync.passwordFile` is migrated to
|
||||
`programs.anki.profiles."User 1".sync.keyFile`.
|
||||
|
||||
- New [](#opt-home.services) namespace for nixpkgs
|
||||
[modular services](https://nixos.org/manual/nixos/unstable/#modular-services).
|
||||
Service modules shipped with packages (e.g.
|
||||
`pkgs.<name>.passthru.services.default`) drop in unchanged and are lifted to
|
||||
user systemd units. See [Modular Services](../usage/modular-services.md#sec-usage-modular-services) for
|
||||
details.
|
||||
|
||||
- Dedicated modules were added for several VSCode forks (`programs.cursor`,
|
||||
`programs.vscodium`, `programs.windsurf`, `programs.kiro`, and
|
||||
`programs.antigravity`), built from a shared `mkVscodeModule` factory. Each
|
||||
fork can now be configured independently and simultaneously. Users who
|
||||
previously selected a fork by setting `programs.vscode.package` should migrate
|
||||
to the matching module; the `programs.vscode.pname` option was removed.
|
||||
|
||||
- The AI coding-assistant modules ([](#opt-programs.claude-code.enable),
|
||||
[](#opt-programs.codex.enable), and [](#opt-programs.opencode.enable)) now
|
||||
share a unified `context` option for providing global instructions. The
|
||||
previous per-module options (`claude-code.memory`,
|
||||
`codex.custom-instructions`, and `opencode.rules`) are deprecated and migrated
|
||||
automatically. MCP server configuration via `programs.mcp.servers` was also
|
||||
extended to more assistant and editor modules through an
|
||||
`enableMcpIntegration` option.
|
||||
|
||||
- The `programs.man` module was split so the man viewer can be selected through
|
||||
the [](#opt-programs.man.man-db.enable) and
|
||||
[](#opt-programs.man.mandoc.enable) submodules, which are mutually exclusive.
|
||||
|
||||
- The `programs.neovim.extraLuaConfig` option was renamed to
|
||||
[](#opt-programs.neovim.initLua). Home Manager now writes generated Lua
|
||||
initialization to {file}`$XDG_CONFIG_HOME/nvim/init.lua` by default. If you
|
||||
manage that file outside Home Manager, set
|
||||
[](#opt-programs.neovim.sideloadInitLua) to `true` to load the generated Lua
|
||||
through the Neovim wrapper instead.
|
||||
|
||||
- A new `sshAuthSock` module manages the `SSH_AUTH_SOCK`
|
||||
environment variable. It is implicitly configured by the
|
||||
SSH-agent-providing modules (e.g. `services.ssh-agent`, `services.gpg-agent`).
|
||||
The old `services.ssh-agent.enable{Bash,Zsh,Fish,Nushell}Integration` options
|
||||
were removed; shell initialization is now provided through `sshAuthSock`.
|
||||
|
||||
- A new [](#opt-services.pipewire.enable) module provides client-side
|
||||
configuration for PipeWire, WirePlumber, and the PulseAudio/JACK compatibility
|
||||
layers. It does not install or manage the PipeWire daemon itself.
|
||||
|
||||
- The `services.swww` module was renamed to [](#opt-services.awww.enable)
|
||||
following the upstream project rename. The `enable`, `package`, and
|
||||
`extraArgs` options are migrated automatically from `services.swww.*` to
|
||||
`services.awww.*`.
|
||||
|
||||
- Several modules dropped their freeform `extraConfig` escape hatches in favor
|
||||
of RFC 42-style `settings`: `programs.aerospace.extraConfig` (and
|
||||
`userSettings`) and `programs.aria2.extraConfig` were removed.
|
||||
`programs.mise.settings` was renamed to `programs.mise.globalConfig.settings`.
|
||||
The `programs.eww.configDir` and
|
||||
`programs.eww.enable{Bash,Zsh,Fish}Integration` options were removed; use
|
||||
[](#opt-programs.eww.yuckConfig) and [](#opt-programs.eww.scssConfig) for
|
||||
declarative Eww config files. The `programs.niriswitcher` options were also
|
||||
removed.
|
||||
|
||||
- Darwin integration received several behavior changes. Home Manager launchd
|
||||
agents now wait for `/nix/store` before starting and use
|
||||
`launchctl bootout --wait` when replacing agents. nix-darwin activations now
|
||||
propagate dry-run mode into Home Manager user activations. On Darwin, Home
|
||||
Manager also exports `TERMINFO_DIRS` so terminfo entries from Home
|
||||
Manager-installed packages are visible to shells.
|
||||
|
||||
- The [](#opt-nix.assumeXdg) option was added for installations where Nix is
|
||||
configured to use XDG base directories outside Home Manager. Home Manager also
|
||||
detects `osConfig.nix.settings.use-xdg-base-directories` when deciding where
|
||||
to place declarative channel entries.
|
||||
- The [](#opt-programs.anki.uiScale) option now expects a value in the
|
||||
range 1.0–2.0, previously it erroneously expected values in the
|
||||
range `0.0–1.0`.
|
||||
|
||||
## State Version Changes {#sec-release-26.05-state-version-changes}
|
||||
|
||||
The state version in this release includes the changes below. These changes are
|
||||
only active if the `home.stateVersion` option is set to \"26.05\" or later.
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
\"26.05\" or later.
|
||||
|
||||
- The [](#opt-gtk.gtk4.theme) option does not mirror [](#opt-gtk.theme) by
|
||||
default anymore.
|
||||
- The [](#opt-gtk.gtk4.theme) option does not mirror
|
||||
[](#opt-gtk.theme) by default anymore.
|
||||
|
||||
- The [](#opt-programs.zsh.dotDir) option now defaults to the XDG configuration
|
||||
directory (usually `~/.config/zsh`) when [](#opt-xdg.enable) is true.
|
||||
- The [](#opt-programs.zsh.dotDir) option now defaults to the XDG
|
||||
configuration directory (usually `~/.config/zsh`) when
|
||||
[](#opt-xdg.enable) is true.
|
||||
|
||||
- The [](#opt-programs.yazi.shellWrapperName) option now defaults to `y` instead
|
||||
of `yy`.
|
||||
- The [](#opt-programs.yazi.shellWrapperName) option now defaults to
|
||||
`y` instead of `yy`. For users with older `home.stateVersion` values,
|
||||
the legacy default `yy` is retained.
|
||||
|
||||
- The [](#opt-xdg.userDirs.setSessionVariables) option now defaults to `false`
|
||||
instead of `true`.
|
||||
@@ -151,39 +45,11 @@ only active if the `home.stateVersion` option is set to \"26.05\" or later.
|
||||
`DESKTOP`. Home Manager 26.05 introduced a warning when the `XDG_<name>_DIR`
|
||||
form is used.
|
||||
|
||||
- The [](#opt-programs.man.package) option now defaults to `null` on Darwin
|
||||
because the GNU `man` from nixpkgs ships `apropos`/`man -k` and
|
||||
`whatis`/`man -f` binaries that don't work on Darwin. Nix-installed manual
|
||||
pages still work with macOS's built-in `man` via
|
||||
- The [](#opt-programs.man.package) option now defaults to `null` on
|
||||
Darwin because the GNU `man` from nixpkgs ships `apropos`/`man -k`
|
||||
and `whatis`/`man -f` binaries that don't work on Darwin. Nix-installed
|
||||
manual pages still work with macOS's built-in `man` via
|
||||
[](#opt-home.extraOutputsToInstall).
|
||||
|
||||
- The options [](#opt-programs.neovim.withPython3) and
|
||||
[](#opt-programs.neovim.withRuby) now default to `false` following nixpkgs.
|
||||
|
||||
- Neovim plugin `config` fragments are assumed to be Lua by default through
|
||||
`programs.neovim.plugins.<name>.type = "lua"`, instead of the previous `viml`
|
||||
default.
|
||||
|
||||
- On Linux, `programs.firefox.configPath` now defaults to
|
||||
`"${config.xdg.configHome}/mozilla/firefox"`, instead of the legacy
|
||||
`".mozilla/firefox"`.
|
||||
|
||||
- The [](#opt-wayland.windowManager.hyprland.configType) option now defaults to
|
||||
`"lua"`, instead of the legacy `"hyprlang"`. Set
|
||||
`wayland.windowManager.hyprland.configType = "hyprlang"` to keep generating
|
||||
{file}`$XDG_CONFIG_HOME/hypr/hyprland.conf`.
|
||||
|
||||
- The [](#opt-programs.docker-cli.configDir) option now defaults to
|
||||
`"${config.xdg.configHome}/docker"` when [](#opt-xdg.enable) is true, instead
|
||||
of `~/.docker`. Similarly, [](#opt-services.colima.profiles) now sets
|
||||
`$DOCKER_HOST` for the default context.
|
||||
|
||||
- The [](#opt-services.home-manager.autoUpgrade.preSwitchCommands) option now
|
||||
defaults to an empty list. Previously, when
|
||||
[](#opt-services.home-manager.autoUpgrade.useFlake) was `true`, it defaulted
|
||||
to `[ "nix flake update" ]`. Set `preSwitchCommands = [ "nix flake update" ]`
|
||||
to keep updating flake inputs before each automatic switch.
|
||||
|
||||
- The [](#opt-programs.mergiraf.enableGitIntegration) and
|
||||
[](#opt-programs.mergiraf.enableJujutsuIntegration) options now default to
|
||||
`false`, so the integrations must be enabled explicitly.
|
||||
[](#opt-programs.neovim.withRuby) now default to `false` following nixpkgs
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Release 26.11 {#sec-release-26.11}
|
||||
|
||||
This is the current unstable branch and the information in this
|
||||
section is therefore not final.
|
||||
|
||||
## Highlights {#sec-release-26.11-highlights}
|
||||
|
||||
This release has the following notable changes:
|
||||
|
||||
- The [](#opt-programs.uv.enable) module can now install uv-managed Python
|
||||
versions and tools through the new `programs.uv.python.versions`,
|
||||
`programs.uv.python.default`, and `programs.uv.tool.packages` options. Unpinned
|
||||
entries track the latest release on each activation while pinned ones stay put,
|
||||
and `programs.uv.python.prune` / `programs.uv.tool.prune` make the managed set
|
||||
fully declarative by removing versions and tools that are no longer listed.
|
||||
|
||||
- On Darwin, Home Manager launchd agents now support
|
||||
[](#opt-launchd.agents._name_.domain) to choose either the user's GUI or
|
||||
background launchd domain. Agents use the GUI domain by default. Set the
|
||||
domain to `user` for agents that should run without an active graphical login
|
||||
session.
|
||||
|
||||
## State Version Changes {#sec-release-26.11-state-version-changes}
|
||||
|
||||
The state version in this release includes the changes below. These
|
||||
changes are only active if the `home.stateVersion` option is set to
|
||||
"26.11" or later.
|
||||
|
||||
- The KDL options under `programs.zellij` will now correctly escape backslashes
|
||||
in string values. For example, the Nix string `"\\"` will now correctly
|
||||
generate the KDL string `"\\"`. Previously, this would have generated `"\"`,
|
||||
which is invalid KDL. The following options are affected:
|
||||
- `programs.zellij.settings`
|
||||
- `programs.zellij.themes`
|
||||
- `programs.zellij.layouts`
|
||||
Generated
+4
-4
@@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1783604885,
|
||||
"narHash": "sha256-tzMgSkV7kljEkqIjlgV6F+n+xD+/a35Db8bs7a4BFAo=",
|
||||
"lastModified": 1775710090,
|
||||
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "767b0d3ec98a143ad9ed7dfc0d5553510ac27133",
|
||||
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
description = "Home Manager for Nix";
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs =
|
||||
{
|
||||
@@ -45,34 +45,15 @@
|
||||
}
|
||||
// (
|
||||
let
|
||||
supportedSystems = [
|
||||
"aarch64-darwin"
|
||||
"aarch64-linux"
|
||||
"i686-linux"
|
||||
"x86_64-darwin"
|
||||
"x86_64-linux"
|
||||
];
|
||||
|
||||
forSystems = systems: f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||
|
||||
forAllPkgs = forSystems nixpkgs.lib.systems.flakeExposed;
|
||||
|
||||
forSupportedPkgs = forSystems supportedSystems;
|
||||
forAllPkgs =
|
||||
f:
|
||||
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed (system: f nixpkgs.legacyPackages.${system});
|
||||
|
||||
forCI = nixpkgs.lib.genAttrs [
|
||||
"aarch64-darwin"
|
||||
"x86_64-linux"
|
||||
];
|
||||
|
||||
releaseInfo = nixpkgs.lib.importJSON ./release.json;
|
||||
|
||||
docsFor =
|
||||
pkgs:
|
||||
import ./docs {
|
||||
inherit pkgs;
|
||||
inherit (releaseInfo) release isReleaseBranch;
|
||||
};
|
||||
|
||||
testChunks =
|
||||
system:
|
||||
let
|
||||
@@ -82,7 +63,8 @@
|
||||
# Create chunked test packages for better CI parallelization
|
||||
tests = import ./tests {
|
||||
inherit pkgs;
|
||||
enableBig = true;
|
||||
# Disable big tests since this is only used for CI
|
||||
enableBig = false;
|
||||
};
|
||||
allTests = lib.attrNames tests.build;
|
||||
# Remove 'all' from the test list as it's a meta-package
|
||||
@@ -175,13 +157,12 @@
|
||||
lib.mapAttrs' renameTestPkg tests;
|
||||
in
|
||||
{
|
||||
formatter = forSupportedPkgs (pkgs: pkgs.callPackage ./home-manager/formatter.nix { });
|
||||
formatter = forAllPkgs (pkgs: pkgs.callPackage ./home-manager/formatter.nix { });
|
||||
|
||||
# TODO: increase buildbot testing scope
|
||||
buildbot = forCI (
|
||||
system:
|
||||
let
|
||||
docs = docsFor nixpkgs.legacyPackages.${system};
|
||||
allIntegrationTests = integrationTests system;
|
||||
workingIntegrationTests = nixpkgs.lib.filterAttrs (
|
||||
name: _:
|
||||
@@ -191,43 +172,28 @@
|
||||
]
|
||||
) allIntegrationTests;
|
||||
in
|
||||
(testChunks system)
|
||||
// workingIntegrationTests
|
||||
// {
|
||||
docs-html = docs.manual.html;
|
||||
docs-json = docs.options.json;
|
||||
docs-jsonModuleMaintainers = docs.jsonModuleMaintainers;
|
||||
docs-manpages = docs.manPages;
|
||||
}
|
||||
(testChunks system) // workingIntegrationTests
|
||||
);
|
||||
|
||||
packages = forAllPkgs (
|
||||
pkgs:
|
||||
let
|
||||
docs = docsFor pkgs;
|
||||
releaseInfo = nixpkgs.lib.importJSON ./release.json;
|
||||
docs = import ./docs {
|
||||
inherit pkgs;
|
||||
inherit (releaseInfo) release isReleaseBranch;
|
||||
};
|
||||
hmPkg = pkgs.callPackage ./home-manager { path = "${self}"; };
|
||||
in
|
||||
{
|
||||
default = hmPkg;
|
||||
home-manager = hmPkg;
|
||||
}
|
||||
// nixpkgs.lib.optionalAttrs (nixpkgs.lib.elem pkgs.stdenv.hostPlatform.system supportedSystems) {
|
||||
|
||||
ci-parse = pkgs.callPackage ./ci/parse.nix { nix = pkgs.nixVersions.latest; };
|
||||
ci-parse-lix = pkgs.callPackage ./ci/parse.nix {
|
||||
nix = pkgs.lixPackageSets.latest.lix;
|
||||
};
|
||||
|
||||
create-news-entry = pkgs.writeShellScriptBin "create-news-entry" ''
|
||||
./modules/misc/news/create-news-entry.sh
|
||||
'';
|
||||
|
||||
tests = pkgs.callPackage ./tests/package.nix {
|
||||
flake = self;
|
||||
inputOverrides = {
|
||||
inherit nixpkgs;
|
||||
};
|
||||
};
|
||||
tests = pkgs.callPackage ./tests/package.nix { flake = self; };
|
||||
|
||||
docs-html = docs.manual.html;
|
||||
docs-htmlOpenTool = docs.manual.htmlOpenTool;
|
||||
@@ -237,11 +203,11 @@
|
||||
}
|
||||
);
|
||||
|
||||
devShells = forSupportedPkgs (pkgs: {
|
||||
devShells = forAllPkgs (pkgs: {
|
||||
default = pkgs.callPackage ./home-manager/devShell.nix { };
|
||||
});
|
||||
|
||||
legacyPackages = forSupportedPkgs (
|
||||
legacyPackages = forAllPkgs (
|
||||
pkgs:
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) system;
|
||||
|
||||
@@ -18,7 +18,6 @@ pkgs.treefmt.withConfig {
|
||||
deadnix
|
||||
keep-sorted
|
||||
nixf-diagnose
|
||||
ruff
|
||||
];
|
||||
settings = pkgs.lib.importTOML ../treefmt.toml;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,6 @@ function doInspectOption() {
|
||||
for path in "${paths[@]}"; do
|
||||
nix-instantiate --eval --json \
|
||||
--arg nixos "$modulesExpr" \
|
||||
"${extraArgs[@]}" \
|
||||
--argstr path "$path" \
|
||||
--arg recursive "$recursive" \
|
||||
"$NIXOS_OPTION_NIX" \
|
||||
@@ -314,7 +313,7 @@ function doInit() {
|
||||
fi
|
||||
|
||||
local homeManagerUrl="github:nix-community/home-manager"
|
||||
local nixpkgsUrl="github:nixos/nixpkgs/nixpkgs-unstable"
|
||||
local nixpkgsUrl="github:nixos/nixpkgs/nixos-unstable"
|
||||
|
||||
while (( $# > 0 )); do
|
||||
local opt="$1"
|
||||
@@ -404,7 +403,7 @@ $xdgVars
|
||||
# You should not change this value, even if you update Home Manager. If you do
|
||||
# want to update the value, then make sure to first check the Home Manager
|
||||
# release notes.
|
||||
home.stateVersion = "26.05"; # Please read the comment before changing.
|
||||
home.stateVersion = "25.11"; # Please read the comment before changing.
|
||||
|
||||
# The home.packages option allows you to install Nix packages into your
|
||||
# environment.
|
||||
@@ -1042,7 +1041,7 @@ function doUninstall() {
|
||||
uninstall = true;
|
||||
home.username = "$(escapeForNix "$USER")";
|
||||
home.homeDirectory = "$(escapeForNix "$HOME")";
|
||||
home.stateVersion = "26.05";
|
||||
home.stateVersion = "25.11";
|
||||
}
|
||||
EOF
|
||||
# shellcheck disable=2064
|
||||
@@ -1280,7 +1279,7 @@ while [[ $# -gt 0 ]]; do
|
||||
export VERBOSE=1
|
||||
;;
|
||||
--version)
|
||||
echo 26.11-pre
|
||||
echo 26.05-pre
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-04-30 04:09+0000\n"
|
||||
"Last-Translator: Troy <radiohotline@disroot.org>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:16+0000\n"
|
||||
"Last-Translator: Anonymous <noreply@weblate.org>\n"
|
||||
"Language-Team: Arabic <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"ar/>\n"
|
||||
"Language: ar\n"
|
||||
@@ -18,17 +18,17 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||
"X-Generator: Weblate 5.17.1-dev\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr "%s: معطيات مفقودة ل %s"
|
||||
msgstr "%s: معطيات مفقوة ل %s"
|
||||
|
||||
#. translators: For example: "home-manager: --rollback can only be used after switch"
|
||||
#: home-manager/home-manager:22
|
||||
msgid "%s: %s can only be used after %s"
|
||||
msgstr "%s%: s يمكن استخدامه فقط بعد %s"
|
||||
msgstr "%s: %s يمكن استخدامه فقط بعد %s"
|
||||
|
||||
#: home-manager/home-manager:71
|
||||
msgid "No configuration file found at %s"
|
||||
@@ -212,7 +212,7 @@ msgstr "لا يمكن تشغيل البناء في مجلد قراءة فقط"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "لا يتضمن ملف الاعدادات التخصص \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR Home Manager contributors
|
||||
# This file is distributed under the same license as the Home Manager package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-05-31 21:01+0000\n"
|
||||
"Last-Translator: Tofaa <tofig.adigozalov.180904@gmail.com>\n"
|
||||
"Language-Team: Azerbaijani <https://hosted.weblate.org/projects/home-manager/"
|
||||
"cli/az/>\n"
|
||||
"Language: az\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2026.6.dev0\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr "%s: {s} üçün tələb olunan arqument verilməyib"
|
||||
|
||||
#. translators: For example: "home-manager: --rollback can only be used after switch"
|
||||
#: home-manager/home-manager:22
|
||||
msgid "%s: %s can only be used after %s"
|
||||
msgstr "%s: %s ancaq %s'dən sonra işlənə bilər"
|
||||
|
||||
#: home-manager/home-manager:71
|
||||
msgid "No configuration file found at %s"
|
||||
msgstr "%s-də konfiqurasiya faylı tapılmadı"
|
||||
|
||||
#. translators: The first '%s' specifier will be replaced by either
|
||||
#. 'home.nix' or 'flake.nix'.
|
||||
#: home-manager/home-manager:88 home-manager/home-manager:92
|
||||
#: home-manager/home-manager:191
|
||||
msgid ""
|
||||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||
"please move it to %s"
|
||||
msgstr ""
|
||||
"Home Manager %s faylının %s daxilində saxlanılması artıq dəstəklənmir.\n"
|
||||
"Zəhmət olmasa onu %s ünvanına köçürün"
|
||||
|
||||
#: home-manager/home-manager:99
|
||||
msgid "No configuration file found. Please create one at %s"
|
||||
msgstr "Konfiqurasiya faylı tapılmadı. Zəhmət olmasa fayli %s'də yaradin"
|
||||
|
||||
#: home-manager/home-manager:114
|
||||
msgid "Home Manager not found at %s."
|
||||
msgstr "Home Manager %s'də tapılmadı."
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:122
|
||||
msgid ""
|
||||
"The fallback Home Manager path %s has been deprecated and a file/directory "
|
||||
"was found there."
|
||||
msgstr ""
|
||||
"Ehtiyat Home Manager yolu %s artıq köhnəlmişdir və həmin ünvanda fayl və ya "
|
||||
"qovluq tapıldı."
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:125
|
||||
msgid ""
|
||||
"To remove this warning, do one of the following.\n"
|
||||
"\n"
|
||||
"1. Explicitly tell Home Manager to use the path, for example by adding\n"
|
||||
"\n"
|
||||
" { programs.home-manager.path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" to your configuration.\n"
|
||||
"\n"
|
||||
" If you import Home Manager directly, you can use the `path` parameter\n"
|
||||
"\n"
|
||||
" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" when calling the Home Manager package.\n"
|
||||
"\n"
|
||||
"2. Remove the deprecated path.\n"
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
msgstr ""
|
||||
"Bu xəbərdarlığı aradan qaldırmaq üçün aşağıdakılardan birini edin.\n"
|
||||
"\n"
|
||||
"1. Home Manager-ə bu yolu istifadə etməsini açıq şəkildə bildirin. Məsələn, "
|
||||
"konfiqurasiyanıza aşağıdakı sətri əlavə edin:\n"
|
||||
"\n"
|
||||
"{ programs.home-manager.path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" Əgər Home Manager-i birbaşa import edirsinizsə, Home Manager paketini\n"
|
||||
" çağırarkən `path` parametrindən istifadə edə bilərsiniz:\n"
|
||||
"\n"
|
||||
" pkgs.callPackage /path/to/home-manager-package { path = \"%s\"; }\n"
|
||||
"\n"
|
||||
"2. Köhnəlmiş yolu silin.\n"
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
|
||||
#: home-manager/home-manager:153
|
||||
msgid "Sanity checking Nix"
|
||||
msgstr "Nix yoxlanılır"
|
||||
|
||||
#: home-manager/home-manager:173
|
||||
msgid "Could not find suitable profile directory, tried %s and %s"
|
||||
msgstr "Uyğun profil qovluğu tapılmadı; %s və %s yolları yoxlanıldı"
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:230
|
||||
msgid "Can't inspect options of a flake configuration"
|
||||
msgstr "Flake konfiqurasiyasının seçimlərinə baxış keçirmək mümkün deyil"
|
||||
|
||||
#: home-manager/home-manager:340 home-manager/home-manager:363
|
||||
#: home-manager/home-manager:769 home-manager/home-manager:1289
|
||||
msgid "%s: unknown option '%s'"
|
||||
msgstr "%s: bilinməyən seçim '%s'"
|
||||
|
||||
#: home-manager/home-manager:345 home-manager/home-manager:1290
|
||||
msgid "Run '%s --help' for usage help"
|
||||
msgstr "İstifadə köməyi üçün '%s --help' işlədin"
|
||||
|
||||
#: home-manager/home-manager:371 home-manager/home-manager:476
|
||||
msgid "The file %s already exists, leaving it unchanged..."
|
||||
msgstr "%s faylı artıq mövcuddur, dəyişdirilmədən saxlanılır..."
|
||||
|
||||
#: home-manager/home-manager:373 home-manager/home-manager:478
|
||||
msgid "Creating %s..."
|
||||
msgstr "%s yaradılır..."
|
||||
|
||||
#: home-manager/home-manager:522
|
||||
msgid "Creating initial Home Manager generation..."
|
||||
msgstr "Ilkin Home Manager nəsili yaradılır..."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a file path.
|
||||
#: home-manager/home-manager:527
|
||||
msgid ""
|
||||
"All done! The home-manager tool should now be installed and you can edit\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"to configure Home Manager. Run 'man home-configuration.nix' to\n"
|
||||
"see all available options."
|
||||
msgstr ""
|
||||
"Hər şey tamamlandı! İndi home-manager aləti quraşdırılıb və Home Manager-i "
|
||||
"konfiqurasiya etmək üçün %s faylını redaktə edə bilərsiniz.\n"
|
||||
"\n"
|
||||
"Mövcud bütün seçimləri görmək üçün 'man home-configuration.nix' əmrini icra "
|
||||
"edin."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a URL.
|
||||
#: home-manager/home-manager:532
|
||||
msgid ""
|
||||
"Uh oh, the installation failed! Please create an issue at\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"if the error seems to be the fault of Home Manager."
|
||||
msgstr ""
|
||||
"Quraşdırma uğursuz oldu! Əgər xəta Home Manager-in səbəbindən baş veribsə, "
|
||||
"%s ünvanında issue yaradın."
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:543
|
||||
msgid "Can't instantiate a flake configuration"
|
||||
msgstr "Flake konfiqurasiyasını yaratmaq mümkün deyil"
|
||||
|
||||
#: home-manager/home-manager:619
|
||||
msgid ""
|
||||
"There is %d unread and relevant news item.\n"
|
||||
"Read it by running the command \"%s news\"."
|
||||
msgid_plural ""
|
||||
"There are %d unread and relevant news items.\n"
|
||||
"Read them by running the command \"%s news\"."
|
||||
msgstr[0] ""
|
||||
"Oxunmamış və uyğun %d xəbər var.\n"
|
||||
"\n"
|
||||
"Onu oxumaq üçün \"%s news\" əmrini icra edin."
|
||||
msgstr[1] ""
|
||||
"Oxunmamış və uyğun %d xəbər var.\n"
|
||||
"\n"
|
||||
"Onları oxumaq üçün \"%s news\" əmrini icra edin."
|
||||
|
||||
#: home-manager/home-manager:633
|
||||
msgid "Unknown \"news.display\" setting \"%s\"."
|
||||
msgstr "Naməlum \"news.display\" ayarı: \"%s\"."
|
||||
|
||||
#: home-manager/home-manager:641
|
||||
#, sh-format
|
||||
msgid "Please set the $EDITOR or $VISUAL environment variable"
|
||||
msgstr "Zəhmət olmasa $EDITOR və ya $VISUAL mühit dəyişənini təyin edin"
|
||||
|
||||
#: home-manager/home-manager:659
|
||||
msgid "Cannot run build in read-only directory"
|
||||
msgstr "Yalnız oxuma rejimində qovluqda build icra etmək mümkün deyil"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "Konfiqurasiya \"%s\" specialisation-ını ehtiva etmir"
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
msgstr "%s ID-li nəsil mövcud deyil"
|
||||
|
||||
#: home-manager/home-manager:878
|
||||
msgid "Cannot remove the current generation %s"
|
||||
msgstr "Cari nəsli (%s) silmək mümkün deyil"
|
||||
|
||||
#: home-manager/home-manager:880
|
||||
msgid "Removing generation %s"
|
||||
msgstr "%s nəsli silinir"
|
||||
|
||||
#: home-manager/home-manager:901
|
||||
msgid "No generations to expire"
|
||||
msgstr "Müddəti bitəcək heç bir nəsil yoxdur"
|
||||
|
||||
#: home-manager/home-manager:912
|
||||
msgid "No home-manager packages seem to be installed."
|
||||
msgstr "Heç bir home-manager paketi quraşdırılmış görünmür."
|
||||
|
||||
#: home-manager/home-manager:997
|
||||
msgid "Unknown argument %s"
|
||||
msgstr "Naməlum arqument: %s"
|
||||
|
||||
#: home-manager/home-manager:1022
|
||||
msgid "This will remove Home Manager from your system."
|
||||
msgstr "Bu, Home Manager-i sisteminizdən siləcək."
|
||||
|
||||
#: home-manager/home-manager:1025
|
||||
msgid "This is a dry run, nothing will actually be uninstalled."
|
||||
msgstr "Bu sınaq icrasıdır, heç nə faktiki olaraq silinməyəcək."
|
||||
|
||||
#: home-manager/home-manager:1029
|
||||
msgid "Really uninstall Home Manager?"
|
||||
msgstr "Home Manager-i həqiqətən silmək istəyirsiniz?"
|
||||
|
||||
#: home-manager/home-manager:1035
|
||||
msgid "Switching to empty Home Manager configuration..."
|
||||
msgstr "Boş Home Manager konfiqurasiyasına keçid edilir..."
|
||||
|
||||
#: home-manager/home-manager:1050
|
||||
msgid "Yay!"
|
||||
msgstr "Əla!"
|
||||
|
||||
#: home-manager/home-manager:1055
|
||||
msgid "Home Manager is uninstalled but your home.nix is left untouched."
|
||||
msgstr "Home Manager silindi, lakin home.nix faylınız dəyişdirilmədi."
|
||||
|
||||
#: home-manager/home-manager:1334
|
||||
msgid "expire-generations expects one argument, got %d."
|
||||
msgstr "expire-generations bir arqument gözləyir, lakin %d arqument verilib."
|
||||
|
||||
#: home-manager/home-manager:1359
|
||||
msgid "Unknown command: %s"
|
||||
msgstr "Naməlum əmr: %s"
|
||||
|
||||
#: home-manager/install.nix:21
|
||||
msgid "This derivation is not buildable, please run it using nix-shell."
|
||||
msgstr ""
|
||||
"Bu derivasiya build edilə bilən deyil, zəhmət olmasa onu nix-shell ilə icra "
|
||||
"edin."
|
||||
+15
-15
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-05-05 10:30+0000\n"
|
||||
"Last-Translator: Ludovic Pagès <nanucq@proton.me>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:16+0000\n"
|
||||
"Last-Translator: TheBlackBeans <adrien.mathieu.net@gmail.com>\n"
|
||||
"Language-Team: French <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"fr/>\n"
|
||||
"Language: fr\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.17.1\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -52,7 +52,7 @@ msgstr ""
|
||||
|
||||
#: home-manager/home-manager:114
|
||||
msgid "Home Manager not found at %s."
|
||||
msgstr "Home Manager absent dans %s."
|
||||
msgstr "Home Manager indisponible à %s."
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:122
|
||||
@@ -84,15 +84,15 @@ msgid ""
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
msgstr ""
|
||||
"Pour supprimer cet avertissement, exécutez l'une des actions suivantes :\n"
|
||||
" \n"
|
||||
"Pour supprimer cet avertissement, exécutez l'une des actions suivantes :\n"
|
||||
"\n"
|
||||
"1. Préciser explicitement à Home Manager d'utiliser le chemin d'accès, par "
|
||||
"exemple en ajoutant ceci à votre configuration :\n"
|
||||
"exemple en ajoutant ceci à votre configuration :\n"
|
||||
"\n"
|
||||
"\t{ programs.home-manager.path = \"%s\" ; }\n"
|
||||
"\n"
|
||||
"Si vous importez Home Manager directement, vous pouvez utiliser le paramètre "
|
||||
"`path` au lancement du package :\n"
|
||||
"`path` au lancement du package :\n"
|
||||
"\n"
|
||||
"\tpkgs.callPackage /path/to/home-manager-package { path = \"%s\" ; }\n"
|
||||
"\n"
|
||||
@@ -120,7 +120,7 @@ msgstr "%s : l'option '%s' est inconnue"
|
||||
|
||||
#: home-manager/home-manager:345 home-manager/home-manager:1290
|
||||
msgid "Run '%s --help' for usage help"
|
||||
msgstr "Exécuter '%s --help' pour de l'aide sur l'utilisation"
|
||||
msgstr "Exécuter « %s --help » pour de l'aide sur l'utilisation"
|
||||
|
||||
#: home-manager/home-manager:371 home-manager/home-manager:476
|
||||
msgid "The file %s already exists, leaving it unchanged..."
|
||||
@@ -144,13 +144,13 @@ msgid ""
|
||||
"to configure Home Manager. Run 'man home-configuration.nix' to\n"
|
||||
"see all available options."
|
||||
msgstr ""
|
||||
"Terminé ! Home Manager devrait désormais être installé et vous pouvez "
|
||||
"Tout est fait! Home Manager devrait désormais être installé et vous pouvez "
|
||||
"éditer\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"pour configurer Home Manager. Pour avoir une liste des options disponibles,\n"
|
||||
"lancez 'man home-configuration.nix'."
|
||||
"essayez 'man home-configuration.nix'."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a URL.
|
||||
#: home-manager/home-manager:532
|
||||
@@ -161,8 +161,8 @@ msgid ""
|
||||
"\n"
|
||||
"if the error seems to be the fault of Home Manager."
|
||||
msgstr ""
|
||||
"Uh oh, l'installation a échoué! Veuillez signaler cette erreur à l'adresse "
|
||||
"suivante\n"
|
||||
"Uh oh, l'installation n'a pas réussi! Veuillez signaler cette erreur à "
|
||||
"l'adresse suivante\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
@@ -198,11 +198,11 @@ msgstr "Veuillez remplir la variable d'environnement $EDITOR ou VISUAL"
|
||||
|
||||
#: home-manager/home-manager:659
|
||||
msgid "Cannot run build in read-only directory"
|
||||
msgstr "Impossible de lancer une compilation dans un dossier en lecture seule"
|
||||
msgstr "Impossible de lancer une compilation dans un dossier en écriture seule"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "La configuration ne contient pas la spécialisation \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-07-19 08:01+0000\n"
|
||||
"Last-Translator: Artur Sannikov <weblate.rbpxz@8shield.net>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:16+0000\n"
|
||||
"Last-Translator: Lorenzo Bevilacqua <lorenzobevilacqua02@gmail.com>\n"
|
||||
"Language-Team: Italian <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"it/>\n"
|
||||
"Language: it\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2026.8.dev0\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -104,7 +104,7 @@ msgstr ""
|
||||
|
||||
#: home-manager/home-manager:153
|
||||
msgid "Sanity checking Nix"
|
||||
msgstr "Verifica di correttezza di Nix"
|
||||
msgstr "Controllando Nix"
|
||||
|
||||
#: home-manager/home-manager:173
|
||||
msgid "Could not find suitable profile directory, tried %s and %s"
|
||||
@@ -204,7 +204,7 @@ msgstr "Impossibile eseguire la build in una cartella in sola lettura"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "La configurazione non contiene la specializzazione \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-05-21 21:11+0000\n"
|
||||
"Last-Translator: jay <jj8z@proton.me>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:15+0000\n"
|
||||
"Last-Translator: Erwin Mintiens <erwin.mintiens@protonmail.com>\n"
|
||||
"Language-Team: Dutch <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"nl/>\n"
|
||||
"Language: nl\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2026.6.dev0\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -185,7 +185,7 @@ msgstr "Het is niet mogelijk om te bouwen in een read-only map"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "De configuratie bevat niet de specialisatie \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
+13
-12
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-04-26 13:09+0000\n"
|
||||
"Last-Translator: Nikodem <35564466+x1pper@users.noreply.github.com>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:15+0000\n"
|
||||
"Last-Translator: Mateusz Kubica <mw.kubica@gmail.com>\n"
|
||||
"Language-Team: Polish <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"pl/>\n"
|
||||
"Language: pl\n"
|
||||
@@ -18,7 +18,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 5.17.1-dev\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -83,24 +83,25 @@ msgid ""
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
msgstr ""
|
||||
"Zrób jedną z tych rzeczy aby pozbyć się tego ostrzeżenia:\n"
|
||||
"Zrób jedną z tych rzeczy aby aby pozbyć się tego ostrzeżenia:\n"
|
||||
"\n"
|
||||
"1. Jednoznacznie skonfiguruj Home Manager żeby używał konkretnej ścieżki, "
|
||||
"np. dodając\n"
|
||||
"\n"
|
||||
" { programs.home-manager.path = \"%s\"; }\n"
|
||||
" { programs.home-manager.path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" do twojej konfiguracji.\n"
|
||||
" do twojej konfiguracji.\n"
|
||||
"\n"
|
||||
" Jeśli importujesz Home Manager bezpośrednio, możesz użyć parametru `path`\n"
|
||||
" Jeśli importujesz Home Manager bezpośrednio, możesz użyć parametru "
|
||||
"`path`\n"
|
||||
"\n"
|
||||
" pkgs.callPackage /ścieżka/do/pakiet-home-manager { path = \"%s\"; }\n"
|
||||
" pkgs.callPackage /ścieżka/do/pakiet-home-manager { path = \"%s\"; }\n"
|
||||
"\n"
|
||||
" przy wywołaniu pakietu Home Manager.\n"
|
||||
" przy wywołaniu pakietu Home Manager.\n"
|
||||
"\n"
|
||||
"2. Usuń przestarzałą ścieżkę:\n"
|
||||
"2. Usuń przestarzałą ścieżkę.\n"
|
||||
"\n"
|
||||
" $ rm -r \"%s\""
|
||||
" $ rm -r \"%s\""
|
||||
|
||||
#: home-manager/home-manager:153
|
||||
msgid "Sanity checking Nix"
|
||||
@@ -206,7 +207,7 @@ msgstr "Nie mogę uruchomić budowania w katalogu tylko-do-odczytu"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "Konfiguracja nie zawiera specjalizacji o nazwie \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-07-19 08:01+0000\n"
|
||||
"Last-Translator: Artur Sannikov <weblate.rbpxz@8shield.net>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:16+0000\n"
|
||||
"Last-Translator: NikSne <commits@niksne.ru>\n"
|
||||
"Language-Team: Russian <https://hosted.weblate.org/projects/home-manager/cli/"
|
||||
"ru/>\n"
|
||||
"Language: ru\n"
|
||||
@@ -18,7 +18,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Weblate 2026.8.dev0\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -205,7 +205,7 @@ msgstr "Не могу начать сборку в директории, защ
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "В конфигурации отсутствует специализация «%s»"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
+31
-58
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-05-27 11:11+0000\n"
|
||||
"Last-Translator: qb114514 <GNUqb114514@outlook.com>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:14+0000\n"
|
||||
"Last-Translator: Anonymous <noreply@weblate.org>\n"
|
||||
"Language-Team: Toki Pona <https://hosted.weblate.org/projects/home-manager/"
|
||||
"cli/tok/>\n"
|
||||
"Language: tok\n"
|
||||
@@ -17,21 +17,21 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 2026.6.dev0\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
msgid "%s: missing argument for %s"
|
||||
msgstr "%s: nimi %s li wile nimi poka"
|
||||
msgstr ""
|
||||
|
||||
#. translators: For example: "home-manager: --rollback can only be used after switch"
|
||||
#: home-manager/home-manager:22
|
||||
msgid "%s: %s can only be used after %s"
|
||||
msgstr "%s: %s li ken lon poka pini %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:71
|
||||
msgid "No configuration file found at %s"
|
||||
msgstr "lipu lawa li lon ala %s"
|
||||
msgstr ""
|
||||
|
||||
#. translators: The first '%s' specifier will be replaced by either
|
||||
#. 'home.nix' or 'flake.nix'.
|
||||
@@ -41,16 +41,14 @@ msgid ""
|
||||
"Keeping your Home Manager %s in %s is deprecated,\n"
|
||||
"please move it to %s"
|
||||
msgstr ""
|
||||
"lipu %s pi ilo Home Manager li wile ala lon %s.\n"
|
||||
"o tawa %s e ona"
|
||||
|
||||
#: home-manager/home-manager:99
|
||||
msgid "No configuration file found. Please create one at %s"
|
||||
msgstr "mi ken ala alasa e lipu lawa. o pali e lipu lawa lon %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:114
|
||||
msgid "Home Manager not found at %s."
|
||||
msgstr "ilo Home Manager li lon ala %s."
|
||||
msgstr ""
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:122
|
||||
@@ -58,8 +56,6 @@ msgid ""
|
||||
"The fallback Home Manager path %s has been deprecated and a file/directory "
|
||||
"was found there."
|
||||
msgstr ""
|
||||
"tenpo pini la, ilo Home Manager li kepeken nasin %s. taso, tenpo ni la ilo "
|
||||
"Home Manager li wile ale e nasin ni. lipu anu kulupu lipu li lon nasin ni."
|
||||
|
||||
#. translators: This message will be seen by very few users that likely are familiar with English. So feel free to leave this untranslated.
|
||||
#: home-manager/home-manager:125
|
||||
@@ -85,40 +81,37 @@ msgstr ""
|
||||
|
||||
#: home-manager/home-manager:153
|
||||
msgid "Sanity checking Nix"
|
||||
msgstr "mi alasa ilo Nix tan ni: ilo Nix li lon ala la ni li ike mute li nasa"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:173
|
||||
msgid "Could not find suitable profile directory, tried %s and %s"
|
||||
msgstr ""
|
||||
"mi wile pana e kulupu lipu sina lon poki sona. taso mi ken ala alasa e ma "
|
||||
"pona lon %s lon %s"
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:230
|
||||
msgid "Can't inspect options of a flake configuration"
|
||||
msgstr "mi ken ala lukin e lipu lawa pi ilo Nix Flakes"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:340 home-manager/home-manager:363
|
||||
#: home-manager/home-manager:769 home-manager/home-manager:1289
|
||||
msgid "%s: unknown option '%s'"
|
||||
msgstr "%s: mi ken ala sona e nimi '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:345 home-manager/home-manager:1290
|
||||
msgid "Run '%s --help' for usage help"
|
||||
msgstr "sina wile kama sona pali e ilo Home Manager la o toki e '%s --help'"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:371 home-manager/home-manager:476
|
||||
msgid "The file %s already exists, leaving it unchanged..."
|
||||
msgstr "lipu %s li lon. mi ante ala e ona."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:373 home-manager/home-manager:478
|
||||
msgid "Creating %s..."
|
||||
msgstr "mi pali e \"%s\"."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:522
|
||||
msgid "Creating initial Home Manager generation..."
|
||||
msgstr ""
|
||||
"tenpo ni la mi pali e kulupu nanpa wan pi lipu lawa tan ilo Home Manager..."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a file path.
|
||||
#: home-manager/home-manager:527
|
||||
@@ -130,12 +123,6 @@ msgid ""
|
||||
"to configure Home Manager. Run 'man home-configuration.nix' to\n"
|
||||
"see all available options."
|
||||
msgstr ""
|
||||
"pini a! ilo \"home-manager\" li lon. sina wile lawa e ilo Home Manager la "
|
||||
"sina ken ante e lipu ni:\n"
|
||||
"\n"
|
||||
" lipu.%s\n"
|
||||
"\n"
|
||||
"sina wile kama sona e nasin lawa o toki e ni: 'man home-configuration.nix'."
|
||||
|
||||
#. translators: The "%s" specifier will be replaced by a URL.
|
||||
#: home-manager/home-manager:532
|
||||
@@ -146,17 +133,11 @@ msgid ""
|
||||
"\n"
|
||||
"if the error seems to be the fault of Home Manager."
|
||||
msgstr ""
|
||||
"ike li lon! mi ken ala pana e ilo Home Manager tawa sina. ken la sina pilin "
|
||||
"e ni: ike ni li tan ilo Home Manager. ni la o pana e sona lon\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
"ni la sina pona e mi mute."
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:543
|
||||
msgid "Can't instantiate a flake configuration"
|
||||
msgstr "mi ken ala pali e lipu lawa pi ilo Nix Flakes"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:619
|
||||
msgid ""
|
||||
@@ -166,88 +147,80 @@ msgid_plural ""
|
||||
"There are %d unread and relevant news items.\n"
|
||||
"Read them by running the command \"%s news\"."
|
||||
msgstr[0] ""
|
||||
"sona sin %d li lon.\n"
|
||||
"sina wile lukin la o toki: \"%s news\"."
|
||||
|
||||
#: home-manager/home-manager:633
|
||||
msgid "Unknown \"news.display\" setting \"%s\"."
|
||||
msgstr ""
|
||||
"sina pana e \"%s\" tawa nimi lawa \"news.display\". nimi lawa ni li ken ala "
|
||||
"jo e nimi ni li ken jo e \"silent\" anu \"notify\" anu \"show\"."
|
||||
|
||||
#: home-manager/home-manager:641
|
||||
#, sh-format
|
||||
msgid "Please set the $EDITOR or $VISUAL environment variable"
|
||||
msgstr "o pana e ilo tawa poki sona $EDITOR anu poki sona $VISUAL"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:659
|
||||
msgid "Cannot run build in read-only directory"
|
||||
msgstr "ma ni li ken ala ante. mi ken ala pali \"build\" lon ma ni"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
#, fuzzy
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "lipu lawa jo ala lipu Specialisation \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
msgstr "kulupu pi lipu lawa pi ilo Home Manager pi nimi %s li lon ala"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:878
|
||||
msgid "Cannot remove the current generation %s"
|
||||
msgstr ""
|
||||
"mi ken ala weka e kulupu pi lipu lawa %s tan ni: tenpo ni la ona li lon tomo "
|
||||
"sina"
|
||||
|
||||
#: home-manager/home-manager:880
|
||||
msgid "Removing generation %s"
|
||||
msgstr "mi weka e kulupu lawa pi nimi %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:901
|
||||
msgid "No generations to expire"
|
||||
msgstr "kulupu ale pi lipu lawa li majuna ala. mi wile ala weka e ona"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:912
|
||||
msgid "No home-manager packages seem to be installed."
|
||||
msgstr "ilo Home Manager li pana ala e ilo ante."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:997
|
||||
msgid "Unknown argument %s"
|
||||
msgstr "mi sona ala e nimi '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1022
|
||||
msgid "This will remove Home Manager from your system."
|
||||
msgstr "ni li weka e ilo Home Manager."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1025
|
||||
msgid "This is a dry run, nothing will actually be uninstalled."
|
||||
msgstr "tenpo ni la mi weka e ala li toki taso."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1029
|
||||
msgid "Really uninstall Home Manager?"
|
||||
msgstr "sina wile ala wile weka e ilo Home Manager?"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1035
|
||||
msgid "Switching to empty Home Manager configuration..."
|
||||
msgstr "tenpo ni la mi lon e lipu lawa pi ijo ala..."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1050
|
||||
msgid "Yay!"
|
||||
msgstr "pona mute a!"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1055
|
||||
msgid "Home Manager is uninstalled but your home.nix is left untouched."
|
||||
msgstr "ilo Home Manager li weka. taso, lipu home.nix li awen lon."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1334
|
||||
msgid "expire-generations expects one argument, got %d."
|
||||
msgstr ""
|
||||
"sina pana e nimi %d tawa ilo expire-generations. o pana e nimi wan taso."
|
||||
|
||||
#: home-manager/home-manager:1359
|
||||
msgid "Unknown command: %s"
|
||||
msgstr "mi sona ala pali %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/install.nix:21
|
||||
msgid "This derivation is not buildable, please run it using nix-shell."
|
||||
msgstr "mi ken ala pali e ni. sina ken pali e ona kepeken ilo nix-shell."
|
||||
msgstr ""
|
||||
|
||||
@@ -8,9 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2026-01-21 09:53+0100\n"
|
||||
"PO-Revision-Date: 2026-07-19 08:01+0000\n"
|
||||
"Last-Translator: reducedradius "
|
||||
"<137701630+flytothehighest@users.noreply.github.com>\n"
|
||||
"PO-Revision-Date: 2026-03-31 16:13+0000\n"
|
||||
"Last-Translator: Zexin Yuan <yuan.zx@outlook.com>\n"
|
||||
"Language-Team: Chinese (Simplified Han script) <https://hosted.weblate.org/"
|
||||
"projects/home-manager/cli/zh_Hans/>\n"
|
||||
"Language: zh_Hans\n"
|
||||
@@ -18,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 2026.8.dev0\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
|
||||
#. translators: For example: "home-manager: missing argument for --cores"
|
||||
#: home-manager/home-manager:16
|
||||
@@ -28,7 +27,7 @@ msgstr "%s:缺少参数 %s"
|
||||
#. translators: For example: "home-manager: --rollback can only be used after switch"
|
||||
#: home-manager/home-manager:22
|
||||
msgid "%s: %s can only be used after %s"
|
||||
msgstr "%s: %s 只能在 %s 后使用"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:71
|
||||
msgid "No configuration file found at %s"
|
||||
@@ -195,7 +194,7 @@ msgstr "无法在只读目录中运行构建"
|
||||
|
||||
#: home-manager/home-manager:822
|
||||
msgid "The configuration does not contain the specialisation \"%s\""
|
||||
msgstr "配置不包含专门化的 “%s”"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:876
|
||||
msgid "No generation with ID %s"
|
||||
|
||||
+34
-1
@@ -2,5 +2,38 @@
|
||||
{
|
||||
inherit ((import ../modules/lib/stdlib-extended.nix lib)) hm;
|
||||
|
||||
homeManagerConfiguration = import ./eval-config.nix;
|
||||
homeManagerConfiguration =
|
||||
{
|
||||
check ? true,
|
||||
extraSpecialArgs ? { },
|
||||
lib ? pkgs.lib,
|
||||
modules ? [ ],
|
||||
pkgs,
|
||||
minimal ? false,
|
||||
}:
|
||||
import ../modules {
|
||||
inherit
|
||||
check
|
||||
extraSpecialArgs
|
||||
lib
|
||||
pkgs
|
||||
minimal
|
||||
;
|
||||
configuration = {
|
||||
imports = modules ++ [
|
||||
{
|
||||
programs.home-manager.path = builtins.path {
|
||||
path = ../.;
|
||||
name = "source";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
nixpkgs = {
|
||||
config = lib.mkDefault pkgs.config;
|
||||
|
||||
inherit (pkgs) overlays;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
check ? true,
|
||||
extraSpecialArgs ? { },
|
||||
lib ? pkgs.lib,
|
||||
modules ? [ ],
|
||||
pkgs,
|
||||
minimal ? false,
|
||||
}:
|
||||
import ../modules {
|
||||
inherit
|
||||
check
|
||||
extraSpecialArgs
|
||||
lib
|
||||
pkgs
|
||||
minimal
|
||||
;
|
||||
configuration = {
|
||||
imports = modules ++ [
|
||||
{
|
||||
programs.home-manager.path = builtins.path {
|
||||
path = ../.;
|
||||
name = "source";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
nixpkgs = {
|
||||
config = lib.mkDefault pkgs.config;
|
||||
|
||||
inherit (pkgs) overlays;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,14 +1,7 @@
|
||||
# Extract maintainers from Home Manager modules using meta.maintainers
|
||||
# This script evaluates all Home Manager modules and extracts the merged maintainer information
|
||||
let
|
||||
flakeLock = builtins.fromJSON (builtins.readFile ../../flake.lock);
|
||||
nixpkgsNodeName = flakeLock.nodes.root.inputs.nixpkgs;
|
||||
nixpkgsLocked = flakeLock.nodes.${nixpkgsNodeName}.locked;
|
||||
|
||||
pkgs = import (fetchTarball {
|
||||
url = "https://github.com/${nixpkgsLocked.owner}/${nixpkgsLocked.repo}/archive/${nixpkgsLocked.rev}.tar.gz";
|
||||
sha256 = nixpkgsLocked.narHash;
|
||||
}) { };
|
||||
pkgs = import <nixpkgs> { };
|
||||
lib = import ../../modules/lib/stdlib-extended.nix pkgs.lib;
|
||||
releaseInfo = pkgs.lib.importJSON ../../release.json;
|
||||
|
||||
@@ -32,23 +25,18 @@ let
|
||||
file:
|
||||
let
|
||||
fileContent = import file;
|
||||
# Arguments expected by docs/home-manager-manual.nix.
|
||||
evaluated =
|
||||
if lib.isFunction fileContent then
|
||||
fileContent {
|
||||
inherit lib;
|
||||
inherit (pkgs)
|
||||
callPackage
|
||||
mdbook
|
||||
python3
|
||||
stdenv
|
||||
;
|
||||
inherit (pkgs) stdenv lib;
|
||||
documentation-highlighter = { };
|
||||
revision = "unknown";
|
||||
home-manager-options = {
|
||||
home-manager = { };
|
||||
nixos = { };
|
||||
nix-darwin = { };
|
||||
};
|
||||
nixos-render-docs = { };
|
||||
}
|
||||
else
|
||||
fileContent;
|
||||
@@ -71,30 +59,27 @@ let
|
||||
|
||||
allMaintainerObjects = extractMaintainerObjects maintainers ++ additionalMaintainerObjects;
|
||||
|
||||
getMaintainerName = maintainer: maintainer.github or maintainer.name or null;
|
||||
|
||||
allMaintainerNames = lib.filter (name: name != null) (map getMaintainerName allMaintainerObjects);
|
||||
allMaintainerNames = lib.filter (name: name != null) (
|
||||
map (maintainer: maintainer.github or maintainer.name or null) allMaintainerObjects
|
||||
);
|
||||
|
||||
hmMaintainers = import ../../modules/lib/maintainers.nix;
|
||||
hmMaintainerNames = lib.filter (name: name != null) (
|
||||
map getMaintainerName (lib.attrValues hmMaintainers)
|
||||
);
|
||||
hmMaintainerNames = lib.attrNames hmMaintainers;
|
||||
|
||||
maintainerDetails = lib.pipe allMaintainerObjects [
|
||||
(lib.filter (obj: (obj.github or obj.name or null) != null))
|
||||
(map (
|
||||
obj:
|
||||
let
|
||||
maintainerName = obj.github or obj.name;
|
||||
in
|
||||
{
|
||||
name = maintainerName;
|
||||
value = obj // {
|
||||
source =
|
||||
if categorizedMaintainers.home-manager ? ${maintainerName} then "home-manager" else "nixpkgs";
|
||||
};
|
||||
}
|
||||
))
|
||||
(map (obj: {
|
||||
name = obj.github or obj.name;
|
||||
value = obj // {
|
||||
source =
|
||||
if categorizedMaintainers.home-manager ? ${obj.github} then
|
||||
"home-manager"
|
||||
else if categorizedMaintainers.nixpkgs ? ${obj.github} then
|
||||
"nixpkgs"
|
||||
else
|
||||
throw "${obj.github} is neither a home-manager or nixpkgs maintainer";
|
||||
};
|
||||
}))
|
||||
lib.listToAttrs
|
||||
];
|
||||
|
||||
|
||||
@@ -17,67 +17,52 @@ def main():
|
||||
print("🔍 Checking for duplicate maintainers between HM and nixpkgs...")
|
||||
|
||||
# Get home-manager maintainers
|
||||
hm_result = subprocess.run(
|
||||
["nix", "eval", "--file", "modules/lib/maintainers.nix", "--json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
hm_result = subprocess.run(['nix', 'eval', '--file', 'modules/lib/maintainers.nix', '--json'],
|
||||
capture_output=True, text=True, check=True)
|
||||
hm_maintainers = json.loads(hm_result.stdout)
|
||||
hm_github_users = set()
|
||||
for name, data in hm_maintainers.items():
|
||||
if "github" in data:
|
||||
hm_github_users.add(data["github"])
|
||||
if 'github' in data:
|
||||
hm_github_users.add(data['github'])
|
||||
|
||||
# Read nixpkgs revision from flake.lock to ensure consistency between local and CI
|
||||
flake_lock_path = Path("flake.lock")
|
||||
with open(flake_lock_path, "r") as f:
|
||||
flake_lock_path = Path('flake.lock')
|
||||
with open(flake_lock_path, 'r') as f:
|
||||
flake_lock = json.load(f)
|
||||
nixpkgs_rev = flake_lock["nodes"]["nixpkgs"]["locked"]["rev"]
|
||||
nixpkgs_rev = flake_lock['nodes']['nixpkgs']['locked']['rev']
|
||||
|
||||
print(f"📌 Using nixpkgs from flake.lock: {nixpkgs_rev[:7]}")
|
||||
|
||||
# Get nixpkgs maintainers from the locked revision
|
||||
nixpkgs_result = subprocess.run(
|
||||
[
|
||||
"nix",
|
||||
"eval",
|
||||
f"github:NixOS/nixpkgs/{nixpkgs_rev}#lib.maintainers",
|
||||
"--json",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
['nix', 'eval', f'github:NixOS/nixpkgs/{nixpkgs_rev}#lib.maintainers', '--json'],
|
||||
capture_output=True, text=True, check=True
|
||||
)
|
||||
nixpkgs_maintainers = json.loads(nixpkgs_result.stdout)
|
||||
nixpkgs_github_users = set()
|
||||
for name, data in nixpkgs_maintainers.items():
|
||||
if isinstance(data, dict) and "github" in data:
|
||||
nixpkgs_github_users.add(data["github"])
|
||||
if isinstance(data, dict) and 'github' in data:
|
||||
nixpkgs_github_users.add(data['github'])
|
||||
|
||||
# Find duplicates
|
||||
duplicates = hm_github_users.intersection(nixpkgs_github_users)
|
||||
|
||||
if duplicates:
|
||||
print(
|
||||
f"❌ Found {len(duplicates)} duplicate maintainers between HM and nixpkgs:"
|
||||
)
|
||||
print(f'❌ Found {len(duplicates)} duplicate maintainers between HM and nixpkgs:')
|
||||
for github_user in sorted(duplicates):
|
||||
# Find the HM attribute name for this github user
|
||||
hm_attr = None
|
||||
for attr_name, data in hm_maintainers.items():
|
||||
if data.get("github") == github_user:
|
||||
if data.get('github') == github_user:
|
||||
hm_attr = attr_name
|
||||
break
|
||||
print(f" - {github_user} (HM attribute: {hm_attr})")
|
||||
print(f' - {github_user} (HM attribute: {hm_attr})')
|
||||
print()
|
||||
print(
|
||||
"These maintainers should be removed from HM maintainers file to avoid duplication."
|
||||
)
|
||||
print("They can be referenced directly from nixpkgs instead.")
|
||||
print('These maintainers should be removed from HM maintainers file to avoid duplication.')
|
||||
print('They can be referenced directly from nixpkgs instead.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("✅ No duplicate maintainers found")
|
||||
print('✅ No duplicate maintainers found')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -16,7 +16,6 @@ from pathlib import Path
|
||||
|
||||
class NixEvalError(Exception):
|
||||
"""Custom exception for errors during Nix evaluation."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -40,9 +39,7 @@ def run_nix_eval(nix_file: Path, *args: str) -> str:
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except FileNotFoundError:
|
||||
logging.error(
|
||||
"'nix-instantiate' command not found. Is Nix installed and in your PATH?"
|
||||
)
|
||||
logging.error("'nix-instantiate' command not found. Is Nix installed and in your PATH?")
|
||||
raise NixEvalError("'nix-instantiate' not found")
|
||||
except subprocess.CalledProcessError as e:
|
||||
logging.error(f"Nix evaluation failed with exit code {e.returncode}")
|
||||
|
||||
@@ -40,7 +40,6 @@ def get_project_root() -> Path:
|
||||
# Assumes this script is at: <root>/flake/dev/generate-all-maintainers/
|
||||
return Path(__file__).parent.parent.parent.parent.resolve()
|
||||
|
||||
|
||||
class MetaMaintainerGenerator:
|
||||
"""Generates maintainers list using meta.maintainers from Home Manager evaluation."""
|
||||
|
||||
@@ -55,12 +54,9 @@ class MetaMaintainerGenerator:
|
||||
print("🔍 Extracting maintainers using meta.maintainers...")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nix", "eval", "--file", str(self.extractor_script), "--json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
result = subprocess.run([
|
||||
"nix", "eval", "--file", str(self.extractor_script), "--json"
|
||||
], capture_output=True, text=True, timeout=60)
|
||||
|
||||
if result.returncode == 0:
|
||||
data = json.loads(result.stdout)
|
||||
@@ -91,7 +87,7 @@ class MetaMaintainerGenerator:
|
||||
print(f"🏠 Home Manager maintainers: {len(hm_maintainers)}")
|
||||
print(f"📦 Nixpkgs maintainers: {len(nixpkgs_maintainers)}")
|
||||
|
||||
with open(self.output_file, "w") as f:
|
||||
with open(self.output_file, 'w') as f:
|
||||
f.write(
|
||||
inspect.cleandoc("""
|
||||
# Home Manager all maintainers list.
|
||||
@@ -118,12 +114,9 @@ class MetaMaintainerGenerator:
|
||||
def validate_generated_file(self) -> bool:
|
||||
"""Validate the generated Nix file syntax."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["nix-instantiate", "--eval", str(self.output_file), "--strict"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
)
|
||||
result = subprocess.run([
|
||||
'nix-instantiate', '--eval', str(self.output_file), '--strict'
|
||||
], capture_output=True, text=True, timeout=10)
|
||||
|
||||
if result.returncode == 0:
|
||||
print("✅ Generated file has valid Nix syntax")
|
||||
@@ -155,16 +148,16 @@ def main():
|
||||
description="Generate Home Manager all-maintainers.nix using meta.maintainers"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--root",
|
||||
'--root',
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Path to Home Manager root (default: auto-detect)",
|
||||
help='Path to Home Manager root (default: auto-detect)'
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
'--output',
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Output file path (default: <root>/all-maintainers.nix)",
|
||||
help='Output file path (default: <root>/all-maintainers.nix)'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
+41
-108
@@ -60,7 +60,6 @@ query($owner: String!, $repo: String!, $prNumber: Int!) {
|
||||
|
||||
class GHError(Exception):
|
||||
"""Custom exception for errors related to 'gh' CLI commands."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -95,28 +94,15 @@ def get_manual_reviewer_actions(
|
||||
tuple: (manually_requested, manually_removed) sets of usernames
|
||||
"""
|
||||
try:
|
||||
result = run_gh_command(
|
||||
[
|
||||
"api",
|
||||
"graphql",
|
||||
"-f",
|
||||
f"query={MANUAL_REVIEW_REQUEST_QUERY}",
|
||||
"-F",
|
||||
f"owner={owner}",
|
||||
"-F",
|
||||
f"repo={repo}",
|
||||
"-F",
|
||||
f"prNumber={pr_number}",
|
||||
]
|
||||
)
|
||||
result = run_gh_command([
|
||||
"api", "graphql",
|
||||
"-f", f"query={MANUAL_REVIEW_REQUEST_QUERY}",
|
||||
"-F", f"owner={owner}",
|
||||
"-F", f"repo={repo}",
|
||||
"-F", f"prNumber={pr_number}",
|
||||
])
|
||||
data = json.loads(result.stdout)
|
||||
nodes = (
|
||||
data.get("data", {})
|
||||
.get("repository", {})
|
||||
.get("pullRequest", {})
|
||||
.get("timelineItems", {})
|
||||
.get("nodes", [])
|
||||
)
|
||||
nodes = data.get("data", {}).get("repository", {}).get("pullRequest", {}).get("timelineItems", {}).get("nodes", [])
|
||||
|
||||
manually_requested = set()
|
||||
manually_removed = set()
|
||||
@@ -157,15 +143,7 @@ def get_users_from_gh(args: list[str], error_message: str) -> set[str]:
|
||||
def get_pending_reviewers(pr_number: int) -> set[str]:
|
||||
"""Gets the set of currently pending reviewers for a PR."""
|
||||
return get_users_from_gh(
|
||||
[
|
||||
"pr",
|
||||
"view",
|
||||
str(pr_number),
|
||||
"--json",
|
||||
"reviewRequests",
|
||||
"--jq",
|
||||
".reviewRequests[].login",
|
||||
],
|
||||
["pr", "view", str(pr_number), "--json", "reviewRequests", "--jq", ".reviewRequests[].login"],
|
||||
"Error getting pending reviewers",
|
||||
)
|
||||
|
||||
@@ -173,12 +151,7 @@ def get_pending_reviewers(pr_number: int) -> set[str]:
|
||||
def get_past_reviewers(owner: str, repo: str, pr_number: int) -> set[str]:
|
||||
"""Gets the set of users who have already reviewed the PR."""
|
||||
return get_users_from_gh(
|
||||
[
|
||||
"api",
|
||||
f"repos/{owner}/{repo}/pulls/{pr_number}/reviews",
|
||||
"--jq",
|
||||
".[].user.login",
|
||||
],
|
||||
["api", f"repos/{owner}/{repo}/pulls/{pr_number}/reviews", "--jq", ".[].user.login"],
|
||||
"Error getting past reviewers",
|
||||
)
|
||||
|
||||
@@ -189,14 +162,17 @@ def is_collaborator(owner: str, repo: str, username: str) -> bool:
|
||||
Handles 404 as a non-collaborator, while other errors are raised.
|
||||
"""
|
||||
result = run_gh_command(
|
||||
["api", f"repos/{owner}/{repo}/collaborators/{username}"], check=False
|
||||
["api", f"repos/{owner}/{repo}/collaborators/{username}"],
|
||||
check=False
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
return True
|
||||
|
||||
if "HTTP 404" in result.stderr:
|
||||
logging.error("'%s' is not a collaborator in this repository.", username)
|
||||
logging.error(
|
||||
"'%s' is not a collaborator in this repository.", username
|
||||
)
|
||||
return False
|
||||
else:
|
||||
logging.error(
|
||||
@@ -219,32 +195,22 @@ def update_reviewers(
|
||||
if reviewers_to_add:
|
||||
logging.info("Requesting reviews from: %s", ", ".join(reviewers_to_add))
|
||||
try:
|
||||
run_gh_command(
|
||||
[
|
||||
"pr",
|
||||
"edit",
|
||||
str(pr_number),
|
||||
"--add-reviewer",
|
||||
",".join(reviewers_to_add),
|
||||
]
|
||||
)
|
||||
run_gh_command([
|
||||
"pr", "edit", str(pr_number),
|
||||
"--add-reviewer", ",".join(reviewers_to_add)
|
||||
])
|
||||
except GHError as e:
|
||||
logging.error("Failed to add reviewers: %s", e)
|
||||
|
||||
if reviewers_to_remove and owner and repo:
|
||||
logging.info(
|
||||
"Removing review requests from: %s", ", ".join(reviewers_to_remove)
|
||||
)
|
||||
logging.info("Removing review requests from: %s", ", ".join(reviewers_to_remove))
|
||||
payload = json.dumps({"reviewers": list(reviewers_to_remove)})
|
||||
try:
|
||||
run_gh_command(
|
||||
[
|
||||
"api",
|
||||
"--method",
|
||||
"DELETE",
|
||||
"api", "--method", "DELETE",
|
||||
f"repos/{owner}/{repo}/pulls/{pr_number}/requested_reviewers",
|
||||
"--input",
|
||||
"-",
|
||||
"--input", "-",
|
||||
],
|
||||
input_data=payload,
|
||||
)
|
||||
@@ -254,33 +220,15 @@ def update_reviewers(
|
||||
|
||||
def main() -> None:
|
||||
"""Main function to handle command-line arguments and manage reviewers."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Manage pull request reviewers for Home Manager."
|
||||
)
|
||||
parser = argparse.ArgumentParser(description="Manage pull request reviewers for Home Manager.")
|
||||
parser.add_argument("--owner", required=True, help="Repository owner.")
|
||||
parser.add_argument("--repo", required=True, help="Repository name.")
|
||||
parser.add_argument(
|
||||
"--pr-number", type=int, required=True, help="Pull request number."
|
||||
)
|
||||
parser.add_argument("--pr-number", type=int, required=True, help="Pull request number.")
|
||||
parser.add_argument("--pr-author", required=True, help="PR author's username.")
|
||||
parser.add_argument(
|
||||
"--current-maintainers",
|
||||
default="",
|
||||
help="Space-separated list of maintainers for the changed files.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--changed-files", default="", help="Newline-separated list of changed files."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--bot-user-name",
|
||||
default="",
|
||||
help="Bot user name to distinguish manual vs automated review requests.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Show what would be done without making actual changes.",
|
||||
)
|
||||
parser.add_argument("--current-maintainers", default="", help="Space-separated list of maintainers for the changed files.")
|
||||
parser.add_argument("--changed-files", default="", help="Newline-separated list of changed files.")
|
||||
parser.add_argument("--bot-user-name", default="", help="Bot user name to distinguish manual vs automated review requests.")
|
||||
parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making actual changes.")
|
||||
args = parser.parse_args()
|
||||
|
||||
no_changed_files = not args.changed_files.strip()
|
||||
@@ -289,15 +237,13 @@ def main() -> None:
|
||||
maintainers: set[str] = set(args.current_maintainers.split())
|
||||
pending_reviewers = get_pending_reviewers(args.pr_number)
|
||||
past_reviewers = get_past_reviewers(args.owner, args.repo, args.pr_number)
|
||||
manually_requested, manually_removed = get_manual_reviewer_actions(
|
||||
args.owner, args.repo, args.pr_number, args.bot_user_name
|
||||
)
|
||||
manually_requested, manually_removed = get_manual_reviewer_actions(args.owner, args.repo, args.pr_number, args.bot_user_name)
|
||||
|
||||
logging.info("File Maintainers: %s", " ".join(maintainers) or "None")
|
||||
logging.info("Pending Reviewers: %s", " ".join(pending_reviewers) or "None")
|
||||
logging.info("Past Reviewers: %s", " ".join(past_reviewers) or "None")
|
||||
logging.info("Manually Requested: %s", " ".join(manually_requested) or "None")
|
||||
logging.info("Manually Removed: %s", " ".join(manually_removed) or "None")
|
||||
logging.info("File Maintainers: %s", ' '.join(maintainers) or "None")
|
||||
logging.info("Pending Reviewers: %s", ' '.join(pending_reviewers) or "None")
|
||||
logging.info("Past Reviewers: %s", ' '.join(past_reviewers) or "None")
|
||||
logging.info("Manually Requested: %s", ' '.join(manually_requested) or "None")
|
||||
logging.info("Manually Removed: %s", ' '.join(manually_removed) or "None")
|
||||
|
||||
# --- 2. Determine reviewers to remove ---
|
||||
reviewers_to_remove: set[str] = set()
|
||||
@@ -311,15 +257,13 @@ def main() -> None:
|
||||
|
||||
if reviewers_to_remove:
|
||||
if args.dry_run:
|
||||
logging.info(
|
||||
"DRY RUN: Would remove reviewers: %s", ", ".join(reviewers_to_remove)
|
||||
)
|
||||
logging.info("DRY RUN: Would remove reviewers: %s", ", ".join(reviewers_to_remove))
|
||||
else:
|
||||
update_reviewers(
|
||||
args.pr_number,
|
||||
owner=args.owner,
|
||||
repo=args.repo,
|
||||
reviewers_to_remove=reviewers_to_remove,
|
||||
reviewers_to_remove=reviewers_to_remove
|
||||
)
|
||||
else:
|
||||
logging.info("No reviewers to remove.")
|
||||
@@ -334,29 +278,20 @@ def main() -> None:
|
||||
MAX_MAINTAINERS_THRESHOLD,
|
||||
)
|
||||
else:
|
||||
users_to_exclude = (
|
||||
{args.pr_author} | past_reviewers | pending_reviewers | manually_removed
|
||||
)
|
||||
users_to_exclude = {args.pr_author} | past_reviewers | pending_reviewers | manually_removed
|
||||
potential_reviewers = maintainers - users_to_exclude
|
||||
|
||||
reviewers_to_add = {
|
||||
user
|
||||
for user in potential_reviewers
|
||||
if is_collaborator(args.owner, args.repo, user)
|
||||
user for user in potential_reviewers if is_collaborator(args.owner, args.repo, user)
|
||||
}
|
||||
|
||||
non_collaborators = potential_reviewers - reviewers_to_add
|
||||
if non_collaborators:
|
||||
logging.warning(
|
||||
"Ignoring non-collaborators: %s", ", ".join(non_collaborators)
|
||||
)
|
||||
logging.warning("Ignoring non-collaborators: %s", ", ".join(non_collaborators))
|
||||
|
||||
manually_removed_maintainers = reviewers_to_add & manually_removed
|
||||
if manually_removed_maintainers:
|
||||
logging.info(
|
||||
"Not re-adding manually removed maintainers: %s",
|
||||
", ".join(manually_removed_maintainers),
|
||||
)
|
||||
logging.info("Not re-adding manually removed maintainers: %s", ", ".join(manually_removed_maintainers))
|
||||
reviewers_to_add -= manually_removed
|
||||
|
||||
if len(reviewers_to_add) > MAX_REVIEWERS:
|
||||
@@ -369,9 +304,7 @@ def main() -> None:
|
||||
|
||||
if reviewers_to_add:
|
||||
if args.dry_run:
|
||||
logging.info(
|
||||
"DRY RUN: Would add reviewers: %s", ", ".join(reviewers_to_add)
|
||||
)
|
||||
logging.info("DRY RUN: Would add reviewers: %s", ", ".join(reviewers_to_add))
|
||||
else:
|
||||
update_reviewers(args.pr_number, reviewers_to_add=reviewers_to_add)
|
||||
else:
|
||||
|
||||
@@ -14,38 +14,32 @@ import sys
|
||||
def main():
|
||||
print("🔍 Validating maintainer entries...")
|
||||
|
||||
result = subprocess.run(
|
||||
["nix", "eval", "--file", "modules/lib/maintainers.nix", "--json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
result = subprocess.run(['nix', 'eval', '--file', 'modules/lib/maintainers.nix', '--json'],
|
||||
capture_output=True, text=True, check=True)
|
||||
maintainers = json.loads(result.stdout)
|
||||
errors = []
|
||||
|
||||
for name, data in maintainers.items():
|
||||
if "github" not in data:
|
||||
if 'github' not in data:
|
||||
errors.append(f'{name}: Missing required field "github"')
|
||||
if "githubId" not in data:
|
||||
if 'githubId' not in data:
|
||||
errors.append(f'{name}: Missing required field "githubId"')
|
||||
|
||||
if "githubId" in data:
|
||||
github_id = data["githubId"]
|
||||
if 'githubId' in data:
|
||||
github_id = data['githubId']
|
||||
if not isinstance(github_id, int):
|
||||
errors.append(
|
||||
f"{name}: githubId must be a number, not a string: {github_id} (type: {type(github_id).__name__})"
|
||||
)
|
||||
errors.append(f'{name}: githubId must be a number, not a string: {github_id} (type: {type(github_id).__name__})')
|
||||
elif github_id <= 0:
|
||||
errors.append(f"{name}: githubId must be positive: {github_id}")
|
||||
errors.append(f'{name}: githubId must be positive: {github_id}')
|
||||
|
||||
if errors:
|
||||
print("❌ Validation errors found:")
|
||||
print('❌ Validation errors found:')
|
||||
for error in errors:
|
||||
print(f" - {error}")
|
||||
print(f' - {error}')
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("✅ All maintainer entries are valid")
|
||||
print(f"✅ Validated {len(maintainers)} maintainer entries")
|
||||
print('✅ All maintainer entries are valid')
|
||||
print(f'✅ Validated {len(maintainers)} maintainer entries')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -13,12 +13,8 @@ def main():
|
||||
print("🔍 Validating maintainers.nix syntax...")
|
||||
|
||||
try:
|
||||
subprocess.run(
|
||||
["nix", "eval", "--file", "modules/lib/maintainers.nix", "--json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(['nix', 'eval', '--file', 'modules/lib/maintainers.nix', '--json'],
|
||||
capture_output=True, text=True, check=True)
|
||||
print("✅ Valid Nix syntax")
|
||||
except subprocess.CalledProcessError:
|
||||
print("❌ Invalid Nix syntax")
|
||||
|
||||
@@ -9,7 +9,7 @@ let
|
||||
;
|
||||
|
||||
cfg = config.accounts.email;
|
||||
enabledAccounts = lib.filterAttrs (_n: v: v.enable) cfg.accounts;
|
||||
enabledAccounts = lib.filterAttrs (n: v: v.enable) cfg.accounts;
|
||||
|
||||
gpgModule = types.submodule {
|
||||
options = {
|
||||
@@ -80,18 +80,6 @@ let
|
||||
default = "none";
|
||||
description = "Method to communicate the signature.";
|
||||
};
|
||||
|
||||
htmlFormat = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether Thunderbird should interpret {option}`text` as an HTML signature.
|
||||
|
||||
This maps to Thunderbird's `mail.identity.id_*.htmlSigFormat`
|
||||
preference. The signature content itself is still written through
|
||||
`mail.identity.id_*.htmlSigText`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -109,9 +97,7 @@ let
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use STARTTLS. This is discouraged and should be avoided if
|
||||
possible. See <https://datatracker.ietf.org/doc/html/rfc8314> for
|
||||
more.
|
||||
Whether to use STARTTLS.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -414,7 +400,6 @@ let
|
||||
"gmail.com"
|
||||
"mailbox.org"
|
||||
"migadu.com"
|
||||
"outlook.office365.com-ews"
|
||||
"outlook.office365.com"
|
||||
"plain"
|
||||
"posteo.de"
|
||||
@@ -626,17 +611,6 @@ let
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (config.flavor == "outlook.office365.com-ews") {
|
||||
userName = mkDefault config.address;
|
||||
|
||||
ews = {
|
||||
host = "outlook.office365.com";
|
||||
serviceDescriptionURL = "https://outlook.office365.com/EWS/Exchange.asmx";
|
||||
authentication = "xoauth2";
|
||||
tls.enable = true;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (config.flavor == "fastmail.com") {
|
||||
userName = mkDefault config.address;
|
||||
|
||||
@@ -659,14 +633,8 @@ let
|
||||
(mkIf (config.flavor == "mailbox.org") {
|
||||
userName = mkDefault config.address;
|
||||
folders.inbox = mkDefault "INBOX";
|
||||
imap = {
|
||||
host = "imap.mailbox.org";
|
||||
port = 993;
|
||||
};
|
||||
smtp = {
|
||||
host = "smtp.mailbox.org";
|
||||
port = 465;
|
||||
};
|
||||
imap.host = "imap.mailbox.org";
|
||||
smtp.host = "smtp.mailbox.org";
|
||||
})
|
||||
|
||||
(mkIf (config.flavor == "migadu.com") {
|
||||
|
||||
@@ -13,10 +13,12 @@ let
|
||||
mkIf
|
||||
mkMerge
|
||||
mkDefault
|
||||
mkAliasOptionModule
|
||||
types
|
||||
literalExpression
|
||||
escapeShellArg
|
||||
hm
|
||||
getAttrFromPath
|
||||
any
|
||||
optional
|
||||
;
|
||||
@@ -138,10 +140,46 @@ in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.league ];
|
||||
|
||||
imports = [
|
||||
(mkAliasOptionModule
|
||||
[ "xsession" "pointerCursor" "package" ]
|
||||
[
|
||||
"home"
|
||||
"pointerCursor"
|
||||
"package"
|
||||
]
|
||||
)
|
||||
(mkAliasOptionModule
|
||||
[ "xsession" "pointerCursor" "name" ]
|
||||
[
|
||||
"home"
|
||||
"pointerCursor"
|
||||
"name"
|
||||
]
|
||||
)
|
||||
(mkAliasOptionModule
|
||||
[ "xsession" "pointerCursor" "size" ]
|
||||
[
|
||||
"home"
|
||||
"pointerCursor"
|
||||
"size"
|
||||
]
|
||||
)
|
||||
(mkAliasOptionModule
|
||||
[ "xsession" "pointerCursor" "defaultCursor" ]
|
||||
[
|
||||
"home"
|
||||
"pointerCursor"
|
||||
"x11"
|
||||
"defaultCursor"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
home.pointerCursor = mkOption {
|
||||
type = pointerCursorModule;
|
||||
default = { };
|
||||
type = types.nullOr pointerCursorModule;
|
||||
default = null;
|
||||
description = ''
|
||||
Cursor configuration.
|
||||
|
||||
@@ -166,10 +204,9 @@ in
|
||||
let
|
||||
# Check if enable option was explicitly defined by the user
|
||||
enableDefined = any (x: x ? enable) opts.definitions;
|
||||
pointerCursorDefined = opts.highestPrio != (lib.mkOptionDefault { }).priority;
|
||||
|
||||
# Determine if cursor configuration should be enabled
|
||||
enable = if enableDefined then cfg.enable else pointerCursorDefined;
|
||||
enable = if enableDefined then cfg.enable else cfg != null;
|
||||
in
|
||||
mkMerge [
|
||||
(mkIf enable (mkMerge [
|
||||
@@ -203,7 +240,7 @@ in
|
||||
(mkIf cfg.dotIcons.enable {
|
||||
# Add symlink of cursor icon directory to $HOME/.icons, needed for
|
||||
# backwards compatibility with some applications. See:
|
||||
# https://specifications.freedesktop.org/icon-theme/latest/#directory_layout
|
||||
# https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s03.html
|
||||
home.file.".icons/default/index.theme".source =
|
||||
"${defaultIndexThemePackage}/share/icons/default/index.theme";
|
||||
home.file.".icons/${cfg.name}".source = "${cfg.package}/share/icons/${cfg.name}";
|
||||
@@ -248,12 +285,39 @@ in
|
||||
]))
|
||||
|
||||
{
|
||||
warnings = optional (pointerCursorDefined && !enableDefined) ''
|
||||
Relying on `home.pointerCursor` to enable cursor config generation is deprecated.
|
||||
Please update your configuration to explicitly set:
|
||||
warnings =
|
||||
(optional
|
||||
(any
|
||||
(
|
||||
x:
|
||||
getAttrFromPath (
|
||||
[
|
||||
"xsession"
|
||||
"pointerCursor"
|
||||
]
|
||||
++ [ x ]
|
||||
++ [ "isDefined" ]
|
||||
) options
|
||||
)
|
||||
[
|
||||
"package"
|
||||
"name"
|
||||
"size"
|
||||
"defaultCursor"
|
||||
]
|
||||
)
|
||||
''
|
||||
The option `xsession.pointerCursor` has been merged into `home.pointerCursor` and will be removed
|
||||
in the future. Please change to set `home.pointerCursor` directly and enable `home.pointerCursor.x11.enable`
|
||||
to generate x11 specific cursor configurations. You can refer to the documentation for more details.
|
||||
''
|
||||
)
|
||||
++ (optional (opts.highestPrio != (lib.mkOptionDefault { }).priority && cfg == null) ''
|
||||
Setting home.pointerCursor to null is deprecated.
|
||||
Please update your configuration to explicitly set:
|
||||
|
||||
home.pointerCursor.enable = ${lib.boolToString enable};
|
||||
'';
|
||||
home.pointerCursor.enable = false;
|
||||
'');
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixpkgs-unstable/pkgs/development/libraries/glibc/nix-locale-archive.patch
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
nixosConfig,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
@@ -56,8 +55,9 @@ in
|
||||
|
||||
This option only applies to the Linux platform.
|
||||
|
||||
If Home Manager is installed as a NixOS submodule, this
|
||||
option defaults to NixOS' {var}`i18n.glibcLocales`.
|
||||
When Home Manager is configured with NixOS, the default value
|
||||
will be set to {var}`i18n.glibcLocales` from the
|
||||
system configuration.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
pkgs.glibcLocales.override {
|
||||
@@ -65,8 +65,9 @@ in
|
||||
locales = [ "en_US.UTF-8/UTF-8" ];
|
||||
}
|
||||
'';
|
||||
default = nixosConfig.i18n.glibcLocales or pkgs.glibcLocales;
|
||||
defaultText = lib.literalExpression "nixosConfig.i18n.glibcLocales or pkgs.glibcLocales";
|
||||
# NB. See nixos/default.nix for NixOS default.
|
||||
default = pkgs.glibcLocales;
|
||||
defaultText = lib.literalExpression "pkgs.glibcLocales";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+69
-220
@@ -34,7 +34,7 @@ let
|
||||
|
||||
inherit
|
||||
(
|
||||
(import ./lib/file-type.nix {
|
||||
(import lib/file-type.nix {
|
||||
inherit homeDirectory lib pkgs;
|
||||
})
|
||||
)
|
||||
@@ -55,8 +55,6 @@ let
|
||||
name = sourceName;
|
||||
};
|
||||
|
||||
putterStatePath = "${config.xdg.stateHome}/home-manager/putter-state.json";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -90,44 +88,11 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
home.fileActivator = lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
enum [
|
||||
"legacy"
|
||||
"putter"
|
||||
];
|
||||
default = "legacy";
|
||||
example = "putter";
|
||||
visible = false;
|
||||
description = ''
|
||||
The tooling to use to place files during activation.
|
||||
|
||||
The legacy option (currently the default) is the built-in tooling that
|
||||
is very robust, but is limited in future potential.
|
||||
|
||||
The putter option is a new external tool that may replace the legacy
|
||||
alternative in the future. It is not as hardened as the legacy
|
||||
alternative but will allow future features such as file copying.
|
||||
|
||||
This option should be considered experimental and is therefore hidden
|
||||
from documentation at this time.
|
||||
'';
|
||||
};
|
||||
|
||||
home-files = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
internal = true;
|
||||
description = "Package to contain all home files";
|
||||
};
|
||||
|
||||
home.internal = {
|
||||
filePutterConfig = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
internal = true;
|
||||
description = "Putter configuration.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
@@ -135,7 +100,7 @@ in
|
||||
(
|
||||
let
|
||||
dups = lib.attrNames (
|
||||
lib.filterAttrs (_n: v: v > 1) (
|
||||
lib.filterAttrs (n: v: v > 1) (
|
||||
lib.foldAttrs (acc: v: acc + v) 0 (map (v: { ${v.target} = 1; }) cfg)
|
||||
)
|
||||
);
|
||||
@@ -184,29 +149,21 @@ in
|
||||
|
||||
storeDir = lib.escapeShellArg builtins.storeDir;
|
||||
|
||||
legacyCheckScript = pkgs.replaceVars ./files/check-link-targets.sh {
|
||||
check = pkgs.replaceVars ./files/check-link-targets.sh {
|
||||
inherit (config.lib.bash) initHomeManagerLib;
|
||||
inherit forcedPaths storeDir;
|
||||
};
|
||||
|
||||
legacyCheckLinkTargets = ''
|
||||
function checkNewGenCollision() {
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${legacyCheckScript} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
checkNewGenCollision || exit 1
|
||||
'';
|
||||
|
||||
putterCheckLinkTargets = ''
|
||||
${lib.getExe pkgs.putter} check $VERBOSE_ARG \
|
||||
--state-file "${putterStatePath}" \
|
||||
${config.home.internal.filePutterConfig}
|
||||
'';
|
||||
in
|
||||
if config.home.fileActivator == "putter" then putterCheckLinkTargets else legacyCheckLinkTargets
|
||||
''
|
||||
function checkNewGenCollision() {
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${check} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
checkNewGenCollision || exit 1
|
||||
''
|
||||
);
|
||||
|
||||
# This activation script will
|
||||
@@ -229,9 +186,7 @@ in
|
||||
# source and target generation.
|
||||
home.activation.linkGeneration = lib.hm.dag.entryAfter [ "writeBoundary" ] (
|
||||
let
|
||||
storeDir = lib.escapeShellArg builtins.storeDir;
|
||||
|
||||
legacyLink = pkgs.writeShellScript "link" ''
|
||||
link = pkgs.writeShellScript "link" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
newGenFiles="$1"
|
||||
@@ -241,8 +196,8 @@ in
|
||||
targetPath="$HOME/$relativePath"
|
||||
if [[ -e "$targetPath" && ! -L "$targetPath" ]] ; then
|
||||
if [[ -n "$HOME_MANAGER_BACKUP_COMMAND" ]] ; then
|
||||
verboseEcho "Running '$HOME_MANAGER_BACKUP_COMMAND' on '$targetPath'."
|
||||
run $HOME_MANAGER_BACKUP_COMMAND "$targetPath" || errorEcho "Running '$HOME_MANAGER_BACKUP_COMMAND' on '$targetPath' failed."
|
||||
verboseEcho "Running $HOME_MANAGER_BACKUP_COMMAND $targetPath."
|
||||
run $HOME_MANAGER_BACKUP_COMMAND "$targetPath" || errorEcho "Running `$HOME_MANAGER_BACKUP_COMMAND` on '$targetPath' failed."
|
||||
elif [[ -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
# The target exists, back it up
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
@@ -265,12 +220,12 @@ in
|
||||
done
|
||||
'';
|
||||
|
||||
legacyCleanup = pkgs.writeShellScript "cleanup" ''
|
||||
cleanup = pkgs.writeShellScript "cleanup" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
# A symbolic link whose target path matches this pattern will be
|
||||
# considered part of a Home Manager generation.
|
||||
homeFilePattern="$(readlink -e ${storeDir})/*-home-manager-files/*"
|
||||
homeFilePattern="$(readlink -e ${lib.escapeShellArg builtins.storeDir})/*-home-manager-files/*"
|
||||
|
||||
newGenFiles="$1"
|
||||
shift 1
|
||||
@@ -301,86 +256,38 @@ in
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
# If Putter is not enabled, then generate a fake state file to allow
|
||||
# switching to Putter in the future.
|
||||
putterCompatState =
|
||||
let
|
||||
putter = import ./lib/putter.nix { inherit lib; };
|
||||
manifest = putter.mkPutterCompatState {
|
||||
sourceBaseDirectory = config.home-files;
|
||||
targetBaseDirectory = config.home.homeDirectory;
|
||||
fileEntries = cfg;
|
||||
};
|
||||
in
|
||||
pkgs.writeText "hm-putter-state.json" manifest;
|
||||
|
||||
# This activation script will
|
||||
#
|
||||
# 1. Remove files from the old generation that are not in the new
|
||||
# generation.
|
||||
#
|
||||
# 2. Symlink files from the new generation into $HOME.
|
||||
#
|
||||
# This order is needed to ensure that we always know which links
|
||||
# belong to which generation. Specifically, if we're moving from
|
||||
# generation A to generation B having sets of home file links FA
|
||||
# and FB, respectively then cleaning before linking produces state
|
||||
# transitions similar to
|
||||
#
|
||||
# FA → FA ∩ FB → (FA ∩ FB) ∪ FB = FB
|
||||
#
|
||||
# and a failure during the intermediate state FA ∩ FB will not
|
||||
# result in lost links because this set of links are in both the
|
||||
# source and target generation.
|
||||
legacyLinkGeneration = ''
|
||||
function linkNewGen() {
|
||||
_i "Creating home file links in %s" "$HOME"
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${legacyLink} "$newGenFiles" {} +
|
||||
|
||||
# Copy in the Putter compatible state file. This is to allow a later
|
||||
# switchover to Putter.
|
||||
run install -Dp -m600 $VERBOSE_ARG ${
|
||||
lib.escapeShellArgs [
|
||||
putterCompatState
|
||||
putterStatePath
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
_i "Cleaning up orphan links from %s" "$HOME"
|
||||
|
||||
local newGenFiles oldGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||
|
||||
# Apply the cleanup script on each leaf in the old
|
||||
# generation. The find command below will print the
|
||||
# relative path of the entry.
|
||||
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
|
||||
| xargs -0 bash ${legacyCleanup} "$newGenFiles"
|
||||
}
|
||||
|
||||
cleanOldGen
|
||||
linkNewGen
|
||||
'';
|
||||
|
||||
putterLinkGeneration = ''
|
||||
${lib.getExe pkgs.putter} apply $VERBOSE_ARG ''${DRY_RUN:+--dry-run} \
|
||||
--state-file "${putterStatePath}" \
|
||||
${config.home.internal.filePutterConfig}
|
||||
'';
|
||||
in
|
||||
if config.home.fileActivator == "putter" then putterLinkGeneration else legacyLinkGeneration
|
||||
''
|
||||
function linkNewGen() {
|
||||
_i "Creating home file links in %s" "$HOME"
|
||||
|
||||
local newGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
find "$newGenFiles" \( -type f -or -type l \) \
|
||||
-exec bash ${link} "$newGenFiles" {} +
|
||||
}
|
||||
|
||||
function cleanOldGen() {
|
||||
if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
_i "Cleaning up orphan links from %s" "$HOME"
|
||||
|
||||
local newGenFiles oldGenFiles
|
||||
newGenFiles="$(readlink -e "$newGenPath/home-files")"
|
||||
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
|
||||
|
||||
# Apply the cleanup script on each leaf in the old
|
||||
# generation. The find command below will print the
|
||||
# relative path of the entry.
|
||||
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
|
||||
| xargs -0 bash ${cleanup} "$newGenFiles"
|
||||
}
|
||||
|
||||
cleanOldGen
|
||||
linkNewGen
|
||||
''
|
||||
);
|
||||
|
||||
home.activation.checkFilesChanged = lib.hm.dag.entryBefore [ "linkGeneration" ] (
|
||||
@@ -427,18 +334,6 @@ in
|
||||
'') (lib.filter (v: v.onChange != "") cfg)
|
||||
);
|
||||
|
||||
home.internal.filePutterConfig =
|
||||
let
|
||||
putter = import ./lib/putter.nix { inherit lib; };
|
||||
manifest = putter.mkPutterManifest {
|
||||
inherit putterStatePath;
|
||||
sourceBaseDirectory = config.home-files;
|
||||
targetBaseDirectory = config.home.homeDirectory;
|
||||
fileEntries = cfg;
|
||||
};
|
||||
in
|
||||
pkgs.writeText "hm-putter.json" manifest;
|
||||
|
||||
# Symlink directories and files that have the right execute bit.
|
||||
# Copy files that need their execute bit changed.
|
||||
home-files =
|
||||
@@ -459,63 +354,6 @@ in
|
||||
# contain the recursion root, not the visited files.
|
||||
declare -A seenTargets
|
||||
|
||||
function setExecutableBit() {
|
||||
local target="$1"
|
||||
local executable="$2"
|
||||
|
||||
if [[ $executable == inherit ]]; then
|
||||
# Don't change file mode if it should match the source.
|
||||
:
|
||||
elif [[ $executable ]]; then
|
||||
chmod +x "$target"
|
||||
else
|
||||
chmod -x "$target"
|
||||
fi
|
||||
}
|
||||
|
||||
function insertFileEntry() {
|
||||
local source="$1"
|
||||
local target="$2"
|
||||
local executable="$3"
|
||||
local isExecutable
|
||||
|
||||
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||
|
||||
# Link the file into the home file directory if possible,
|
||||
# i.e., if the executable bit of the source is the same we
|
||||
# expect for the target. Otherwise, we copy the file and
|
||||
# set the executable bit to the expected value.
|
||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||
ln -s "$source" "$target"
|
||||
else
|
||||
cp "$source" "$target"
|
||||
setExecutableBit "$target" "$executable"
|
||||
fi
|
||||
}
|
||||
|
||||
function setLinkedFileExecutableBit() {
|
||||
local target="$1"
|
||||
local executable="$2"
|
||||
local isExecutable
|
||||
|
||||
if [[ -d $target || ! -e $target ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
[[ -x $target ]] && isExecutable=1 || isExecutable=""
|
||||
|
||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local tmp
|
||||
tmp="$(mktemp "$target.XXXXXX")"
|
||||
|
||||
cp "$target" "$tmp"
|
||||
setExecutableBit "$tmp" "$executable"
|
||||
mv -f "$tmp" "$target"
|
||||
}
|
||||
|
||||
function insertFile() {
|
||||
local source="$1"
|
||||
local relTarget="$2"
|
||||
@@ -571,19 +409,30 @@ in
|
||||
else
|
||||
lndir -silent "$source" "$target"
|
||||
fi
|
||||
|
||||
if [[ $executable != inherit ]]; then
|
||||
local linkedFile
|
||||
|
||||
while IFS= read -r -d "" linkedFile; do
|
||||
setLinkedFileExecutableBit "$linkedFile" "$executable"
|
||||
done < <(find "$target" \( -type f -or -type l \) -print0)
|
||||
fi
|
||||
else
|
||||
ln -s "$source" "$target"
|
||||
fi
|
||||
else
|
||||
insertFileEntry "$source" "$target" "$executable"
|
||||
[[ -x $source ]] && isExecutable=1 || isExecutable=""
|
||||
|
||||
# Link the file into the home file directory if possible,
|
||||
# i.e., if the executable bit of the source is the same we
|
||||
# expect for the target. Otherwise, we copy the file and
|
||||
# set the executable bit to the expected value.
|
||||
if [[ $executable == inherit || $isExecutable == $executable ]]; then
|
||||
ln -s "$source" "$target"
|
||||
else
|
||||
cp "$source" "$target"
|
||||
|
||||
if [[ $executable == inherit ]]; then
|
||||
# Don't change file mode if it should match the source.
|
||||
:
|
||||
elif [[ $executable ]]; then
|
||||
chmod +x "$target"
|
||||
else
|
||||
chmod -x "$target"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
''
|
||||
|
||||
@@ -32,7 +32,7 @@ for sourcePath in "$@" ; do
|
||||
warnEcho "Existing file '$targetPath' is in the way of '$sourcePath', will be skipped since they are the same"
|
||||
elif [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_COMMAND" ]] ; then
|
||||
# Next, try to run the custom backup command. Assume this always succeeds.
|
||||
verboseEcho "Existing file '$targetPath' exists and differs from '$sourcePath'. '$HOME_MANAGER_BACKUP_COMMAND' will be used to backup the file."
|
||||
verboseEcho "Existing file '$targetPath' exists and differs from '$sourcePath'. `$HOME_MANAGER_BACKUP_COMMAND` will be used to backup the file."
|
||||
elif [[ ! -L "$targetPath" && -n "$HOME_MANAGER_BACKUP_EXT" ]] ; then
|
||||
# Next, try to move the file to a backup location if configured and possible
|
||||
backup="$targetPath.$HOME_MANAGER_BACKUP_EXT"
|
||||
|
||||
@@ -184,62 +184,38 @@ in
|
||||
|
||||
options = {
|
||||
home.username = mkOption {
|
||||
type = types.nonEmptyStr;
|
||||
defaultText = lib.literalMD ''
|
||||
`$USER`, for state version < 20.09,
|
||||
undefined, otherwise.
|
||||
type = types.str;
|
||||
defaultText = literalExpression ''
|
||||
"$USER" for state version < 20.09,
|
||||
undefined for state version ≥ 20.09
|
||||
'';
|
||||
example = "jane.doe";
|
||||
description = ''
|
||||
The user's username.
|
||||
|
||||
If Home Manager is installed as a NixOS or nix-darwin submodule, it is
|
||||
set to `osConfig.users.users.<name>.name`.
|
||||
'';
|
||||
description = "The user's username.";
|
||||
};
|
||||
|
||||
home.uid = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 1000;
|
||||
description = ''
|
||||
The user's uid.
|
||||
|
||||
If Home Manager is installed as a NixOS or nix-darwin submodule, it is
|
||||
set to `osConfig.users.users.<name>.uid`.
|
||||
'';
|
||||
description = "The user's uid.";
|
||||
};
|
||||
|
||||
home.homeDirectory = mkOption {
|
||||
type = types.path;
|
||||
defaultText = lib.literalMD ''
|
||||
`$HOME`, for state version < 20.09
|
||||
undefined, otherwise.
|
||||
defaultText = literalExpression ''
|
||||
"$HOME" for state version < 20.09,
|
||||
undefined for state version ≥ 20.09
|
||||
'';
|
||||
apply = toString;
|
||||
example = "/home/jane.doe";
|
||||
description = ''
|
||||
The user's home directory. Must be an absolute path.
|
||||
|
||||
If Home Manager is installed as a NixOS or nix-darwin submodule, it is
|
||||
set to `osConfig.users.users.<name>.home`.
|
||||
'';
|
||||
description = "The user's home directory. Must be an absolute path.";
|
||||
};
|
||||
|
||||
home.profileDirectory = mkOption {
|
||||
type = types.path;
|
||||
default =
|
||||
if config.submoduleSupport.enable && config.submoduleSupport.externalPackageInstall then
|
||||
"/etc/profiles/per-user/${cfg.username}"
|
||||
else if config.nix.useXdg then
|
||||
"${config.xdg.stateHome}/nix/profile"
|
||||
else
|
||||
cfg.homeDirectory + "/.nix-profile";
|
||||
defaultText = lib.literalMD ''
|
||||
- `/etc/profiles/per-user/''${home.username}`, if Home Manager is installed as
|
||||
a submodule and `home-manager.useUserPackages` is enabled, else
|
||||
- `''${xdg.stateHome}/nix/profile`, if `nix.useXdg` is enabled, else
|
||||
- `''${home.homeDirectory}/.nix-profile`.
|
||||
defaultText = literalExpression ''
|
||||
"''${home.homeDirectory}/.nix-profile" or
|
||||
"/etc/profiles/per-user/''${home.username}"
|
||||
'';
|
||||
readOnly = true;
|
||||
description = ''
|
||||
@@ -290,15 +266,12 @@ in
|
||||
default = { };
|
||||
type =
|
||||
with types;
|
||||
lazyAttrsOf (
|
||||
nullOr (oneOf [
|
||||
str
|
||||
path
|
||||
int
|
||||
float
|
||||
bool
|
||||
])
|
||||
);
|
||||
lazyAttrsOf (oneOf [
|
||||
str
|
||||
path
|
||||
int
|
||||
float
|
||||
]);
|
||||
example = {
|
||||
EDITOR = "emacs";
|
||||
GS_OPTIONS = "-sPAPERSIZE=a4";
|
||||
@@ -334,9 +307,6 @@ in
|
||||
BAR = "''${config.home.sessionVariables.FOO} World!";
|
||||
};
|
||||
```
|
||||
|
||||
Setting a value to `null` will skip setting the variable at all, which
|
||||
may be useful when overriding.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -593,6 +563,17 @@ in
|
||||
};
|
||||
|
||||
config = {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.home.username != "";
|
||||
message = "Username could not be determined";
|
||||
}
|
||||
{
|
||||
assertion = config.home.homeDirectory != "";
|
||||
message = "Home directory could not be determined";
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
let
|
||||
hmRelease = config.home.version.release;
|
||||
@@ -634,6 +615,14 @@ in
|
||||
lib.mkDefault (builtins.getEnv "HOME")
|
||||
);
|
||||
|
||||
home.profileDirectory =
|
||||
if config.submoduleSupport.enable && config.submoduleSupport.externalPackageInstall then
|
||||
"/etc/profiles/per-user/${cfg.username}"
|
||||
else if config.nix.useXdg then
|
||||
"${config.xdg.stateHome}/nix/profile"
|
||||
else
|
||||
cfg.homeDirectory + "/.nix-profile";
|
||||
|
||||
programs.bash.shellAliases = cfg.shellAliases;
|
||||
programs.zsh.shellAliases = cfg.shellAliases;
|
||||
programs.fish.shellAliases = cfg.shellAliases;
|
||||
@@ -662,7 +651,7 @@ in
|
||||
destination = "/etc/profile.d/hm-session-vars.sh";
|
||||
text = ''
|
||||
# Only source this once.
|
||||
if [ -n "''${__HM_SESS_VARS_SOURCED-}" ]; then return; fi
|
||||
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
|
||||
export __HM_SESS_VARS_SOURCED=1
|
||||
|
||||
${config.lib.shell.exportAll cfg.sessionVariables}
|
||||
@@ -917,7 +906,6 @@ in
|
||||
--subst-var-by GENERATION_DIR $out
|
||||
|
||||
ln -s ${config.home-files} $out/home-files
|
||||
ln -s ${config.home.internal.filePutterConfig} $out/putter.json
|
||||
ln -s ${cfg.path} $out/home-path
|
||||
|
||||
cp "$extraDependenciesPath" "$out/extra-dependencies"
|
||||
|
||||
@@ -46,6 +46,7 @@ let
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
da157
|
||||
kranzes
|
||||
];
|
||||
|
||||
|
||||
@@ -10,16 +10,6 @@ let
|
||||
fcitx5Package = cfg.fcitx5-with-addons.override { inherit (cfg) addons; };
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
iniGlobalFormat = pkgs.formats.iniWithGlobalSection { };
|
||||
normalizeFcitx5Value =
|
||||
value:
|
||||
if lib.isAttrs value then
|
||||
lib.mapAttrs (_: normalizeFcitx5Value) value
|
||||
else if builtins.isList value then
|
||||
map normalizeFcitx5Value value
|
||||
else if builtins.isBool value then
|
||||
if value then "True" else "False"
|
||||
else
|
||||
value;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@@ -53,10 +43,12 @@ in
|
||||
quickPhrase = lib.mkOption {
|
||||
type = with lib.types; attrsOf str;
|
||||
default = { };
|
||||
example = {
|
||||
smile = "(・∀・)";
|
||||
angry = "( ̄ー ̄)";
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
smile = "(・∀・)";
|
||||
angry = "( ̄ー ̄)";
|
||||
}
|
||||
'';
|
||||
description = "Quick phrases.";
|
||||
};
|
||||
|
||||
@@ -81,16 +73,18 @@ in
|
||||
description = ''
|
||||
The global options in `config` file in ini format.
|
||||
'';
|
||||
example = {
|
||||
Behavior = {
|
||||
ActiveByDefault = false;
|
||||
};
|
||||
Hotkey = {
|
||||
EnumerateWithTriggerKeys = true;
|
||||
EnumerateSkipFirst = false;
|
||||
ModifierOnlyKeyTimeout = 250;
|
||||
};
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
Behavior = {
|
||||
ActiveByDefault = false;
|
||||
};
|
||||
Hotkey = {
|
||||
EnumerateWithTriggerKeys = true;
|
||||
EnumerateSkipFirst = false;
|
||||
ModifierOnlyKeyTimeout = 250;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
inputMethod = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
@@ -100,16 +94,18 @@ in
|
||||
description = ''
|
||||
The input method configure in `profile` file in ini format.
|
||||
'';
|
||||
example = {
|
||||
GroupOrder."0" = "Default";
|
||||
"Groups/0" = {
|
||||
Name = "Default";
|
||||
"Default Layout" = "us";
|
||||
DefaultIM = "pinyin";
|
||||
};
|
||||
"Groups/0/Items/0".Name = "keyboard-us";
|
||||
"Groups/0/Items/1".Name = "pinyin";
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
GroupOrder."0" = "Default";
|
||||
"Groups/0" = {
|
||||
Name = "Default";
|
||||
"Default Layout" = "us";
|
||||
DefaultIM = "pinyin";
|
||||
};
|
||||
"Groups/0/Items/0".Name = "keyboard-us";
|
||||
"Groups/0/Items/1".Name = "pinyin";
|
||||
}
|
||||
'';
|
||||
};
|
||||
addons = lib.mkOption {
|
||||
type = with lib.types; (attrsOf iniGlobalFormat.type);
|
||||
@@ -118,10 +114,12 @@ in
|
||||
The addon configures in `conf` folder in ini format with global sections.
|
||||
Each item is written to the corresponding file.
|
||||
'';
|
||||
example = {
|
||||
classicui.globalSection.Theme = "example";
|
||||
pinyin.globalSection.EmojiEnabled = "True";
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
classicui.globalSection.Theme = "example";
|
||||
pinyin.globalSection.EmojiEnabled = "True";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -233,12 +231,11 @@ in
|
||||
lib.optionalAttrs (v != { }) {
|
||||
${p} = f "fcitx5-${builtins.replaceStrings [ "/" ] [ "-" ] p}" v;
|
||||
};
|
||||
|
||||
entries = lib.attrsets.mergeAttrsList [
|
||||
(optionalFile "config" iniFormat.generate (normalizeFcitx5Value cfg.settings.globalOptions))
|
||||
(optionalFile "profile" iniFormat.generate (normalizeFcitx5Value cfg.settings.inputMethod))
|
||||
(optionalFile "config" iniFormat.generate cfg.settings.globalOptions)
|
||||
(optionalFile "profile" iniFormat.generate cfg.settings.inputMethod)
|
||||
(lib.concatMapAttrs (
|
||||
name: value: optionalFile "conf/${name}.conf" iniGlobalFormat.generate (normalizeFcitx5Value value)
|
||||
name: value: optionalFile "conf/${name}.conf" iniGlobalFormat.generate value
|
||||
) cfg.settings.addons)
|
||||
];
|
||||
in
|
||||
@@ -261,7 +258,7 @@ in
|
||||
else if builtins.isString attrs.theme then
|
||||
pkgs.writeText "fcitx5-theme.conf" attrs.theme
|
||||
else
|
||||
iniFormat.generate "fcitx5-${name}-theme" (normalizeFcitx5Value attrs.theme)
|
||||
iniFormat.generate "fcitx5-${name}-theme" attrs.theme
|
||||
))
|
||||
]
|
||||
) cfg.themes;
|
||||
|
||||
+55
-275
@@ -14,55 +14,33 @@ let
|
||||
dstDir = "${config.home.homeDirectory}/Library/LaunchAgents";
|
||||
|
||||
launchdConfig =
|
||||
{ name, config, ... }:
|
||||
{ config, name, ... }:
|
||||
{
|
||||
options = {
|
||||
enable = lib.mkEnableOption name;
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"gui"
|
||||
"user"
|
||||
];
|
||||
default = "gui";
|
||||
example = "user";
|
||||
description = ''
|
||||
The launchd domain to bootstrap this agent into.
|
||||
|
||||
The `gui` domain is appropriate for agents that need the user's
|
||||
Aqua session, such as window managers, hotkey daemons, and other
|
||||
graphical tools. The `user` domain is appropriate for background
|
||||
services that do not require a graphical login session.
|
||||
'';
|
||||
};
|
||||
config = lib.mkOption {
|
||||
type = lib.types.submodule (import ./launchd.nix);
|
||||
default = { };
|
||||
example = {
|
||||
ProgramArguments = [
|
||||
"/usr/bin/say"
|
||||
"Good afternoon"
|
||||
];
|
||||
StartCalendarInterval = [
|
||||
{
|
||||
Hour = 12;
|
||||
Minute = 0;
|
||||
}
|
||||
];
|
||||
};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
ProgramArguments = [ "/usr/bin/say" "Good afternoon" ];
|
||||
StartCalendarInterval = [
|
||||
{
|
||||
Hour = 12;
|
||||
Minute = 0;
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Define a launchd job. See {manpage}`launchd.plist(5)` for details.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
config.Label = lib.mkDefault "${labelPrefix}${name}";
|
||||
}
|
||||
(lib.mkIf (config.domain == "user") {
|
||||
config.LimitLoadToSessionType = lib.mkDefault "Background";
|
||||
})
|
||||
];
|
||||
config = {
|
||||
config.Label = lib.mkDefault "${labelPrefix}${name}";
|
||||
};
|
||||
};
|
||||
|
||||
# mutateConfig calls /bin/sh with /bin/wait4path to wait for /nix/store before
|
||||
@@ -91,16 +69,9 @@ let
|
||||
toAgent =
|
||||
config: pkgs.writeText "${config.Label}.plist" (toPlist { escape = true; } (mutateConfig config));
|
||||
|
||||
agentPlists = lib.mapAttrs' (
|
||||
_n: v: lib.nameValuePair "${v.config.Label}.plist" (toAgent v.config)
|
||||
) (lib.filterAttrs (_n: v: v.enable) cfg.agents);
|
||||
|
||||
agentDomains = lib.mapAttrs' (
|
||||
_n: v:
|
||||
lib.nameValuePair "${v.config.Label}.domain" (
|
||||
pkgs.writeText "${v.config.Label}.domain" "${v.domain}\n"
|
||||
)
|
||||
) (lib.filterAttrs (_n: v: v.enable) cfg.agents);
|
||||
agentPlists = lib.mapAttrs' (n: v: lib.nameValuePair "${v.config.Label}.plist" (toAgent v.config)) (
|
||||
lib.filterAttrs (n: v: v.enable) cfg.agents
|
||||
);
|
||||
|
||||
agentsDrv = pkgs.runCommand "home-manager-agents" { } ''
|
||||
mkdir -p "$out"
|
||||
@@ -115,20 +86,6 @@ let
|
||||
ln -s "$src" "$out/$dest"
|
||||
done
|
||||
'';
|
||||
|
||||
agentDomainsDrv = pkgs.runCommand "home-manager-agent-domains" { } ''
|
||||
mkdir -p "$out"
|
||||
|
||||
declare -A domains
|
||||
domains=(${
|
||||
lib.concatStringsSep " " (lib.mapAttrsToList (name: value: "['${name}']='${value}'") agentDomains)
|
||||
})
|
||||
|
||||
for dest in "''${!domains[@]}"; do
|
||||
src="''${domains[$dest]}"
|
||||
ln -s "$src" "$out/$dest"
|
||||
done
|
||||
'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
@@ -171,7 +128,6 @@ in
|
||||
(lib.mkIf isDarwin {
|
||||
home.extraBuilderCommands = ''
|
||||
ln -s "${agentsDrv}" $out/LaunchAgents
|
||||
ln -s "${agentDomainsDrv}" $out/LaunchAgentDomains
|
||||
'';
|
||||
|
||||
# NOTE: Launch Agent configurations can't be symlinked from the Nix store
|
||||
@@ -179,53 +135,9 @@ in
|
||||
home.activation.setupLaunchAgents =
|
||||
lib.hm.dag.entryAfter [ "writeBoundary" ] # Bash
|
||||
''
|
||||
# Get the OS version to see if we can use --wait
|
||||
version="$(/usr/bin/sw_vers --productVersion | cut -d. -f 1)"
|
||||
|
||||
# Disable errexit to ensure we process all agents even if some fail
|
||||
set +e
|
||||
|
||||
readAgentDomain() {
|
||||
local domainsDir="$1"
|
||||
local agentName="$2"
|
||||
local domainFile="$domainsDir/$agentName.domain"
|
||||
|
||||
if [[ -n "$domainsDir" && -f "$domainFile" ]]; then
|
||||
local domainName
|
||||
domainName="$(<"$domainFile")"
|
||||
case "$domainName" in
|
||||
gui|user)
|
||||
printf '%s\n' "$domainName"
|
||||
;;
|
||||
*)
|
||||
printf 'gui\n'
|
||||
;;
|
||||
esac
|
||||
else
|
||||
printf 'gui\n'
|
||||
fi
|
||||
}
|
||||
|
||||
resolveDomain() {
|
||||
local domainName="$1"
|
||||
|
||||
case "$domainName" in
|
||||
gui)
|
||||
printf 'gui/%s\n' "$UID"
|
||||
;;
|
||||
user)
|
||||
printf 'user/%s\n' "$UID"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
agentIsLoaded() {
|
||||
local domain="$1"
|
||||
local agentName="$2"
|
||||
|
||||
run /bin/launchctl print "$domain/$agentName" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Stop an agent if it's running
|
||||
bootoutAgent() {
|
||||
local domain="$1"
|
||||
@@ -233,37 +145,24 @@ in
|
||||
|
||||
verboseEcho "Stopping agent '$domain/$agentName'..."
|
||||
local bootout_output
|
||||
|
||||
if [[ "$version" -ge "26" ]]; then
|
||||
if bootout_output=$(run /bin/launchctl bootout --wait "$domain/$agentName" 2>&1); then
|
||||
# --wait already makes sure it was unloaded (BUT we can only use it in >=26)
|
||||
return 0
|
||||
bootout_output=$(run /bin/launchctl bootout "$domain/$agentName" 2>&1) || {
|
||||
# Only show warning if it's not the common "No such process" error
|
||||
if [[ "$bootout_output" != *"No such process"* ]]; then
|
||||
warnEcho "Failed to stop agent '$domain/$agentName': $bootout_output"
|
||||
else
|
||||
verboseEcho "Agent '$domain/$agentName' was not running"
|
||||
fi
|
||||
else
|
||||
if bootout_output=$(run /bin/launchctl bootout "$domain/$agentName" 2>&1); then
|
||||
# Otherwise on <26 give the system a moment to fully unload the agent
|
||||
run sleep 1
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# At this point we know exit code is not 0 because otherwise we
|
||||
# would have returned by now
|
||||
|
||||
# Only show warning if it's not a common harmless error
|
||||
if [[ "$bootout_output" != *"No such process"* && "$bootout_output" != *"Domain does not support specified action"* ]]; then
|
||||
warnEcho "Failed to stop agent '$domain/$agentName': $bootout_output"
|
||||
return 1
|
||||
else
|
||||
verboseEcho "Agent '$domain/$agentName' was not running"
|
||||
return 2
|
||||
fi
|
||||
# Give the system a moment to fully unload the agent
|
||||
sleep 1
|
||||
}
|
||||
|
||||
installAgentFile() {
|
||||
installAndBootstrapAgent() {
|
||||
local srcPath="$1"
|
||||
local dstPath="$2"
|
||||
local agentName="$3"
|
||||
local domain="$3"
|
||||
local agentName="$4"
|
||||
|
||||
verboseEcho "Installing agent file to $dstPath"
|
||||
if ! run install -Dm444 -T "$srcPath" "$dstPath"; then
|
||||
@@ -271,17 +170,11 @@ in
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
bootstrapAgent() {
|
||||
local domain="$1"
|
||||
local dstPath="$2"
|
||||
local agentName="$3"
|
||||
|
||||
verboseEcho "Starting agent '$domain/$agentName'"
|
||||
local bootstrap_output
|
||||
bootstrap_output=$(run /bin/launchctl bootstrap "$domain" "$dstPath" 2>&1) || {
|
||||
local error_code=$?
|
||||
|
||||
if [[ "$bootstrap_output" == *"Bootstrap failed: 5: Input/output error"* ]]; then
|
||||
errorEcho "Failed to start agent '$domain/$agentName' with I/O error (code 5)"
|
||||
errorEcho "This typically happens when the agent wasn't unloaded before attempting to bootstrap the new agent."
|
||||
@@ -296,120 +189,42 @@ in
|
||||
return 0
|
||||
}
|
||||
|
||||
restoreAgent() {
|
||||
local oldSrcPath="$1"
|
||||
local dstPath="$2"
|
||||
local oldDomain="$3"
|
||||
local agentName="$4"
|
||||
|
||||
if [[ ! -f "$oldSrcPath" ]]; then
|
||||
warnEcho "Cannot restore previous agent '$oldDomain/$agentName', old file '$oldSrcPath' is missing"
|
||||
return 1
|
||||
fi
|
||||
|
||||
warnEcho "Restoring previous agent '$oldDomain/$agentName'"
|
||||
installAgentFile "$oldSrcPath" "$dstPath" "$agentName" \
|
||||
&& bootstrapAgent "$oldDomain" "$dstPath" "$agentName"
|
||||
}
|
||||
|
||||
processAgent() {
|
||||
local srcPath="$1"
|
||||
local dstDir="$2"
|
||||
local oldDir="$3"
|
||||
local oldDomainsDir="$4"
|
||||
local newDomainsDir="$5"
|
||||
local domain="$3"
|
||||
|
||||
local agentFile="''${srcPath##*/}"
|
||||
local agentName="''${agentFile%.plist}"
|
||||
local dstPath="$dstDir/$agentFile"
|
||||
local oldSrcPath=""
|
||||
local oldDomainName
|
||||
local newDomainName
|
||||
local oldDomain
|
||||
local newDomain
|
||||
local oldAgentBootedOut=0
|
||||
|
||||
oldDomainName="$(readAgentDomain "$oldDomainsDir" "$agentName")"
|
||||
newDomainName="$(readAgentDomain "$newDomainsDir" "$agentName")"
|
||||
oldDomain="$(resolveDomain "$oldDomainName")"
|
||||
newDomain="$(resolveDomain "$newDomainName")"
|
||||
if [[ -n "$oldDir" ]]; then
|
||||
oldSrcPath="$oldDir/$agentFile"
|
||||
fi
|
||||
|
||||
# Skip if unchanged
|
||||
if cmp -s "$srcPath" "$dstPath" && [[ "$oldDomainName" == "$newDomainName" ]]; then
|
||||
if agentIsLoaded "$newDomain" "$agentName"; then
|
||||
verboseEcho "Agent '$newDomain/$agentName' is already up-to-date"
|
||||
return 0
|
||||
else
|
||||
verboseEcho "Agent '$newDomain/$agentName' is up-to-date but not loaded"
|
||||
fi
|
||||
fi
|
||||
|
||||
verboseEcho "Processing agent '$newDomain/$agentName'"
|
||||
|
||||
# Stop/Unload agent if it's already running
|
||||
if [[ -f "$dstPath" ]]; then
|
||||
bootoutAgent "$oldDomain" "$agentName"
|
||||
case "$?" in
|
||||
0)
|
||||
oldAgentBootedOut=1
|
||||
;;
|
||||
2)
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ "$oldDomainName" != "$newDomainName" ]]; then
|
||||
bootoutAgent "$newDomain" "$agentName"
|
||||
case "$?" in
|
||||
0|2)
|
||||
;;
|
||||
*)
|
||||
if [[ "$oldAgentBootedOut" -eq 1 ]]; then
|
||||
restoreAgent "$oldSrcPath" "$dstPath" "$oldDomain" "$agentName"
|
||||
fi
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! installAgentFile "$srcPath" "$dstPath" "$agentName"; then
|
||||
if [[ "$oldAgentBootedOut" -eq 1 ]]; then
|
||||
restoreAgent "$oldSrcPath" "$dstPath" "$oldDomain" "$agentName"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
if bootstrapAgent "$newDomain" "$dstPath" "$agentName"; then
|
||||
if cmp -s "$srcPath" "$dstPath"; then
|
||||
verboseEcho "Agent '$agentName' is already up-to-date"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$oldAgentBootedOut" -eq 1 ]]; then
|
||||
restoreAgent "$oldSrcPath" "$dstPath" "$oldDomain" "$agentName"
|
||||
verboseEcho "Processing agent '$agentName'"
|
||||
|
||||
# Stop/Unload agent if it's already running
|
||||
if [[ -f "$dstPath" ]]; then
|
||||
bootoutAgent "$domain" "$agentName"
|
||||
fi
|
||||
|
||||
return 1
|
||||
installAndBootstrapAgent "$srcPath" "$dstPath" "$domain" "$agentName"
|
||||
# Note: We continue processing even if this agent fails
|
||||
return 0
|
||||
}
|
||||
|
||||
removeAgent() {
|
||||
local srcPath="$1"
|
||||
local dstDir="$2"
|
||||
local newDir="$3"
|
||||
local oldDomainsDir="$4"
|
||||
local domain="$4"
|
||||
|
||||
local agentFile="''${srcPath##*/}"
|
||||
local agentName="''${agentFile%.plist}"
|
||||
local dstPath="$dstDir/$agentFile"
|
||||
local domainName
|
||||
local domain
|
||||
|
||||
domainName="$(readAgentDomain "$oldDomainsDir" "$agentName")"
|
||||
domain="$(resolveDomain "$domainName")"
|
||||
|
||||
if [[ -e "$newDir/$agentFile" ]]; then
|
||||
verboseEcho "Agent '$agentName' still exists in new generation, skipping cleanup"
|
||||
@@ -428,32 +243,23 @@ in
|
||||
|
||||
# Stop and remove the agent
|
||||
bootoutAgent "$domain" "$agentName"
|
||||
case "$?" in
|
||||
0|2)
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
verboseEcho "Removing agent file '$dstPath'"
|
||||
if run rm -f $VERBOSE_ARG "$dstPath"; then
|
||||
verboseEcho "Successfully removed agent file for '$agentName'"
|
||||
else
|
||||
warnEcho "Failed to remove agent file '$dstPath'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
setupLaunchAgents() {
|
||||
local oldDir newDir oldDomainsDir newDomainsDir dstDir launchdStatus
|
||||
local oldDir newDir dstDir domain
|
||||
|
||||
newDir="$(readlink -m "$newGenPath/LaunchAgents")"
|
||||
newDomainsDir="$(readlink -m "$newGenPath/LaunchAgentDomains")"
|
||||
dstDir=${lib.escapeShellArg dstDir}
|
||||
launchdStatus=0
|
||||
domain="gui/$UID"
|
||||
|
||||
if [[ -n "''${oldGenPath:-}" ]]; then
|
||||
oldDir="$(readlink -m "$oldGenPath/LaunchAgents")"
|
||||
@@ -461,60 +267,34 @@ in
|
||||
verboseEcho "No previous LaunchAgents directory found"
|
||||
oldDir=""
|
||||
fi
|
||||
|
||||
oldDomainsDir="$(readlink -m "$oldGenPath/LaunchAgentDomains")"
|
||||
if [[ ! -d "$oldDomainsDir" ]]; then
|
||||
oldDomainsDir=""
|
||||
fi
|
||||
else
|
||||
oldDir=""
|
||||
oldDomainsDir=""
|
||||
fi
|
||||
|
||||
verboseEcho "Setting up LaunchAgents in $dstDir"
|
||||
if [[ ! -d "$dstDir" ]] && ! run mkdir -p "$dstDir"; then
|
||||
errorEcho "Failed to create LaunchAgents directory '$dstDir'"
|
||||
return 1
|
||||
fi
|
||||
[[ -d "$dstDir" ]] || run mkdir -p "$dstDir"
|
||||
|
||||
verboseEcho "Processing new/updated LaunchAgents..."
|
||||
while IFS= read -r srcPath; do
|
||||
processAgent "$srcPath" "$dstDir" "$oldDir" "$oldDomainsDir" "$newDomainsDir" \
|
||||
|| launchdStatus=1
|
||||
done < <(find -L "$newDir" -maxdepth 1 -name '*.plist' -type f)
|
||||
find -L "$newDir" -maxdepth 1 -name '*.plist' -type f | while read -r srcPath; do
|
||||
processAgent "$srcPath" "$dstDir" "$domain"
|
||||
done
|
||||
|
||||
# Skip cleanup if there's no previous generation
|
||||
if [[ -z "$oldDir" || ! -d "$oldDir" ]]; then
|
||||
if [[ "$launchdStatus" -ne 0 ]]; then
|
||||
errorEcho "Failed to activate one or more LaunchAgents"
|
||||
fi
|
||||
|
||||
verboseEcho "LaunchAgents setup complete"
|
||||
return "$launchdStatus"
|
||||
return
|
||||
fi
|
||||
|
||||
verboseEcho "Cleaning up removed LaunchAgents..."
|
||||
while IFS= read -r srcPath; do
|
||||
removeAgent "$srcPath" "$dstDir" "$newDir" "$oldDomainsDir" \
|
||||
|| launchdStatus=1
|
||||
done < <(find -L "$oldDir" -maxdepth 1 -name '*.plist' -type f)
|
||||
|
||||
if [[ "$launchdStatus" -ne 0 ]]; then
|
||||
errorEcho "Failed to activate one or more LaunchAgents"
|
||||
fi
|
||||
|
||||
return "$launchdStatus"
|
||||
find -L "$oldDir" -maxdepth 1 -name '*.plist' -type f | while read -r srcPath; do
|
||||
removeAgent "$srcPath" "$dstDir" "$newDir" "$domain"
|
||||
done
|
||||
}
|
||||
|
||||
launchdStatus=0
|
||||
setupLaunchAgents || launchdStatus=$?
|
||||
setupLaunchAgents
|
||||
|
||||
# Restore errexit
|
||||
set -e
|
||||
|
||||
if [[ "$launchdStatus" -ne 0 ]]; then
|
||||
exit "$launchdStatus"
|
||||
fi
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{ lib }:
|
||||
{
|
||||
# Converts a boolean to a yes/no string. This is used in lots of
|
||||
# configuration formats.
|
||||
|
||||
+24
-40
@@ -12,32 +12,20 @@
|
||||
let
|
||||
inherit (lib)
|
||||
all
|
||||
attrNames
|
||||
attrValues
|
||||
elem
|
||||
filter
|
||||
filterAttrs
|
||||
head
|
||||
hm
|
||||
isAttrs
|
||||
mapAttrs
|
||||
length
|
||||
tail
|
||||
toposort
|
||||
;
|
||||
|
||||
inherit (hm.dag)
|
||||
empty
|
||||
entriesBetween
|
||||
entryAfter
|
||||
entryBetween
|
||||
isEntry
|
||||
;
|
||||
in
|
||||
{
|
||||
empty = { };
|
||||
|
||||
isEntry = e: e ? data && e ? after && e ? before;
|
||||
isDag = dag: isAttrs dag && all isEntry (attrValues dag);
|
||||
isDag = dag: builtins.isAttrs dag && all hm.dag.isEntry (builtins.attrValues dag);
|
||||
|
||||
# Takes an attribute set containing entries built by entryAnywhere,
|
||||
# entryAfter, and entryBefore to a topologically sorted list of
|
||||
@@ -96,19 +84,16 @@ in
|
||||
# }
|
||||
# true
|
||||
topoSort =
|
||||
let
|
||||
before = a: b: elem a.name b.after;
|
||||
in
|
||||
dag:
|
||||
let
|
||||
names = attrNames dag;
|
||||
dagBefore = name: filter (n: elem name dag.${n}.before) names;
|
||||
dagBefore = dag: name: builtins.attrNames (filterAttrs (n: v: builtins.elem name v.before) dag);
|
||||
normalizedDag = mapAttrs (n: v: {
|
||||
name = n;
|
||||
inherit (v) data;
|
||||
after = v.after ++ dagBefore n;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
}) dag;
|
||||
sorted = toposort before (attrValues normalizedDag);
|
||||
before = a: b: builtins.elem a.name b.after;
|
||||
sorted = toposort before (builtins.attrValues normalizedDag);
|
||||
in
|
||||
if sorted ? result then
|
||||
{
|
||||
@@ -123,10 +108,10 @@ in
|
||||
entryBetween = before: after: data: { inherit data before after; };
|
||||
|
||||
# Create a DAG entry with no particular dependency information.
|
||||
entryAnywhere = entryBetween [ ] [ ];
|
||||
entryAnywhere = hm.dag.entryBetween [ ] [ ];
|
||||
|
||||
entryAfter = entryBetween [ ];
|
||||
entryBefore = before: entryBetween before [ ];
|
||||
entryAfter = hm.dag.entryBetween [ ];
|
||||
entryBefore = before: hm.dag.entryBetween before [ ];
|
||||
|
||||
# Given a list of entries, this function places them in order within the DAG.
|
||||
# Each entry is labeled "${tag}-${entry index}" and other DAG entries can be
|
||||
@@ -139,25 +124,24 @@ in
|
||||
let
|
||||
go =
|
||||
i: before: after: entries:
|
||||
let
|
||||
name = "${tag}-${toString i}";
|
||||
in
|
||||
if entries == [ ] then
|
||||
empty
|
||||
hm.dag.empty
|
||||
else if length entries == 1 then
|
||||
{
|
||||
"${name}" = hm.dag.entryBetween before after (head entries);
|
||||
}
|
||||
else
|
||||
let
|
||||
name = "${tag}-${toString i}";
|
||||
in
|
||||
if length entries == 1 then
|
||||
{
|
||||
"${name}" = entryBetween before after (head entries);
|
||||
}
|
||||
else
|
||||
{
|
||||
"${name}" = entryAfter after (head entries);
|
||||
}
|
||||
// go (i + 1) before [ name ] (tail entries);
|
||||
{
|
||||
"${name}" = hm.dag.entryAfter after (head entries);
|
||||
}
|
||||
// go (i + 1) before [ name ] (tail entries);
|
||||
in
|
||||
go 0;
|
||||
|
||||
entriesAnywhere = tag: entriesBetween tag [ ] [ ];
|
||||
entriesAfter = tag: entriesBetween tag [ ];
|
||||
entriesBefore = tag: before: entriesBetween tag before [ ];
|
||||
entriesAnywhere = tag: hm.dag.entriesBetween tag [ ] [ ];
|
||||
entriesAfter = tag: hm.dag.entriesBetween tag [ ];
|
||||
entriesBefore = tag: before: hm.dag.entriesBetween tag before [ ];
|
||||
}
|
||||
|
||||
@@ -5,14 +5,12 @@ rec {
|
||||
|
||||
assertions = import ./assertions.nix { inherit lib; };
|
||||
|
||||
booleans = import ./booleans.nix;
|
||||
booleans = import ./booleans.nix { inherit lib; };
|
||||
darwin = import ./darwin.nix { inherit lib; };
|
||||
deprecations = import ./deprecations.nix { inherit lib; };
|
||||
generators = import ./generators.nix { inherit lib; };
|
||||
git = import ./git.nix { inherit lib; };
|
||||
gvariant = import ./gvariant.nix { inherit lib; };
|
||||
maintainers = import ./maintainers.nix;
|
||||
mcp = import ./mcp.nix { inherit lib; };
|
||||
strings = import ./strings.nix { inherit lib; };
|
||||
types = import ./types.nix { inherit gvariant lib; };
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user