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.

Reply via email to