1. 10
  1. 3

    Your site’s awesome! It doesn’t have a fallback for browsers that don’t have Javascript enabled or supported, but is so endearing that I think it’s worth it. I’m sure you’ve heard that Ice-9 is the namespace of the Guile standard library? I’ve been sinking my teeth into GNU Guix lately, and hacked together my own nïeve approach in the Makefile of my dotfiles repo:

    Makefile:
    #!/usr/bin/env make
    SHELL := ./make-shell-wrapper.sh
    ONESHELL:

    make-shell-wrapper.sh:
    #!/bin/sh
    CHANNELS\_DIR="..." # basically my modulesPath

    guix environment \
    --load-path=$CHANNELS\_DIR/{nonguix,etc}{,/modules} \
    --manifest=manifest.scm \
    -- sh "$@"

    All setups are unique, so not everyone would keep a directory of channels checked out or need to load it like I do. The manifest could also be an in-line list of packages like --ad-hoc hello, but we might as well use the same manifest.scm file that we’d load from the command line. I enable .ONESHELL in the Makefile in order to avoid invoking guix environment multiple times, which might be acceptable on my desktop but takes a second too long on my Pinebook Pro. I also just like .ONESHELL.

    Your approach of setting $PATH feels a lot cleaner for the exclusive purpose of providing dependencies, and I’ll likely start using it in several repos:
    export PATH := $(shell guix environment --manifest=manifest.scm -- echo $$PATH)

    But I’m still attached to wrapping the shell executable because it hypothetically allows us to containerize the execuation of Makefiles (without invoking nix/guix directly in each recipe). This is good for all the same reasons that containerization is good for packaging: we can ensure that every essential input has been explicitly declared, down to the shell itself, within the context of the collective recipies. We still assume that the user has make and nix/guix to execute the Makefile with, but those dependencies will need restated if they’re used within the recipies themselves.
    --pure --container --network \
    --user make \
    --expose="$CHANNELS\_DIR" \
    --expose="/var/guix/daemon-socket/socket" \

    For context, --expose is the read-only equivalent of --share, and --user specifies the user that make will hallucinate as itself inside the container.

    Unfortunately I haven’t got a magic shebang yet either, though I’m sure I could refactor my wrapper around the shell into a wrapper around make (ie. nix-make/guix-make) and toss that in the shebang line; loading the static file $PWD/manifests.scm might be generic enough for reuse.

    1. 1

      Sorry for the slow response; tied up with a wedding this weekend. Thanks for reading and engaging :)

      Your site’s awesome! It doesn’t have a fallback for browsers that don’t have Javascript enabled or supported, but is so endearing that I think it’s worth it.

      <3

      I’m sure you’ve heard that Ice-9 is the namespace of the Guile standard library?

      I didn’t know it from personal experience, but someone did let me know in an HN thread a while back: https://news.ycombinator.com/item?id=29388139

      I’ve been sinking my teeth into GNU Guix lately …

      The wrapper approach is a good one to keep in mind. I’m not quite sure why, but always a bit slow to think of a wrapper.

      Your approach of setting $PATH feels a lot cleaner for the exclusive purpose of providing dependencies, and I’ll likely start using it in several repos:

      export PATH := $(shell guix environment --manifest=manifest.scm -- echo $$PATH)
      

      But I’m still attached to wrapping the shell executable because it hypothetically allows us to containerize the execuation of Makefiles (without invoking nix/guix directly in each recipe). This is good for all the same reasons that containerization is good for packaging: we can ensure that every essential input has been explicitly declared, down to the shell itself, within the context of the collective recipies. We still assume that the user has make and nix/guix to execute the Makefile with, but those dependencies will need restated if they’re used within the recipies themselves.

      If I’m reading your use of ~containerization here right, you may also find https://github.com/abathur/resholve interesting. It’s focused on actually trying to ~containerize (again, if I’m reading you right) Bash/Shell scripts. It’s very Nix-ecosystem facing, but I try to keep the core tool as generic as possible and I’ve assumed at some point someone in the Guix ecosystem (and maybe even others) will package it.

      Much of its value is that it throws build errors until it can account for every identifier it can is a command-word. It almost inevitably finds additional unspecified dependencies in all but very trivial Shell packages (unless they’ve been very carefully packaged…).

      I’ve thought at some point that it would be nice to extend resholve’s approach to makefiles as well (though resholve would only really be able to handle tools immediately invoked, and perhaps one level into shell-scripts invoked). I’m not quite sure if this would take the form of a translation layer (that takes the Makefile, converts it into one or more Shell scripts, feeds those scripts to resholve, and translates the resholve-rewritten forms back into each Make recipe?) or if it is something that would only come along by doing some more work to abstract/generalize parts of resholve well enough to bolt on a Make parser or something.

    2. 2

      Cool trick. The debian/rules files in .deb source packages use a #!/usr/bin/make -f as their shebang. If the -i argument to nix-shell was smart enough to split the interpreter argument, this problem would be trivially solvable.

      I personally prefer to provide shell.nix or flake.nix, and expect people to have the correct tools on hand to run Makefile commands. This also means you have the tools on hand if you want to run commands to debug the build or whatever.

      1. 1

        Yes. I think it could also just tailor the case. Or have a ~nix-make affordances that both handles this and better advertises it’s presence.

        I have used the shell.nix approach (and am not really set in my ways here), but I feel like there’s a tension between providing a shell.nix for hacking on a project VS one for using/trialing it. This is letting me have this cake and eat it too.

        1. 1

          Flakes can ease that devShell/testShell tension somewhat because nix develop and nix shell are separate commands. To hack on a project: nix develop, but to try it out nix shell <reference to the flake package output>.

          1. 1

            That makes sense. I’ve been keeping my head in the sand on flakes, though I’m not sure how much longer I’ll try to sustain that…

            1. 2

              Fortunately there is a second good nix post today to help with that!

              1. 2

                Grin. I did save it. Now, to remember to look at my saves someday…