From 2919c496ea10a99d08baffbef485cfb719233b9f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 May 2019 21:10:13 +0200 Subject: [PATCH] nix dev-shell: Use 'provides.devShell' by default Thus $ nix dev-shell will now build the 'provides.devShell' attribute from the flake in the current directory. If it doesn't exist, it falls back to 'provides.defaultPackage'. --- flake.nix | 5 +++++ shell.nix | 6 ++++-- src/nix/command.hh | 5 +++++ src/nix/installables.cc | 42 ++++++++++++++++++++++++++++++----------- src/nix/shell.cc | 6 ++++++ 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index 95ec5d952..ab316c7c6 100644 --- a/flake.nix +++ b/flake.nix @@ -17,5 +17,10 @@ packages.nix = hydraJobs.build.x86_64-linux; defaultPackage = packages.nix; + + devShell = import ./shell.nix { + nixpkgs = deps.nixpkgs; + }; + }; } diff --git a/shell.nix b/shell.nix index 8167f87a2..d7e63bad3 100644 --- a/shell.nix +++ b/shell.nix @@ -1,6 +1,8 @@ -{ useClang ? false }: +{ useClang ? false +, nixpkgs ? builtins.fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-19.03.tar.gz +}: -with import (builtins.fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-19.03.tar.gz) {}; +with import nixpkgs { system = builtins.currentSystem or "x86_64-linux"; }; with import ./release-common.nix { inherit pkgs; }; diff --git a/src/nix/command.hh b/src/nix/command.hh index 6d43261ac..640c6cd16 100644 --- a/src/nix/command.hh +++ b/src/nix/command.hh @@ -88,6 +88,11 @@ struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs std::shared_ptr parseInstallable( ref store, const std::string & installable); + virtual Strings getDefaultFlakeAttrPaths() + { + return {"defaultPackage"}; + } + private: std::shared_ptr evalState; diff --git a/src/nix/installables.cc b/src/nix/installables.cc index c3ca87aa7..db67952e1 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -142,13 +142,18 @@ struct InstallableAttrPath : InstallableValue struct InstallableFlake : InstallableValue { FlakeRef flakeRef; - std::string attrPath; + Strings attrPaths; + bool searchPackages = false; - InstallableFlake(SourceExprCommand & cmd, FlakeRef && flakeRef, const std::string & attrPath) - : InstallableValue(cmd), flakeRef(flakeRef), attrPath(attrPath) + InstallableFlake(SourceExprCommand & cmd, FlakeRef && flakeRef, Strings attrPaths) + : InstallableValue(cmd), flakeRef(flakeRef), attrPaths(std::move(attrPaths)) { } - std::string what() override { return flakeRef.to_string() + ":" + attrPath; } + InstallableFlake(SourceExprCommand & cmd, FlakeRef && flakeRef, std::string attrPath) + : InstallableValue(cmd), flakeRef(flakeRef), attrPaths{attrPath}, searchPackages(true) + { } + + std::string what() override { return flakeRef.to_string() + ":" + *attrPaths.begin(); } Value * toValue(EvalState & state) override { @@ -166,18 +171,31 @@ struct InstallableFlake : InstallableValue auto emptyArgs = state.allocBindings(0); - if (auto aPackages = *vProvides->attrs->get(state.symbols.create("packages"))) { + // As a convenience, look for the attribute in + // 'provides.packages'. + if (searchPackages) { + if (auto aPackages = *vProvides->attrs->get(state.symbols.create("packages"))) { + try { + auto * v = findAlongAttrPath(state, *attrPaths.begin(), *emptyArgs, *aPackages->value); + state.forceValue(*v); + return v; + } catch (AttrPathNotFound & e) { + } + } + } + + // Otherwise, look for it in 'provides'. + for (auto & attrPath : attrPaths) { try { - auto * v = findAlongAttrPath(state, attrPath, *emptyArgs, *aPackages->value); + auto * v = findAlongAttrPath(state, attrPath, *emptyArgs, *vProvides); state.forceValue(*v); return v; } catch (AttrPathNotFound & e) { } } - auto * v = findAlongAttrPath(state, attrPath, *emptyArgs, *vProvides); - state.forceValue(*v); - return v; + throw Error("flake '%s' does not provide attribute %s", + flakeRef, concatStringsSep(", ", quoteStrings(attrPaths))); } }; @@ -216,7 +234,8 @@ std::vector> SourceExprCommand::parseInstallables( else if (hasPrefix(s, "nixpkgs.")) { bool static warned; warnOnce(warned, "the syntax 'nixpkgs.' is deprecated; use 'nixpkgs:' instead"); - result.push_back(std::make_shared(*this, FlakeRef("nixpkgs"), std::string(s, 8))); + result.push_back(std::make_shared(*this, FlakeRef("nixpkgs"), + Strings{"packages." + std::string(s, 8)})); } else if ((colon = s.rfind(':')) != std::string::npos) { @@ -233,7 +252,8 @@ std::vector> SourceExprCommand::parseInstallables( if (storePath != "") result.push_back(std::make_shared(storePath)); else - result.push_back(std::make_shared(*this, FlakeRef(s, true), "defaultPackage")); + result.push_back(std::make_shared(*this, FlakeRef(s, true), + getDefaultFlakeAttrPaths())); } else diff --git a/src/nix/shell.cc b/src/nix/shell.cc index 14d88faeb..2e17111d6 100644 --- a/src/nix/shell.cc +++ b/src/nix/shell.cc @@ -125,6 +125,7 @@ struct Common : InstallableCommand "BASHOPTS", "EUID", "NIX_BUILD_TOP", + "NIX_ENFORCE_PURITY", "PPID", "PWD", "SHELLOPTS", @@ -156,6 +157,11 @@ struct Common : InstallableCommand for (auto & i : {"TMP", "TMPDIR", "TEMP", "TEMPDIR"}) out << fmt("export %s=\"$NIX_BUILD_TOP\"\n", i); } + + Strings getDefaultFlakeAttrPaths() override + { + return {"devShell", "defaultPackage"}; + } }; std::pair createTempFile(const Path & prefix = "nix")