Hello developers! "PROBLEM"SCOPE In https://guix.gnu.org/cookbook/en/guix-cookbook.html#Software-Development there is a nice guide to use Guix for local development on software projects, and also build it directly using `guix build -f guix.scm`. It says: > The whole point of building with Guix is that it’s a “clean” build > — you can be sure nothing from your working tree or system interferes with > the build result — and it lets you test a variety of things.
I think the current guide can have some surprising results (see 'envisioned behaviours') AND can be extended to have a more comfortable local development flow (as seen by various adaptations in real-world usages of 'guix.scm'). Sounds maybe heavy, but I'm actually only talking about minor adaptations to (package (source ...) ; Give different choices with unsurprising (or documented) results (version ...) ; Make more meaningful than 'git' or 'checkout' (properties ...)) ; (if needed) For the (version) part, this proposal is driven by my need for better traceability of ad-hoc build artifacts and by the adaptations seen 'in the wild'. Aka: just being generally less confused when looking at multiple derivations of the same local repo, varying only by a hash. PROPOSED CHANGES / ENVISIONED BEHAVIOURS: * source: There are multiple possibilities when including the build source * clean build of the current VCS checkout (commit HEAD is pointing to) * Possible behaviour: use '--with-source' https://lists.gnu.org/archive/html/guix-devel/2019-07/msg00111.html The solution from Ludo might work (didn't test), but it's still a good example why we want to improve documentation, providing some options. * build of current VCS checkout, any updates to files IN THE CHECKOUT are included (current behaviour. Since modified files are included, you might forget & get surprised that newly created files are not included.) * build of current VCS checkout, all non-ignored files are included - especially newly added files (I'm unsure if there are more possible differences besides added files) * Add all files from the repo root (const #t) * version Instead of (source) depending on (version) like for packages in guix, I would invert this dependency for developing on local packages: let (version) depend on (source) (the VCS repo) AND maybe (inputs) It should look similar to `git describe --always --dirty --long` * get version from VCS => '<tag>' * get revision from VCS => '<n commits since tag>' OR 'HEAD' * do we need a hash prefix depending on the VCS? Like `git describe` does... * get commit/state from VCS => '<truncated hash>' * if working tree in 'dirty' state (get from VCS) => '-dirty' * if working tree 'clean', but dependencies (inputs) are dirty => '-dirty-deps' * This would really be a nice bonus * Would probably need to use the properties field: (properties '((dirty . #t))) IF package is dirty or has dirty dependencies * properties * only used as a tool to cascade the information of a dirty package when working on multiple local packages depending on each other. Maybe not needed. Of course, this should all remain usable when the same file is used for a channel in the same repo (next step in the guide). When used/build in the channel, the version can never be 'dirty' and the different options for (source) should amount to the same. I would propose updates to the guide, but also create some convenience functions to be incorporated into guix. SEEN IN THE WILD * version * mescc-tools (https://github.com/oriansj/mescc-tools) (version (string-append "HEAD-" (string-take (read-string (open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2" OPEN_READ)) 7))) * guix.vim (https://git.sr.ht/~efraim/guix.vim) (define %git-commit ("again using git show HEAD")) (version (git-version (package-version vim-guix-vim) "HEAD" %git-commit)) * source * guix.vim (source (local-file ... ;yet another mechanism, just excludes .git, .log & guix.scm * mescc-tools ; probably written before git-predicate? was available - more or less same result, but uses 'git ls-files'! (source (local-file %source-dir #:recursive? #t #:select? git-file?)) * 8sync (located in ./guix.scm) (https://git.savannah.gnu.org/cgit/8sync.git) (define %source-dir (dirname (current-filename))) (source (local-file %source-dir #:recursive? #t #:select? (git-predicate %source-dir))) * guile-package (located in ./.guix/modules/file.scm) (https://git.savannah.gnu.org/cgit/guile.git) ; like in guide - uses (current-source-directory) "/../.." POSSIBLE ROADBLOCKS: (mostly a list of things to look out for when implementing this proposal) * local-file shenanigans * https://lists.gnu.org/archive/html/guix-devel/2024-08/msg00047.html * https://lists.gnu.org/archive/html/guix-devel/2023-09/msg00498.html * https://issues.guix.gnu.org/55464 * https://issues.guix.gnu.org/72867 THOUGHTS? Let me know what you think: * Have you used the workflow described in the cookbook before? * Would you use this 'improved' workflow? * Am I being silly? * ... I would continue working on this, once I'm convinced this is NOT a stupid idea, and when some other folks think this too :) I'm already doing a (very convoluted) version of this, written in my own channel. I would clean these up, think more about usability, edge cases, ... Best regards, Ingar PS: I CC'ed you Ludo, since you wrote that chapter.