Also, move a few free-standing functions into StoreAPI and Derivation.
Also, introduce a non-nullable smart pointer, ref<T>, which is just a
wrapper around std::shared_ptr ensuring that the pointer is never
null. (For reference-counted values, this is better than passing a
"T&", because the latter doesn't maintain the refcount. Usually, the
caller will have a shared_ptr keeping the value alive, but that's not
always the case, e.g., when passing a reference to a std::thread via
std::bind.)
The nixpkgs manual prescribes the use of values from stdenv.lib.licenses
for the meta.license attribute. Those values are attribute sets and
currently skipped when running nix-env with '--xml --meta'. This has the
consequence that also nixpkgs-lint will report missing licenses.
With this commit nix-env with '--xml --meta' will print all attributes
of an attribute set that are of type tString. For example the output for
the package nixpkgs.hello is
<meta name="license" type="strings">
<string type="url" value="http://spdx.org/licenses/GPL-3.0+" />
<string type="shortName" value="gpl3Plus" />
<string type="fullName" value="GNU General Public License v3.0 or later" />
<string type="spdxId" value="GPL-3.0+" />
</meta>
This commit fixes nixpkgs-lint, too.
It was strange to show "upgrading" when the version was getting lower.
This is left on "upgrading" when the versions are the same,
as I can't see any better wording.
Until now, if one explicitly installed a low-priority version,
nix-env --upgrade would downgrade it by default and even with --leq.
Let's never accept an upgrade with version not matching the upgradeType.
Additionally, let's never decrease the priority of an installed package;
you can use --install to force that.
Also refactor to use variable bestVersion instead of bestName,
as only version was used from it.
The value pointers of lists with 1 or 2 elements are now stored in the
list value itself. In particular, this makes the "concatMap (x: if
cond then [(f x)] else [])" idiom cheaper.
The option '--delete-generations Nd' deletes all generations older than N
days. However, most likely the user does not want to delete the
generation that was active N days ago.
For example, say that you have these 3 generations:
1: <30 days ago>
2: <15 days ago>
3: <1 hour ago>
If you do --delete-generations 7d (say, as part of a cron job), most
likely you still want to keep generation 2, i.e. the generation that was
active 7 days ago (and for most of the past 7 days, in fact).
This patch fixes this issue. Note that this also affects
'nix-collect-garbage --delete-older-than Nd'.
Thanks to @roconnor for noticing the issue!
The flag ‘--check’ to ‘nix-store -r’ or ‘nix-build’ will cause Nix to
redo the build of a derivation whose output paths are already valid.
If the new output differs from the original output, an error is
printed. This makes it easier to test if a build is deterministic.
(Obviously this cannot catch all sources of non-determinism, but it
catches the most common one, namely the current time.)
For example:
$ nix-build '<nixpkgs>' -A patchelf
...
$ nix-build '<nixpkgs>' -A patchelf --check
error: derivation `/nix/store/1ipvxsdnbhl1rw6siz6x92s7sc8nwkkb-patchelf-0.6' may not be deterministic: hash mismatch in output `/nix/store/4pc1dmw5xkwmc6q3gdc9i5nbjl4dkjpp-patchelf-0.6.drv'
The --check build fails if not all outputs are valid. Thus the first
call to nix-build is necessary to ensure that all outputs are valid.
The current outputs are left untouched: the new outputs are either put
in a chroot or diverted to a different location in the store using
hash rewriting.
This is equivalent to running ‘nix-env -e '*'’ first, except that it
happens in a single transaction. Thus, ‘nix-env -i pkgs...’ replaces
the profile with the specified set of packages.
The main motivation is to support declarative package management
(similar to environment.systemPackages in NixOS). That is, if you
have a specification ‘profile.nix’ like this:
with import <nixpkgs> {};
[ thunderbird
geeqie
...
]
then after any change to ‘profile.nix’, you can run:
$ nix-env -f profile.nix -ir
to update the profile to match the specification. (Without the ‘-r’
flag, if you remove a package from ‘profile.nix’, it won't be removed
from the actual profile.)
Suggested by @zefhemel.
This prevents some duplicate evaluation in nix-env and
nix-instantiate.
Also, when traversing ~/.nix-defexpr, only read regular files with the
extension .nix. Previously it was reading files like
.../channels/binary-caches/<name>. The only reason this didn't cause
problems is pure luck (namely, <name> shadows an actual Nix
expression, the binary-caches files happen to be syntactically valid
Nix expressions, and we iterate over the directory contents in just
the right order).
Since we already cache files in normal form (fileEvalCache), caching
parse trees is redundant.
Note that getting rid of this cache doesn't actually save much memory
at the moment, because parse trees are currently not freed / GC'ed.
We now print all output paths of a package, e.g.
openssl-1.0.0i bin=/nix/store/gq2mvh0wb9l90djvsagln3aqywqmr6vl-openssl-1.0.0i-bin;man=/nix/store/7zwf5r5hsdarl3n86dasvb4chm2xzw9n-openssl-1.0.0i-man;/nix/store/cj7xvk7fjp9q887359j75pw3pzjfmqf1-openssl-1.0.0i
or (in XML mode)
<item attrPath="openssl" name="openssl-1.0.0i" system="x86_64-linux">
<output name="bin" path="/nix/store/gq2mvh0wb9l90djvsagln3aqywqmr6vl-openssl-1.0.0i-bin" />
<output name="man" path="/nix/store/7zwf5r5hsdarl3n86dasvb4chm2xzw9n-openssl-1.0.0i-man" />
<output name="out" path="/nix/store/cj7xvk7fjp9q887359j75pw3pzjfmqf1-openssl-1.0.0i" />
</item>
I.e. do what git does. I'm too lazy to keep the builtin help text up
to date :-)
Also add ‘--help’ to various commands that lacked it
(e.g. nix-collect-garbage).
Channels are implemented using a profile now, and profiles contain a
manifest.nix file. This should be ignored to prevent bogus packages
from showing up in nix-env.
queryValidPaths() combines multiple calls to isValidPath() in one.
This matters when using the Nix daemon because it reduces latency.
For instance, on "nix-env -qas \*" it reduces execution time from 5.7s
to 4.7s (which is indistinguishable from the non-daemon case).
This should also fix:
nix-instantiate: ./../boost/shared_ptr.hpp:254: T* boost::shared_ptr<T>::operator->() const [with T = nix::StoreAPI]: Assertion `px != 0' failed.
which was caused by hashDerivationModulo() calling the ‘store’
object (during store upgrades) before openStore() assigned it.
brackets, e.g.
import <nixpkgs/pkgs/lib>
are resolved by looking them up relative to the elements listed in
the search path. This allows us to get rid of hacks like
import "${builtins.getEnv "NIXPKGS_ALL"}/pkgs/lib"
The search path can be specified through the ‘-I’ command-line flag
and through the colon-separated ‘NIX_PATH’ environment variable,
e.g.,
$ nix-build -I /etc/nixos ...
If a file is not found in the search path, an error message is
lazily thrown.
checked too soon whether substitutes are available. That is, it did
so for every available package, rather than those matching installed
packages. This was very slow and subject to assertion failures. So
do the check much later. Idem for `nix-env -qab' and `nix-env -ib'.
a pointer to a Value, rather than the Value directly. This improves
the effectiveness of garbage collection a lot: if the Value is
stored inside the set directly, then any live pointer to the Value
causes all other attributes in the set to be live as well.
instance) "nix-env -i wine" works on x86_64-linux, even though Wine
is built on i686-linux. In the event that there are multiple
matching derivations, prefer those built for the current system.
errors with position info.
* For all positions, use the position of the first character of the
first token, rather than the last character of the first token plus
one.
attributes from the meta attribute. Not doing so caused nix-env to
barf on the "psi" package, which has a meta.function attribute,
the textual serialisation of which causes a gigantic string to be
produced --- so big that it causes nix-env to run out of memory.
Note however that "meta" really only should contain strings.
meta.function should be passthru.function.
~/.nix-defexpr, otherwise the attribute cannot be selected with the
`-A' option. Useful if you want to stick a Nix expression directly
in ~/.nix-defexpr.
`-u'. Instead of acquiring an exclusive lock on the profile for the
entire duration of the operation, we just perform the operation
optimistically (without an exclusive lock), and check at the end
whether the profile changed while we were busy (i.e., the symlink
target changed). If so, the operation is restarted. Restarting is
generally cheap, since the build results are still in the Nix store.
Most of the time, only the user environment has to be rebuilt.
$ nix-env -e $(which firefox)
or
$ nix-env -e /nix/store/nywzlygrkfcgz7dfmhm5xixlx1l0m60v-pan-0.132
* nix-env -i: if an argument contains a slash anywhere, treat it as a
path and follow it through symlinks into the Nix store. This allows
things like
$ nix-build -A firefox
$ nix-env -i ./result
* nix-env -q/-i/-e: don't complain when the `*' selector doesn't match
anything. In particular, `nix-env -q \*' doesn't fail anymore on an
empty profile.
but installations/upgrades as well. So `nix-env -ub \*' will
upgrade only those packages for which a substitute is available (or
to be precise, it will upgrade each package to the highest version
for which a substitute is available).
the given attribute path (just as -A does with other option)
(NIX-83). So you can now say
$ nix-env -qa -A nixpkgs_unstable.gnome \*
atk-1.12.4
esound-0.2.36
...
to see the packages in the "gnome" attribute in Nixpkgs.
To *print* the attribute path, you should now use "--attr-path" /
"-P" (running out of letters...).
Nix expressions in that directory are combined into an attribute set
{file1 = import file1; file2 = import file2; ...}, i.e. each Nix
expression is an attribute with the file name as the attribute
name. Also recurses into directories.
* nix-env: removed the "--import" (-I) option which set the
~/.nix-defexpr symlink.
* nix-channel: don't use "nix-env --import", instead symlink
~/.nix-defexpr/channels. So finally nix-channel --update doesn't
override any default Nix expressions but combines with them.
This means that you can have (say) a local Nixpkgs SVN tree and use
it as a default for nix-env:
$ ln -s .../path-to-nixpkgs-tree ~/.nix-defexpr/nixpkgs_svn
and be subscribed to channels (including Nixpkgs) at the same time.
(If there is any ambiguity, the -A flag can be used to
disambiguate, e.g. "nix-env -i -A nixpkgs_svn.pan".)