How do I run nix-shell with a package from my own new channel?

What am I trying to do?

Being new to Nix and NixOS, it seems to me that rather than installing packages globally, we prefer to use nix-shell -p some-package when we need them.

So now I’m trying to figure out how to create a repo of packages for the 5-10 scripts that I’ve created myself, so they’re easy to use. Had this been debian, I would be wanting to add a URL to /etc/apt/sources.list.

So I have a default.nix that can build a package for myscript and want to:

$ nix-shell -p myscript --run "myscript ..."

Or perhaps:

$ nix-shell -p myrepo.myscript --run "myscript ..."

Overlays seem to work, so are overlays the canonical way to do this? Are there other ways?

Setting up a nix-channel and fiddling with NIX_PATH did not work for me.

I’ve kept my failed attempts with nix-channel and fiddling with NIX_PATH for posterity, but mostly I want to know if there are other ways than overlays to be able to run my scripts with e.g. nix-shell in a handy way.

I’ve put my default.nix on GitHub - pmorch/bogus-nix-channel and from that I’ve created a release.

Overlay seems to work

First:

export NIX_PATH=$NIX_PATH:nixpkgs-overlays=/path/to/overlays/

And then I put this in /path/to/overlays/bogus-nix-channel.nix:

final: prev:
    import (
      builtins.fetchTarball {
        url = https://github.com/pmorch/bogus-nix-channel/archive/refs/tags/first-version.tar.gz;
      }
    ) {}

Or, if I just want myscript:

final: prev: {
   myscript = (
    import (
      builtins.fetchTarball {
        url = https://github.com/pmorch/bogus-nix-channel/archive/refs/tags/first-version.tar.gz;
      }
    ) {}
  ).myscript;
}

Create a channel?

I thought I’d create a channel. But apparently that is a bad idea:

I have tried creating a channel anyway, but it looks to me like nix-shell does not support channels. Or I at least I can’t get it to work.

nix-env works with channels:

$ sudo nix-channel --add https://github.com/pmorch/bogus-nix-channel/archive/refs/tags/first-$version.tar.gz bogus
$ sudo nix-channel --update bogus
$ nix-env -iA bogus.myscript
$ myscript
(profit)

But nix-shell does not work with channels:

$ nix-shell -p bogus.myscript
...
       error: undefined variable 'bogus'
...

I can not figure out how use myscript from channel bogus with nix-shell.

Setting NIX_PATH

After trying for a long time, I have not yet managed to achieve anything remotely as handy or memorable for nix-shell. The closest I’ve come is:

$ nix-shell \
  -I bogus=https://github.com/pmorch/bogus-nix-channel/archive/refs/tags/first-version.tar.gz \
  -p '(import <bogus> {}).myscript'

I’m guessing I could move the -I option to setting nix.nixPath in configuration.nix on NixOS machines, or setting NIX_PATH for nix when not under NixOS.

But is there nothing better than this?

nix-shell -p '(import <bogus> {}).myscript'`

In How do I create my own ${pkgs.mypkg} based on a shell script? (that led me to be able to create default.nix - thank you @rgoulter), @rgoulter replies:

IMO, Nix flakes solve this pretty well: with nix flakes, it’s possible to use nix shell someFlake#package.

Without flakes… the most practical thing to do is to write some shell.nix file, and invoke nix-shell with that.

It’s possible to add myscript to nixpkgs such that literally nix-shell -p myscript, you’d define a nixpkgs overlay with myscript. c.f. Overlays in the nixpkgs manual: Nixpkgs Manual

Feel free to answer here also. If I don’t see other answers in 24h, I’ll mark this as the accepted answer.