I'm not sure why you think there is any 'config' involved. Perhaps you're conflating Nix the package manager with NixOS? Nix is many things, but it's also just a package manager like any other. For example:
nix profile install nixpkgs#vim # installs a package into your environment
nix shell nixpkgs#binwalk nixpkgs#vim # drops you into a shell with the given packages
nix run nixpkgs#firefox # runs the mainProgram of the given package
A couple of things to note:The aforementioned commands are the "experimental" Nix 2.4 CLI commands that integrate with Nix Flakes. They are only experimental in name though, their status of being experimental being sort of a meme at this point. I recommend using these new commands (you can opt in by supplying a command-line flag or by tweaking the package manager config).
Packages that are not in active use (e.g. packages that you've referred to in 'nix shell' or 'nix run' invocations that are not installed using 'nix profile') are due for garbage collection. The garbage collection settings can be configured (either through NixOS, home-manager or the package manager's standalone configuration). The garbage collection can also be triggred manually. This makes experimenting with programs that you don't necessarily want to keep a joy.
The 'nixpkgs' in the aforementioned invocations is a default input that is set during installation. It refers to the nixpkgs package archive's flake's master branch's latest revision (https://github.com/nixos/nixpkgs). The available inputs are configurable (again, either through NixOS, home-manager or the package manager's standalone configuration).
https://github.com/nixos/nixpkgs/ would be a great benchmark for a tool like this :) One of the larger repos on github, close to half a million commits by a large set of contributors to thousands of files.
package manager (whether on Darwin or any linux distro), to have some tools globally available:
nix-env -iA nixpkgs.${some-package}
per project, most shell.nix can just look like this: {
pkgs ? import {},
}:
let
some_var = some_value;
in pkgs.mkShell {
buildInputs = [
pkgs.some_package
...
];
shellHook = ''
# this is bash, so, whatever floats your boat
'''
e.g asdf, only much more generic with full non-leaking package management: {
pkgs ? import {},
}:
let
some_package = pkgs.some_package_1_2;
in pkgs.mkShell {
buildInputs = [
some_package
pkgs.some_other_package
...
];
shellHook = ''
export SOME_VAR="some_value"
...
'';
}
ruby/rvm/rbenv/bundle exec (example for rails >= 6): {
pkgs ? import {},
}:
let
ruby = pkgs.ruby_2_7;
python = pkgs.python27;
node = pkgs.nodejs-14_x;
in pkgs.mkShell {
buildInputs = [
ruby
pkgs.sqlite
python
node
pkgs.nodePackages.yarn
];
shellHook = ''
export RUBY_VERSION="$(ruby -e 'puts RUBY_VERSION.gsub(/\d+$/, "0")')"
export GEM_HOME="$(pwd)/vendor/bundle/ruby/$RUBY_VERSION"
export BUNDLE_PATH="$(pwd)/vendor/bundle"
export PATH="$GEM_HOME/bin:$PATH"
'';
}
python/pyenv/venv: {
pkgs ? import {},
}:
let
python_packages = python-packages: [
python-packages.pip
];
python = pkgs.python38.withPackages python_packages;
in pkgs.mkShell {
buildInputs = [
python
];
shellHook = ''
export PYTHON_VERSION="$(python -c 'import platform; import re; print(re.sub(r"\.\d+$", "", platform.python_version()))')"
export PIP_PREFIX="$PWD/vendor/python/$PYTHON_VERSION/packages"
export PYTHONPATH="$PIP_PREFIX/lib/python$PYTHON_VERSION/site-packages:$PYTHONPATH"
unset SOURCE_DATE_EPOCH
export PATH="$PIP_PREFIX/bin:$PATH"
'';
}
mixing arm64 and x86_64 on an Apple Silicon machine: {
x86_64 ? import { localSystem = "aarch64-darwin"; },
aarch64 ? import { localSystem = "x86_64-darwin"; }
}:
let
foo = aarch64.foo;
in aarch64.mkShell { # this makes nix-shell drop to an arm64 shell, change it to x86_64 to be intel/Rosetta2
buildInputs = [
foo
x86_64.bar
aarch64.baz
];
}
using an unstable/pinned/git package: {
stable ? import {},
unstable ? import (fetchTarball http://nixos.org/channels/nixos-unstable/nixexprs.tar.xz) {},
pinned ? import (fetchTarball https://github.com/nixos/nixpkgs/archive/ca2ba44cab47767c8127d1c8633e2b581644eb8f.tar.gz) {},
git ? import (fetchGit { url = "https://github.com/nixos/nixpkgs/"; ref = "refs/heads/nixos-unstable"; rev = "ca2ba44cab47767c8127d1c8633e2b581644eb8f"; }) {},
}:
let
foo = stable.foo;
in stable.mkShell {
buildInputs = [
foo
unstable.bar
pinned.baz
git.qux
];
}
selecting a particular C/C++ compiler&stdlibc++ version: {
pkgs ? import {},
}:
let
clang = pkgs.clang_12
in pkgs.llvmPackages_12.stdenv.mkDerivation {
buildInputs = [
clang
];
}
The trap is: You could handle all of that by using or writing nix features. You could even use NixOS instead of whatever distro you're used to. But then by going cold-turkey you have to learn whatever nix feature on top of all the basic (as in fundamental) things nix has to offer. Purists would say "no no no this is not the sanctioned way", which is kind of true but also setting yourself up for failure; it'd be like looking at a mountain and trying to jump right to the top, which of course you will fail to, when you could just be climbing it and be successful. Whatever practical gets you on board is fine. You can get to the "pure nix" stuff later, if you ever need to.I am all for trying to maximize technology advancement / alienating division of labor. (This is why I spend so much time on https://github.com/nixos/nixpkgs/ to untangle our great open source commons and make even in it's totality it graspable!), but "everyone gets to be a farmer too" is like the hardest-to-achieve form of that, and a failed attempt could easily wipe out what nature remains.
I would much prefer to abolish all non-highly-intense agriculture and try to return as much and to parkland as possible. IMO it's no coincidence California, Korea, and Japan are all prosperous. Mountains containing developing to smaller areas greatly improve things. We need the political will to do same thing in the flat areas by fiat.
I don't mean to "hawk my wares" in what feels like many threads, but seriously, this is a solved problem, despite the continued mess-making of people that don't use it.
git clone https://github.com/nixos/nixpkgs
cd nixpkgs
git checkout origin/nix-2.0
nix-env -i $(nix-build --no-out-link . -A nix)
Nix 'packages' are just text files describing the build/install process, so they can be version controlled (e.g. there's a big repo at https://github.com/nixos/nixpkgs ).
Dependencies, build environments, etc. are fully specified by the package and isolated from each other, and there is an emphasis on reproducibility, so building/installing a particular package should always give the same results. (This isn't enforced, but a non-reproducible package is considered buggy, and there are tools to check if a package can be reproduced)
Nix packages themselves can reference external dependencies, like git repos and URLs, and usually provide a fixed checksum to compare the output against; if it doesn't match, the build is aborted. Wrappers/translators are also available to integrate with other package manager ecosystems, e.g. cabal/hackage for Haskell packages.
Results are cached locally (packages are only built once, until they get garbage collected) and remotely (if a build server has already built a package, you can fetch it from there instead).
For development environments, you can write a Nix package for your project then run the 'nix-shell' command to enter its build environment (i.e. all dependencies available, environment variables set, etc.)
Benefits:
* It's declarative, so no one has to run anything to get to the correct state when a dependency has changed. Open a new nix-shell and automatically get everything. It's impossible to get in a bad state because it doesn't touch your system.
* We know we're all running the same software because the build will fail if hashes don't match.
* Portable across most unix's, and windows support is in progress.
* Patching other people's code is as easy as referencing a .patch file from a nix expression. You don't have to wait for your patch to be accepted in the main project or fork the project to build a custom release.
* There's no virtualization of IO like in containers. It effectively has no overhead.
* We can easily use different versions of the same piece of software in parallel; they don't collide because the hashes don't match.
* It has a very active community. The package repository, nixpkgs [1], has 73k commits, 650 contributors, and median pull request acceptance of 18 hours.
* Our software won't silently break because one of our package managers replaced a package. We maintain a fork of nixpkgs which we rebase on our own schedule.
If you've ever been frustrated with your package manager or build tools, give nix a shot!