diff options
Diffstat (limited to 'nixpkgs/pkgs/test/nixpkgs-check-by-name')
102 files changed, 794 insertions, 374 deletions
diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/README.md index 19865ca0952b..1aa256978416 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/README.md +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/README.md @@ -1,9 +1,13 @@ # Nixpkgs pkgs/by-name checker This directory implements a program to check the [validity](#validity-checks) of the `pkgs/by-name` Nixpkgs directory. -It is being used by [this GitHub Actions workflow](../../../.github/workflows/check-by-name.yml). This is part of the implementation of [RFC 140](https://github.com/NixOS/rfcs/pull/140). +A [pinned version](./scripts/pinned-tool.json) of this tool is used by [this GitHub Actions workflow](../../../.github/workflows/check-by-name.yml). +See [./scripts](./scripts/README.md#update-pinned-toolsh) for how to update the pinned version. + +The source of the tool being right inside Nixpkgs allows any Nixpkgs committer to make updates to it. + ## Interface The interface of the tool is shown with `--help`: @@ -28,6 +32,8 @@ These checks are performed by this tool: - Each package directory must not refer to files outside itself using symlinks or Nix path expressions. ### Nix evaluation checks + +Evaluate Nixpkgs with `system` set to `x86_64-linux` and check that: - For each package directory, the `pkgs.${name}` attribute must be defined as `callPackage pkgs/by-name/${shard}/${name}/package.nix args` for some `args`. - For each package directory, `pkgs.lib.isDerivation pkgs.${name}` must be `true`. @@ -43,6 +49,8 @@ The current ratchets are: - New manual definitions of `pkgs.${name}` (e.g. in `pkgs/top-level/all-packages.nix`) with `args = { }` (see [nix evaluation checks](#nix-evaluation-checks)) must not be introduced. +- New top-level packages defined using `pkgs.callPackage` must be defined with a package directory. + - Once a top-level package uses `pkgs/by-name`, it also can't be moved back out of it. ## Development @@ -65,7 +73,7 @@ Tests are declared in [`./tests`](./tests) as subdirectories imitating Nixpkgs w - `default.nix`: Always contains ```nix - import ../mock-nixpkgs.nix { root = ./.; } + import <test-nixpkgs> { root = ./.; } ``` which makes ``` @@ -92,18 +100,3 @@ Tests are declared in [`./tests`](./tests) as subdirectories imitating Nixpkgs w - `expected` (optional): A file containing the expected standard output. The default is expecting an empty standard output. - -## Hydra builds - -This program will always be available pre-built for `x86_64-linux` on the `nixos-unstable` channel and `nixos-XX.YY` channels. -This is ensured by including it in the `tested` jobset description in [`nixos/release-combined.nix`](../../../nixos/release-combined.nix). - -This allows CI for PRs to development branches `master` and `release-XX.YY` to fetch the pre-built program from the corresponding channel and use that to check the PR. This has the following benefits: -- It allows CI to check all PRs, even if they would break the CI tooling. -- It makes the CI check very fast, since no Nix builds need to be done, even for mass rebuilds. -- It improves security, since we don't have to build potentially untrusted code from PRs. - The tool only needs a very minimal Nix evaluation at runtime, which can work with [readonly-mode](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-readonly-mode) and [restrict-eval](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-restrict-eval). -- It allows anybody to make updates to the tooling and for those updates to be automatically used by CI without needing a separate release mechanism. - -The tradeoff is that there's a delay between updates to the tool and those updates being used by CI. -This needs to be considered when updating the [API](#api). diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/default.nix index fc24b1fd3398..8836da1f403f 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/default.nix @@ -6,13 +6,41 @@ clippy, mkShell, makeWrapper, + runCommand, }: let runtimeExprPath = ./src/eval.nix; + nixpkgsLibPath = ../../../lib; + testNixpkgsPath = ./tests/mock-nixpkgs.nix; + + # Needed to make Nix evaluation work inside nix builds + initNix = '' + export TEST_ROOT=$(pwd)/test-tmp + export NIX_CONF_DIR=$TEST_ROOT/etc + export NIX_LOCALSTATE_DIR=$TEST_ROOT/var + export NIX_LOG_DIR=$TEST_ROOT/var/log/nix + export NIX_STATE_DIR=$TEST_ROOT/var/nix + export NIX_STORE_DIR=$TEST_ROOT/store + + # Ensure that even if tests run in parallel, we don't get an error + # We'd run into https://github.com/NixOS/nix/issues/2706 unless the store is initialised first + nix-store --init + ''; + + fs = lib.fileset; + package = rustPlatform.buildRustPackage { name = "nixpkgs-check-by-name"; - src = lib.cleanSource ./.; + src = fs.toSource { + root = ./.; + fileset = fs.unions [ + ./Cargo.lock + ./Cargo.toml + ./src + ./tests + ]; + }; cargoLock.lockFile = ./Cargo.lock; nativeBuildInputs = [ nix @@ -21,19 +49,8 @@ let makeWrapper ]; env.NIX_CHECK_BY_NAME_EXPR_PATH = "${runtimeExprPath}"; - # Needed to make Nix evaluation work inside the nix build - preCheck = '' - export TEST_ROOT=$(pwd)/test-tmp - export NIX_CONF_DIR=$TEST_ROOT/etc - export NIX_LOCALSTATE_DIR=$TEST_ROOT/var - export NIX_LOG_DIR=$TEST_ROOT/var/log/nix - export NIX_STATE_DIR=$TEST_ROOT/var/nix - export NIX_STORE_DIR=$TEST_ROOT/store - - # Ensure that even if tests run in parallel, we don't get an error - # We'd run into https://github.com/NixOS/nix/issues/2706 unless the store is initialised first - nix-store --init - ''; + env.NIX_PATH = "test-nixpkgs=${testNixpkgsPath}:test-nixpkgs/lib=${nixpkgsLibPath}"; + preCheck = initNix; postCheck = '' cargo fmt --check cargo clippy -- -D warnings @@ -44,8 +61,22 @@ let ''; passthru.shell = mkShell { env.NIX_CHECK_BY_NAME_EXPR_PATH = toString runtimeExprPath; + env.NIX_PATH = "test-nixpkgs=${toString testNixpkgsPath}:test-nixpkgs/lib=${toString nixpkgsLibPath}"; inputsFrom = [ package ]; }; + + # Tests the tool on the current Nixpkgs tree, this is a good sanity check + passthru.tests.nixpkgs = runCommand "test-nixpkgs-check-by-name" { + nativeBuildInputs = [ + package + nix + ]; + nixpkgsPath = lib.cleanSource ../../..; + } '' + ${initNix} + nixpkgs-check-by-name --base "$nixpkgsPath" "$nixpkgsPath" + touch $out + ''; }; in package diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md index 41b3012b7d95..ccd4108ea288 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/README.md @@ -1,6 +1,7 @@ # CI-related Scripts -This directory contains scripts used and related to the CI running the `pkgs/by-name` checks in Nixpkgs. See also the [CI GitHub Action](../../../../.github/workflows/check-by-name.yml). +This directory contains scripts and files used and related to the CI running the `pkgs/by-name` checks in Nixpkgs. +See also the [CI GitHub Action](../../../../.github/workflows/check-by-name.yml). ## `./run-local.sh BASE_BRANCH [REPOSITORY]` @@ -15,12 +16,23 @@ Arguments: - `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 - `REPOSITORY`: The repository to fetch the base branch from, defaults to https://github.com/NixOS/nixpkgs.git -## `./fetch-tool.sh BASE_BRANCH OUTPUT_PATH` +## `./update-pinned-tool.sh` -Fetches the Hydra-prebuilt nixpkgs-check-by-name to use from the NixOS channel corresponding to the given base branch. +Updates the pinned CI tool in [`./pinned-tool.json`](./pinned-tool.json) to the +[latest version from the `nixos-unstable` channel](https://hydra.nixos.org/job/nixos/trunk-combined/nixpkgs.tests.nixpkgs-check-by-name.x86_64-linux). -This script is used both by [`./run-local.sh`](#run-local-sh-base-branch-repository) and CI. +This script needs to be called manually when the CI tooling needs to be updated. + +The `pinned-tool.json` file gets populated with both: +- The `/nix/store` path for `x86_64-linux`, such that CI doesn't have to evaluate Nixpkgs and can directly fetch it from the cache instead. +- The Nixpkgs revision, such that the `./run-local.sh` script can be used to run the checks locally on any system. + +To ensure that the tool is always pre-built for `x86_64-linux` in the `nixos-unstable` channel, +it's included in the `tested` jobset description in [`nixos/release-combined.nix`](../../../nixos/release-combined.nix). + +Why not just build the tooling right from the PRs Nixpkgs version? +- Because it allows CI to check all PRs, even if they would break the CI tooling. +- Because it makes the CI check very fast, since no Nix builds need to be done, even for mass rebuilds. +- Because it improves security, since we don't have to build potentially untrusted code from PRs. + The tool only needs a very minimal Nix evaluation at runtime, which can work with [readonly-mode](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-readonly-mode) and [restrict-eval](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-restrict-eval). -Arguments: -- `BASE_BRANCH`: The base branch to use, e.g. master or release-23.11 -- `OUTPUT_PATH`: The output symlink path for the tool diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh deleted file mode 100755 index 19a48b6fb1fd..000000000000 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -# Fetches the prebuilt nixpkgs-check-by-name to use from -# the NixOS channel corresponding to the given base branch - -set -o pipefail -o errexit -o nounset - -trace() { echo >&2 "$@"; } - -if (( $# < 2 )); then - trace "Usage: $0 BASE_BRANCH OUTPUT_PATH" - trace "BASE_BRANCH: The base branch to use, e.g. master or release-23.11" - trace "OUTPUT_PATH: The output symlink path for the tool" - exit 1 -fi -baseBranch=$1 -output=$2 - -trace -n "Determining the channel to use for PR base branch $baseBranch.. " -if [[ "$baseBranch" =~ ^(release|staging|staging-next)-([0-9][0-9]\.[0-9][0-9])$ ]]; then - # Use the release channel for all PRs to release-XX.YY, staging-XX.YY and staging-next-XX.YY - preferredChannel=nixos-${BASH_REMATCH[2]} -else - # Use the nixos-unstable channel for all other PRs - preferredChannel=nixos-unstable -fi - -# Check that the channel exists. It doesn't exist for fresh release branches -if curl -fSs "https://channels.nixos.org/$preferredChannel"; then - channel=$preferredChannel - trace "$channel" -else - # Fall back to nixos-unstable, makes sense for fresh release branches - channel=nixos-unstable - trace -e "\e[33mWarning: Preferred channel $preferredChannel could not be fetched, using fallback: $channel\e[0m" -fi - -trace -n "Fetching latest version of channel $channel.. " -# This is probably the easiest way to get Nix to output the path to a downloaded channel! -nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") -trace "$nixpkgs" - -# This file only exists in channels -trace -e "Git revision of channel $channel is \e[34m$(<"$nixpkgs/.git-revision")\e[0m" - -trace -n "Fetching the prebuilt version of nixpkgs-check-by-name.. " -nix-build -o "$output" "$nixpkgs" -A tests.nixpkgs-check-by-name -j 0 >/dev/null -realpath "$output" >&2 diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json new file mode 100644 index 000000000000..b703ce74771e --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json @@ -0,0 +1,4 @@ +{ + "rev": "9b19f5e77dd906cb52dade0b7bd280339d2a1f3d", + "ci-path": "/nix/store/qlls5ca8q88qpyygg9ddi60gl1nmvpij-nixpkgs-check-by-name" +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh index 72d3e8dc3de3..46cbd5e858e2 100755 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh @@ -1,4 +1,5 @@ -#!/usr/bin/env bash +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p jq set -o pipefail -o errexit -o nounset @@ -13,6 +14,7 @@ cleanup() { [[ -e "$tmp/base" ]] && git worktree remove --force "$tmp/base" [[ -e "$tmp/merged" ]] && git worktree remove --force "$tmp/merged" + [[ -e "$tmp/tool-nixpkgs" ]] && git worktree remove --force "$tmp/tool-nixpkgs" rm -rf "$tmp" @@ -61,7 +63,20 @@ trace -n "Merging base branch into the HEAD commit in $tmp/merged.. " git -C "$tmp/merged" merge -q --no-edit "$baseSha" trace -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m" -"$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/fetch-tool.sh" "$baseBranch" "$tmp/tool" +trace -n "Reading pinned nixpkgs-check-by-name revision from pinned-tool.json.. " +toolSha=$(jq -r .rev "$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json") +trace -e "\e[34m$toolSha\e[0m" + +trace -n "Creating Git worktree for the nixpkgs-check-by-name revision in $tmp/tool-nixpkgs.. " +git worktree add -q "$tmp/tool-nixpkgs" "$toolSha" +trace "Done" + +trace "Building/fetching nixpkgs-check-by-name.." +nix-build -o "$tmp/tool" "$tmp/tool-nixpkgs" \ + -A tests.nixpkgs-check-by-name \ + --arg config '{}' \ + --arg overlays '[]' \ + -j 0 trace "Running nixpkgs-check-by-name.." "$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged" diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/update-pinned-tool.sh b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/update-pinned-tool.sh new file mode 100755 index 000000000000..dbc6e91df08a --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/scripts/update-pinned-tool.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p jq + +set -o pipefail -o errexit -o nounset + +trace() { echo >&2 "$@"; } + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Determined by `runs-on: ubuntu-latest` in .github/workflows/check-by-name.yml +CI_SYSTEM=x86_64-linux + +channel=nixos-unstable +pin_file=$SCRIPT_DIR/pinned-tool.json + +trace -n "Fetching latest version of channel $channel.. " +# This is probably the easiest way to get Nix to output the path to a downloaded channel! +nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel") +trace "$nixpkgs" + +# This file only exists in channels +rev=$(<"$nixpkgs/.git-revision") +trace -e "Git revision of channel $channel is \e[34m$rev\e[0m" + +trace -n "Fetching the prebuilt version of nixpkgs-check-by-name for $CI_SYSTEM.. " +# This is the architecture used by CI, we want to prefetch the exact path to avoid having to evaluate Nixpkgs +ci_path=$(nix-build --no-out-link "$nixpkgs" \ + -A tests.nixpkgs-check-by-name \ + --arg config '{}' \ + --argstr system "$CI_SYSTEM" \ + --arg overlays '[]' \ + -j 0 \ + | tee /dev/stderr) + +trace "Updating $pin_file" +jq -n \ + --arg rev "$rev" \ + --arg ci-path "$ci_path" \ + '$ARGS.named' \ + > "$pin_file" diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix index bf9f19d8e460..87c54b6444ee 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix @@ -1,11 +1,7 @@ # Takes a path to nixpkgs and a path to the json-encoded list of attributes to check. -# Returns an attribute set containing information on each requested attribute. -# If the attribute is missing from Nixpkgs it's also missing from the result. -# -# The returned information is an attribute set with: -# - call_package_path: The <path> from `<attr> = callPackage <path> { ... }`, -# or null if it's not defined as with callPackage, or if the <path> is not a path -# - is_derivation: The result of `lib.isDerivation <attr>` +# Returns an value containing information on each requested attribute, +# which is decoded on the Rust side. +# See ./eval.rs for the meaning of the returned values { attrsPath, nixpkgsPath, @@ -13,70 +9,107 @@ let attrs = builtins.fromJSON (builtins.readFile attrsPath); - # This overlay mocks callPackage to persist the path of the first argument - callPackageOverlay = self: super: { + nixpkgsPathLength = builtins.stringLength (toString nixpkgsPath) + 1; + removeNixpkgsPrefix = builtins.substring nixpkgsPathLength (-1); + + # We need access to the `callPackage` arguments of each attribute. + # The only way to do so is to override `callPackage` with our own version that adds this information to the result, + # and then try to access this information. + overlay = final: prev: { + + # Information for attributes defined using `callPackage` callPackage = fn: args: - let - result = super.callPackage fn args; - variantInfo._attributeVariant = { - # These names are used by the deserializer on the Rust side - CallPackage.path = + addVariantInfo (prev.callPackage fn args) { + Manual = { + path = if builtins.isPath fn then - toString fn + removeNixpkgsPrefix (toString fn) else null; - CallPackage.empty_arg = + empty_arg = args == { }; }; - in - if builtins.isAttrs result then - # If this was the last overlay to be applied, we could just only return the `_callPackagePath`, - # but that's not the case because stdenv has another overlays on top of user-provided ones. - # So to not break the stdenv build we need to return the mostly proper result here - result // variantInfo - else - # It's very rare that callPackage doesn't return an attribute set, but it can occur. - variantInfo; + }; + # Information for attributes that are auto-called from pkgs/by-name. + # This internal attribute is only used by pkgs/by-name _internalCallByNamePackageFile = file: - let - result = super._internalCallByNamePackageFile file; - variantInfo._attributeVariant = { - # This name is used by the deserializer on the Rust side - AutoCalled = null; - }; - in - if builtins.isAttrs result then - # If this was the last overlay to be applied, we could just only return the `_callPackagePath`, - # but that's not the case because stdenv has another overlays on top of user-provided ones. - # So to not break the stdenv build we need to return the mostly proper result here - result // variantInfo - else - # It's very rare that callPackage doesn't return an attribute set, but it can occur. - variantInfo; + addVariantInfo (prev._internalCallByNamePackageFile file) { + Auto = null; + }; + }; + # We can't just replace attribute values with their info in the overlay, + # because attributes can depend on other attributes, so this would break evaluation. + addVariantInfo = value: variant: + if builtins.isAttrs value then + value // { + _callPackageVariant = variant; + } + else + # It's very rare that callPackage doesn't return an attribute set, but it can occur. + # In such a case we can't really return anything sensible that would include the info, + # so just don't return the info and let the consumer handle it. + value; + pkgs = import nixpkgsPath { # Don't let the users home directory influence this result config = { }; - overlays = [ callPackageOverlay ]; + overlays = [ overlay ]; + # We check evaluation and callPackage only for x86_64-linux. + # Not ideal, but hard to fix + system = "x86_64-linux"; }; - attrInfo = attr: - let - value = pkgs.${attr}; - in - { - # These names are used by the deserializer on the Rust side - variant = value._attributeVariant or { Other = null; }; - is_derivation = pkgs.lib.isDerivation value; - }; + attrInfo = name: value: + if ! builtins.isAttrs value then + { + NonAttributeSet = null; + } + else if ! value ? _callPackageVariant then + { + NonCallPackage = null; + } + else + { + CallPackage = { + call_package_variant = value._callPackageVariant; + is_derivation = pkgs.lib.isDerivation value; + }; + }; - attrInfos = builtins.listToAttrs (map (name: { + byNameAttrs = builtins.listToAttrs (map (name: { inherit name; - value = attrInfo name; + value.ByName = + if ! pkgs ? ${name} then + { Missing = null; } + else + { Existing = attrInfo name pkgs.${name}; }; }) attrs); + # Information on all attributes that exist but are not in pkgs/by-name. + # We need this to enforce pkgs/by-name for new packages + nonByNameAttrs = builtins.mapAttrs (name: value: + let + output = attrInfo name value; + result = builtins.tryEval (builtins.deepSeq output null); + in + { + NonByName = + if result.success then + { EvalSuccess = output; } + else + { EvalFailure = null; }; + } + ) (builtins.removeAttrs pkgs attrs); + + # All attributes + attributes = byNameAttrs // nonByNameAttrs; in -# Filter out attributes not in Nixpkgs -builtins.intersectAttrs pkgs attrInfos +# We output them in the form [ [ <name> <value> ] ]` such that the Rust side +# doesn't need to sort them again to get deterministic behavior (good for testing) +map (name: [ + name + attributes.${name} +]) (builtins.attrNames attributes) diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs index cd8c70472cf2..e4584f09d8cd 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs @@ -6,33 +6,63 @@ use std::path::Path; use anyhow::Context; use serde::Deserialize; -use std::collections::HashMap; use std::path::PathBuf; use std::process; use tempfile::NamedTempFile; /// Attribute set of this structure is returned by eval.nix #[derive(Deserialize)] -struct AttributeInfo { - variant: AttributeVariant, +enum Attribute { + /// An attribute that should be defined via pkgs/by-name + ByName(ByNameAttribute), + /// An attribute not defined via pkgs/by-name + NonByName(NonByNameAttribute), +} + +#[derive(Deserialize)] +enum NonByNameAttribute { + /// The attribute doesn't evaluate + EvalFailure, + EvalSuccess(AttributeInfo), +} + +#[derive(Deserialize)] +enum ByNameAttribute { + /// The attribute doesn't exist at all + Missing, + Existing(AttributeInfo), +} + +#[derive(Deserialize)] +enum AttributeInfo { + /// The attribute exists, but its value isn't an attribute set + NonAttributeSet, + /// The attribute exists, but its value isn't defined using callPackage + NonCallPackage, + /// The attribute exists and its value is an attribute set + CallPackage(CallPackageInfo), +} + +#[derive(Deserialize)] +struct CallPackageInfo { + call_package_variant: CallPackageVariant, + /// Whether the attribute is a derivation (`lib.isDerivation`) is_derivation: bool, } #[derive(Deserialize)] -enum AttributeVariant { +enum CallPackageVariant { /// The attribute is auto-called as pkgs.callPackage using pkgs/by-name, /// and it is not overridden by a definition in all-packages.nix - AutoCalled, + Auto, /// The attribute is defined as a pkgs.callPackage <path> <args>, /// and overridden by all-packages.nix - CallPackage { + Manual { /// The <path> argument or None if it's not a path path: Option<PathBuf>, /// true if <args> is { } empty_arg: bool, }, - /// The attribute is not defined as pkgs.callPackage - Other, } /// Check that the Nixpkgs attribute values corresponding to the packages in pkgs/by-name are @@ -41,32 +71,32 @@ enum AttributeVariant { pub fn check_values( nixpkgs_path: &Path, package_names: Vec<String>, - eval_accessible_paths: &[&Path], + keep_nix_path: bool, ) -> validation::Result<ratchet::Nixpkgs> { // Write the list of packages we need to check into a temporary JSON file. // This can then get read by the Nix evaluation. - let attrs_file = NamedTempFile::new().context("Failed to create a temporary file")?; + let attrs_file = NamedTempFile::new().with_context(|| "Failed to create a temporary file")?; // We need to canonicalise this path because if it's a symlink (which can be the case on // Darwin), Nix would need to read both the symlink and the target path, therefore need 2 // NIX_PATH entries for restrict-eval. But if we resolve the symlinks then only one predictable // entry is needed. let attrs_file_path = attrs_file.path().canonicalize()?; - serde_json::to_writer(&attrs_file, &package_names).context(format!( - "Failed to serialise the package names to the temporary path {}", - attrs_file_path.display() - ))?; + serde_json::to_writer(&attrs_file, &package_names).with_context(|| { + format!( + "Failed to serialise the package names to the temporary path {}", + attrs_file_path.display() + ) + })?; let expr_path = std::env::var("NIX_CHECK_BY_NAME_EXPR_PATH") - .context("Could not get environment variable NIX_CHECK_BY_NAME_EXPR_PATH")?; + .with_context(|| "Could not get environment variable NIX_CHECK_BY_NAME_EXPR_PATH")?; // With restrict-eval, only paths in NIX_PATH can be accessed, so we explicitly specify the // ones needed needed let mut command = process::Command::new("nix-instantiate"); command // Inherit stderr so that error messages always get shown .stderr(process::Stdio::inherit()) - // Clear NIX_PATH to be sure it doesn't influence the result - .env_remove("NIX_PATH") .args([ "--eval", "--json", @@ -87,90 +117,174 @@ pub fn check_values( .arg("-I") .arg(nixpkgs_path); - // Also add extra paths that need to be accessible - for path in eval_accessible_paths { - command.arg("-I"); - command.arg(path); + // Clear NIX_PATH to be sure it doesn't influence the result + // But not when requested to keep it, used so that the tests can pass extra Nix files + if !keep_nix_path { + command.env_remove("NIX_PATH"); } + command.args(["-I", &expr_path]); command.arg(expr_path); let result = command .output() - .context(format!("Failed to run command {command:?}"))?; + .with_context(|| format!("Failed to run command {command:?}"))?; if !result.status.success() { anyhow::bail!("Failed to run command {command:?}"); } // Parse the resulting JSON value - let actual_files: HashMap<String, AttributeInfo> = serde_json::from_slice(&result.stdout) - .context(format!( - "Failed to deserialise {}", - String::from_utf8_lossy(&result.stdout) - ))?; - - Ok( - validation::sequence(package_names.into_iter().map(|package_name| { - let relative_package_file = structure::relative_file_for_package(&package_name); - let absolute_package_file = nixpkgs_path.join(&relative_package_file); - - if let Some(attribute_info) = actual_files.get(&package_name) { - let check_result = if !attribute_info.is_derivation { - NixpkgsProblem::NonDerivation { - relative_package_file: relative_package_file.clone(), - package_name: package_name.clone(), - } - .into() - } else { - Success(()) - }; - - let check_result = check_result.and(match &attribute_info.variant { - AttributeVariant::AutoCalled => Success(ratchet::Package { - empty_non_auto_called: ratchet::EmptyNonAutoCalled::Valid, - }), - AttributeVariant::CallPackage { path, empty_arg } => { - let correct_file = if let Some(call_package_path) = path { - absolute_package_file == *call_package_path - } else { - false - }; - - if correct_file { - Success(ratchet::Package { - // Empty arguments for non-auto-called packages are not allowed anymore. - empty_non_auto_called: if *empty_arg { - ratchet::EmptyNonAutoCalled::Invalid - } else { - ratchet::EmptyNonAutoCalled::Valid - }, - }) - } else { - NixpkgsProblem::WrongCallPackage { - relative_package_file: relative_package_file.clone(), - package_name: package_name.clone(), - } - .into() + let attributes: Vec<(String, Attribute)> = serde_json::from_slice(&result.stdout) + .with_context(|| { + format!( + "Failed to deserialise {}", + String::from_utf8_lossy(&result.stdout) + ) + })?; + + let check_result = validation::sequence(attributes.into_iter().map( + |(attribute_name, attribute_value)| { + let relative_package_file = structure::relative_file_for_package(&attribute_name); + + use ratchet::RatchetState::*; + use Attribute::*; + use AttributeInfo::*; + use ByNameAttribute::*; + use CallPackageVariant::*; + use NonByNameAttribute::*; + + let check_result = match attribute_value { + // The attribute succeeds evaluation and is NOT defined in pkgs/by-name + NonByName(EvalSuccess(attribute_info)) => { + let uses_by_name = match attribute_info { + // In these cases the package doesn't qualify for being in pkgs/by-name, + // so the UsesByName ratchet is already as tight as it can be + NonAttributeSet => Success(Tight), + NonCallPackage => Success(Tight), + // This is the case when the `pkgs/by-name`-internal _internalCallByNamePackageFile + // is used for a package outside `pkgs/by-name` + CallPackage(CallPackageInfo { + call_package_variant: Auto, + .. + }) => { + // With the current detection mechanism, this also triggers for aliases + // to pkgs/by-name packages, and there's no good method of + // distinguishing alias vs non-alias. + // Using `config.allowAliases = false` at least currently doesn't work + // because there's nothing preventing people from defining aliases that + // are present even with that disabled. + // In the future we could kind of abuse this behavior to have better + // enforcement of conditional aliases, but for now we just need to not + // give an error. + Success(Tight) } - } - AttributeVariant::Other => NixpkgsProblem::WrongCallPackage { - relative_package_file: relative_package_file.clone(), - package_name: package_name.clone(), - } - .into(), - }); - - check_result.map(|value| (package_name.clone(), value)) - } else { - NixpkgsProblem::UndefinedAttr { + // Only derivations can be in pkgs/by-name, + // so this attribute doesn't qualify + CallPackage(CallPackageInfo { + is_derivation: false, + .. + }) => Success(Tight), + + // The case of an attribute that qualifies: + // - Uses callPackage + // - Is a derivation + CallPackage(CallPackageInfo { + is_derivation: true, + call_package_variant: Manual { path, empty_arg }, + }) => Success(Loose(ratchet::UsesByName { + call_package_path: path, + empty_arg, + })), + }; + uses_by_name.map(|x| ratchet::Package { + empty_non_auto_called: Tight, + uses_by_name: x, + }) + } + NonByName(EvalFailure) => { + // This is a bit of an odd case: We don't even _know_ whether this attribute + // would qualify for using pkgs/by-name. We can either: + // - Assume it's not using pkgs/by-name, which has the problem that if a + // package evaluation gets broken temporarily, the fix can remove it from + // pkgs/by-name again + // - Assume it's using pkgs/by-name already, which has the problem that if a + // package evaluation gets broken temporarily, fixing it requires a move to + // pkgs/by-name + // We choose the latter, since we want to move towards pkgs/by-name, not away + // from it + Success(ratchet::Package { + empty_non_auto_called: Tight, + uses_by_name: Tight, + }) + } + ByName(Missing) => NixpkgsProblem::UndefinedAttr { + relative_package_file: relative_package_file.clone(), + package_name: attribute_name.clone(), + } + .into(), + ByName(Existing(NonAttributeSet)) => NixpkgsProblem::NonDerivation { + relative_package_file: relative_package_file.clone(), + package_name: attribute_name.clone(), + } + .into(), + ByName(Existing(NonCallPackage)) => NixpkgsProblem::WrongCallPackage { relative_package_file: relative_package_file.clone(), - package_name: package_name.clone(), + package_name: attribute_name.clone(), } - .into() - } - })) - .map(|elems| ratchet::Nixpkgs { - packages: elems.into_iter().collect(), - }), - ) + .into(), + ByName(Existing(CallPackage(CallPackageInfo { + is_derivation, + call_package_variant, + }))) => { + let check_result = if !is_derivation { + NixpkgsProblem::NonDerivation { + relative_package_file: relative_package_file.clone(), + package_name: attribute_name.clone(), + } + .into() + } else { + Success(()) + }; + + check_result.and(match &call_package_variant { + Auto => Success(ratchet::Package { + empty_non_auto_called: Tight, + uses_by_name: Tight, + }), + Manual { path, empty_arg } => { + let correct_file = if let Some(call_package_path) = path { + relative_package_file == *call_package_path + } else { + false + }; + + if correct_file { + Success(ratchet::Package { + // Empty arguments for non-auto-called packages are not allowed anymore. + empty_non_auto_called: if *empty_arg { + Loose(ratchet::EmptyNonAutoCalled) + } else { + Tight + }, + uses_by_name: Tight, + }) + } else { + NixpkgsProblem::WrongCallPackage { + relative_package_file: relative_package_file.clone(), + package_name: attribute_name.clone(), + } + .into() + } + } + }) + } + }; + check_result.map(|value| (attribute_name.clone(), value)) + }, + )); + + Ok(check_result.map(|elems| ratchet::Nixpkgs { + package_names: elems.iter().map(|(name, _)| name.to_owned()).collect(), + package_map: elems.into_iter().collect(), + })) } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/main.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/main.rs index 18c950d0a6eb..8179ec8ded74 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/main.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/main.rs @@ -38,15 +38,13 @@ pub struct Args { /// Path to the base Nixpkgs to run ratchet checks against. /// For PRs, this should be set to a checkout of the PRs base branch. - /// If not specified, no ratchet checks will be performed. - /// However, this flag will become required once CI uses it. #[arg(long)] - base: Option<PathBuf>, + base: PathBuf, } fn main() -> ExitCode { let args = Args::parse(); - match process(args.base.as_deref(), &args.nixpkgs, &[], &mut io::stderr()) { + match process(&args.base, &args.nixpkgs, false, &mut io::stderr()) { Ok(true) => { eprintln!("{}", "Validated successfully".green()); ExitCode::SUCCESS @@ -67,9 +65,9 @@ fn main() -> ExitCode { /// # Arguments /// - `base_nixpkgs`: Path to the base Nixpkgs to run ratchet checks against. /// - `main_nixpkgs`: Path to the main Nixpkgs to check. -/// - `eval_accessible_paths`: -/// Extra paths that need to be accessible to evaluate Nixpkgs using `restrict-eval`. -/// This is used to allow the tests to access the mock-nixpkgs.nix file +/// - `keep_nix_path`: Whether the value of the NIX_PATH environment variable should be kept for +/// the evaluation stage, allowing its contents to be accessed. +/// This is used to allow the tests to access e.g. the mock-nixpkgs.nix file /// - `error_writer`: An `io::Write` value to write validation errors to, if any. /// /// # Return value @@ -77,28 +75,24 @@ fn main() -> ExitCode { /// - `Ok(false)` if there are problems, all of which will be written to `error_writer`. /// - `Ok(true)` if there are no problems pub fn process<W: io::Write>( - base_nixpkgs: Option<&Path>, + base_nixpkgs: &Path, main_nixpkgs: &Path, - eval_accessible_paths: &[&Path], + keep_nix_path: bool, error_writer: &mut W, ) -> anyhow::Result<bool> { // Check the main Nixpkgs first - let main_result = check_nixpkgs(main_nixpkgs, eval_accessible_paths, error_writer)?; + let main_result = check_nixpkgs(main_nixpkgs, keep_nix_path, error_writer)?; let check_result = main_result.result_map(|nixpkgs_version| { // If the main Nixpkgs doesn't have any problems, run the ratchet checks against the base // Nixpkgs - if let Some(base) = base_nixpkgs { - check_nixpkgs(base, eval_accessible_paths, error_writer)?.result_map( - |base_nixpkgs_version| { - Ok(ratchet::Nixpkgs::compare( - Some(base_nixpkgs_version), - nixpkgs_version, - )) - }, - ) - } else { - Ok(ratchet::Nixpkgs::compare(None, nixpkgs_version)) - } + check_nixpkgs(base_nixpkgs, keep_nix_path, error_writer)?.result_map( + |base_nixpkgs_version| { + Ok(ratchet::Nixpkgs::compare( + base_nixpkgs_version, + nixpkgs_version, + )) + }, + ) })?; match check_result { @@ -119,14 +113,16 @@ pub fn process<W: io::Write>( /// ratchet check against another result. pub fn check_nixpkgs<W: io::Write>( nixpkgs_path: &Path, - eval_accessible_paths: &[&Path], + keep_nix_path: bool, error_writer: &mut W, ) -> validation::Result<ratchet::Nixpkgs> { Ok({ - let nixpkgs_path = nixpkgs_path.canonicalize().context(format!( - "Nixpkgs path {} could not be resolved", - nixpkgs_path.display() - ))?; + let nixpkgs_path = nixpkgs_path.canonicalize().with_context(|| { + format!( + "Nixpkgs path {} could not be resolved", + nixpkgs_path.display() + ) + })?; if !nixpkgs_path.join(utils::BASE_SUBPATH).exists() { writeln!( @@ -138,7 +134,7 @@ pub fn check_nixpkgs<W: io::Write>( } else { check_structure(&nixpkgs_path)?.result_map(|package_names| // Only if we could successfully parse the structure, we do the evaluation checks - eval::check_values(&nixpkgs_path, package_names, eval_accessible_paths))? + eval::check_values(&nixpkgs_path, package_names, keep_nix_path))? } }) } @@ -230,20 +226,18 @@ mod tests { } fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> { - let extra_nix_path = Path::new("tests/mock-nixpkgs.nix"); - let base_path = path.join("base"); let base_nixpkgs = if base_path.exists() { - Some(base_path.as_path()) + base_path.as_path() } else { - None + Path::new("tests/empty-base") }; // We don't want coloring to mess up the tests let writer = temp_env::with_var("NO_COLOR", Some("1"), || -> anyhow::Result<_> { let mut writer = vec![]; - process(base_nixpkgs, &path, &[&extra_nix_path], &mut writer) - .context(format!("Failed test case {name}"))?; + process(base_nixpkgs, &path, true, &mut writer) + .with_context(|| format!("Failed test case {name}"))?; Ok(writer) })?; diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/nixpkgs_problem.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/nixpkgs_problem.rs index 2344a8cc1325..16ea65deebfc 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/nixpkgs_problem.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/nixpkgs_problem.rs @@ -1,3 +1,4 @@ +use crate::structure; use crate::utils::PACKAGE_NIX_FILENAME; use rnix::parser::ParseError; use std::ffi::OsString; @@ -87,6 +88,16 @@ pub enum NixpkgsProblem { text: String, io_error: io::Error, }, + MovedOutOfByName { + package_name: String, + call_package_path: Option<PathBuf>, + empty_arg: bool, + }, + NewPackageNotUsingByName { + package_name: String, + call_package_path: Option<PathBuf>, + empty_arg: bool, + }, } impl fmt::Display for NixpkgsProblem { @@ -213,6 +224,48 @@ impl fmt::Display for NixpkgsProblem { subpath.display(), text, ), + NixpkgsProblem::MovedOutOfByName { package_name, call_package_path, empty_arg } => { + let call_package_arg = + if let Some(path) = &call_package_path { + format!("./{}", path.display()) + } else { + "...".into() + }; + if *empty_arg { + write!( + f, + "pkgs.{package_name}: This top-level package was previously defined in {}, but is now manually defined as `callPackage {call_package_arg} {{ }}` (e.g. in `pkgs/top-level/all-packages.nix`). Please move the package back and remove the manual `callPackage`.", + structure::relative_file_for_package(package_name).display(), + ) + } else { + // This can happen if users mistakenly assume that for custom arguments, + // pkgs/by-name can't be used. + write!( + f, + "pkgs.{package_name}: This top-level package was previously defined in {}, but is now manually defined as `callPackage {call_package_arg} {{ ... }}` (e.g. in `pkgs/top-level/all-packages.nix`). While the manual `callPackage` is still needed, it's not necessary to move the package files.", + structure::relative_file_for_package(package_name).display(), + ) + } + }, + NixpkgsProblem::NewPackageNotUsingByName { package_name, call_package_path, empty_arg } => { + let call_package_arg = + if let Some(path) = &call_package_path { + format!("./{}", path.display()) + } else { + "...".into() + }; + let extra = + if *empty_arg { + "Since the second `callPackage` argument is `{ }`, no manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is needed anymore." + } else { + "Since the second `callPackage` argument is not `{ }`, the manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is still needed." + }; + write!( + f, + "pkgs.{package_name}: This is a new top-level package of the form `callPackage {call_package_arg} {{ }}`. Please define it in {} instead. See `pkgs/by-name/README.md` for more details. {extra}", + structure::relative_file_for_package(package_name).display(), + ) + }, } } } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/ratchet.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/ratchet.rs index c12f1ead2540..f8c129626cc0 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/ratchet.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/ratchet.rs @@ -6,80 +6,141 @@ use crate::nixpkgs_problem::NixpkgsProblem; use crate::structure; use crate::validation::{self, Validation, Validation::Success}; use std::collections::HashMap; +use std::path::PathBuf; /// The ratchet value for the entirety of Nixpkgs. #[derive(Default)] pub struct Nixpkgs { - /// The ratchet values for each package in `pkgs/by-name` - pub packages: HashMap<String, Package>, + /// Sorted list of packages in package_map + pub package_names: Vec<String>, + /// The ratchet values for all packages + pub package_map: HashMap<String, Package>, } impl Nixpkgs { /// Validates the ratchet checks for Nixpkgs - pub fn compare(optional_from: Option<Self>, to: Self) -> Validation<()> { + pub fn compare(from: Self, to: Self) -> Validation<()> { validation::sequence_( // We only loop over the current attributes, // we don't need to check ones that were removed - to.packages.into_iter().map(|(name, attr_to)| { - let attr_from = if let Some(from) = &optional_from { - from.packages.get(&name) - } else { - // This pretends that if there's no base version to compare against, all - // attributes existed without conforming to the new strictness check for - // backwards compatibility. - // TODO: Remove this case. This is only needed because the `--base` - // argument is still optional, which doesn't need to be once CI is updated - // to pass it. - Some(&Package { - empty_non_auto_called: EmptyNonAutoCalled::Invalid, - }) - }; - Package::compare(&name, attr_from, &attr_to) + to.package_names.into_iter().map(|name| { + Package::compare(&name, from.package_map.get(&name), &to.package_map[&name]) }), ) } } -/// The ratchet value for a single package in `pkgs/by-name` +/// The ratchet value for a top-level package pub struct Package { /// The ratchet value for the check for non-auto-called empty arguments - pub empty_non_auto_called: EmptyNonAutoCalled, + pub empty_non_auto_called: RatchetState<EmptyNonAutoCalled>, + + /// The ratchet value for the check for new packages using pkgs/by-name + pub uses_by_name: RatchetState<UsesByName>, } impl Package { - /// Validates the ratchet checks for a single package defined in `pkgs/by-name` + /// Validates the ratchet checks for a top-level package pub fn compare(name: &str, optional_from: Option<&Self>, to: &Self) -> Validation<()> { - EmptyNonAutoCalled::compare( - name, - optional_from.map(|x| &x.empty_non_auto_called), - &to.empty_non_auto_called, - ) + validation::sequence_([ + RatchetState::<EmptyNonAutoCalled>::compare( + name, + optional_from.map(|x| &x.empty_non_auto_called), + &to.empty_non_auto_called, + ), + RatchetState::<UsesByName>::compare( + name, + optional_from.map(|x| &x.uses_by_name), + &to.uses_by_name, + ), + ]) } } -/// The ratchet value of a single package in `pkgs/by-name` +/// The ratchet state of a generic ratchet check. +pub enum RatchetState<Context> { + /// The ratchet is loose, it can be tightened more. + /// In other words, this is the legacy state we're trying to move away from. + /// Introducing new instances is not allowed but previous instances will continue to be allowed. + /// The `Context` is context for error messages in case a new instance of this state is + /// introduced + Loose(Context), + /// The ratchet is tight, it can't be tightened any further. + /// This is either because we already use the latest state, or because the ratchet isn't + /// relevant. + Tight, +} + +/// A trait that can convert an attribute-specific error context into a NixpkgsProblem +pub trait ToNixpkgsProblem { + /// How to convert an attribute-specific error context into a NixpkgsProblem + fn to_nixpkgs_problem(name: &str, context: &Self, existed_before: bool) -> NixpkgsProblem; +} + +impl<Context: ToNixpkgsProblem> RatchetState<Context> { + /// Compare the previous ratchet state of an attribute to the new state. + /// The previous state may be `None` in case the attribute is new. + fn compare(name: &str, optional_from: Option<&Self>, to: &Self) -> Validation<()> { + // If we don't have a previous state, enforce a tight ratchet + let from = optional_from.unwrap_or(&RatchetState::Tight); + match (from, to) { + // Always okay to keep it tight or tighten the ratchet + (_, RatchetState::Tight) => Success(()), + + // Grandfathering policy for a loose ratchet + (RatchetState::Loose { .. }, RatchetState::Loose { .. }) => Success(()), + + // Loosening a ratchet is now allowed + (RatchetState::Tight, RatchetState::Loose(context)) => { + Context::to_nixpkgs_problem(name, context, optional_from.is_some()).into() + } + } + } +} + +/// The ratchet value of an attribute /// for the non-auto-called empty argument check of a single. /// /// This checks that packages defined in `pkgs/by-name` cannot be overridden /// with an empty second argument like `callPackage ... { }`. -#[derive(PartialEq, PartialOrd)] -pub enum EmptyNonAutoCalled { - Invalid, - Valid, +pub struct EmptyNonAutoCalled; + +impl ToNixpkgsProblem for EmptyNonAutoCalled { + fn to_nixpkgs_problem(name: &str, _context: &Self, _existed_before: bool) -> NixpkgsProblem { + NixpkgsProblem::WrongCallPackage { + relative_package_file: structure::relative_file_for_package(name), + package_name: name.to_owned(), + } + } } -impl EmptyNonAutoCalled { - /// Validates the non-auto-called empty argument ratchet check for a single package defined in `pkgs/by-name` - fn compare(name: &str, optional_from: Option<&Self>, to: &Self) -> Validation<()> { - let from = optional_from.unwrap_or(&Self::Valid); - if to >= from { - Success(()) +/// The ratchet value of an attribute +/// for the check that new packages use pkgs/by-name +/// +/// This checks that all new package defined using callPackage must be defined via pkgs/by-name +/// It also checks that once a package uses pkgs/by-name, it can't switch back to all-packages.nix +#[derive(Clone)] +pub struct UsesByName { + /// The first callPackage argument, used for better errors + pub call_package_path: Option<PathBuf>, + /// Whether the second callPackage argument is empty, used for better errors + pub empty_arg: bool, +} + +impl ToNixpkgsProblem for UsesByName { + fn to_nixpkgs_problem(name: &str, a: &Self, existed_before: bool) -> NixpkgsProblem { + if existed_before { + NixpkgsProblem::MovedOutOfByName { + package_name: name.to_owned(), + call_package_path: a.call_package_path.clone(), + empty_arg: a.empty_arg, + } } else { - NixpkgsProblem::WrongCallPackage { - relative_package_file: structure::relative_file_for_package(name), + NixpkgsProblem::NewPackageNotUsingByName { package_name: name.to_owned(), + call_package_path: a.call_package_path.clone(), + empty_arg: a.empty_arg, } - .into() } } } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/references.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/references.rs index 0561a9b22e85..ce7403afb32d 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/references.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/references.rs @@ -17,10 +17,12 @@ pub fn check_references( ) -> validation::Result<()> { // The empty argument here is the subpath under the package directory to check // An empty one means the package directory itself - check_path(relative_package_dir, absolute_package_dir, Path::new("")).context(format!( - "While checking the references in package directory {}", - relative_package_dir.display() - )) + check_path(relative_package_dir, absolute_package_dir, Path::new("")).with_context(|| { + format!( + "While checking the references in package directory {}", + relative_package_dir.display() + ) + }) } /// Checks for a specific path to not have references outside @@ -62,7 +64,9 @@ fn check_path( .map(|entry| { let entry_subpath = subpath.join(entry.file_name()); check_path(relative_package_dir, absolute_package_dir, &entry_subpath) - .context(format!("Error while recursing into {}", subpath.display())) + .with_context(|| { + format!("Error while recursing into {}", subpath.display()) + }) }) .collect_vec()?, ) @@ -70,8 +74,8 @@ fn check_path( // Only check Nix files if let Some(ext) = path.extension() { if ext == OsStr::new("nix") { - check_nix_file(relative_package_dir, absolute_package_dir, subpath).context( - format!("Error while checking Nix file {}", subpath.display()), + check_nix_file(relative_package_dir, absolute_package_dir, subpath).with_context( + || format!("Error while checking Nix file {}", subpath.display()), )? } else { Success(()) @@ -93,16 +97,19 @@ fn check_nix_file( subpath: &Path, ) -> validation::Result<()> { let path = absolute_package_dir.join(subpath); - let parent_dir = path.parent().context(format!( - "Could not get parent of path {}", - subpath.display() - ))?; + let parent_dir = path + .parent() + .with_context(|| format!("Could not get parent of path {}", subpath.display()))?; - let contents = - read_to_string(&path).context(format!("Could not read file {}", subpath.display()))?; + let contents = read_to_string(&path) + .with_context(|| format!("Could not read file {}", subpath.display()))?; let root = Root::parse(&contents); if let Some(error) = root.errors().first() { + // NOTE: There's now another Nixpkgs CI check to make sure all changed Nix files parse + // correctly, though that uses mainline Nix instead of rnix, so it doesn't give the same + // errors. In the future we should unify these two checks, ideally moving the other CI + // check into this tool as well and checking for both mainline Nix and rnix. return Ok(NixpkgsProblem::CouldNotParseNix { relative_package_dir: relative_package_dir.to_path_buf(), subpath: subpath.to_path_buf(), diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/utils.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/utils.rs index 5cc4a0863ba8..7e0198dede42 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/utils.rs +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/utils.rs @@ -10,10 +10,10 @@ pub const PACKAGE_NIX_FILENAME: &str = "package.nix"; pub fn read_dir_sorted(base_dir: &Path) -> anyhow::Result<Vec<fs::DirEntry>> { let listing = base_dir .read_dir() - .context(format!("Could not list directory {}", base_dir.display()))?; + .with_context(|| format!("Could not list directory {}", base_dir.display()))?; let mut shard_entries = listing .collect::<io::Result<Vec<_>>>() - .context(format!("Could not list directory {}", base_dir.display()))?; + .with_context(|| format!("Could not list directory {}", base_dir.display()))?; shard_entries.sort_by_key(|entry| entry.file_name()); Ok(shard_entries) } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/aliases.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/aliases.nix new file mode 100644 index 000000000000..c70ec23478ea --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/aliases.nix @@ -0,0 +1,3 @@ +self: super: { + baz = self.foo; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/all-packages.nix new file mode 100644 index 000000000000..2cdfcef08fa6 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/all-packages.nix @@ -0,0 +1,3 @@ +self: super: { + bar = self.foo; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/pkgs/by-name/aa/aa/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/pkgs/by-name/fo/foo/package.nix index a1b92efbbadb..a1b92efbbadb 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/pkgs/by-name/aa/aa/package.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/aliases/pkgs/by-name/fo/foo/package.nix diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/broken-autocall/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/broken-autocall/default.nix index 793dfabd6553..bd4825f8bad8 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/broken-autocall/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/broken-autocall/default.nix @@ -1,4 +1,4 @@ args: builtins.removeAttrs - (import ../mock-nixpkgs.nix { root = ./.; } args) + (import <test-nixpkgs> { root = ./.; } args) [ "foo" ] diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/empty-base/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/incorrect-shard/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/incorrect-shard/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/incorrect-shard/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/incorrect-shard/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/all-packages.nix new file mode 100644 index 000000000000..95478a87fb32 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/all-packages.nix @@ -0,0 +1,3 @@ +self: super: { + foo = self._internalCallByNamePackageFile ./foo.nix; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/foo.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/foo.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/foo.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/internalCallPackage/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-package-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-package-name/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-package-name/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-package-name/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-shard-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-shard-name/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-shard-name/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/invalid-shard-name/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/missing-package-nix/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/missing-package-nix/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/missing-package-nix/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/missing-package-nix/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/mock-nixpkgs.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/mock-nixpkgs.nix index 01bb27a48038..81a9c916ac2d 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/mock-nixpkgs.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/mock-nixpkgs.nix @@ -19,34 +19,20 @@ It returns a Nixpkgs-like function that can be auto-called and evaluates to an a overlays ? [], # Passed by the checker to make sure a real Nixpkgs isn't influenced by impurities config ? {}, + # Passed by the checker to make sure a real Nixpkgs isn't influenced by impurities + system ? null, }: let # Simplified versions of lib functions - lib = { - fix = f: let x = f x; in x; - - extends = overlay: f: final: - let - prev = f final; - in - prev // overlay final prev; - - callPackageWith = autoArgs: fn: args: - let - f = if builtins.isFunction fn then fn else import fn; - fargs = builtins.functionArgs f; - allArgs = builtins.intersectAttrs fargs autoArgs // args; - in - f allArgs; - - isDerivation = value: value.type or null == "derivation"; - }; + lib = import <test-nixpkgs/lib>; # The base fixed-point function to populate the resulting attribute set pkgsFun = self: { inherit lib; - callPackage = lib.callPackageWith self; + newScope = extra: lib.callPackageWith (self // extra); + callPackage = self.newScope { }; + callPackages = lib.callPackagesWith self; someDrv = { type = "derivation"; }; }; @@ -91,12 +77,21 @@ let else [ ]; + # A list optionally containing the `aliases.nix` file from the test case as an overlay + # But only if config.allowAliases is not false + optionalAliasesOverlay = + if (config.allowAliases or true) && builtins.pathExists (root + "/aliases.nix") then + [ (import (root + "/aliases.nix")) ] + else + [ ]; + # All the overlays in the right order, including the user-supplied ones allOverlays = [ autoCalledPackages ] ++ optionalAllPackagesOverlay + ++ optionalAliasesOverlay ++ overlays; # Apply all the overlays in order to the base fixed-point function pkgsFun diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/all-packages.nix new file mode 100644 index 000000000000..16834c4f7856 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/all-packages.nix @@ -0,0 +1,10 @@ +self: super: { + foo1 = self.callPackage ({ someDrv }: someDrv) { }; + foo2 = self.callPackage ./without-config.nix { }; + foo3 = self.callPackage ({ someDrv, enableFoo }: someDrv) { + enableFoo = null; + }; + foo4 = self.callPackage ./with-config.nix { + enableFoo = null; + }; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo1/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo1/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo1/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo2/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo2/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo2/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo3/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo3/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo3/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo4/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo4/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/base/pkgs/by-name/fo/foo4/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/expected new file mode 100644 index 000000000000..96da50b52491 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/expected @@ -0,0 +1,4 @@ +pkgs.foo1: This top-level package was previously defined in pkgs/by-name/fo/foo1/package.nix, but is now manually defined as `callPackage ... { }` (e.g. in `pkgs/top-level/all-packages.nix`). Please move the package back and remove the manual `callPackage`. +pkgs.foo2: This top-level package was previously defined in pkgs/by-name/fo/foo2/package.nix, but is now manually defined as `callPackage ./without-config.nix { }` (e.g. in `pkgs/top-level/all-packages.nix`). Please move the package back and remove the manual `callPackage`. +pkgs.foo3: This top-level package was previously defined in pkgs/by-name/fo/foo3/package.nix, but is now manually defined as `callPackage ... { ... }` (e.g. in `pkgs/top-level/all-packages.nix`). While the manual `callPackage` is still needed, it's not necessary to move the package files. +pkgs.foo4: This top-level package was previously defined in pkgs/by-name/fo/foo4/package.nix, but is now manually defined as `callPackage ./with-config.nix { ... }` (e.g. in `pkgs/top-level/all-packages.nix`). While the manual `callPackage` is still needed, it's not necessary to move the package files. diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/with-config.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/with-config.nix new file mode 100644 index 000000000000..7cca53882ea5 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/with-config.nix @@ -0,0 +1 @@ +{ someDrv, enableFoo }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/without-config.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/without-config.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/move-to-non-by-name/without-config.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/expected new file mode 100644 index 000000000000..ff5d18556ef0 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/expected @@ -0,0 +1,13 @@ +pkgs/by-name/A: Invalid directory name "A", must be at most 2 ASCII characters consisting of a-z, 0-9, "-" or "_". +pkgs/by-name/A/fo@: Invalid package directory name "fo@", must be ASCII characters consisting of a-z, A-Z, 0-9, "-" or "_". +pkgs/by-name/A/fo@: Path foo is a symlink which cannot be resolved: No such file or directory (os error 2). +pkgs/by-name/A/fo@: Path package.nix is a symlink pointing to a path outside the directory of that package. +pkgs/by-name/aa: This is a file, but it should be a directory. +pkgs/by-name/ba/bar: This path is a file, but it should be a directory. +pkgs/by-name/ba/baz: "package.nix" must be a file. +pkgs/by-name/ba/foo: Incorrect directory location, should be pkgs/by-name/fo/foo instead. +pkgs/by-name/ba/foo: File package.nix at line 2 contains the path expression "/bar" which cannot be resolved: No such file or directory (os error 2). +pkgs/by-name/ba/foo: File package.nix at line 3 contains the path expression "../." which may point outside the directory of that package. +pkgs/by-name/ba/foo: File package.nix at line 4 contains the nix search path expression "<nixpkgs>" which may point outside the directory of that package. +pkgs/by-name/ba/foo: File package.nix at line 5 contains the path expression "./${"test"}", which is not yet supported and may point outside the directory of that package. +pkgs/by-name/fo/foo: Missing required "package.nix" file. diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/foo b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/foo new file mode 120000 index 000000000000..c86c3f3551ec --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/foo @@ -0,0 +1 @@ +none \ No newline at end of file diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/package.nix new file mode 120000 index 000000000000..f079163d158a --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/A/fo@/package.nix @@ -0,0 +1 @@ +../../../../someDrv.nix \ No newline at end of file diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/aa b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/aa new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/aa diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/bar b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/bar new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/bar diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/baz/package.nix/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/baz/package.nix/default.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/baz/package.nix/default.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/foo/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/foo/package.nix new file mode 100644 index 000000000000..31b4742f5914 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/ba/foo/package.nix @@ -0,0 +1,6 @@ +{ someDrv }: someDrv // { + escapeAbsolute = /bar; + escapeRelative = ../.; + nixPath = <nixpkgs>; + pathWithSubexpr = ./${"test"}; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/fo/foo/.git-keep b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/fo/foo/.git-keep new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/pkgs/by-name/fo/foo/.git-keep diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/someDrv.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/someDrv.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/multiple-failures/someDrv.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/all-packages.nix new file mode 100644 index 000000000000..069119ad4c7b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/all-packages.nix @@ -0,0 +1,11 @@ +self: super: { + before = self.callPackage ({ someDrv }: someDrv) { }; + new1 = self.callPackage ({ someDrv }: someDrv) { }; + new2 = self.callPackage ./without-config.nix { }; + new3 = self.callPackage ({ someDrv, enableNew }: someDrv) { + enableNew = null; + }; + new4 = self.callPackage ./with-config.nix { + enableNew = null; + }; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/all-packages.nix new file mode 100644 index 000000000000..c2665d04d5f2 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/all-packages.nix @@ -0,0 +1,5 @@ +self: super: { + + before = self.callPackage ({ someDrv }: someDrv) { }; + +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/base/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/expected new file mode 100644 index 000000000000..3f294f26dfd8 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/expected @@ -0,0 +1,4 @@ +pkgs.new1: This is a new top-level package of the form `callPackage ... { }`. Please define it in pkgs/by-name/ne/new1/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is `{ }`, no manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is needed anymore. +pkgs.new2: This is a new top-level package of the form `callPackage ./without-config.nix { }`. Please define it in pkgs/by-name/ne/new2/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is `{ }`, no manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is needed anymore. +pkgs.new3: This is a new top-level package of the form `callPackage ... { }`. Please define it in pkgs/by-name/ne/new3/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is not `{ }`, the manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is still needed. +pkgs.new4: This is a new top-level package of the form `callPackage ./with-config.nix { }`. Please define it in pkgs/by-name/ne/new4/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is not `{ }`, the manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is still needed. diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/with-config.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/with-config.nix new file mode 100644 index 000000000000..65bcbf9928a2 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/with-config.nix @@ -0,0 +1 @@ +{ someDrv, enableNew }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/without-config.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/without-config.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/new-package-non-by-name/without-config.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-by-name/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-by-name/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-by-name/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-by-name/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/all-packages.nix new file mode 100644 index 000000000000..e2831c2d542e --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/all-packages.nix @@ -0,0 +1,3 @@ +self: super: { + iDontEval = throw "I don't eval"; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/pkgs/by-name/fo/foo/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/pkgs/by-name/fo/foo/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/no-eval/pkgs/by-name/fo/foo/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-attrs/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-attrs/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-attrs/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-attrs/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-derivation/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-derivation/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-derivation/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/non-derivation/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/one-letter/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/one-letter/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/one-letter/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/one-letter/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/all-packages.nix new file mode 100644 index 000000000000..5b1ed9d2ccda --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/all-packages.nix @@ -0,0 +1,16 @@ +self: super: { + alternateCallPackage = self.myScope.callPackage ({ myScopeValue, someDrv }: + assert myScopeValue; + someDrv + ) { }; + + myScope = self.lib.makeScope self.newScope (self: { + myScopeValue = true; + }); + + myPackages = self.callPackages ({ someDrv }: { + a = someDrv; + b = someDrv; + }) { }; + inherit (self.myPackages) a b; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/pkgs/by-name/README.md b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/pkgs/by-name/README.md new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/only-callPackage-derivations/pkgs/by-name/README.md diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-different-file/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-different-file/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-different-file/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-different-file/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/base/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/base/default.nix index 2875ea6327ef..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/base/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/base/default.nix @@ -1 +1 @@ -import ../../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg-gradual/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/base/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/base/default.nix index 2875ea6327ef..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/base/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/base/default.nix @@ -1 +1 @@ -import ../../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-empty-arg/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-call-package/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-call-package/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-call-package/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-call-package/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-file/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-file/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-file/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-no-file/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-success/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-success/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-success/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/override-success/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-dir-is-file/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-dir-is-file/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-dir-is-file/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-dir-is-file/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-nix-dir/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-nix-dir/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-nix-dir/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/package-nix-dir/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-absolute/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-absolute/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-absolute/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-absolute/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-escape/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-escape/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-escape/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-escape/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-nix-path/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-nix-path/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-nix-path/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-nix-path/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/default.nix deleted file mode 100644 index af25d1450122..000000000000 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/default.nix +++ /dev/null @@ -1 +0,0 @@ -import ../mock-nixpkgs.nix { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/expected deleted file mode 100644 index 281aba009236..000000000000 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/expected +++ /dev/null @@ -1 +0,0 @@ -pkgs/by-name/aa/aa: File invalid.nix could not be parsed by rnix: unexpected token at 28..29 diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/pkgs/by-name/aa/aa/invalid.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/pkgs/by-name/aa/aa/invalid.nix deleted file mode 100644 index ee6b002a529b..000000000000 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-parse-failure/pkgs/by-name/aa/aa/invalid.nix +++ /dev/null @@ -1 +0,0 @@ -this is not a valid nix file! diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-path-subexpr/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-path-subexpr/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-path-subexpr/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-path-subexpr/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-success/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-success/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-success/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/ref-success/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/shard-file/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/shard-file/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/shard-file/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/shard-file/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/all-packages.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/all-packages.nix new file mode 100644 index 000000000000..688f52b9358f --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/all-packages.nix @@ -0,0 +1,6 @@ +self: super: { + a = self.callPackage ./pkgs/by-name/a/a/package.nix { }; + b = self.callPackage ({ someDrv }: someDrv) { }; + c = self.callPackage ./pkgs/by-name/c/c/package.nix { }; + d = self.callPackage ({ someDrv }: someDrv) { }; +} diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/default.nix new file mode 100644 index 000000000000..861260cdca4b --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/default.nix @@ -0,0 +1 @@ +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/expected new file mode 100644 index 000000000000..349e9ad47c41 --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/expected @@ -0,0 +1,4 @@ +pkgs.a: This attribute is manually defined (most likely in pkgs/top-level/all-packages.nix), which is only allowed if the definition is of the form `pkgs.callPackage pkgs/by-name/a/a/package.nix { ... }` with a non-empty second argument. +pkgs.b: This is a new top-level package of the form `callPackage ... { }`. Please define it in pkgs/by-name/b/b/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is `{ }`, no manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is needed anymore. +pkgs.c: This attribute is manually defined (most likely in pkgs/top-level/all-packages.nix), which is only allowed if the definition is of the form `pkgs.callPackage pkgs/by-name/c/c/package.nix { ... }` with a non-empty second argument. +pkgs.d: This is a new top-level package of the form `callPackage ... { }`. Please define it in pkgs/by-name/d/d/package.nix instead. See `pkgs/by-name/README.md` for more details. Since the second `callPackage` argument is `{ }`, no manual `callPackage` (e.g. in `pkgs/top-level/all-packages.nix`) is needed anymore. diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/a/a/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/a/a/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/a/a/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/c/c/package.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/c/c/package.nix new file mode 100644 index 000000000000..a1b92efbbadb --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/sorted-order/pkgs/by-name/c/c/package.nix @@ -0,0 +1 @@ +{ someDrv }: someDrv diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/success/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/success/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/success/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/success/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-escape/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-escape/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-escape/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-escape/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/expected b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/expected index f622f3e7fd6d..c1e7a28205a7 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/expected +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/expected @@ -1 +1 @@ -pkgs/by-name/fo/foo: Path foo.nix is a symlink which cannot be resolved: No such file or directory (os error 2). +pkgs/by-name/fo/foo: Path foo is a symlink which cannot be resolved: No such file or directory (os error 2). diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo new file mode 120000 index 000000000000..c86c3f3551ec --- /dev/null +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo @@ -0,0 +1 @@ +none \ No newline at end of file diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo.nix deleted file mode 120000 index 49cd425a8cdb..000000000000 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/symlink-invalid/pkgs/by-name/fo/foo/foo.nix +++ /dev/null @@ -1 +0,0 @@ -none.nix \ No newline at end of file diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/uppercase/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/uppercase/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/uppercase/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/uppercase/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/with-readme/default.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/with-readme/default.nix index af25d1450122..861260cdca4b 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/with-readme/default.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/tests/with-readme/default.nix @@ -1 +1 @@ -import ../mock-nixpkgs.nix { root = ./.; } +import <test-nixpkgs> { root = ./.; } |