# Questions about Tracking issues

**URL:** https://discourse.nixos.org/t/questions-about-tracking-issues/80708
**Category:** Nixpkgs Architecture
**Created:** [October 23, 2026, 6:37pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708 "2026-10-23T18:37:03Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 23, 2026, 6:37pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/1 "2026-10-23T18:37:03Z")

</div>

I’m interested in getting `finalAttrs` pushed more across `nixpkgs`, especially in cases like this where it fixes potential AppImage double extraction ([thanks](https://github.com/NixOS/nixpkgs/pull/498806) @uku3lig!):

> <https://github.com/NixOS/nixpkgs/pull/553377>
>
> This pull request refactors multiple Nix package definitions for AppImage-based …applications to use a more modern and consistent pattern with \`appimageTools.wrapType2\`. The main focus is on improving maintainability and reducing code duplication by eliminating manual extraction of AppImage contents and standardizing the use of \`finalAttrs\`. No functional changes to the packaged applications are intended.
> 
> Key changes by theme:
> 
> \*\*Migration to \`appimageTools.wrapType2\` and \`finalAttrs\`:\*\*
> \* Refactored all affected packages to use \`appimageTools.wrapType2 (finalAttrs: { ... })\` instead of the previous \`let ... in appimageTools.wrapType2 { ... }\` pattern, removing manual extraction (\`appimageTools.extract\`) and direct attribute passing (\`inherit pname version src\`). This brings consistency and leverages the more robust attribute set provided by \`finalAttrs\`. \[\[1\]\](diffhunk://#diff-2282dd71e981c4d8ae0b455d9bdbd3816522bf7efa32c79860d4bace0856d8deL8-R26) \[\[2\]\](diffhunk://#diff-d6d1bd9ca7e87b8babe91ad60c37cd353d380d2e21ebc2d85ed5608f2bf76cffL8-R22) \[\[3\]\](diffhunk://#diff-8b382cd33cd86e337c55a8ab0ecf102a14e0cf99dbf1be0ff7aab91bbb7aa3d4L6-R7) \[\[4\]\](diffhunk://#diff-df2afd4dcbc46f64747fee8685d575c98d88e6719baf9ea950495201f17b12cfL8-L36) \[\[5\]\](diffhunk://#diff-e625e8a8a3064459943959084e0c378e86360ba4188858bd11363722075c95fbL7-R19) \[\[6\]\](diffhunk://#diff-edf871fe4d22fd41fdbaed06517b94be110bb65ad84625ceebdd9846ee6e4dd7L3-R19) \[\[7\]\](diffhunk://#diff-4cf5a7e5eca240bfe78f85d47d40877b757501c91432963492613f77d4c974a6L7-R23) \[\[8\]\](diffhunk://#diff-b9c1ac2e1e9d721c230f6fa954afee6944a85739f8639cf869110867f4160bbaL7-R21) \[\[9\]\](diffhunk://#diff-c14b1b5fe0f4cf325df763f6000397571d6346b89ff9f96e07d6a46844613356L7-R26) \[\[10\]\](diffhunk://#diff-905beab46f6d65cf5754451b2d520dab9599596470e344e74a6d6540aa4641baL7-R22) \[\[11\]\](diffhunk://#diff-8f904ff150fac950788fc8bcc2c75c00d6e40729c22ab38a2ad6006f1cdd8af8R29-R48)
> 
> \*\*Standardization of variable usage:\*\*
> \* Updated all references to \`version\`, \`pname\`, and extracted contents to use \`finalAttrs.version\`, \`finalAttrs.contents\`, etc., ensuring that all dynamic attributes are consistently sourced from the final attribute set. \[\[1\]\](diffhunk://#diff-2282dd71e981c4d8ae0b455d9bdbd3816522bf7efa32c79860d4bace0856d8deL8-R26) \[\[2\]\](diffhunk://#diff-d6d1bd9ca7e87b8babe91ad60c37cd353d380d2e21ebc2d85ed5608f2bf76cffL8-R22) \[\[3\]\](diffhunk://#diff-8b382cd33cd86e337c55a8ab0ecf102a14e0cf99dbf1be0ff7aab91bbb7aa3d4L19-R25) \[\[4\]\](diffhunk://#diff-df2afd4dcbc46f64747fee8685d575c98d88e6719baf9ea950495201f17b12cfL53-R50) \[\[5\]\](diffhunk://#diff-e625e8a8a3064459943959084e0c378e86360ba4188858bd11363722075c95fbL7-R19) \[\[6\]\](diffhunk://#diff-edf871fe4d22fd41fdbaed06517b94be110bb65ad84625ceebdd9846ee6e4dd7L3-R19) \[\[7\]\](diffhunk://#diff-4cf5a7e5eca240bfe78f85d47d40877b757501c91432963492613f77d4c974a6L7-R23) \[\[8\]\](diffhunk://#diff-b9c1ac2e1e9d721c230f6fa954afee6944a85739f8639cf869110867f4160bbaL7-R21) \[\[9\]\](diffhunk://#diff-c14b1b5fe0f4cf325df763f6000397571d6346b89ff9f96e07d6a46844613356L7-R26) \[\[10\]\](diffhunk://#diff-905beab46f6d65cf5754451b2d520dab9599596470e344e74a6d6540aa4641baL7-R22) \[\[11\]\](diffhunk://#diff-8f904ff150fac950788fc8bcc2c75c00d6e40729c22ab38a2ad6006f1cdd8af8R29-R48)
> 
> \*\*Simplification and modernization of desktop integration:\*\*
> \* Replaced manual desktop item creation and icon installation to use the new pattern, updating paths and commands to use \`finalAttrs.contents\` and ensuring all substitutions and file operations are robust (e.g., using \`--replace-fail\`). \[\[1\]\](diffhunk://#diff-2282dd71e981c4d8ae0b455d9bdbd3816522bf7efa32c79860d4bace0856d8deL8-R26) \[\[2\]\](diffhunk://#diff-d6d1bd9ca7e87b8babe91ad60c37cd353d380d2e21ebc2d85ed5608f2bf76cffL8-R22) \[\[3\]\](diffhunk://#diff-8b382cd33cd86e337c55a8ab0ecf102a14e0cf99dbf1be0ff7aab91bbb7aa3d4L19-R25) \[\[4\]\](diffhunk://#diff-df2afd4dcbc46f64747fee8685d575c98d88e6719baf9ea950495201f17b12cfL53-R50) \[\[5\]\](diffhunk://#diff-e625e8a8a3064459943959084e0c378e86360ba4188858bd11363722075c95fbL7-R19) \[\[6\]\](diffhunk://#diff-edf871fe4d22fd41fdbaed06517b94be110bb65ad84625ceebdd9846ee6e4dd7L3-R19) \[\[7\]\](diffhunk://#diff-4cf5a7e5eca240bfe78f85d47d40877b757501c91432963492613f77d4c974a6L7-R23) \[\[8\]\](diffhunk://#diff-b9c1ac2e1e9d721c230f6fa954afee6944a85739f8639cf869110867f4160bbaL7-R21) \[\[9\]\](diffhunk://#diff-c14b1b5fe0f4cf325df763f6000397571d6346b89ff9f96e07d6a46844613356L7-R26) \[\[10\]\](diffhunk://#diff-905beab46f6d65cf5754451b2d520dab9599596470e344e74a6d6540aa4641baL7-R22) \[\[11\]\](diffhunk://#diff-8f904ff150fac950788fc8bcc2c75c00d6e40729c22ab38a2ad6006f1cdd8af8R29-R48)
> 
> \*\*Meta attribute improvements:\*\*
> \* Updated \`meta.changelog\` and similar attributes to use \`finalAttrs.version\` for dynamic versioning in URLs, improving maintainability. \[\[1\]\](diffhunk://#diff-d6d1bd9ca7e87b8babe91ad60c37cd353d380d2e21ebc2d85ed5608f2bf76cffL39-R37) \[\[2\]\](diffhunk://#diff-e625e8a8a3064459943959084e0c378e86360ba4188858bd11363722075c95fbL35-R37) \[\[3\]\](diffhunk://#diff-b9c1ac2e1e9d721c230f6fa954afee6944a85739f8639cf869110867f4160bbaL33-R38)
> 
> \*\*Removal of redundant code and improved readability:\*\*
> \* Eliminated unnecessary \`let\` bindings, intermediate variables, and redundant code blocks, leading to cleaner and more maintainable package definitions. \[\[1\]\](diffhunk://#diff-2282dd71e981c4d8ae0b455d9bdbd3816522bf7efa32c79860d4bace0856d8deL42-R37) \[\[2\]\](diffhunk://#diff-d6d1bd9ca7e87b8babe91ad60c37cd353d380d2e21ebc2d85ed5608f2bf76cffL39-R37) \[\[3\]\](diffhunk://#diff-8b382cd33cd86e337c55a8ab0ecf102a14e0cf99dbf1be0ff7aab91bbb7aa3d4L44-R39) \[\[4\]\](diffhunk://#diff-8b382cd33cd86e337c55a8ab0ecf102a14e0cf99dbf1be0ff7aab91bbb7aa3d4L59-R54) \[\[5\]\](diffhunk://#diff-df2afd4dcbc46f64747fee8685d575c98d88e6719baf9ea950495201f17b12cfL68-R61) \[\[6\]\](diffhunk://#diff-e625e8a8a3064459943959084e0c378e86360ba4188858bd11363722075c95fbL35-R37) \[\[7\]\](diffhunk://#diff-edf871fe4d22fd41fdbaed06517b94be110bb65ad84625ceebdd9846ee6e4dd7L36-R31) \[\[8\]\](diffhunk://#diff-4cf5a7e5eca240bfe78f85d47d40877b757501c91432963492613f77d4c974a6L39-R37) \[\[9\]\](diffhunk://#diff-b9c1ac2e1e9d721c230f6fa954afee6944a85739f8639cf869110867f4160bbaL33-R38) \[\[10\]\](diffhunk://#diff-c14b1b5fe0f4cf325df763f6000397571d6346b89ff9f96e07d6a46844613356L47-R40) \[\[11\]\](diffhunk://#diff-905beab46f6d65cf5754451b2d520dab9599596470e344e74a6d6540aa4641baL36-R33) \[\[12\]\](diffhunk://#diff-8f904ff150fac950788fc8bcc2c75c00d6e40729c22ab38a2ad6006f1cdd8af8R29-R48)
> 
> 
> \## Things done
> 
> 
> 
> \- Built on platform:
> - \[x\] x86\_64-linux
> - \[\] aarch64-linux
> - \[\] aarch64-darwin
> \- Tested, as applicable:
> - \[\] \[NixOS tests\] in \[nixos/tests\].
> - \[\] \[Package tests\] at \`passthru.tests\`.
> - \[\] Tests in \[lib/tests\] or \[pkgs/test\] for functions and "core" functionality.
> \- \[x\] Ran \`nixpkgs-review\` on this PR. See \[nixpkgs-review usage\].
> \- \[x\] Tested basic functionality of all binary files, usually in \`./result/bin/\`.
> \- Nixpkgs Release Notes
> - \[\] Package update: when the change is major or breaking.
> \- NixOS Release Notes
> - \[\] Module addition: when adding a new NixOS module.
> - \[\] Module update: when the change is significant.
> \- \[x\] Fits \[CONTRIBUTING.md\], \[pkgs/README.md\], \[maintainers/README.md\] and other READMEs.
> \- \[x\] Follows the \[automation/AI policy\].
> 
> \[NixOS tests\]: https://nixos.org/manual/nixos/unstable/index.html#sec-nixos-tests
> \[Package tests\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#package-tests
> \[nixpkgs-review usage\]: https://github.com/Mic92/nixpkgs-review#usage
> 
> \[CONTRIBUTING.md\]: https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md
> \[automation/AI policy\]: https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#automationai-policy
> \[lib/tests\]: https://github.com/NixOS/nixpkgs/blob/master/lib/tests
> \[maintainers/README.md\]: https://github.com/NixOS/nixpkgs/blob/master/maintainers/README.md
> \[nixos/tests\]: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests
> \[pkgs/README.md\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md
> \[pkgs/test\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/test

Unfortunately, it seems like bulk PRs like this aren’t a good way to go, and creating 1 LLM-asissted PR for each package is just more spammy.

It seems like a sprintable tracking issue is the way to go for this specific case, but I have a few questions about making one:

- Is there any way to notify all maintainers of each package listed in a tracking issue?
- Should we even notify all the maintainers of listed packages in tracking issues?
- What about if you created an independently verifiable check that the new LLM-assisted `finalAttrs` output is the byte-for-byte identical (at least excluding embedded store paths) to the old `appimageTools.extract` pattern? Would a bulk PR/independent PR for each package be more likely to be accepted I was to do that?
  - Do we have any existing tools to help with this? I know that [Lila](https://github.com/nix-community/lila) recommends [diffoscope](https://diffoscope.org/) for reviewing diffs, but do we have any existing tools to compare the outputs of 2 different derivations w/o self output path noise?
    - Maybe I should make small script like this that subs out the self store paths and then runs diffoscope.

---

<div class="post-metadata">

### Author: ![tree-sapii](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tree-sapii/32/36774_2.png) [@tree-sapii](https://discourse.nixos.org/u/tree-sapii)
#### Post date: [October 23, 2026, 9:09pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/2 "2026-10-23T21:09:42Z")

</div>

1. You would have to manually ping them in the tracking issue, i have seen scripts used to create the issue desc
2. For finalattrs matters, maybe not, for something EOL, for sure
3. finalAttrs shound not change the closure at all iirc

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 23, 2026, 9:20pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/3 "2026-10-23T21:20:26Z")

</div>

> [@tree-sapii](#):
>
> 1. finalAttrs shound not change the closure at all iirc

Ah, there were some whitespace changes in the scripts for some of them (additional blank lines), which is why my agent-assisted diffoscope run of the PR I linked had some output path changes. I thought it might have some other changes, but apparently manual `extract` (usually, at least in the cases I checked) gets called with the same arguments that `wrapType2` does, so this is mostly just an overriding/cleanliness change.

---

<div class="post-metadata">

### Author: ![not-jack](https://discourse.nixos.org/user_avatar/discourse.nixos.org/not-jack/32/33123_2.png) [@not-jack](https://discourse.nixos.org/u/not-jack)
#### Post date: [October 23, 2026, 9:26pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/4 "2026-10-23T21:26:53Z")

</div>

I made this a few months ago: [jackr/finalAttrs-migrator: little project for funzies - Codeberg.org](https://codeberg.org/jackr/finalattrs-migrator) and landed [this PR](https://github.com/NixOS/nixpkgs/pull/510587) with it. Feel free to use it if it’s helpful 🙂

Be aware that it’s quite hard to land these PRs when they get large, since review is costly.

A more sophisticated approach would build an AST, as opposed to text replacement. I’ll be trying my hand at that in a few months probably.

---

<div class="post-metadata">

### Author: ![Sigmanificient](https://discourse.nixos.org/user_avatar/discourse.nixos.org/sigmanificient/32/10706_2.png) [@Sigmanificient](https://discourse.nixos.org/u/Sigmanificient)
#### Post date: [October 23, 2026, 9:46pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/5 "2026-10-23T21:46:58Z")

</div>

My rule of thumb with large scale migration is generally to avoid treewide when rebuild get involved or that the diff is not trivially predictible (with finalAttrs, I would have to look the entire package in cases there is a missing case). Thus I would personally split this one or keep up varous pr small. In any case, theses type of migration can be planned and spread on a long period to avoid spamming prs too much (this is also what was done with pyproject). We had good result with pinging maintainers on meta.changelog, but I think that it is preferable to not ask for modernization.

A good part of the finalAttrs is also happening within other type of cleanup or packages update. For instance with python “format” migration. I do like the approach of individual investigation, to take the time to do things properly, remove unwanted packages or catch problems (in the pyproject, we plenty of weird cases, even some unnoticed broken software…)

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 23, 2026, 9:50pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/6 "2026-10-23T21:50:11Z")

</div>

Neat, although a bit different then the specific `finalAttrs` use-case I’m targeting with AppImage support.  
I’ll go ahead and make a simple Tracking issue for all `appimageTools`-based packages not using `finalAttrs`, and clean them up and verify as I find the time. Just wanted to make sure I’m doing everything right here!

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 23, 2026, 10:07pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/7 "2026-10-23T22:07:11Z")

</div>

Made a tracking issue here:

> <https://github.com/NixOS/nixpkgs/issues/578068>
>
> After https://github.com/NixOS/nixpkgs/pull/498806, we can now use \`finalAttrs.c…ontents\` instead of manually invoking \`appimageTools.extract\`. This brings us the usual \`finalAttrs\` benefits, as well as reducing boilerplate when the extracted AppImage is needed.
> 
> \## Packages
> \- \[\] \`altair\`
> \- \[\] \`altus\`
> \- \[\] \`ankama-launcher\`
> \- \[\] \`apidog\`
> \- \[\] \`arduino-ide\`
> \- \[\] \`artisan\`
> \- \[\] \`artix-games-launcher\`
> \- \[\] \`betterdiscord-installer\`
> \- \[\] \`beyond-all-reason\`
> \- \[\] \`bloomrpc\`
> \- \[\] \`bootstrap-studio\`
> \- \[\] \`buckets\`
> \- \[\] \`buttercup-desktop\`
> \- \[\] \`cables\`
> \- \[\] \`caido-desktop\`
> \- \[\] \`capacities\`
> \- \[\] \`caprine-bin\`
> \- \[\] \`chatzone-desktop\`
> \- \[\] \`chrysalis\`
> \- \[\] \`cisco-packet-tracer\_9\`
> \- \[\] \`clash-nyanpasu\`
> \- \[\] \`clickup\`
> \- \[\] \`clockify\`
> \- \[\] \`codux\`
> \- \[\] \`cozy-drive\`
> \- \[\] \`cubelify\`
> \- \[\] \`cura-appimage\`
> \- \[\] \`dbgate\`
> \- \[\] \`deskreen\`
> \- \[\] \`electron-mail\`
> \- \[\] \`everdo\`
> \- \[\] \`fiddler-everywhere\`
> \- \[\] \`firefly-desktop\`
> \- \[\] \`fluent-reader\`
> \- \[\] \`freelens-bin\`
> \- \[\] \`ftb-app\`
> \- \[\] \`gdevelop\`
> \- \[\] \`golden-cheetah-bin\`
> \- \[\] \`gsender\`
> \- \[\] \`hamrs\`
> \- \[\] \`hamrs-pro\`
> \- \[\] \`hamsket\`
> \- \[\] \`handheld-daemon-ui\`
> \- \[\] \`heynote\`
> \- \[\] \`hifile\`
> \- \[\] \`hoppscotch\`
> \- \[\] \`httpie-desktop\`
> \- \[\] \`hydralauncher\`
> \- \[\] \`insomnia\`
> \- \[\] \`irccloud\`
> \- \[\] \`jan\`
> \- \[\] \`jbrowse\`
> \- \[\] \`jet-pilot\`
> \- \[\] \`kchat\`
> \- \[\] \`keet\`
> \- \[\] \`kirimoto\`
> \- \[\] \`kmeet\`
> \- \[\] \`krunker\`
> \- \[\] \`labymod-launcher\`
> \- \[\] \`ledger-live-desktop\`
> \- \[\] \`lens\`
> \- \[\] \`listen1\`
> \- \[\] \`lmath\`
> \- \[\] \`lmstudio\`
> \- \[\] \`lmstudio-bionic\`
> \- \[\] \`losslesscut-bin\`
> \- \[\] \`lunar-client\`
> \- \[\] \`lunatask\`
> \- \[\] \`mathpix-snipping-tool\`
> \- \[\] \`mobilecoin-wallet\`
> \- \[\] \`mochi\`
> \- \[\] \`mockoon\`
> \- \[\] \`molotov\`
> \- \[\] \`motrix\`
> \- \[\] \`mqttx\`
> \- \[\] \`muffon\`
> \- \[\] \`mycrypto\`
> \- \[\] \`nosql-booster\`
> \- \[\] \`nosql-workbench\`
> \- \[\] \`notable\`
> \- \[\] \`notesnook\`
> \- \[\] \`notion-app-enhanced\`
> \- \[\] \`nrfconnect\`
> \- \[\] \`nrfconnect-bluetooth-low-energy\`
> \- \[\] \`nuclear\`
> \- \[\] \`p3x-onenote\`
> \- \[\] \`parsify\`
> \- \[\] \`pinokio\`
> \- \[\] \`plexamp\`
> \- \[\] \`protonup-qt\`
> \- \[\] \`pureref\`
> \- \[\] \`qidi-slicer-bin\`
> \- \[\] \`qidi-studio\`
> \- \[\] \`quba\`
> \- \[\] \`rambox\`
> \- \[\] \`raven-reader\`
> \- \[\] \`redact\`
> \- \[\] \`requestly\`
> \- \[\] \`saleae-logic-2\`
> \- \[\] \`simplenote\`
> \- \[\] \`simplex-chat-desktop\`
> \- \[\] \`snipaste\`
> \- \[\] \`sonixd\`
> \- \[\] \`sozi\`
> \- \[\] \`spinshare\`
> \- \[\] \`ssb-patchwork\`
> \- \[\] \`steam-art-manager\`
> \- \[\] \`steam-rom-manager\`
> \- \[\] \`sunsama\`
> \- \[\] \`timeular\`
> \- \[\] \`trezor-suite\`
> \- \[\] \`trucky\`
> \- \[\] \`tutanota-desktop\`
> \- \[\] \`upscayl\`
> \- \[\] \`via\`
> \- \[\] \`vial\`
> \- \[\] \`vita3k\`
> \- \[\] \`volanta\`
> \- \[\] \`wootility\`
> \- \[\] \`wowup-cf\`
> \- \[\] \`xlights\`
> \- \[\] \`zecwallet-lite\`
> \- \[\] \`zettlr\`
> \- \[\] \`zoho-mail-desktop\`

---

<div class="post-metadata">

### Author: ![pbsds](https://discourse.nixos.org/user_avatar/discourse.nixos.org/pbsds/32/11198_2.png) [@pbsds](https://discourse.nixos.org/u/pbsds)
#### Post date: [October 24, 2026, 4:10pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/8 "2026-10-24T16:10:46Z")

</div>

I rarely see a benefit of using `finalAttrs` over `rec` or `let ... in`: it doesn’t make overriding `src` any easier.

The main pro i see is if you need to be able to react to overrides (e.g. in `passthru.tests`) or if you need access to `finalAttrs.finalPackage`. The con on the other hand is more expensive eval.

As such i don’t see the benefit or blindly migrating to it.

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 24, 2026, 4:24pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/9 "2026-10-24T16:24:21Z")

</div>

I’m just interested in this because `appimageContents = appimageTools.extract { inherit pname version src; };` is a common pattern and IMO `finalAttrs.contents` is cleaner.  
`finalAttrs.contents` also responds to `src` overrides, as opposed to `appimageTools.extract` in a `let` block.

---

<div class="post-metadata">

### Author: ![pbsds](https://discourse.nixos.org/user_avatar/discourse.nixos.org/pbsds/32/11198_2.png) [@pbsds](https://discourse.nixos.org/u/pbsds)
#### Post date: [October 24, 2026, 4:35pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/10 "2026-10-24T16:35:44Z")

</div>

In this case yes, `finalAttrs` is strictly beneficial 👍

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 24, 2026, 7:15pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/11 "2026-10-24T19:15:12Z")

</div>

Update: after a few very annoying hours with my coding agent, I was able to get an `ast-grep`-based treewide for some trivial cases ( ~~Still needs me to do a manual test to make sure that I didn’t break any packages with this~~ EDIT: 0 rebuilds! Although it did break [`nixpkgs-review`](https://github.com/Mic92/nixpkgs-review/issues/679#issuecomment-6388542562) 😉).

> <https://github.com/NixOS/nixpkgs/pull/578434>
>
> Ran this AI-generated \`ast-grep\` rule with \`ast-grep\` 0.51.0:
> \`\`\`yaml
> id: appi…mage-wraptype2-finalattrs
> language: Nix
> rule:
> pattern:
> context: |
> let
> pname = $PNAME;
> version = $VERSION;
> src = $SRC;
> appimageContents = appimageTools.extract { inherit pname version src; };
> in
> appimageTools.wrapType2 $ATTRSET
> selector: let\_expression
> # Exact AST shape rejects extra let bindings; comments remain match-significant.
> strictness: ast
> constraints:
> ATTRSET:
> # Keep only the common package inherit order.
> all:
> - kind: attrset\_expression
> - pattern: '{ inherit pname version src; $$$REST }'
> transform:
> # Resolve \`src\` in finalAttrs scope; rewrite references in package attrs.
> FINAL\_SRC:
> rewrite:
> source: $SRC
> rewriters:
> - finalattrs-pname
> - finalattrs-version
> - finalattrs-src
> - finalattrs-contents
> FINAL\_ATTRSET:
> rewrite:
> source: $ATTRSET
> rewriters:
> - remove-package-inherit
> - finalattrs-pname
> - finalattrs-version
> - finalattrs-src
> - finalattrs-contents
> FINAL\_ATTRS\_BODY:
> substring:
> source: $FINAL\_ATTRSET
> startChar: 1
> endChar: -2
> rewriters:
> # Remove only the package identity inherit; add those attrs in the root fix.
> - id: remove-package-inherit
> rule:
> pattern:
> context: '{ inherit pname version src; }'
> selector: inherit
> fix: ''
> # Rewrite variable references, not binding names or shell text.
> # These anchored regexes constrain captured AST variable expressions, not attrset structure.
> - id: finalattrs-pname
> rule:
> pattern: $REF
> kind: variable\_expression
> constraints:
> REF:
> regex: '^pname$'
> fix: finalAttrs.pname
> - id: finalattrs-version
> rule:
> pattern: $REF
> kind: variable\_expression
> constraints:
> REF:
> regex: '^version$'
> fix: finalAttrs.version
> - id: finalattrs-src
> rule:
> pattern: $REF
> kind: variable\_expression
> constraints:
> REF:
> regex: '^src$'
> fix: finalAttrs.src
> - id: finalattrs-contents
> rule:
> pattern: $REF
> kind: variable\_expression
> constraints:
> REF:
> regex: '^appimageContents$'
> fix: finalAttrs.contents
> fix: |-
> appimageTools.wrapType2 (finalAttrs: {
> pname = $PNAME;
> version = $VERSION;
> src = $FINAL\_SRC;
> $FINAL\_ATTRS\_BODY
> })
> \`\`\`
> (It took a REALLY LONG TIME to get this rule)
> Then I ran \`nix fmt\`.
> 
> Part of https://github.com/NixOS/nixpkgs/issues/578068.
> 
> \## Things done
> 
> 
> 
> \- \[x\] Fits \[CONTRIBUTING.md\], \[pkgs/README.md\], \[maintainers/README.md\] and other READMEs.
> \- \[x\] Follows the \[automation/AI policy\].
> \- Built on platform:
> - \[\] x86\_64-linux
> - \[\] aarch64-linux
> - \[\] aarch64-darwin
> \- Tested, as applicable:
> - \[\] Basic functionality of all binary files, usually in \`./result/bin/\`.
> - \[\] Ran \`nixpkgs-review\` on this PR. See \[nixpkgs-review usage\].
> - \[\] \[Package tests\] at \`passthru.tests\`.
> - \[\] \[NixOS tests\] in \[nixos/tests\].
> - \[\] Tests in \[lib/tests\] or \[pkgs/test\] for functions and "core" functionality.
> \- Nixpkgs Release Notes
> - \[\] Package update: when the change is major or breaking.
> \- NixOS Release Notes
> - \[\] Module addition: when adding a new NixOS module.
> - \[\] Module update: when the change is significant.
> 
> \[Package tests\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#package-tests
> \[NixOS tests\]: https://nixos.org/manual/nixos/unstable/index.html#sec-nixos-tests
> \[nixpkgs-review usage\]: https://github.com/Mic92/nixpkgs-review#usage
> 
> \[CONTRIBUTING.md\]: https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md
> \[automation/AI policy\]: https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#automationai-policy
> \[lib/tests\]: https://github.com/NixOS/nixpkgs/blob/master/lib/tests
> \[maintainers/README.md\]: https://github.com/NixOS/nixpkgs/blob/master/maintainers/README.md
> \[nixos/tests\]: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests
> \[pkgs/README.md\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md
> \[pkgs/test\]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/test

For the rest, I think that I’ll just get my coding agent to fix them in batch with more autonomous self-verification, then do a manual review of their changes and submit them to `nixpkgs` as I have the time to do review.

---

<div class="post-metadata">

### Author: ![pbsds](https://discourse.nixos.org/user_avatar/discourse.nixos.org/pbsds/32/11198_2.png) [@pbsds](https://discourse.nixos.org/u/pbsds)
#### Post date: [October 24, 2026, 7:23pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/12 "2026-10-24T19:23:40Z")

</div>

This prior art with treesitter might be of interest in the future [GitHub - Aleksanaa/by-name-migrate · GitHub](https://github.com/Aleksanaa/by-name-migrate) (it also has a neat open PR waiting to get merged)

---

<div class="post-metadata">

### Author: ![bitbloxhub](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bitbloxhub/32/35210_2.png) [@bitbloxhub](https://discourse.nixos.org/u/bitbloxhub)
#### Post date: [October 24, 2026, 7:36pm UTC](https://discourse.nixos.org/t/questions-about-tracking-issues/80708/13 "2026-10-24T19:36:18Z")

</div>

Neat, although not all cases are as clear-cut as these. I just thought I’d save tokens (given the amount of tokens it took to make that rule though, I’m not sure it succeeded) and time (definitely failed that one) by doing a simple AST migration for trivial cases, as most other cases are non-trivial (trivial by LLMs, but not by pure deterministic automation, at least not without building in 20 edge cases used by 1 package each).
