Vscode extensions, maintenance-friendly, HM, from both MarketPlace and nixpkgs (once more)

What I want/need:

  • in my HM config 2 lists of vscode extensions
    1. from nixpkgs (i.e. from pkgs.vscode-extensions.)
    2. from Marketplace (either openvsx or MS)
  • I explicitly don’t want to maintain sha256 or version for the second list, I just want to get the latest

Until now I’ve been using a half baked way based on update_installed_exts.sh and some awk magic to list all installed extensions, filter out the ones that are in list (1), overwrite list (2) with the remaining (with updated version and sha) and then rebuild the HM generation.

This is unsatisfactory mostly because the (text-based) filtering to obtain list (1) is not robust.

I.e.: for now the construction looks like this:

    programs.vscode = {
        enable = true;
        enableUpdateCheck = false;
        enableExtensionUpdateCheck =false;
        userSettings = with builtins; fromJSON (readFile ./_files/settings.json);
        keybindings = with builtins; fromJSON (readFile ./_files/keybindings.json);
        package = unstable.vscode;
        extensions = (with unstable.vscode-extensions; [
            ... # list (1)
        ]) ++ unstable.vscode-utils.extensionsFromVscodeMarketplace (import ./vscode-ext-marketplace.inc.nix){};
    }; # the import contains the list as generated by the update script

There’s got to be a better (fully idiomatic) way?

A fully idiomatic way would pin versions with SHAs. Without that there is no reproducibility nor rollback.

Maybe it could work as flake inputs (adding the noflake (I think) option), then it should automatically be put in the lock file.

So you explicitly want non-reproducibility. That’s kinda against nix’s reason for existence, but may be possible outside a flake (or with --impure) if you use builtin fetchers rather than FODs.

Non-reproducibility can never really be called “idiomatic” in nix-land, though… I recommend against it.

You could have a tool automatically maintain those hashes for you, however. Things like niv and nvfetcher are made to do that easily, not to mention the flake input system itself.


nvfetcher has native vs marketplace support. So maybe you are interested in have a sources.toml from which you can generate a generated.nix with every hashed source for your extensions.

example: hive/nix/utils/overlays/vscode at main · GTrunSec/hive · GitHub


I guess my point is that I don’t want “more verbose/cumbersome” pinning than I would do if I would pin e.g. my nixpkgs flake input. I.e. with flakes I can “live on the edge” by not pinning if I want to (which indeed I normally do), but with marketplace extensions I have to go out of my way to update an “elaborate list” before I can actually update…

Thanks all for the informative input, seems like nvfetcher might be the closest to the requirement.

In fact in the meantime I did something similar, by just taking the core function from the update_installed_exts.sh script and put it in my switch wrapper script.
It simply reads a text file part of my HM config in my flake with lines publisher.vscode-extension and generates vscode-ext-marketplace.inc.nix.
I.e. the difference with the previous situation is that I don’t need to parse the nix list but only a text file, and just overwrite the nix one. Effectively the same as using nvfetcher but arguably a bit simpler (at least the list).

@juaningan Those configs of @GTrunSec in your link are seriously elaborate, that could give inspiration for some time to come…

1 Like