diff --git a/doc/manual/generate-dp-features-shortlist.nix b/doc/manual/generate-dp-features-shortlist.nix new file mode 100644 index 00000000000..05226039953 --- /dev/null +++ b/doc/manual/generate-dp-features-shortlist.nix @@ -0,0 +1,9 @@ +with builtins; +with import ; + +let + showDeprecatedFeature = name: doc: '' + - [`${name}`](@docroot@/development/deprecated-features.md#dp-feature-${name}) + ''; +in +dps: indent " " (concatStrings (attrValues (mapAttrs showDeprecatedFeature dps))) diff --git a/doc/manual/generate-dp-features.nix b/doc/manual/generate-dp-features.nix new file mode 100644 index 00000000000..73eb9f806ae --- /dev/null +++ b/doc/manual/generate-dp-features.nix @@ -0,0 +1,14 @@ +with builtins; +with import ; + +let + showDeprecatedFeature = + name: doc: + squash '' + ## [`${name}`]{#dp-feature-${name}} + + ${doc} + ''; +in + +dps: (concatStringsSep "\n" (attrValues (mapAttrs showDeprecatedFeature dps))) diff --git a/doc/manual/meson.build b/doc/manual/meson.build index 6fd841e80cb..c2244a86314 100644 --- a/doc/manual/meson.build +++ b/doc/manual/meson.build @@ -154,6 +154,8 @@ if get_option('html-manual') nix3_cli_files, experimental_features_shortlist_md, experimental_feature_descriptions_md, + deprecated_features_shortlist_md, + deprecated_feature_descriptions_md, types_dir, conf_file_md, builtins_md, @@ -393,7 +395,11 @@ nix_manpages = [ 'nix.conf', 5, conf_file_md.full_path(), - [ conf_file_md, experimental_features_shortlist_md ], + [ + conf_file_md, + experimental_features_shortlist_md, + deprecated_features_shortlist_md, + ], ], [ 'nix-daemon', 8 ], [ 'nix-profiles', 5, 'files/profiles.md' ], diff --git a/doc/manual/rl-next/disallow-url-literals.md b/doc/manual/rl-next/disallow-url-literals.md new file mode 100644 index 00000000000..78dd1c579ba --- /dev/null +++ b/doc/manual/rl-next/disallow-url-literals.md @@ -0,0 +1,8 @@ +--- +synopsis: Disallow URL literals +--- + +- URL literals (unquoted URLs) are now disabled by default in the Nix language. + They were previously optionally disallowable via the `no-url-literals` experimental feature, which has now been removed. + Existing Nix expressions containing URL literals must be updated to use quoted strings (e.g. `"http://example.com"` instead of `http://example.com`). + However, for transitional purposes, URL literals can be re-enabled using the new `url-literals` deprecated feature (e.g. `--extra-deprecated-features url-literals`). diff --git a/doc/manual/source/SUMMARY.md.in b/doc/manual/source/SUMMARY.md.in index 05eed77837f..328690b88ce 100644 --- a/doc/manual/source/SUMMARY.md.in +++ b/doc/manual/source/SUMMARY.md.in @@ -150,6 +150,7 @@ - [JSON guideline](development/json-guideline.md) - [C++ style guide](development/cxx.md) - [Experimental Features](development/experimental-features.md) + - [Deprecated Features](development/deprecated-features.md) - [Contributing](development/contributing.md) - [Releases](release-notes/index.md) {{#include ./SUMMARY-rl-next.md}} diff --git a/doc/manual/source/command-ref/meson.build b/doc/manual/source/command-ref/meson.build index 06aed261a60..9d25b77238c 100644 --- a/doc/manual/source/command-ref/meson.build +++ b/doc/manual/source/command-ref/meson.build @@ -18,6 +18,26 @@ experimental_features_shortlist_md = custom_target( env : nix_env_for_docs, ) +dp_features_json = custom_target( + command : [ nix, '__dump-dp-features' ], + capture : true, + output : 'dp-features.json', + env : nix_env_for_docs, +) + +deprecated_features_shortlist_md = custom_target( + command : nix_eval_for_docs + [ + '--expr', 'import @INPUT0@ (builtins.fromJSON (builtins.readFile ./@INPUT1@))', + ], + input : [ + '../../generate-dp-features-shortlist.nix', + dp_features_json, + ], + output : 'deprecated-features-shortlist.md', + capture : true, + env : nix_env_for_docs, +) + nix3_cli_files = custom_target( command : [ python.full_path(), '@INPUT0@', '@OUTPUT@', '--' ] + nix_eval_for_docs + [ '--expr', 'import @INPUT1@ true (builtins.readFile ./@INPUT2@)', diff --git a/doc/manual/source/development/deprecated-features.md b/doc/manual/source/development/deprecated-features.md new file mode 100644 index 00000000000..b766c336028 --- /dev/null +++ b/doc/manual/source/development/deprecated-features.md @@ -0,0 +1,11 @@ +This section describes the notion of *deprecated features*, and how it fits into the big picture of the development of Nix. + +# What are deprecated features? + +Deprecated features are legacy features that are scheduled for removal. +They are disabled by default but can be re-enabled by toggling the associated [deprecated feature flags](@docroot@/command-ref/conf-file.md#conf-deprecated-features). +This allows for a transition period where users can adapt their code. + +# Deprecated feature descriptions + +{{#include @generated@/development/deprecated-feature-descriptions.md}} diff --git a/doc/manual/source/development/meson.build b/doc/manual/source/development/meson.build index b3fb110230d..a474121e985 100644 --- a/doc/manual/source/development/meson.build +++ b/doc/manual/source/development/meson.build @@ -10,3 +10,16 @@ experimental_feature_descriptions_md = custom_target( env : nix_env_for_docs, output : 'experimental-feature-descriptions.md', ) + +deprecated_feature_descriptions_md = custom_target( + command : nix_eval_for_docs + [ + '--expr', 'import @INPUT0@ (builtins.fromJSON (builtins.readFile @INPUT1@))', + ], + input : [ + '../../generate-dp-features.nix', + dp_features_json, + ], + capture : true, + env : nix_env_for_docs, + output : 'deprecated-feature-descriptions.md', +) diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index c9ad3040771..155fd333333 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -26,6 +26,7 @@ #include "nix/util/finally.hh" #include "nix/util/util.hh" #include "nix/util/users.hh" +#include "nix/util/configuration.hh" #include "nix/expr/nixexpr.hh" #include "nix/expr/eval.hh" @@ -314,12 +315,12 @@ expr_simple state->exprs.add(state->exprs.alloc, path)}); } | URI { - static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals); - if (noURLLiterals) + if (!experimentalFeatureSettings.isEnabled(DeprecatedFeature::UrlLiterals)) { throw ParseError({ .msg = HintFmt("URL literals are disabled"), .pos = state->positions[CUR_POS] }); + } $$ = state->exprs.add(state->exprs.alloc, $1); } | '(' expr ')' { $$ = $2; } diff --git a/src/libutil/config-global.cc b/src/libutil/config-global.cc index b63b4aaa1bb..200c57e61c1 100644 --- a/src/libutil/config-global.cc +++ b/src/libutil/config-global.cc @@ -64,7 +64,7 @@ GlobalConfig::Register::Register(Config * config) configRegistrations().emplace_back(config); } -ExperimentalFeatureSettings experimentalFeatureSettings; +FeatureSettings experimentalFeatureSettings; static GlobalConfig::Register rSettings(&experimentalFeatureSettings); diff --git a/src/libutil/configuration.cc b/src/libutil/configuration.cc index 832099dab99..f52a623fa98 100644 --- a/src/libutil/configuration.cc +++ b/src/libutil/configuration.cc @@ -3,6 +3,7 @@ #include "nix/util/abstract-setting-to-json.hh" #include "nix/util/environment-variables.hh" #include "nix/util/experimental-features.hh" +#include "nix/util/deprecated-features.hh" #include "nix/util/util.hh" #include "nix/util/file-system.hh" @@ -425,6 +426,36 @@ std::string BaseSetting>::to_string() const return concatStringsSep(" ", stringifiedXpFeatures); } +template<> +std::set BaseSetting>::parse(const std::string & str) const +{ + std::set res; + for (auto & s : tokenizeString(str)) { + if (auto thisDpFeature = parseDeprecatedFeature(s); thisDpFeature) + res.insert(thisDpFeature.value()); + else + warn("unknown deprecated feature '%s'", s); + } + return res; +} + +template<> +void BaseSetting>::appendOrSet(std::set newValue, bool append) +{ + if (!append) + value.clear(); + value.insert(std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end())); +} + +template<> +std::string BaseSetting>::to_string() const +{ + StringSet stringifiedDpFeatures; + for (const auto & feature : value) + stringifiedDpFeatures.insert(std::string(showDeprecatedFeature(feature))); + return concatStringsSep(" ", stringifiedDpFeatures); +} + template<> StringMap BaseSetting::parse(const std::string & str) const { @@ -505,6 +536,7 @@ template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting>; +template class BaseSetting>; template class BaseSetting; template class BaseSetting>; @@ -548,24 +580,47 @@ void OptionalPathSetting::operator=(const std::optional & v) this->assign(v); } -bool ExperimentalFeatureSettings::isEnabled(const ExperimentalFeature & feature) const +bool FeatureSettings::isEnabled(const ExperimentalFeature & feature) const { auto & f = experimentalFeatures.get(); return std::find(f.begin(), f.end(), feature) != f.end(); } -void ExperimentalFeatureSettings::require(const ExperimentalFeature & feature, std::string reason) const +void FeatureSettings::require(const ExperimentalFeature & feature, std::string reason) const { if (!isEnabled(feature)) throw MissingExperimentalFeature(feature, std::move(reason)); } -bool ExperimentalFeatureSettings::isEnabled(const std::optional & feature) const +bool FeatureSettings::isEnabled(const std::optional & feature) const +{ + return !feature || isEnabled(*feature); +} + +void FeatureSettings::require(const std::optional & feature) const +{ + if (feature) + require(*feature); +} + +bool FeatureSettings::isEnabled(const DeprecatedFeature & feature) const +{ + auto & f = deprecatedFeatures.get(); + return std::find(f.begin(), f.end(), feature) != f.end(); +} + +void FeatureSettings::require(const DeprecatedFeature & feature) const +{ + if (!isEnabled(feature)) + throw MissingDeprecatedFeature(feature); +} + +bool FeatureSettings::isEnabled(const std::optional & feature) const { return !feature || isEnabled(*feature); } -void ExperimentalFeatureSettings::require(const std::optional & feature) const +void FeatureSettings::require(const std::optional & feature) const { if (feature) require(*feature); diff --git a/src/libutil/deprecated-features.cc b/src/libutil/deprecated-features.cc new file mode 100644 index 00000000000..2cfd4a8265f --- /dev/null +++ b/src/libutil/deprecated-features.cc @@ -0,0 +1,100 @@ +#include "nix/util/deprecated-features.hh" +#include "nix/util/fmt.hh" +#include "nix/util/strings.hh" +#include "nix/util/util.hh" + +#include + +namespace nix { + +struct DeprecatedFeatureDetails +{ + DeprecatedFeature tag; + std::string_view name; + std::string_view description; +}; + +// Add features here +constexpr std::array depFeatureDetails = {{{ + .tag = DeprecatedFeature::UrlLiterals, + .name = "url-literals", + .description = R"( + Re-enable support for URL literals. + )", +}}}; + +const std::optional parseDeprecatedFeature(const std::string_view & name) +{ + using ReverseDepMap = std::map; + + static std::unique_ptr reverseDepMap = []() { + auto reverseDepMap = std::make_unique(); + for (auto & depFeature : depFeatureDetails) + (*reverseDepMap)[depFeature.name] = depFeature.tag; + return reverseDepMap; + }(); + + if (auto feature = get(*reverseDepMap, name)) + return *feature; + else + return std::nullopt; +} + +std::string_view showDeprecatedFeature(const DeprecatedFeature tag) +{ + for (const auto & detail : depFeatureDetails) { + if (detail.tag == tag) + return detail.name; + } + throw Error("Unknown deprecated feature tag"); +} + +nlohmann::json documentDeprecatedFeatures() +{ + std::map res; + for (auto & depFeature : depFeatureDetails) + res[std::string{depFeature.name}] = trim(stripIndentation(depFeature.description)); + return (nlohmann::json) res; +} + +std::set parseDeprecatedFeatures(const std::set & rawFeatures) +{ + std::set res; + for (auto & rawFeature : rawFeatures) + if (auto feature = parseDeprecatedFeature(rawFeature)) + res.insert(*feature); + else + warn("unknown deprecated feature '%s'", rawFeature); + return res; +} + +MissingDeprecatedFeature::MissingDeprecatedFeature(DeprecatedFeature feature) + : Error( + "Feature '%1%' is deprecated and should not be used anymore; use '--extra-deprecated-features %1%' to disable this error", + showDeprecatedFeature(feature)) + , missingFeature(feature) +{ +} + +std::ostream & operator<<(std::ostream & str, const DeprecatedFeature & feature) +{ + return str << showDeprecatedFeature(feature); +} + +void to_json(nlohmann::json & j, const DeprecatedFeature & feature) +{ + j = showDeprecatedFeature(feature); +} + +void from_json(const nlohmann::json & j, DeprecatedFeature & feature) +{ + const std::string input = j; + const auto parsed = parseDeprecatedFeature(input); + + if (parsed.has_value()) + feature = *parsed; + else + throw Error("Unknown deprecated feature '%s' in JSON input", input); +} + +} // namespace nix diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc index 20d1a082a66..9c90ce1bb4a 100644 --- a/src/libutil/experimental-features.cc +++ b/src/libutil/experimental-features.cc @@ -156,48 +156,6 @@ constexpr std::array xpFeatureDetails )", .trackingUrl = "https://github.com/NixOS/nix/milestone/47", }, - { - .tag = Xp::NoUrlLiterals, - .name = "no-url-literals", - .description = R"( - Disallow unquoted URLs as part of the Nix language syntax. The Nix - language allows for URL literals, like so: - - ``` - $ nix repl - Welcome to Nix 2.15.0. Type :? for help. - - nix-repl> http://foo - "http://foo" - ``` - - But enabling this experimental feature will cause the Nix parser to - throw an error when encountering a URL literal: - - ``` - $ nix repl --extra-experimental-features 'no-url-literals' - Welcome to Nix 2.15.0. Type :? for help. - - nix-repl> http://foo - error: URL literals are disabled - - at «string»:1:1: - - 1| http://foo - | ^ - - ``` - - While this is currently an experimental feature, unquoted URLs are - being deprecated and their usage is discouraged. - - The reason is that, as opposed to path literals, URLs have no - special properties that distinguish them from regular strings, URLs - containing parameters have to be quoted anyway, and unquoted URLs - may confuse external tooling. - )", - .trackingUrl = "https://github.com/NixOS/nix/milestone/44", - }, { .tag = Xp::FetchClosure, .name = "fetch-closure", diff --git a/src/libutil/include/nix/util/config-impl.hh b/src/libutil/include/nix/util/config-impl.hh index 8f6f9a358a4..68f5e89a5d2 100644 --- a/src/libutil/include/nix/util/config-impl.hh +++ b/src/libutil/include/nix/util/config-impl.hh @@ -44,6 +44,12 @@ struct BaseSetting>::trait static constexpr bool appendable = true; }; +template<> +struct BaseSetting>::trait +{ + static constexpr bool appendable = true; +}; + template struct BaseSetting::trait { @@ -64,6 +70,8 @@ template<> void BaseSetting::appendOrSet(StringMap newValue, bool append); template<> void BaseSetting>::appendOrSet(std::set newValue, bool append); +template<> +void BaseSetting>::appendOrSet(std::set newValue, bool append); template void BaseSetting::appendOrSet(T newValue, bool append) @@ -135,6 +143,7 @@ DECLARE_CONFIG_SERIALISER(Strings) DECLARE_CONFIG_SERIALISER(StringSet) DECLARE_CONFIG_SERIALISER(StringMap) DECLARE_CONFIG_SERIALISER(std::set) +DECLARE_CONFIG_SERIALISER(std::set) DECLARE_CONFIG_SERIALISER(std::filesystem::path) DECLARE_CONFIG_SERIALISER(std::optional) diff --git a/src/libutil/include/nix/util/configuration.hh b/src/libutil/include/nix/util/configuration.hh index 541febdb5f9..9ecf98e2e14 100644 --- a/src/libutil/include/nix/util/configuration.hh +++ b/src/libutil/include/nix/util/configuration.hh @@ -9,6 +9,7 @@ #include "nix/util/types.hh" #include "nix/util/experimental-features.hh" +#include "nix/util/deprecated-features.hh" namespace nix { @@ -431,7 +432,7 @@ public: void operator=(const std::optional & v); }; -struct ExperimentalFeatureSettings : Config +struct FeatureSettings : Config { Setting> experimentalFeatures{ @@ -489,9 +490,47 @@ struct ExperimentalFeatureSettings : Config * disabled, and so the function does nothing in that case. */ void require(const std::optional &) const; + + Setting> deprecatedFeatures{ + this, + {}, + "deprecated-features", + R"( + Deprecated features that are enabled. (Currently there are none.) + + The following deprecated feature features can be re-activated: + + {{#include deprecated-features-shortlist.md}} + + Deprecated features are [further documented in the manual](@docroot@/development/deprecated-features.md). + )"}; + + /** + * Check whether the given deprecated feature is enabled. + */ + bool isEnabled(const DeprecatedFeature &) const; + + /** + * Require an deprecated feature be enabled, throwing an error if it is + * not. + */ + void require(const DeprecatedFeature &) const; + + /** + * `std::nullopt` pointer means no feature, which means there is nothing that could be + * disabled, and so the function returns true in that case. + */ + bool isEnabled(const std::optional &) const; + + /** + * `std::nullopt` pointer means no feature, which means there is nothing that could be + * disabled, and so the function does nothing in that case. + */ + void require(const std::optional &) const; }; // FIXME: don't use a global variable. -extern ExperimentalFeatureSettings experimentalFeatureSettings; +extern FeatureSettings experimentalFeatureSettings; +using ExperimentalFeatureSettings = FeatureSettings; } // namespace nix diff --git a/src/libutil/include/nix/util/deprecated-features.hh b/src/libutil/include/nix/util/deprecated-features.hh new file mode 100644 index 00000000000..1167d8f8c1f --- /dev/null +++ b/src/libutil/include/nix/util/deprecated-features.hh @@ -0,0 +1,90 @@ +#pragma once +///@file + +#include "nix/util/error.hh" +#include "nix/util/types.hh" +#include "nix/util/json-non-null.hh" + +#include + +namespace nix { + +/** + * The list of available deprecated features. + * + * If you update this, don’t forget to also change the map defining + * their string representation and documentation in the corresponding + * `.cc` file as well. + * + * Reminder: New deprecated features should start out with a warning without throwing an error. + * See the developer documentation for details. + */ +enum struct DeprecatedFeature { + UrlLiterals, +}; + +/** + * Just because writing `DeprecatedFeature::UrlLiterals` is way too long + */ +using Dep = DeprecatedFeature; + +/** + * Parse a deprecated feature (enum value) from its name. Deprecated + * feature flag names are hyphenated and do not contain spaces. + */ +const std::optional parseDeprecatedFeature(const std::string_view & name); + +/** + * Show the name of a deprecated feature. This is the opposite of + * parseDeprecatedFeature(). + */ +std::string_view showDeprecatedFeature(const DeprecatedFeature); + +/** + * Compute the documentation of all deprecated features. + * + * See `doc/manual` for how this information is used. + */ +nlohmann::json documentDeprecatedFeatures(); + +/** + * Shorthand for `str << showDeprecatedFeature(feature)`. + */ +std::ostream & operator<<(std::ostream & str, const DeprecatedFeature & feature); + +/** + * Parse a set of strings to the corresponding set of deprecated + * features, ignoring (but warning for) any unknown feature. + */ +std::set parseDeprecatedFeatures(const StringSet &); + +/** + * A deprecated feature used for some + * operation, but was not enabled. + */ +class MissingDeprecatedFeature : public Error +{ +public: + /** + * The deprecated feature that was required but not enabled. + */ + DeprecatedFeature missingFeature; + + MissingDeprecatedFeature(DeprecatedFeature missingFeature); +}; + +/** + * `DeprecatedFeature` is always rendered as a string. + */ +template<> +struct json_avoids_null : std::true_type +{}; + +/** + * Semi-magic conversion to and from json. + * See the nlohmann/json readme for more details. + */ +void to_json(nlohmann::json &, const DeprecatedFeature &); +void from_json(const nlohmann::json &, DeprecatedFeature &); + +} // namespace nix diff --git a/src/libutil/include/nix/util/experimental-features.hh b/src/libutil/include/nix/util/experimental-features.hh index aca14bfbb41..ce18e8ebab0 100644 --- a/src/libutil/include/nix/util/experimental-features.hh +++ b/src/libutil/include/nix/util/experimental-features.hh @@ -24,7 +24,6 @@ enum struct ExperimentalFeature { NixCommand, GitHashing, RecursiveNix, - NoUrlLiterals, FetchClosure, AutoAllocateUids, Cgroups, diff --git a/src/libutil/include/nix/util/meson.build b/src/libutil/include/nix/util/meson.build index 1ab2c47e47d..ff2365f0c71 100644 --- a/src/libutil/include/nix/util/meson.build +++ b/src/libutil/include/nix/util/meson.build @@ -26,6 +26,7 @@ headers = files( 'config-impl.hh', 'configuration.hh', 'current-process.hh', + 'deprecated-features.hh', 'english.hh', 'environment-variables.hh', 'error.hh', diff --git a/src/libutil/meson.build b/src/libutil/meson.build index fdd310ad8e4..a02e65556ce 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -132,6 +132,7 @@ sources = [ config_priv_h ] + files( 'config-global.cc', 'configuration.cc', 'current-process.cc', + 'deprecated-features.cc', 'english.cc', 'environment-variables.cc', 'error.cc', diff --git a/src/nix/main.cc b/src/nix/main.cc index 811d1c495a6..ba5af5e1975 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -21,6 +21,7 @@ #include "nix/flake/flake.hh" #include "nix/flake/settings.hh" #include "nix/util/json-utils.hh" +#include "nix/util/deprecated-features.hh" #include "self-exe.hh" #include "crash-handler.hh" @@ -481,6 +482,11 @@ void mainWrapped(int argc, char ** argv) return; } + if (argc == 2 && std::string(argv[1]) == "__dump-dp-features") { + logger->cout(documentDeprecatedFeatures().dump()); + return; + } + Finally printCompletions([&]() { if (args.completions) { switch (args.completions->type) { diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index da04cf852ce..2992020f16a 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -31,15 +31,15 @@ rev2=$(git -C "$repo" rev-parse HEAD) git -C "$repo" tag -a tag2 -m tag2 # Check whether fetching in read-only mode works. -nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit file://$TEST_ROOT/worktree) + \"/hello\") == \"utrecht\\n\"" +nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit \"file://$TEST_ROOT/worktree\") + \"/hello\") == \"utrecht\\n\"" # Fetch a worktree. unset _NIX_FORCE_HTTP -expectStderr 0 nix eval -vvvv --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath" | grepQuiet "copying '$TEST_ROOT/worktree/' to the store" -path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath") -path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath") +expectStderr 0 nix eval -vvvv --impure --raw --expr "(builtins.fetchGit \"file://$TEST_ROOT/worktree\").outPath" | grepQuiet "copying '$TEST_ROOT/worktree/' to the store" +path0=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$TEST_ROOT/worktree\").outPath") +path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = \"file://$TEST_ROOT/worktree\"; }).outPath") [[ $path0 = "$path0_" ]] -path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree git+file://$TEST_ROOT/worktree).outPath") +path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree \"git+file://$TEST_ROOT/worktree\").outPath") [[ $path0 = "$path0_" ]] export _NIX_FORCE_HTTP=1 [[ $(tail -n 1 "$path0"/hello) = "hello" ]] @@ -48,7 +48,7 @@ export _NIX_FORCE_HTTP=1 rm -rf "$TEST_HOME"/.cache/nix # Fetch the default branch. -path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath") +path=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") [[ $(cat "$path"/hello) = world ]] # Fetch again. This should be cached. @@ -56,18 +56,18 @@ path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath" # the reason being that the lookup on the cache uses the ref-file `/refs/heads/master` # which does not exist after packing. mv "$repo" "${repo}"-tmp -path2=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath") +path2=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") [[ $path = "$path2" ]] -[[ $(nix eval --impure --expr "(builtins.fetchGit file://$repo).revCount") = 2 ]] -[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).rev") = "$rev2" ]] -[[ $(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).shortRev") = "${rev2:0:7}" ]] +[[ $(nix eval --impure --expr "(builtins.fetchGit \"file://$repo\").revCount") = 2 ]] +[[ $(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").rev") = "$rev2" ]] +[[ $(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").shortRev") = "${rev2:0:7}" ]] # Fetching with a explicit hash should succeed. -path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev2\"; }).outPath") +path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; rev = \"$rev2\"; }).outPath") [[ $path = "$path2" ]] -path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev1\"; }).outPath") +path2=$(nix eval --refresh --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; rev = \"$rev1\"; }).outPath") [[ $(cat "$path2"/hello) = utrecht ]] mv "${repo}"-tmp "$repo" @@ -75,7 +75,7 @@ mv "${repo}"-tmp "$repo" # Fetch when the cache has packed-refs # Regression test of #8822 git -C "$TEST_HOME"/.cache/nix/gitv3/*/ pack-refs --all -path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath") +path=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") # Fetch a rev from another branch git -C "$repo" checkout -b devtest @@ -84,20 +84,20 @@ git -C "$repo" add differentbranch git -C "$repo" commit -m 'Test2' git -C "$repo" checkout master devrev=$(git -C "$repo" rev-parse devtest) -nix eval --raw --expr "builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; }" +nix eval --raw --expr "builtins.fetchGit { url = \"file://$repo\"; rev = \"$devrev\"; }" -[[ $(nix eval --raw --expr "builtins.readFile (builtins.fetchGit { url = file://$repo; rev = \"$devrev\"; allRefs = true; } + \"/differentbranch\")") = 'different file' ]] +[[ $(nix eval --raw --expr "builtins.readFile (builtins.fetchGit { url = \"file://$repo\"; rev = \"$devrev\"; allRefs = true; } + \"/differentbranch\")") = 'different file' ]] # In pure eval mode, fetchGit without a revision should fail. -[[ $(nix eval --impure --raw --expr "builtins.readFile (fetchGit file://$repo + \"/hello\")") = world ]] -(! nix eval --raw --expr "builtins.readFile (fetchGit file://$repo + \"/hello\")") +[[ $(nix eval --impure --raw --expr "builtins.readFile (fetchGit \"file://$repo\" + \"/hello\")") = world ]] +(! nix eval --raw --expr "builtins.readFile (fetchGit \"file://$repo\" + \"/hello\")") # Fetch using an explicit revision hash. -path2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev2\"; }).outPath") +path2=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; rev = \"$rev2\"; }).outPath") [[ $path = "$path2" ]] # In pure eval mode, fetchGit with a revision should succeed. -[[ $(nix eval --raw --expr "builtins.readFile (fetchGit { url = file://$repo; rev = \"$rev2\"; } + \"/hello\")") = world ]] +[[ $(nix eval --raw --expr "builtins.readFile (fetchGit { url = \"file://$repo\"; rev = \"$rev2\"; } + \"/hello\")") = world ]] # But without a hash, it fails. expectStderr 1 nix eval --expr 'builtins.fetchGit "file:///foo"' | grepQuiet "'fetchGit' doesn't fetch unlocked input" @@ -136,7 +136,7 @@ path3=$(nix eval --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\" # Committing should not affect the store path. git -C "$repo" commit -m 'Bla3' -a -path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$repo).outPath") +path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") [[ $path2 = "$path4" ]] [[ $(nix eval --impure --expr "builtins.hasAttr \"rev\" (builtins.fetchGit $repo)") == "true" ]] @@ -162,14 +162,14 @@ rev3=$(git -C "$repo" rev-parse HEAD) nix eval --tarball-ttl 3600 --expr "builtins.fetchGit { url = $repo; rev = \"$rev3\"; }" >/dev/null # Update 'path' to reflect latest master -path=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath") +path=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") # Check behavior when non-master branch is used git -C "$repo" checkout "$rev2" -b dev echo dev > "$repo"/hello # File URI uses dirty tree unless specified otherwise -path2=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$repo).outPath") +path2=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath") [ "$(cat "$path2"/hello)" = dev ] # Using local path with branch other than 'master' should work when clean or dirty @@ -254,7 +254,7 @@ echo "/exported-wonky export-ignore=wonk" >> "$repo"/.gitattributes git -C "$repo" add not-exported-file exported-wonky .gitattributes git -C "$repo" commit -m 'Bla6' rev5=$(git -C "$repo" rev-parse HEAD) -path12=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$repo; rev = \"$rev5\"; }).outPath") +path12=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; rev = \"$rev5\"; }).outPath") [[ ! -e $path12/not-exported-file ]] [[ -e $path12/exported-wonky ]] diff --git a/tests/functional/fetchGitSubmodules.sh b/tests/functional/fetchGitSubmodules.sh index bf5fe5df387..33bdf5cbba0 100755 --- a/tests/functional/fetchGitSubmodules.sh +++ b/tests/functional/fetchGitSubmodules.sh @@ -40,16 +40,16 @@ git -C "$rootRepo" commit -m "Add submodule" rev=$(git -C "$rootRepo" rev-parse HEAD) -r1=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath") -r2=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = false; }).outPath") -r3=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") +r1=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; }).outPath") +r2=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; submodules = false; }).outPath") +r3=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; submodules = true; }).outPath") [[ $r1 == "$r2" ]] [[ $r2 != "$r3" ]] -r4=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; }).outPath") -r5=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = false; }).outPath") -r6=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") +r4=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; ref = \"master\"; rev = \"$rev\"; }).outPath") +r5=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; ref = \"master\"; rev = \"$rev\"; submodules = false; }).outPath") +r6=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") r7=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") r8=$(nix eval --raw --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).outPath") @@ -68,10 +68,10 @@ have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \ have_submodules=$(nix eval --expr "(builtins.fetchGit { url = $rootRepo; rev = \"$rev\"; submodules = true; }).submodules") [[ $have_submodules == true ]] -pathWithoutSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; }).outPath") -pathWithSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") -pathWithSubmodulesAgain=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }).outPath") -pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") +pathWithoutSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; }).outPath") +pathWithSubmodules=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; submodules = true; }).outPath") +pathWithSubmodulesAgain=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; submodules = true; }).outPath") +pathWithSubmodulesAgainWithRef=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; ref = \"master\"; rev = \"$rev\"; submodules = true; }).outPath") # The resulting store path cannot be the same. [[ $pathWithoutSubmodules != "$pathWithSubmodules" ]] @@ -93,8 +93,8 @@ test "$(find "$pathWithSubmodules" -name .git)" = "" # Git repos without submodules can be fetched with submodules = true. subRev=$(git -C "$subRepo" rev-parse HEAD) -noSubmoduleRepoBaseline=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; }).outPath") -noSubmoduleRepo=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$subRepo; rev = \"$subRev\"; submodules = true; }).outPath") +noSubmoduleRepoBaseline=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$subRepo\"; rev = \"$subRev\"; }).outPath") +noSubmoduleRepo=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$subRepo\"; rev = \"$subRev\"; submodules = true; }).outPath") [[ $noSubmoduleRepoBaseline == "$noSubmoduleRepo" ]] @@ -114,7 +114,7 @@ git -C "$rootRepo" commit -a -m "Add bad submodules" rev=$(git -C "$rootRepo" rev-parse HEAD) -r=$(nix eval --raw --expr "builtins.fetchGit { url = file://$rootRepo; rev = \"$rev\"; submodules = true; }") +r=$(nix eval --raw --expr "builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev\"; submodules = true; }") [[ -f $r/file ]] [[ ! -e $r/missing ]] @@ -126,14 +126,14 @@ initGitRepo "$rootRepo" git -C "$rootRepo" submodule add ../gitSubmodulesSub sub git -C "$rootRepo" commit -m "Add submodule" rev2=$(git -C "$rootRepo" rev-parse HEAD) -pathWithRelative=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$rootRepo; rev = \"$rev2\"; submodules = true; }).outPath") +pathWithRelative=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; rev = \"$rev2\"; submodules = true; }).outPath") diff -r -x .gitmodules "$pathWithSubmodules" "$pathWithRelative" # Test clones that have an upstream with relative submodule URLs. rm "$TEST_HOME"/.cache/nix/fetcher-cache* cloneRepo=$TEST_ROOT/a/b/gitSubmodulesClone # NB /a/b to make the relative path not work relative to $cloneRepo git clone "$rootRepo" "$cloneRepo" -pathIndirect=$(nix eval --raw --expr "(builtins.fetchGit { url = file://$cloneRepo; rev = \"$rev2\"; submodules = true; }).outPath") +pathIndirect=$(nix eval --raw --expr "(builtins.fetchGit { url = \"file://$cloneRepo\"; rev = \"$rev2\"; submodules = true; }).outPath") [[ $pathIndirect = "$pathWithRelative" ]] # Test submodule export-ignore interaction @@ -161,7 +161,7 @@ git -C "$rootRepo" status # # TBD: not supported yet, because semantics are undecided and current implementation leaks rules from the root to submodules # # exportIgnore can be used with submodules -# pathWithExportIgnore=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = file://$rootRepo; submodules = true; exportIgnore = true; }).outPath") +# pathWithExportIgnore=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; submodules = true; exportIgnore = true; }).outPath") # # find $pathWithExportIgnore # # git -C $rootRepo archive --format=tar HEAD | tar -t # # cp -a $rootRepo /tmp/rootRepo @@ -176,14 +176,14 @@ git -C "$rootRepo" status # exportIgnore can be explicitly disabled with submodules -pathWithoutExportIgnore=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = file://$rootRepo; submodules = true; exportIgnore = false; }).outPath") +pathWithoutExportIgnore=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; submodules = true; exportIgnore = false; }).outPath") # find $pathWithoutExportIgnore [[ -e $pathWithoutExportIgnore/exclude-from-root ]] [[ -e $pathWithoutExportIgnore/sub/exclude-from-sub ]] # exportIgnore defaults to false when submodules = true -pathWithSubmodules=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = file://$rootRepo; submodules = true; }).outPath") +pathWithSubmodules=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$rootRepo\"; submodules = true; }).outPath") [[ -e $pathWithoutExportIgnore/exclude-from-root ]] [[ -e $pathWithoutExportIgnore/sub/exclude-from-sub ]] diff --git a/tests/functional/fetchMercurial.sh b/tests/functional/fetchMercurial.sh index 6293fb76ac2..c965936002b 100755 --- a/tests/functional/fetchMercurial.sh +++ b/tests/functional/fetchMercurial.sh @@ -34,42 +34,42 @@ rev2=$(hg log --cwd "$repo" -r tip --template '{node}') # Fetch an unclean branch. echo unclean > "$repo"/hello -path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath") +path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial \"file://$repo\").outPath") [[ $(cat "$path"/hello) = unclean ]] hg revert --cwd "$repo" --all # Fetch the default branch. -path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath") +path=$(nix eval --impure --raw --expr "(builtins.fetchMercurial \"file://$repo\").outPath") [[ $(cat "$path"/hello) = world ]] # In pure eval mode, fetchGit without a revision should fail. -[[ $(nix eval --impure --raw --expr "(builtins.readFile (fetchMercurial file://$repo + \"/hello\"))") = world ]] -(! nix eval --raw --expr "builtins.readFile (fetchMercurial file://$repo + \"/hello\")") +[[ $(nix eval --impure --raw --expr "(builtins.readFile (fetchMercurial \"file://$repo\" + \"/hello\"))") = world ]] +(! nix eval --raw --expr "builtins.readFile (fetchMercurial \"file://$repo\" + \"/hello\")") # Fetch using an explicit revision hash. -path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath") +path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial { url = \"file://$repo\"; rev = \"$rev2\"; }).outPath") [[ $path = "$path2" ]] # In pure eval mode, fetchGit with a revision should succeed. -[[ $(nix eval --raw --expr "builtins.readFile (fetchMercurial { url = file://$repo; rev = \"$rev2\"; } + \"/hello\")") = world ]] +[[ $(nix eval --raw --expr "builtins.readFile (fetchMercurial { url = \"file://$repo\"; rev = \"$rev2\"; } + \"/hello\")") = world ]] # Fetch again. This should be cached. mv "$repo" "${repo}"-tmp -path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).outPath") +path2=$(nix eval --impure --raw --expr "(builtins.fetchMercurial \"file://$repo\").outPath") [[ $path = "$path2" ]] -[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).branch") = default ]] -[[ $(nix eval --impure --expr "(builtins.fetchMercurial file://$repo).revCount") = 1 ]] -[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial file://$repo).rev") = "$rev2" ]] +[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial \"file://$repo\").branch") = default ]] +[[ $(nix eval --impure --expr "(builtins.fetchMercurial \"file://$repo\").revCount") = 1 ]] +[[ $(nix eval --impure --raw --expr "(builtins.fetchMercurial \"file://$repo\").rev") = "$rev2" ]] # But with TTL 0, it should fail. -(! nix eval --impure --refresh --expr "builtins.fetchMercurial file://$repo") +(! nix eval --impure --refresh --expr "builtins.fetchMercurial \"file://$repo\"") # Fetching with a explicit hash should succeed. -path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath") +path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = \"file://$repo\"; rev = \"$rev2\"; }).outPath") [[ $path = "$path2" ]] -path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev1\"; }).outPath") +path2=$(nix eval --refresh --raw --expr "(builtins.fetchMercurial { url = \"file://$repo\"; rev = \"$rev1\"; }).outPath") [[ $(cat "$path2"/hello) = utrecht ]] mv "${repo}"-tmp "$repo" @@ -102,7 +102,7 @@ path3=$(nix eval --impure --raw --expr "(builtins.fetchMercurial { url = $repo; # Committing should not affect the store path. hg commit --cwd "$repo" -m 'Bla3' -path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchMercurial file://$repo).outPath") +path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchMercurial \"file://$repo\").outPath") [[ $path2 = "$path4" ]] echo paris > "$repo"/hello diff --git a/tests/functional/flakes/circular.sh b/tests/functional/flakes/circular.sh index 5304496ba57..0ee111d641a 100755 --- a/tests/functional/flakes/circular.sh +++ b/tests/functional/flakes/circular.sh @@ -13,7 +13,7 @@ createGitRepo "$flakeB" cat > "$flakeA"/flake.nix < "$flakeB"/flake.nix < "$flake3Dir/flake.nix" < "$flake3Dir/flake.nix" < "$flake3Dir/flake.nix" < { impure = true; url = file://$PWD/impure-derivations.sh; }") +path7=$(nix build -L --no-link --print-out-paths --expr "import { impure = true; url = \"file://$PWD/impure-derivations.sh\"; }") cmp "$path7" "$PWD"/impure-derivations.sh diff --git a/tests/functional/lang/parse-fail-url.err.exp b/tests/functional/lang/parse-fail-url.err.exp new file mode 100644 index 00000000000..40d84bc890e --- /dev/null +++ b/tests/functional/lang/parse-fail-url.err.exp @@ -0,0 +1,5 @@ +error: URL literals are disabled + at «stdin»:1:1: + 1| http://example.org + | ^ + 2| diff --git a/tests/functional/lang/parse-fail-url.nix b/tests/functional/lang/parse-fail-url.nix new file mode 100644 index 00000000000..86501757d14 --- /dev/null +++ b/tests/functional/lang/parse-fail-url.nix @@ -0,0 +1 @@ +http://example.org diff --git a/tests/functional/lang/parse-okay-regression-20041027.nix b/tests/functional/lang/parse-okay-regression-20041027.nix index ae2e256eeaa..e1bd41a2114 100644 --- a/tests/functional/lang/parse-okay-regression-20041027.nix +++ b/tests/functional/lang/parse-okay-regression-20041027.nix @@ -3,7 +3,7 @@ stdenv.mkDerivation { name = "libXi-6.0.1"; src = fetchurl { - url = http://freedesktop.org/~xlibs/release/libXi-6.0.1.tar.bz2; + url = "http://freedesktop.org/~xlibs/release/libXi-6.0.1.tar.bz2"; md5 = "7e935a42428d63a387b3c048be0f2756"; }; /* buildInputs = [pkgconfig]; diff --git a/tests/functional/lang/parse-okay-subversion.nix b/tests/functional/lang/parse-okay-subversion.nix index 356272815d2..360b695b291 100644 --- a/tests/functional/lang/parse-okay-subversion.nix +++ b/tests/functional/lang/parse-okay-subversion.nix @@ -21,7 +21,7 @@ stdenv.mkDerivation { builder = /foo/bar; src = fetchurl { - url = http://subversion.tigris.org/tarballs/subversion-1.1.1.tar.bz2; + url = "http://subversion.tigris.org/tarballs/subversion-1.1.1.tar.bz2"; md5 = "a180c3fe91680389c210c99def54d9e0"; }; diff --git a/tests/functional/lang/parse-okay-url.exp b/tests/functional/lang/parse-okay-url.exp deleted file mode 100644 index e5f0829b0ce..00000000000 --- a/tests/functional/lang/parse-okay-url.exp +++ /dev/null @@ -1 +0,0 @@ -[ ("x:x") ("https://svn.cs.uu.nl:12443/repos/trace/trunk") ("http://www2.mplayerhq.hu/MPlayer/releases/fonts/font-arial-iso-8859-1.tar.bz2") ("http://losser.st-lab.cs.uu.nl/~armijn/.nix/gcc-3.3.4-static-nix.tar.gz") ("http://fpdownload.macromedia.com/get/shockwave/flash/english/linux/7.0r25/install_flash_player_7_linux.tar.gz") ("https://ftp5.gwdg.de/pub/linux/archlinux/extra/os/x86_64/unzip-6.0-14-x86_64.pkg.tar.zst") ("ftp://ftp.gtk.org/pub/gtk/v1.2/gtk+-1.2.10.tar.gz") ] diff --git a/tests/functional/lang/parse-okay-url.nix b/tests/functional/lang/parse-okay-url.nix deleted file mode 100644 index 08de27d0a4c..00000000000 --- a/tests/functional/lang/parse-okay-url.nix +++ /dev/null @@ -1,8 +0,0 @@ -[ x:x - https://svn.cs.uu.nl:12443/repos/trace/trunk - http://www2.mplayerhq.hu/MPlayer/releases/fonts/font-arial-iso-8859-1.tar.bz2 - http://losser.st-lab.cs.uu.nl/~armijn/.nix/gcc-3.3.4-static-nix.tar.gz - http://fpdownload.macromedia.com/get/shockwave/flash/english/linux/7.0r25/install_flash_player_7_linux.tar.gz - https://ftp5.gwdg.de/pub/linux/archlinux/extra/os/x86_64/unzip-6.0-14-x86_64.pkg.tar.zst - ftp://ftp.gtk.org/pub/gtk/v1.2/gtk+-1.2.10.tar.gz -] diff --git a/tests/functional/no-url-literals.sh b/tests/functional/no-url-literals.sh index fbc6e1cec24..c193cb36f6f 100644 --- a/tests/functional/no-url-literals.sh +++ b/tests/functional/no-url-literals.sh @@ -4,25 +4,19 @@ source common.sh clearStoreIfPossible -# Test 1: By default, unquoted URLs are accepted -nix eval --expr 'http://example.com' 2>&1 | grepQuietInverse "error: URL literals are disabled" +# Unquoted URLs are rejected +expect 1 nix eval --expr 'http://example.com' 2>&1 | grepQuiet "error: URL literals are disabled" -# Test 2: With the experimental feature enabled, unquoted URLs are rejected -expect 1 nix eval --extra-experimental-features 'no-url-literals' --expr 'http://example.com' 2>&1 | grepQuiet "error: URL literals are disabled" +# But accepted when explicitly enabled as a deprecated feature +nix eval --extra-deprecated-features url-literals --expr 'http://example.com' 2>&1 | grepQuietInverse "error: URL literals are disabled" -# Test 3: Quoted URLs are always accepted -nix eval --extra-experimental-features 'no-url-literals' --expr '"http://example.com"' 2>&1 | grepQuietInverse "error: URL literals are disabled" +# Quoted URLs are always accepted +nix eval --expr '"http://example.com"' 2>&1 | grepQuietInverse "error: URL literals are disabled" -# Test 4: URLs with parameters (which must be quoted) are accepted -nix eval --extra-experimental-features 'no-url-literals' --expr '"http://example.com?foo=bar"' 2>&1 | grepQuietInverse "error: URL literals are disabled" +# URLs with parameters (which must be quoted) are accepted +nix eval --expr '"http://example.com?foo=bar"' 2>&1 | grepQuietInverse "error: URL literals are disabled" -# Test 5: The feature can be enabled via NIX_CONFIG -expect 1 env NIX_CONFIG='extra-experimental-features = no-url-literals' nix eval --expr 'http://example.com' 2>&1 | grepQuiet "error: URL literals are disabled" - -# Test 6: The feature can be enabled via CLI even if not set in config -expect 1 env NIX_CONFIG='' nix eval --extra-experimental-features 'no-url-literals' --expr 'http://example.com' 2>&1 | grepQuiet "error: URL literals are disabled" - -# Test 7: Evaluation still works for quoted URLs -nix eval --raw --extra-experimental-features no-url-literals --expr '"http://example.com"' | grepQuiet "^http://example.com$" +# Evaluation still works for quoted URLs +nix eval --raw --expr '"http://example.com"' | grepQuiet "^http://example.com$" echo "no-url-literals test passed!" diff --git a/tests/functional/pure-eval.sh b/tests/functional/pure-eval.sh index b769b2150f1..4af4bc0d244 100755 --- a/tests/functional/pure-eval.sh +++ b/tests/functional/pure-eval.sh @@ -22,9 +22,9 @@ echo "$missingImpureErrorMsg" | grepQuiet -- --impure || \ (! nix-instantiate --pure-eval ./simple.nix) -[[ $(nix eval --impure --expr "(import (builtins.fetchurl { url = file://$(pwd)/pure-eval.nix; })).x") == 123 ]] -(! nix eval --expr "(import (builtins.fetchurl { url = file://$(pwd)/pure-eval.nix; })).x") -nix eval --expr "(import (builtins.fetchurl { url = file://$(pwd)/pure-eval.nix; sha256 = \"$(nix hash file pure-eval.nix --type sha256)\"; })).x" +[[ $(nix eval --impure --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x") == 123 ]] +(! nix eval --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x") +nix eval --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; sha256 = \"$(nix hash file pure-eval.nix --type sha256)\"; })).x" rm -rf "$TEST_ROOT"/eval-out nix eval --store dummy:// --write-to "$TEST_ROOT"/eval-out --expr '{ x = "foo" + "bar"; y = { z = "bla"; }; }' diff --git a/tests/functional/restricted.sh b/tests/functional/restricted.sh index 2f65f15fe5d..c86abebee3d 100755 --- a/tests/functional/restricted.sh +++ b/tests/functional/restricted.sh @@ -26,18 +26,18 @@ nix-instantiate --restrict-eval --eval -E 'builtins.readFile ./simple.nix' -I sr expectStderr 1 nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile ' | grepQuiet "forbidden in restricted mode" nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in builtins.readFile ' -I src=. -p=$(nix eval --raw --expr "builtins.fetchurl file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}") +p=$(nix eval --raw --expr "builtins.fetchurl \"file://${_NIX_TEST_SOURCE_DIR}/restricted.sh\"" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}") cmp "$p" "${_NIX_TEST_SOURCE_DIR}/restricted.sh" -(! nix eval --raw --expr "builtins.fetchurl file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" --impure --restrict-eval) +(! nix eval --raw --expr "builtins.fetchurl \"file://${_NIX_TEST_SOURCE_DIR}/restricted.sh\"" --impure --restrict-eval) -(! nix eval --raw --expr "builtins.fetchurl file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}/restricted.sh/") +(! nix eval --raw --expr "builtins.fetchurl \"file://${_NIX_TEST_SOURCE_DIR}/restricted.sh\"" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}/restricted.sh/") -nix eval --raw --expr "builtins.fetchurl file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" +nix eval --raw --expr "builtins.fetchurl \"file://${_NIX_TEST_SOURCE_DIR}/restricted.sh\"" --impure --restrict-eval --allowed-uris "file://${_NIX_TEST_SOURCE_DIR}/restricted.sh" -(! nix eval --raw --expr "builtins.fetchurl https://github.com/NixOS/patchelf/archive/master.tar.gz" --impure --restrict-eval) -(! nix eval --raw --expr "builtins.fetchTarball https://github.com/NixOS/patchelf/archive/master.tar.gz" --impure --restrict-eval) -(! nix eval --raw --expr "fetchGit git://github.com/NixOS/patchelf.git" --impure --restrict-eval) +(! nix eval --raw --expr "builtins.fetchurl \"https://github.com/NixOS/patchelf/archive/master.tar.gz\"" --impure --restrict-eval) +(! nix eval --raw --expr "builtins.fetchTarball \"https://github.com/NixOS/patchelf/archive/master.tar.gz\"" --impure --restrict-eval) +(! nix eval --raw --expr "fetchGit \"git://github.com/NixOS/patchelf.git\"" --impure --restrict-eval) ln -sfn "${_NIX_TEST_SOURCE_DIR}/restricted.nix" "$TEST_ROOT/restricted.nix" [[ $(nix-instantiate --eval "$TEST_ROOT"/restricted.nix) == 3 ]] diff --git a/tests/functional/tarball.sh b/tests/functional/tarball.sh index 6b09cf6a5ce..2359768527b 100755 --- a/tests/functional/tarball.sh +++ b/tests/functional/tarball.sh @@ -28,18 +28,18 @@ test_tarball() { nix-build -o "$TEST_ROOT"/result '' -I foo=file://"$tarball" - nix-build -o "$TEST_ROOT"/result -E "import (fetchTarball file://$tarball)" + nix-build -o "$TEST_ROOT"/result -E "import (fetchTarball \"file://$tarball\")" # Do not re-fetch paths already present - nix-build -o "$TEST_ROOT"/result -E "import (fetchTarball { url = file:///does-not-exist/must-remain-unused/$tarball; sha256 = \"$hash\"; })" + nix-build -o "$TEST_ROOT"/result -E "import (fetchTarball { url = \"file:///does-not-exist/must-remain-unused/$tarball\"; sha256 = \"$hash\"; })" - nix-build -o "$TEST_ROOT"/result -E "import (fetchTree file://$tarball)" - nix-build -o "$TEST_ROOT"/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; })" - nix-build -o "$TEST_ROOT"/result -E "import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })" + nix-build -o "$TEST_ROOT"/result -E "import (fetchTree \"file://$tarball\")" + nix-build -o "$TEST_ROOT"/result -E "import (fetchTree { type = \"tarball\"; url = \"file://$tarball\"; })" + nix-build -o "$TEST_ROOT"/result -E "import (fetchTree { type = \"tarball\"; url = \"file://$tarball\"; narHash = \"$hash\"; })" - [[ $(nix eval --impure --expr "(fetchTree file://$tarball).lastModified") = 1000000000 ]] + [[ $(nix eval --impure --expr "(fetchTree \"file://$tarball\").lastModified") = 1000000000 ]] - nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })) ? submodules)" >&2 - nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; })) ? submodules)" 2>&1 | grep 'true' + nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = \"file://$tarball\"; narHash = \"$hash\"; })) ? submodules)" >&2 + nix-instantiate --strict --eval -E "!((import (fetchTree { type = \"tarball\"; url = \"file://$tarball\"; narHash = \"$hash\"; })) ? submodules)" 2>&1 | grep 'true' nix-instantiate --eval -E '1 + 2' -I fnord=file:///no-such-tarball.tar"$ext" nix-instantiate --eval -E 'with ; 1 + 2' -I fnord=file:///no-such-tarball"$ext" @@ -49,7 +49,7 @@ test_tarball() { # Ensure that the `name` attribute isn’t accepted as that would mess # with the content-addressing - (! nix-instantiate --eval -E "fetchTree { type = \"tarball\"; url = file://$tarball; narHash = \"$hash\"; name = \"foo\"; }") + (! nix-instantiate --eval -E "fetchTree { type = \"tarball\"; url = \"file://$tarball\"; narHash = \"$hash\"; name = \"foo\"; }") store_path=$(nix store prefetch-file --json "file://$tarball" | jq -r .storePath) if ! cmp -s "$store_path" "$tarball"; then