forked from lix-project/lix
Merge pull request #2877 from NixOS/improve-flake-command
FlakeCommand improvements
This commit is contained in:
commit
3cecf3f39c
|
@ -482,9 +482,8 @@ ResolvedFlake resolveFlake(EvalState & state, const FlakeRef & topRef, HandleLoc
|
||||||
return resFlake;
|
return resFlake;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateLockFile(EvalState & state, const FlakeUri & flakeUri, bool recreateLockFile)
|
void updateLockFile(EvalState & state, const FlakeRef & flakeRef, bool recreateLockFile)
|
||||||
{
|
{
|
||||||
FlakeRef flakeRef(flakeUri);
|
|
||||||
resolveFlake(state, flakeRef, recreateLockFile ? RecreateLockFile : UpdateLockFile);
|
resolveFlake(state, flakeRef, recreateLockFile ? RecreateLockFile : UpdateLockFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,10 +550,8 @@ static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
|
|
||||||
static RegisterPrimOp r2("getFlake", 1, prim_getFlake);
|
static RegisterPrimOp r2("getFlake", 1, prim_getFlake);
|
||||||
|
|
||||||
void gitCloneFlake (std::string flakeUri, EvalState & state, Registries registries,
|
void gitCloneFlake(FlakeRef flakeRef, EvalState & state, Registries registries, const Path & destDir)
|
||||||
Path endDirectory)
|
|
||||||
{
|
{
|
||||||
FlakeRef flakeRef(flakeUri);
|
|
||||||
flakeRef = lookupFlake(state, flakeRef, registries);
|
flakeRef = lookupFlake(state, flakeRef, registries);
|
||||||
|
|
||||||
std::string uri;
|
std::string uri;
|
||||||
|
@ -576,8 +573,8 @@ void gitCloneFlake (std::string flakeUri, EvalState & state, Registries registri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endDirectory != "")
|
if (destDir != "")
|
||||||
args.push_back(endDirectory);
|
args.push_back(destDir);
|
||||||
|
|
||||||
runProgram("git", true, args);
|
runProgram("git", true, args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ typedef std::vector<std::shared_ptr<FlakeRegistry>> Registries;
|
||||||
|
|
||||||
Path getUserRegistryPath();
|
Path getUserRegistryPath();
|
||||||
|
|
||||||
enum HandleLockFile
|
enum HandleLockFile : unsigned int
|
||||||
{ AllPure // Everything is handled 100% purely
|
{ AllPure // Everything is handled 100% purely
|
||||||
, TopRefUsesRegistries // The top FlakeRef uses the registries, apart from that, everything happens 100% purely
|
, TopRefUsesRegistries // The top FlakeRef uses the registries, apart from that, everything happens 100% purely
|
||||||
, UpdateLockFile // Update the existing lockfile and write it to file
|
, UpdateLockFile // Update the existing lockfile and write it to file
|
||||||
|
@ -133,7 +133,8 @@ struct ResolvedFlake
|
||||||
|
|
||||||
ResolvedFlake resolveFlake(EvalState &, const FlakeRef &, HandleLockFile);
|
ResolvedFlake resolveFlake(EvalState &, const FlakeRef &, HandleLockFile);
|
||||||
|
|
||||||
void updateLockFile(EvalState &, const FlakeUri &, bool recreateLockFile);
|
void updateLockFile(EvalState &, const FlakeRef & flakeRef, bool recreateLockFile);
|
||||||
|
|
||||||
|
void gitCloneFlake(FlakeRef flakeRef, EvalState &, Registries, const Path & destDir);
|
||||||
|
|
||||||
void gitCloneFlake (std::string flakeUri, EvalState &, Registries, Path);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ extern std::string programPath;
|
||||||
struct Value;
|
struct Value;
|
||||||
class Bindings;
|
class Bindings;
|
||||||
class EvalState;
|
class EvalState;
|
||||||
|
|
||||||
class Store;
|
class Store;
|
||||||
|
enum HandleLockFile : unsigned int;
|
||||||
|
|
||||||
/* A command that require a Nix store. */
|
/* A command that require a Nix store. */
|
||||||
struct StoreCommand : virtual Command
|
struct StoreCommand : virtual Command
|
||||||
|
@ -35,26 +35,6 @@ struct Buildable
|
||||||
|
|
||||||
typedef std::vector<Buildable> Buildables;
|
typedef std::vector<Buildable> Buildables;
|
||||||
|
|
||||||
struct GitRepoCommand : virtual Args
|
|
||||||
{
|
|
||||||
std::string gitPath = absPath(".");
|
|
||||||
|
|
||||||
GitRepoCommand ()
|
|
||||||
{
|
|
||||||
expectArg("git-path", &gitPath, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FlakeCommand : virtual Args
|
|
||||||
{
|
|
||||||
std::string flakeUri;
|
|
||||||
|
|
||||||
FlakeCommand()
|
|
||||||
{
|
|
||||||
expectArg("flake-uri", &flakeUri);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Installable
|
struct Installable
|
||||||
{
|
{
|
||||||
virtual std::string what() = 0;
|
virtual std::string what() = 0;
|
||||||
|
@ -72,19 +52,33 @@ struct Installable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs
|
struct EvalCommand : virtual StoreCommand, MixEvalArgs
|
||||||
{
|
{
|
||||||
std::optional<Path> file;
|
ref<EvalState> getEvalState();
|
||||||
|
|
||||||
SourceExprCommand();
|
private:
|
||||||
|
|
||||||
|
std::shared_ptr<EvalState> evalState;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MixFlakeOptions : virtual Args
|
||||||
|
{
|
||||||
bool recreateLockFile = false;
|
bool recreateLockFile = false;
|
||||||
|
|
||||||
bool saveLockFile = true;
|
bool saveLockFile = true;
|
||||||
|
|
||||||
bool noRegistries = false;
|
bool useRegistries = true;
|
||||||
|
|
||||||
ref<EvalState> getEvalState();
|
MixFlakeOptions();
|
||||||
|
|
||||||
|
HandleLockFile getLockFileMode();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SourceExprCommand : virtual Args, EvalCommand, MixFlakeOptions
|
||||||
|
{
|
||||||
|
std::optional<Path> file;
|
||||||
|
|
||||||
|
SourceExprCommand();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Installable>> parseInstallables(
|
std::vector<std::shared_ptr<Installable>> parseInstallables(
|
||||||
ref<Store> store, std::vector<std::string> ss);
|
ref<Store> store, std::vector<std::string> ss);
|
||||||
|
@ -96,10 +90,6 @@ struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs
|
||||||
{
|
{
|
||||||
return {"defaultPackage"};
|
return {"defaultPackage"};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::shared_ptr<EvalState> evalState;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RealiseMode { Build, NoBuild, DryRun };
|
enum RealiseMode { Build, NoBuild, DryRun };
|
||||||
|
|
|
@ -10,7 +10,38 @@
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
struct CmdFlakeList : StoreCommand, MixEvalArgs
|
class FlakeCommand : virtual Args, public EvalCommand, public MixFlakeOptions
|
||||||
|
{
|
||||||
|
std::string flakeUri = ".";
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FlakeCommand()
|
||||||
|
{
|
||||||
|
expectArg("flake-uri", &flakeUri, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlakeRef getFlakeRef()
|
||||||
|
{
|
||||||
|
if (flakeUri.find('/') != std::string::npos || flakeUri == ".")
|
||||||
|
return FlakeRef(flakeUri, true);
|
||||||
|
else
|
||||||
|
return FlakeRef(flakeUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
Flake getFlake()
|
||||||
|
{
|
||||||
|
auto evalState = getEvalState();
|
||||||
|
return nix::getFlake(*evalState, getFlakeRef(), useRegistries);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvedFlake resolveFlake()
|
||||||
|
{
|
||||||
|
return nix::resolveFlake(*getEvalState(), getFlakeRef(), getLockFileMode());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmdFlakeList : EvalCommand
|
||||||
{
|
{
|
||||||
std::string name() override
|
std::string name() override
|
||||||
{
|
{
|
||||||
|
@ -24,9 +55,7 @@ struct CmdFlakeList : StoreCommand, MixEvalArgs
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto registries = getEvalState()->getFlakeRegistries();
|
||||||
|
|
||||||
auto registries = evalState->getFlakeRegistries();
|
|
||||||
|
|
||||||
stopProgressBar();
|
stopProgressBar();
|
||||||
|
|
||||||
|
@ -41,7 +70,7 @@ struct CmdFlakeList : StoreCommand, MixEvalArgs
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void printFlakeInfo(Flake & flake, bool json) {
|
void printFlakeInfo(const Flake & flake, bool json) {
|
||||||
if (json) {
|
if (json) {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["id"] = flake.id;
|
j["id"] = flake.id;
|
||||||
|
@ -60,7 +89,7 @@ void printFlakeInfo(Flake & flake, bool json) {
|
||||||
std::cout << "URI: " << flake.resolvedRef.to_string() << "\n";
|
std::cout << "URI: " << flake.resolvedRef.to_string() << "\n";
|
||||||
std::cout << "Description: " << flake.description << "\n";
|
std::cout << "Description: " << flake.description << "\n";
|
||||||
if (flake.resolvedRef.ref)
|
if (flake.resolvedRef.ref)
|
||||||
std::cout << "Branch: " << *flake.resolvedRef.ref;
|
std::cout << "Branch: " << *flake.resolvedRef.ref << "\n";
|
||||||
if (flake.resolvedRef.rev)
|
if (flake.resolvedRef.rev)
|
||||||
std::cout << "Revision: " << flake.resolvedRef.rev->to_string(Base16, false) << "\n";
|
std::cout << "Revision: " << flake.resolvedRef.rev->to_string(Base16, false) << "\n";
|
||||||
if (flake.revCount)
|
if (flake.revCount)
|
||||||
|
@ -69,7 +98,7 @@ void printFlakeInfo(Flake & flake, bool json) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printNonFlakeInfo(NonFlake & nonFlake, bool json) {
|
void printNonFlakeInfo(const NonFlake & nonFlake, bool json) {
|
||||||
if (json) {
|
if (json) {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["id"] = nonFlake.alias;
|
j["id"] = nonFlake.alias;
|
||||||
|
@ -95,7 +124,8 @@ void printNonFlakeInfo(NonFlake & nonFlake, bool json) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CmdFlakeDeps : FlakeCommand, MixJSON, StoreCommand, MixEvalArgs
|
// FIXME: merge info CmdFlakeInfo?
|
||||||
|
struct CmdFlakeDeps : FlakeCommand, MixJSON
|
||||||
{
|
{
|
||||||
std::string name() override
|
std::string name() override
|
||||||
{
|
{
|
||||||
|
@ -109,30 +139,28 @@ struct CmdFlakeDeps : FlakeCommand, MixJSON, StoreCommand, MixEvalArgs
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto evalState = getEvalState();
|
||||||
evalState->addRegistryOverrides(registryOverrides);
|
evalState->addRegistryOverrides(registryOverrides);
|
||||||
|
|
||||||
FlakeRef flakeRef(flakeUri);
|
|
||||||
|
|
||||||
ResolvedFlake resFlake = resolveFlake(*evalState, flakeRef, UpdateLockFile);
|
|
||||||
|
|
||||||
std::queue<ResolvedFlake> todo;
|
std::queue<ResolvedFlake> todo;
|
||||||
todo.push(resFlake);
|
todo.push(resolveFlake());
|
||||||
|
|
||||||
while (!todo.empty()) {
|
while (!todo.empty()) {
|
||||||
resFlake = todo.front();
|
auto resFlake = std::move(todo.front());
|
||||||
todo.pop();
|
todo.pop();
|
||||||
|
|
||||||
for (NonFlake & nonFlake : resFlake.nonFlakeDeps)
|
for (auto & nonFlake : resFlake.nonFlakeDeps)
|
||||||
printNonFlakeInfo(nonFlake, json);
|
printNonFlakeInfo(nonFlake, json);
|
||||||
|
|
||||||
for (auto info : resFlake.flakeDeps)
|
for (auto & info : resFlake.flakeDeps) {
|
||||||
|
printFlakeInfo(info.second.flake, json);
|
||||||
todo.push(info.second);
|
todo.push(info.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFlakeUpdate : StoreCommand, FlakeCommand, MixEvalArgs
|
struct CmdFlakeUpdate : FlakeCommand
|
||||||
{
|
{
|
||||||
std::string name() override
|
std::string name() override
|
||||||
{
|
{
|
||||||
|
@ -146,14 +174,18 @@ struct CmdFlakeUpdate : StoreCommand, FlakeCommand, MixEvalArgs
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto evalState = getEvalState();
|
||||||
|
|
||||||
bool recreateLockFile = true;
|
auto flakeRef = getFlakeRef();
|
||||||
updateLockFile(*evalState, flakeUri, recreateLockFile);
|
|
||||||
|
if (std::get_if<FlakeRef::IsPath>(&flakeRef.data))
|
||||||
|
updateLockFile(*evalState, flakeRef, true);
|
||||||
|
else
|
||||||
|
throw Error("cannot update lockfile of flake '%s'", flakeRef);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFlakeInfo : FlakeCommand, MixJSON, MixEvalArgs, StoreCommand
|
struct CmdFlakeInfo : FlakeCommand, MixJSON
|
||||||
{
|
{
|
||||||
std::string name() override
|
std::string name() override
|
||||||
{
|
{
|
||||||
|
@ -169,8 +201,7 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON, MixEvalArgs, StoreCommand
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto flake = getFlake();
|
||||||
Flake flake = getFlake(*evalState, FlakeRef(flakeUri), true);
|
|
||||||
printFlakeInfo(flake, json);
|
printFlakeInfo(flake, json);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -235,7 +266,7 @@ struct CmdFlakeRemove : virtual Args, MixEvalArgs, Command
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFlakePin : virtual Args, StoreCommand, MixEvalArgs
|
struct CmdFlakePin : virtual Args, EvalCommand
|
||||||
{
|
{
|
||||||
FlakeUri alias;
|
FlakeUri alias;
|
||||||
|
|
||||||
|
@ -256,7 +287,7 @@ struct CmdFlakePin : virtual Args, StoreCommand, MixEvalArgs
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto evalState = getEvalState();
|
||||||
|
|
||||||
Path userRegistryPath = getUserRegistryPath();
|
Path userRegistryPath = getUserRegistryPath();
|
||||||
FlakeRegistry userRegistry = *readRegistry(userRegistryPath);
|
FlakeRegistry userRegistry = *readRegistry(userRegistryPath);
|
||||||
|
@ -307,9 +338,9 @@ struct CmdFlakeInit : virtual Args, Command
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFlakeClone : StoreCommand, FlakeCommand, MixEvalArgs
|
struct CmdFlakeClone : FlakeCommand
|
||||||
{
|
{
|
||||||
Path endDirectory = "";
|
Path destDir;
|
||||||
|
|
||||||
std::string name() override
|
std::string name() override
|
||||||
{
|
{
|
||||||
|
@ -323,15 +354,15 @@ struct CmdFlakeClone : StoreCommand, FlakeCommand, MixEvalArgs
|
||||||
|
|
||||||
CmdFlakeClone()
|
CmdFlakeClone()
|
||||||
{
|
{
|
||||||
expectArg("end-dir", &endDirectory, true);
|
expectArg("dest-dir", &destDir, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(nix::ref<nix::Store> store) override
|
void run(nix::ref<nix::Store> store) override
|
||||||
{
|
{
|
||||||
auto evalState = std::make_shared<EvalState>(searchPath, store);
|
auto evalState = getEvalState();
|
||||||
|
|
||||||
Registries registries = evalState->getFlakeRegistries();
|
Registries registries = evalState->getFlakeRegistries();
|
||||||
gitCloneFlake(flakeUri, *evalState, registries, endDirectory);
|
gitCloneFlake(getFlakeRef().to_string(), *evalState, registries, destDir);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,34 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
MixFlakeOptions::MixFlakeOptions()
|
||||||
|
{
|
||||||
|
mkFlag()
|
||||||
|
.longName("recreate-lock-file")
|
||||||
|
.description("recreate lock file from scratch")
|
||||||
|
.set(&recreateLockFile, true);
|
||||||
|
|
||||||
|
mkFlag()
|
||||||
|
.longName("no-save-lock-file")
|
||||||
|
.description("do not save the newly generated lock file")
|
||||||
|
.set(&saveLockFile, false);
|
||||||
|
|
||||||
|
mkFlag()
|
||||||
|
.longName("no-registries")
|
||||||
|
.description("don't use flake registries")
|
||||||
|
.set(&useRegistries, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleLockFile MixFlakeOptions::getLockFileMode()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
useRegistries
|
||||||
|
? recreateLockFile
|
||||||
|
? (saveLockFile ? RecreateLockFile : UseNewLockFile)
|
||||||
|
: (saveLockFile ? UpdateLockFile : UseUpdatedLockFile)
|
||||||
|
: AllPure;
|
||||||
|
}
|
||||||
|
|
||||||
SourceExprCommand::SourceExprCommand()
|
SourceExprCommand::SourceExprCommand()
|
||||||
{
|
{
|
||||||
mkFlag()
|
mkFlag()
|
||||||
|
@ -21,24 +49,9 @@ SourceExprCommand::SourceExprCommand()
|
||||||
.label("file")
|
.label("file")
|
||||||
.description("evaluate a set of attributes from FILE (deprecated)")
|
.description("evaluate a set of attributes from FILE (deprecated)")
|
||||||
.dest(&file);
|
.dest(&file);
|
||||||
|
|
||||||
mkFlag()
|
|
||||||
.longName("recreate-lock-file")
|
|
||||||
.description("recreate lock file from scratch")
|
|
||||||
.set(&recreateLockFile, true);
|
|
||||||
|
|
||||||
mkFlag()
|
|
||||||
.longName("dont-save-lock-file")
|
|
||||||
.description("save the newly generated lock file")
|
|
||||||
.set(&saveLockFile, false);
|
|
||||||
|
|
||||||
mkFlag()
|
|
||||||
.longName("no-registries")
|
|
||||||
.description("don't use flake registries")
|
|
||||||
.set(&noRegistries, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<EvalState> SourceExprCommand::getEvalState()
|
ref<EvalState> EvalCommand::getEvalState()
|
||||||
{
|
{
|
||||||
if (!evalState)
|
if (!evalState)
|
||||||
evalState = std::make_shared<EvalState>(searchPath, getStore());
|
evalState = std::make_shared<EvalState>(searchPath, getStore());
|
||||||
|
@ -169,11 +182,7 @@ struct InstallableFlake : InstallableValue
|
||||||
{
|
{
|
||||||
auto vFlake = state.allocValue();
|
auto vFlake = state.allocValue();
|
||||||
|
|
||||||
HandleLockFile handle = cmd.noRegistries ? AllPure :
|
makeFlakeValue(state, flakeRef, cmd.getLockFileMode(), *vFlake);
|
||||||
cmd.recreateLockFile ?
|
|
||||||
(cmd.saveLockFile ? RecreateLockFile : UseNewLockFile)
|
|
||||||
: (cmd.saveLockFile ? UpdateLockFile : UseUpdatedLockFile);
|
|
||||||
makeFlakeValue(state, flakeRef, handle, *vFlake);
|
|
||||||
|
|
||||||
auto vProvides = (*vFlake->attrs->get(state.symbols.create("provides")))->value;
|
auto vProvides = (*vFlake->attrs->get(state.symbols.create("provides")))->value;
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,11 @@ EOF
|
||||||
# Test 'nix flake info'.
|
# Test 'nix flake info'.
|
||||||
nix flake info --flake-registry $registry flake1 | grep -q 'ID: *flake1'
|
nix flake info --flake-registry $registry flake1 | grep -q 'ID: *flake1'
|
||||||
|
|
||||||
|
# Test 'nix flake info' on a local flake.
|
||||||
|
(cd $flake1Dir && nix flake info) | grep -q 'ID: *flake1'
|
||||||
|
(cd $flake1Dir && nix flake info .) | grep -q 'ID: *flake1'
|
||||||
|
nix flake info $flake1Dir | grep -q 'ID: *flake1'
|
||||||
|
|
||||||
# Test 'nix flake info --json'.
|
# Test 'nix flake info --json'.
|
||||||
json=$(nix flake info --flake-registry $registry flake1 --json | jq .)
|
json=$(nix flake info --flake-registry $registry flake1 --json | jq .)
|
||||||
[[ $(echo "$json" | jq -r .description) = 'Bla bla' ]]
|
[[ $(echo "$json" | jq -r .description) = 'Bla bla' ]]
|
||||||
|
|
Loading…
Reference in a new issue