Patching package source code

I am looking for the best workflow for patching any package that is currently apart of my nix os config or I guess in the nix store.

For example say I install suckless’ simple terminal and now I want to write a patch for it.

How can I get access to the source code in a dev friendly manor so I can create a patch on the fly?

I come from a Yocto background so for Yocto devs I can describe what I’m looking for in the Yocto equivalent:

devtool modify <recipe>
cd build/workspace/<recipe>
echo hey > file
git add file
git commit -m “add file to codebase”
cd -
devtool finish <recipe> <layer-to-save-patches>

How can I have an equivalent workflow but for patching the nix packages that are currently in my nix store?

This workflow looks imperative. The way with nix is to override the package and provide patches or a different src even. Suckless in particular has patches as an override, so no need for overrideAttrs.

Sorry I guess wasn’t very clear about what that codeblock does. Yocto is very similar to nix as a way to declaratively build packages.

When I want to patch a codebase in Yocto I would use that workflow to get a temporary dev environment with the source code I want to build

devtool modify <recipe>
# fetch source code to build/workspace/<recipe>
# checkout exact revision

cd build/workspace/<recipe>
# go to temporary workspace to play with the code

echo hey > file
git add file
git commit -m “add file to codebase”
# Make modifications as a git commit

cd -
devtool finish <recipe> <layer-to-save-patches>
# automatically create a patch from the commits made
# add the patch so that the build system picks it up
# now I can source control the patch so that my changes are reproducible 

I have been able to patch st with the patches from their website but I want to be able to have a temporary workspace of the exact source code of the package so that I can create custom patches.

So far I have been getting by with just cloning the project, making changes, creating a patch and hoping the codebase is close enough to the one in nixpkgs for the patch to cleanly apply.

But that’s going to break at some point for bigger projects.

Nix knows where to get the source code and which revision to use so I was wondering if nix provided a way to get a temporary workspace of the exact source so that I can create patches from that.

Nix often, but doesn’t necessarily, have a way to get at the source control repository for a given package. Usually it downloads a tarball instead, and if it gets that from something that isn’t a repo (like an FTP mirror for example, as is common for GNU projects), then there’d be no fully automated way for you to get a repo from which to get a nice git diff.

If that isn’t important, a reliable way to get the exact source Nixpkgs uses would be to run nix-shell '<nixpkgs>' -A st (replace st with any other package, as desired), and then inside that shell, run runPhase unpackPhase && runPhase patchPhase.

1 Like

Reality with suckless is, that most users just maintain their fork and rebase their patches regularly.

The alternative if you want to stick to a list of patches, is of course to checkout exactly the tag used by nixpkgs, and build the patch on that.

Perfect! Thanks!

This is really close to what I was looking for, I remember at some point I was working on packaging an application with nix and I don’t remember the command but it created a result symlink to the build folder

Do you know if there is a way to also get a symlink to the source folder created from that nix-shell command?

Because I just ran it and it puts the source code in /nix/store/<hash>-source which is great because now I can go look at the exact source code but I’m inventivatbly going to forget that path.

If there is nothing to automatically create the symlink do you know if there is a way to get the path to the source code it put in the nix store so that I can create the symlink myself?

Thanks!

This depends on whether you want the source with or without the patches that Nixpkgs already applies. The path you found in the store is without; the only way to get the source with patches applied (if there are any!) is to run the patch phase, and the results of that don’t end up in the store. You might care if the patch you’d be writing might conflict with a patch Nixpkgs ships.

If you don’t care about Nixpkgs patches, then there is an even easier thing you can do: nix-build '<nixpkgs>' -A st.src, with the usual --out-link/--no-out-link options to control symlink creation.

1 Like

Thank you so much! This is exactly what I was looking for, thanks!

1 Like