forked from lix-project/lix
Issue #15 is finished
This commit is contained in:
parent
e007f367bd
commit
5e4d92d267
6 changed files with 136 additions and 15 deletions
|
@ -12,9 +12,14 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
Path getUserRegistryPath()
|
||||
{
|
||||
return getHome() + "/.config/nix/registry.json";
|
||||
}
|
||||
|
||||
/* Read the registry or a lock file. (Currently they have an identical
|
||||
format. */
|
||||
static std::unique_ptr<FlakeRegistry> readRegistry(const Path & path)
|
||||
std::unique_ptr<FlakeRegistry> readRegistry(const Path & path)
|
||||
{
|
||||
auto registry = std::make_unique<FlakeRegistry>();
|
||||
|
||||
|
@ -40,7 +45,7 @@ void writeRegistry(FlakeRegistry registry, Path path)
|
|||
json["version"] = 1;
|
||||
json["flakes"] = {};
|
||||
for (auto elem : registry.entries) {
|
||||
json["flakes"][elem.first] = elem.second.ref.to_string();
|
||||
json["flakes"][elem.first] = { {"uri", elem.second.ref.to_string()} };
|
||||
}
|
||||
writeFile(path, json.dump(4)); // The '4' is the number of spaces used in the indentation in the json file.
|
||||
}
|
||||
|
@ -183,8 +188,8 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef)
|
|||
if (std::get_if<FlakeRef::IsGitHub>(&newFlakeRef.data)) {
|
||||
FlakeSourceInfo srcInfo = fetchFlake(state, newFlakeRef);
|
||||
if (srcInfo.rev) {
|
||||
std::string uri = flakeRef.to_string();
|
||||
newFlakeRef = FlakeRef(uri + "/" + srcInfo.rev->to_string());
|
||||
std::string uri = flakeRef.baseRef().to_string();
|
||||
newFlakeRef = FlakeRef(uri + "/" + srcInfo.rev->to_string(Base16, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,19 @@ struct FlakeRegistry
|
|||
{
|
||||
FlakeRef ref;
|
||||
Entry(const FlakeRef & flakeRef) : ref(flakeRef) {};
|
||||
Entry operator=(const Entry & entry) { return Entry(entry.ref); }
|
||||
};
|
||||
std::map<FlakeId, Entry> entries;
|
||||
};
|
||||
|
||||
Path getUserRegistryPath();
|
||||
|
||||
Value * makeFlakeRegistryValue(EvalState & state);
|
||||
|
||||
Value * makeFlakeValue(EvalState & state, std::string flakeUri, Value & v);
|
||||
|
||||
std::unique_ptr<FlakeRegistry> readRegistry(const Path &);
|
||||
|
||||
void writeRegistry(FlakeRegistry, Path);
|
||||
|
||||
struct Flake
|
||||
|
|
|
@ -152,4 +152,19 @@ bool FlakeRef::isImmutable() const
|
|||
else abort();
|
||||
}
|
||||
|
||||
FlakeRef FlakeRef::baseRef() const // Removes the ref and rev from a FlakeRef.
|
||||
{
|
||||
FlakeRef result(*this);
|
||||
if (auto refData = std::get_if<FlakeRef::IsGitHub>(&result.data)) {
|
||||
refData->ref = std::nullopt;
|
||||
refData->rev = std::nullopt;
|
||||
} else if (auto refData = std::get_if<FlakeRef::IsGit>(&result.data)) {
|
||||
refData->ref = std::nullopt;
|
||||
refData->rev = std::nullopt;
|
||||
} else if (auto refData = std::get_if<FlakeRef::IsGit>(&result.data)) {
|
||||
refData->ref = std::nullopt;
|
||||
refData->rev = std::nullopt;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,6 +153,7 @@ struct FlakeRef
|
|||
/* Check whether this is an "immutable" flake reference, that is,
|
||||
one that contains a commit hash or content hash. */
|
||||
bool isImmutable() const;
|
||||
};
|
||||
|
||||
FlakeRef baseRef() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ struct GitRepoCommand : virtual Args
|
|||
}
|
||||
};
|
||||
|
||||
struct FlakeCommand : virtual Args, StoreCommand, MixEvalArgs
|
||||
struct FlakeCommand : virtual Args
|
||||
{
|
||||
std::string flakeUri;
|
||||
|
||||
|
|
113
src/nix/flake.cc
113
src/nix/flake.cc
|
@ -50,17 +50,12 @@ struct CmdFlakeUpdate : StoreCommand, GitRepoCommand, MixEvalArgs
|
|||
{
|
||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
||||
|
||||
if (flakeUri == "") flakeUri = absPath("./flake.nix");
|
||||
int result = updateLockFile(*evalState, flakeUri);
|
||||
if (result == 1) {
|
||||
std::cout << "You can only update local flakes, not flakes on GitHub.\n";
|
||||
} else if (result == 2) {
|
||||
std::cout << "You can only update local flakes, not flakes through their FlakeId.\n";
|
||||
}
|
||||
if (gitPath == "") gitPath = absPath(".");
|
||||
updateLockFile(*evalState, gitPath);
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdFlakeInfo : FlakeCommand, MixJSON
|
||||
struct CmdFlakeInfo : FlakeCommand, MixJSON, MixEvalArgs, StoreCommand
|
||||
{
|
||||
std::string name() override
|
||||
{
|
||||
|
@ -88,12 +83,112 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON
|
|||
}
|
||||
};
|
||||
|
||||
struct CmdFlakeAdd : MixEvalArgs, Command
|
||||
{
|
||||
std::string flakeId;
|
||||
std::string flakeUri;
|
||||
|
||||
std::string name() override
|
||||
{
|
||||
return "add";
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "upsert flake in user flake registry";
|
||||
}
|
||||
|
||||
CmdFlakeAdd()
|
||||
{
|
||||
expectArg("flake-id", &flakeId);
|
||||
expectArg("flake-uri", &flakeUri);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
FlakeRef newFlakeRef(flakeUri);
|
||||
Path userRegistryPath = getUserRegistryPath();
|
||||
auto userRegistry = readRegistry(userRegistryPath);
|
||||
FlakeRegistry::Entry entry(newFlakeRef);
|
||||
userRegistry->entries.erase(flakeId);
|
||||
userRegistry->entries.insert_or_assign(flakeId, newFlakeRef);
|
||||
writeRegistry(*userRegistry, userRegistryPath);
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdFlakeRemove : virtual Args, MixEvalArgs, Command
|
||||
{
|
||||
std::string flakeId;
|
||||
|
||||
std::string name() override
|
||||
{
|
||||
return "remove";
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "remove flake from user flake registry";
|
||||
}
|
||||
|
||||
CmdFlakeRemove()
|
||||
{
|
||||
expectArg("flake-id", &flakeId);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
Path userRegistryPath = getUserRegistryPath();
|
||||
auto userRegistry = readRegistry(userRegistryPath);
|
||||
userRegistry->entries.erase(flakeId);
|
||||
writeRegistry(*userRegistry, userRegistryPath);
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdFlakePin : virtual Args, StoreCommand, MixEvalArgs
|
||||
{
|
||||
std::string flakeId;
|
||||
|
||||
std::string name() override
|
||||
{
|
||||
return "pin";
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "pin flake require in user flake registry";
|
||||
}
|
||||
|
||||
CmdFlakePin()
|
||||
{
|
||||
expectArg("flake-id", &flakeId);
|
||||
}
|
||||
|
||||
void run(nix::ref<nix::Store> store) override
|
||||
{
|
||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
||||
|
||||
Path userRegistryPath = getUserRegistryPath();
|
||||
FlakeRegistry userRegistry = *readRegistry(userRegistryPath);
|
||||
auto it = userRegistry.entries.find(flakeId);
|
||||
if (it != userRegistry.entries.end()) {
|
||||
FlakeRef oldRef = it->second.ref;
|
||||
it->second.ref = getFlake(*evalState, oldRef).ref;
|
||||
// The 'ref' in 'flake' is immutable.
|
||||
writeRegistry(userRegistry, userRegistryPath);
|
||||
} else
|
||||
throw Error("the flake identifier '%s' does not exist in the user registry", flakeId);
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdFlake : virtual MultiCommand, virtual Command
|
||||
{
|
||||
CmdFlake()
|
||||
: MultiCommand({make_ref<CmdFlakeList>()
|
||||
, make_ref<CmdFlakeUpdate>()
|
||||
, make_ref<CmdFlakeInfo>()
|
||||
, make_ref<CmdFlakeUpdate>()})
|
||||
, make_ref<CmdFlakeAdd>()
|
||||
, make_ref<CmdFlakeRemove>()
|
||||
, make_ref<CmdFlakePin>()})
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue