1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-18 16:29:36 +01:00

Merge pull request #14581 from NixOS/clone-all

nix flake clone: Support all input types
This commit is contained in:
Eelco Dolstra 2025-11-17 19:28:19 +00:00 committed by GitHub
commit f6aa8c0486
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 15 deletions

View file

@ -6,6 +6,7 @@
#include "nix/fetchers/fetch-settings.hh"
#include "nix/fetchers/fetch-to-store.hh"
#include "nix/util/url.hh"
#include "nix/util/archive.hh"
#include <nlohmann/json.hpp>
@ -368,10 +369,10 @@ Input Input::applyOverrides(std::optional<std::string> ref, std::optional<Hash>
return scheme->applyOverrides(*this, ref, rev);
}
void Input::clone(const Settings & settings, const Path & destDir) const
void Input::clone(const Settings & settings, ref<Store> store, const std::filesystem::path & destDir) const
{
assert(scheme);
scheme->clone(settings, *this, destDir);
scheme->clone(settings, store, *this, destDir);
}
std::optional<std::filesystem::path> Input::getSourcePath() const
@ -484,9 +485,19 @@ void InputScheme::putFile(
throw Error("input '%s' does not support modifying file '%s'", input.to_string(), path);
}
void InputScheme::clone(const Settings & settings, const Input & input, const Path & destDir) const
void InputScheme::clone(
const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir) const
{
throw Error("do not know how to clone input '%s'", input.to_string());
if (std::filesystem::exists(destDir))
throw Error("cannot clone into existing path %s", destDir);
auto [accessor, input2] = getAccessor(settings, store, input);
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s' to %s...", input2.to_string(), destDir));
auto source = sinkToSource([&](Sink & sink) { accessor->dumpPath(CanonPath::root, sink); });
restorePath(destDir, *source);
}
std::optional<ExperimentalFeature> InputScheme::experimentalFeature() const

View file

@ -433,7 +433,8 @@ struct GitInputScheme : InputScheme
return res;
}
void clone(const Settings & settings, const Input & input, const Path & destDir) const override
void clone(const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir)
const override
{
auto repoInfo = getRepoInfo(input);

View file

@ -457,12 +457,13 @@ struct GitHubInputScheme : GitArchiveInputScheme
return DownloadUrl{parseURL(url), headers};
}
void clone(const Settings & settings, const Input & input, const Path & destDir) const override
void clone(const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir)
const override
{
auto host = getHost(input);
Input::fromURL(settings, fmt("git+https://%s/%s/%s.git", host, getOwner(input), getRepo(input)))
.applyOverrides(input.getRef(), input.getRev())
.clone(settings, destDir);
.clone(settings, store, destDir);
}
};
@ -544,7 +545,8 @@ struct GitLabInputScheme : GitArchiveInputScheme
return DownloadUrl{parseURL(url), headers};
}
void clone(const Settings & settings, const Input & input, const Path & destDir) const override
void clone(const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir)
const override
{
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
// FIXME: get username somewhere
@ -552,7 +554,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
settings,
fmt("git+https://%s/%s/%s.git", host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")))
.applyOverrides(input.getRef(), input.getRev())
.clone(settings, destDir);
.clone(settings, store, destDir);
}
};
@ -639,14 +641,15 @@ struct SourceHutInputScheme : GitArchiveInputScheme
return DownloadUrl{parseURL(url), headers};
}
void clone(const Settings & settings, const Input & input, const Path & destDir) const override
void clone(const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir)
const override
{
auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
Input::fromURL(
settings,
fmt("git+https://%s/%s/%s", host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")))
.applyOverrides(input.getRef(), input.getRev())
.clone(settings, destDir);
.clone(settings, store, destDir);
}
};

View file

@ -143,7 +143,7 @@ public:
Input applyOverrides(std::optional<std::string> ref, std::optional<Hash> rev) const;
void clone(const Settings & settings, const Path & destDir) const;
void clone(const Settings & settings, ref<Store> store, const std::filesystem::path & destDir) const;
std::optional<std::filesystem::path> getSourcePath() const;
@ -229,7 +229,8 @@ struct InputScheme
virtual Input applyOverrides(const Input & input, std::optional<std::string> ref, std::optional<Hash> rev) const;
virtual void clone(const Settings & settings, const Input & input, const Path & destDir) const;
virtual void clone(
const Settings & settings, ref<Store> store, const Input & input, const std::filesystem::path & destDir) const;
virtual std::optional<std::filesystem::path> getSourcePath(const Input & input) const;

View file

@ -1019,7 +1019,7 @@ struct CmdFlakeNew : CmdFlakeInitCommon
struct CmdFlakeClone : FlakeCommand
{
Path destDir;
std::filesystem::path destDir;
std::string description() override
{
@ -1049,7 +1049,7 @@ struct CmdFlakeClone : FlakeCommand
if (destDir.empty())
throw Error("missing flag '--dest'");
getFlakeRef().resolve(fetchSettings, store).input.clone(fetchSettings, destDir);
getFlakeRef().resolve(fetchSettings, store).input.clone(fetchSettings, store, destDir);
}
};

View file

@ -369,6 +369,10 @@ tar cfz "$TEST_ROOT"/flake.tar.gz -C "$TEST_ROOT" flake5
nix build -o "$TEST_ROOT"/result file://"$TEST_ROOT"/flake.tar.gz
nix flake clone "file://$TEST_ROOT/flake.tar.gz" --dest "$TEST_ROOT/unpacked"
[[ -e $TEST_ROOT/unpacked/flake.nix ]]
expectStderr 1 nix flake clone "file://$TEST_ROOT/flake.tar.gz" --dest "$TEST_ROOT/unpacked" | grep 'existing path'
# Building with a tarball URL containing a SRI hash should also work.
url=$(nix flake metadata --json file://"$TEST_ROOT"/flake.tar.gz | jq -r .url)
[[ $url =~ sha256- ]]