|
13 | 13 | #include <boost/container/small_vector.hpp> |
14 | 14 | #include <boost/unordered/concurrent_flat_map.hpp> |
15 | 15 | #include <nlohmann/json.hpp> |
| 16 | +#include <optional> |
16 | 17 |
|
17 | 18 | namespace nix { |
18 | 19 |
|
@@ -791,71 +792,63 @@ std::string outputPathName(std::string_view drvName, OutputNameView outputName) |
791 | 792 |
|
792 | 793 | DerivationType BasicDerivation::type() const |
793 | 794 | { |
794 | | - std::set<std::string_view> inputAddressedOutputs, fixedCAOutputs, floatingCAOutputs, deferredIAOutputs, |
795 | | - impureOutputs; |
796 | 795 | std::optional<HashAlgorithm> floatingHashAlgo; |
| 796 | + std::optional<DerivationType> ty; |
| 797 | + |
| 798 | + auto decide = [&](DerivationType newTy) { |
| 799 | + if (!ty) |
| 800 | + ty = newTy; |
| 801 | + else if (ty.value() != newTy) |
| 802 | + throw Error("can't mix derivation output types"); |
| 803 | + else if (ty.value() == DerivationType::ContentAddressed{.sandboxed = false, .fixed = true}) |
| 804 | + // FIXME: Experimental feature? |
| 805 | + throw Error("only one fixed output is allowed for now"); |
| 806 | + }; |
797 | 807 |
|
798 | 808 | for (auto & i : outputs) { |
799 | 809 | std::visit( |
800 | 810 | overloaded{ |
801 | | - [&](const DerivationOutput::InputAddressed &) { inputAddressedOutputs.insert(i.first); }, |
802 | | - [&](const DerivationOutput::CAFixed &) { fixedCAOutputs.insert(i.first); }, |
| 811 | + [&](const DerivationOutput::InputAddressed &) { |
| 812 | + decide( |
| 813 | + DerivationType::InputAddressed{ |
| 814 | + .deferred = false, |
| 815 | + }); |
| 816 | + }, |
| 817 | + [&](const DerivationOutput::CAFixed &) { |
| 818 | + decide( |
| 819 | + DerivationType::ContentAddressed{ |
| 820 | + .sandboxed = false, |
| 821 | + .fixed = true, |
| 822 | + }); |
| 823 | + if (i.first != "out"sv) |
| 824 | + throw Error("single fixed output must be named \"out\""); |
| 825 | + }, |
803 | 826 | [&](const DerivationOutput::CAFloating & dof) { |
804 | | - floatingCAOutputs.insert(i.first); |
805 | | - if (!floatingHashAlgo) { |
| 827 | + decide( |
| 828 | + DerivationType::ContentAddressed{ |
| 829 | + .sandboxed = true, |
| 830 | + .fixed = false, |
| 831 | + }); |
| 832 | + if (!floatingHashAlgo) |
806 | 833 | floatingHashAlgo = dof.hashAlgo; |
807 | | - } else { |
808 | | - if (*floatingHashAlgo != dof.hashAlgo) |
809 | | - throw Error("all floating outputs must use the same hash algorithm"); |
810 | | - } |
| 834 | + else if (*floatingHashAlgo != dof.hashAlgo) |
| 835 | + throw Error("all floating outputs must use the same hash algorithm"); |
| 836 | + }, |
| 837 | + [&](const DerivationOutput::Deferred &) { |
| 838 | + decide( |
| 839 | + DerivationType::InputAddressed{ |
| 840 | + .deferred = true, |
| 841 | + }); |
811 | 842 | }, |
812 | | - [&](const DerivationOutput::Deferred &) { deferredIAOutputs.insert(i.first); }, |
813 | | - [&](const DerivationOutput::Impure &) { impureOutputs.insert(i.first); }, |
| 843 | + [&](const DerivationOutput::Impure &) { decide(DerivationType::Impure{}); }, |
814 | 844 | }, |
815 | 845 | i.second.raw); |
816 | 846 | } |
817 | 847 |
|
818 | | - if (inputAddressedOutputs.empty() && fixedCAOutputs.empty() && floatingCAOutputs.empty() |
819 | | - && deferredIAOutputs.empty() && impureOutputs.empty()) |
| 848 | + if (!ty) |
820 | 849 | throw Error("must have at least one output"); |
821 | 850 |
|
822 | | - if (!inputAddressedOutputs.empty() && fixedCAOutputs.empty() && floatingCAOutputs.empty() |
823 | | - && deferredIAOutputs.empty() && impureOutputs.empty()) |
824 | | - return DerivationType::InputAddressed{ |
825 | | - .deferred = false, |
826 | | - }; |
827 | | - |
828 | | - if (inputAddressedOutputs.empty() && !fixedCAOutputs.empty() && floatingCAOutputs.empty() |
829 | | - && deferredIAOutputs.empty() && impureOutputs.empty()) { |
830 | | - if (fixedCAOutputs.size() > 1) |
831 | | - // FIXME: Experimental feature? |
832 | | - throw Error("only one fixed output is allowed for now"); |
833 | | - if (*fixedCAOutputs.begin() != "out"sv) |
834 | | - throw Error("single fixed output must be named \"out\""); |
835 | | - return DerivationType::ContentAddressed{ |
836 | | - .sandboxed = false, |
837 | | - .fixed = true, |
838 | | - }; |
839 | | - } |
840 | | - |
841 | | - if (inputAddressedOutputs.empty() && fixedCAOutputs.empty() && !floatingCAOutputs.empty() |
842 | | - && deferredIAOutputs.empty() && impureOutputs.empty()) |
843 | | - return DerivationType::ContentAddressed{ |
844 | | - .sandboxed = true, |
845 | | - .fixed = false, |
846 | | - }; |
847 | | - |
848 | | - if (inputAddressedOutputs.empty() && fixedCAOutputs.empty() && floatingCAOutputs.empty() |
849 | | - && !deferredIAOutputs.empty() && impureOutputs.empty()) |
850 | | - return DerivationType::InputAddressed{ |
851 | | - .deferred = true, |
852 | | - }; |
853 | | - |
854 | | - if (inputAddressedOutputs.empty() && fixedCAOutputs.empty() && floatingCAOutputs.empty() |
855 | | - && deferredIAOutputs.empty() && !impureOutputs.empty()) |
856 | | - return DerivationType::Impure{}; |
857 | | - |
858 | | - throw Error("can't mix derivation output types"); |
| 851 | + return ty.value(); |
859 | 852 | } |
860 | 853 |
|
861 | 854 | DrvHashes drvHashes; |
|
0 commit comments