Unverified Commit 754ee2fc authored by Philip Taron's avatar Philip Taron Committed by GitHub
Browse files

fetchgit: Add rootDir argument (#427165)

parents 7122c347 34612851
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -829,6 +829,10 @@ Additionally, the following optional arguments can be given:

  See [git sparse-checkout](https://git-scm.com/docs/git-sparse-checkout) for more information.

*`rootDir`* (String)

: When not empty, copy only contents of the subdirectory of the repository to the result. Automatically sets `sparseCheckout` and `nonConeMode` to avoid checking out any extra pieces. Incompatible with `leaveDotGit`.

Some additional parameters for niche use-cases can be found listed in the function parameters in the declaration of `fetchgit`: `pkgs/build-support/fetchgit/default.nix`.
Future parameters additions might also happen without immediately being documented here.

+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@
  * `$debug/lib/debug/.build-id/48/3bd7f7229bdb06462222e1e353e4f37e15c293.sourceoverlay` is a symlink to a directory with the same structure as the expanded `$sourceRoot` but containing only a copy of files which were patched during the build
  * `$debug/lib/debug/.build-id/48/3bd7f7229bdb06462222e1e353e4f37e15c293.debug` is the file containing debug symbols (like before).

- `fetchgit`: Add `rootDir` argument to limit the resulting source to one subdirectory of the whole Git repository. Corresponding `--root-dir` option added to `nix-prefetch-git`.

## Nixpkgs Library {#sec-nixpkgs-release-25.11-lib}

+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ $SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" --name "$name"
  ${fetchTags:+--fetch-tags} \
  ${sparseCheckout:+--sparse-checkout "$sparseCheckout"} \
  ${nonConeMode:+--non-cone-mode} \
  ${branchName:+--branch-name "$branchName"}
  ${branchName:+--branch-name "$branchName"} \
  ${rootDir:+--root-dir "$rootDir"}

runHook postFetch
+18 −5
Original line number Diff line number Diff line
@@ -8,12 +8,16 @@

let
  urlToName =
    url: rev:
    {
      url,
      rev,
      append,
    }:
    let
      shortRev = lib.sources.shortRev rev;
      appendShort = lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null) "-${shortRev}";
    in
    "${lib.sources.urlToName url}${appendShort}";
    "${lib.sources.urlToName url}${if append == "" then appendShort else append}";
in

lib.makeOverridable (
@@ -24,15 +28,20 @@ lib.makeOverridable (
      url,
      tag ? null,
      rev ? null,
      name ? urlToName url (lib.revOrTag rev tag),
      name ? urlToName {
        inherit url;
        rev = lib.revOrTag rev tag;
        # when rootDir is specified, avoid invalidating the result when rev changes
        append = if rootDir != "" then "-${lib.strings.sanitizeDerivationName rootDir}" else "";
      },
      leaveDotGit ? deepClone || fetchTags,
      outputHash ? lib.fakeHash,
      outputHashAlgo ? null,
      fetchSubmodules ? true,
      deepClone ? false,
      branchName ? null,
      sparseCheckout ? [ ],
      nonConeMode ? false,
      sparseCheckout ? lib.optional (rootDir != "") rootDir,
      nonConeMode ? rootDir != "",
      nativeBuildInputs ? [ ],
      # Shell code executed before the file has been fetched.  This, in
      # particular, can do things like set NIX_PREFETCH_GIT_CHECKOUT_HOOK to
@@ -53,6 +62,8 @@ lib.makeOverridable (
      allowedRequisites ? null,
      # fetch all tags after tree (useful for git describe)
      fetchTags ? false,
      # make this subdirectory the root of the result
      rootDir ? "",
    }:

    /*
@@ -80,6 +91,7 @@ lib.makeOverridable (

    assert nonConeMode -> (sparseCheckout != [ ]);
    assert fetchTags -> leaveDotGit;
    assert rootDir != "" -> !leaveDotGit;

    let
      revWithTag =
@@ -135,6 +147,7 @@ lib.makeOverridable (
          preFetch
          postFetch
          fetchTags
          rootDir
          ;
        rev = revWithTag;

+45 −17
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ Options:
      --fetch-submodules Fetch submodules.
      --fetch-tags    Fetch all tags (useful for git describe).
      --builder       Clone as fetchgit does, but url, rev, and out option are mandatory.
      --root-dir dir  Directory in the repository that will be copied to the output instead of the full repository.
      --quiet         Only print the final json summary.
"
    exit 1
@@ -90,6 +91,7 @@ for arg; do
            --fetch-submodules) fetchSubmodules=true;;
            --fetch-tags) fetchTags=true;;
            --builder) builder=true;;
            --root-dir) argfun=set_rootDir;;
            -h|--help) usage; exit;;
            *)
                : $((++argi))
@@ -155,11 +157,17 @@ url_to_name(){
    local base
    base=$(basename "$url" .git | cut -d: -f2)

    if test -n "$rootDir"; then
        # Sanitize by removing leading dots and replacing all invalid character sequences with dashes.
        # See sanitizeDerivationName in ../../../lib/strings.nix for reference.
        echo "$base-$(sed -E 's/^\.+//;s/[^[:alnum:]+._?=-]+/-/g' <<< $rootDir)"
    else
        if [[ $ref =~ ^[a-z0-9]+$ ]]; then
            echo "$base-${ref:0:7}"
        else
            echo "$base"
        fi
    fi
}

# Fetch and checkout the right sha1
@@ -353,6 +361,23 @@ clone_user_rev() {
    fi
}

clone_user_rev_to_tmpfile(){
    local url="$1"
    local rev="${2:-HEAD}"

    # nix>=2.20 rejects adding symlinked paths to the store, so use realpath
    # to resolve to a physical path. https://github.com/NixOS/nix/issues/11941
    tmpPath="$(realpath "$(mktemp -d --tmpdir git-checkout-tmp-XXXXXXXX)")"
    exit_handlers+=(remove_tmpPath)

    tmpOut="$tmpPath/out/$storePathName"
    tmpClone="$tmpPath/clone"
    mkdir -p "$tmpPath/out" "$tmpClone"

    # Perform the checkout.
    clone_user_rev "$tmpClone" "$url" "$rev"
}

exit_handlers=()

run_exit_handlers() {
@@ -418,7 +443,8 @@ print_results() {
  "fetchSubmodules": $([[ -n "$fetchSubmodules" ]] && echo true || echo false),
  "deepClone": $([[ -n "$deepClone" ]] && echo true || echo false),
  "fetchTags": $([[ -n "$fetchTags" ]] && echo true || echo false),
  "leaveDotGit": $([[ -n "$leaveDotGit" ]] && echo true || echo false)
  "leaveDotGit": $([[ -n "$leaveDotGit" ]] && echo true || echo false),
  "rootDir": "$(json_escape "$rootDir")"
}
EOF
    fi
@@ -456,8 +482,13 @@ export GIT_CONFIG_NOSYSTEM=1

if test -n "$builder"; then
    test -n "$out" -a -n "$url" -a -n "$rev" || usage
    if test -n "$rootDir"; then
        clone_user_rev_to_tmpfile "$url" "$rev"
        mv "$tmpClone/$rootDir" "$out"
    else
        mkdir -p "$out"
        clone_user_rev "$out" "$url" "$rev"
    fi
else
    if test -z "$hashType"; then
        hashType=sha256
@@ -476,22 +507,19 @@ else
    # If we don't know the hash or a path with that hash doesn't exist,
    # download the file and add it to the store.
    if test -z "$finalPath"; then
        # nix>=2.20 rejects adding symlinked paths to the store, so use realpath
        # to resolve to a physical path. https://github.com/NixOS/nix/issues/11941
        tmpPath="$(realpath "$(mktemp -d --tmpdir git-checkout-tmp-XXXXXXXX)")"
        exit_handlers+=(remove_tmpPath)

        tmpFile="$tmpPath/$storePathName"
        mkdir -p "$tmpFile"
        clone_user_rev_to_tmpfile "$url" "$rev"

        # Perform the checkout.
        clone_user_rev "$tmpFile" "$url" "$rev"
        if test -z "$rootDir"; then
            mv "$tmpClone" "$tmpOut"
        else
            mv "$tmpClone/$rootDir" "$tmpOut"
        fi

        # Compute the hash.
        hash=$(nix-hash --type $hashType --base32 "$tmpFile")
        hash=$(nix-hash --type $hashType --base32 "$tmpOut")

        # Add the downloaded file to the Nix store.
        finalPath=$(nix-store --add-fixed --recursive "$hashType" "$tmpFile")
        finalPath=$(nix-store --add-fixed --recursive "$hashType" "$tmpOut")

        if test -n "$expHash" -a "$expHash" != "$hash"; then
            echo "hash mismatch for URL \`$url'. Got \`$hash'; expected \`$expHash'." >&2
Loading