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:
commit
f6aa8c0486
6 changed files with 35 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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- ]]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue