From 1c55f16a1648431301f044710644a674c018321d Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Fri, 12 Jun 2020 12:26:08 -0500 Subject: Add --flat to nix add-to-store This can be used to add flat hashes to the nix store. --- src/nix/add-to-store.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/nix') diff --git a/src/nix/add-to-store.cc b/src/nix/add-to-store.cc index f43f774c1..a5a77f17c 100644 --- a/src/nix/add-to-store.cc +++ b/src/nix/add-to-store.cc @@ -9,6 +9,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand { Path path; std::optional namePart; + FileIngestionMethod ingestionMethod = FileIngestionMethod::Recursive; CmdAddToStore() { @@ -21,6 +22,13 @@ struct CmdAddToStore : MixDryRun, StoreCommand .labels = {"name"}, .handler = {&namePart}, }); + + addFlag({ + .longName = "flat", + .shortName = 0, + .description = "use flat file ingestion", + .handler = {&ingestionMethod, FileIngestionMethod::Flat}, + }); } std::string description() override @@ -45,10 +53,24 @@ struct CmdAddToStore : MixDryRun, StoreCommand auto narHash = hashString(htSHA256, *sink.s); - ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, *namePart)); + ValidPathInfo info(store->makeFixedOutputPath(ingestionMethod, narHash, *namePart)); info.narHash = narHash; info.narSize = sink.s->size(); - info.ca = makeFixedOutputCA(FileIngestionMethod::Recursive, info.narHash); + + Hash hash; + switch (ingestionMethod) { + case FileIngestionMethod::Recursive: { + hash = info.narHash; + break; + } + case FileIngestionMethod::Flat: { + HashSink hsink(htSHA256); + readFile(path, hsink); + hash = hsink.finish().first; + break; + } + } + info.ca = makeFixedOutputCA(ingestionMethod, hash); if (!dryRun) { auto source = StringSource { *sink.s }; -- cgit v1.2.3 From e3cb536f19920018b522f76ac2661d68627b7c9e Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Fri, 12 Jun 2020 15:25:29 -0500 Subject: Fix add-to-store --flat to put in correct hash --- src/nix/add-to-store.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nix') diff --git a/src/nix/add-to-store.cc b/src/nix/add-to-store.cc index a5a77f17c..26edcf95a 100644 --- a/src/nix/add-to-store.cc +++ b/src/nix/add-to-store.cc @@ -53,14 +53,10 @@ struct CmdAddToStore : MixDryRun, StoreCommand auto narHash = hashString(htSHA256, *sink.s); - ValidPathInfo info(store->makeFixedOutputPath(ingestionMethod, narHash, *namePart)); - info.narHash = narHash; - info.narSize = sink.s->size(); - Hash hash; switch (ingestionMethod) { case FileIngestionMethod::Recursive: { - hash = info.narHash; + hash = narHash; break; } case FileIngestionMethod::Flat: { @@ -70,6 +66,10 @@ struct CmdAddToStore : MixDryRun, StoreCommand break; } } + + ValidPathInfo info(store->makeFixedOutputPath(ingestionMethod, hash, *namePart)); + info.narHash = narHash; + info.narSize = sink.s->size(); info.ca = makeFixedOutputCA(ingestionMethod, hash); if (!dryRun) { -- cgit v1.2.3 From 6438ba1e990ddf76602a70d5c1143b73ed31855c Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Wed, 17 Jun 2020 12:31:01 -0400 Subject: Update strings from review comment --- src/nix/add-to-store.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nix') diff --git a/src/nix/add-to-store.cc b/src/nix/add-to-store.cc index 26edcf95a..7abb82556 100644 --- a/src/nix/add-to-store.cc +++ b/src/nix/add-to-store.cc @@ -26,7 +26,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand addFlag({ .longName = "flat", .shortName = 0, - .description = "use flat file ingestion", + .description = "add flat file to the Nix store", .handler = {&ingestionMethod, FileIngestionMethod::Flat}, }); } -- cgit v1.2.3 From 3f6e88a5527dcc4d58e3147f78388a88eb8896e0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jul 2020 13:10:49 +0200 Subject: unsigned long long -> uint64_t --- src/nix/path-info.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nix') diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc index 65f73cd94..0c12efaf0 100644 --- a/src/nix/path-info.cc +++ b/src/nix/path-info.cc @@ -61,7 +61,7 @@ struct CmdPathInfo : StorePathsCommand, MixJSON }; } - void printSize(unsigned long long value) + void printSize(uint64_t value) { if (!humanReadable) { std::cout << fmt("\t%11d", value); -- cgit v1.2.3 From 2f4250a4167f2b1c10e5fa9c6163f84bb9bbd740 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 11:33:22 -0500 Subject: Add "export" to Nix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a ‘nix export’ command which hooks into nix-bundle. It can be used in a similar way as nix-bundle, with the benefit of hooking into the new “app” functionality. For instance, $ nix export nixpkgs#jq $ ./jq --help jq - commandline JSON processor [version 1.6] ... $ scp jq machine-without-nix: $ ssh machine-without-nix ./jq jq - commandline JSON processor [version 1.6] ... Note that nix-bundle currently requires Linux to run. Other exporters might not have that requirement. “exporters” are meant to be reusable, so that, other repos can implement their own bundling. Fixes #3705 --- src/nix/export.cc | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nix/flake.cc | 25 +++++++++++ 2 files changed, 151 insertions(+) create mode 100644 src/nix/export.cc (limited to 'src/nix') diff --git a/src/nix/export.cc b/src/nix/export.cc new file mode 100644 index 000000000..9e7816605 --- /dev/null +++ b/src/nix/export.cc @@ -0,0 +1,126 @@ +#include "command.hh" +#include "common-args.hh" +#include "shared.hh" +#include "store-api.hh" +#include "fs-accessor.hh" + +using namespace nix; + +struct CmdExport : InstallableCommand +{ + std::string exporter = "github:matthewbauer/nix-bundle"; + Path outLink; + + CmdExport() + { + addFlag({ + .longName = "exporter", + .description = "use custom exporter", + .labels = {"flake-url"}, + .handler = {&exporter}, + .completer = {[&](size_t, std::string_view prefix) { + completeFlakeRef(getStore(), prefix); + }} + }); + + addFlag({ + .longName = "out-link", + .shortName = 'o', + .description = "path of the symlink to the build result", + .labels = {"path"}, + .handler = {&outLink}, + .completer = completePath + }); + } + + std::string description() override + { + return "export an application out of the Nix store"; + } + + Examples examples() override + { + return { + Example{ + "To export Hello:", + "nix export hello" + }, + }; + } + + Strings getDefaultFlakeAttrPaths() override + { + Strings res{"defaultApp." + settings.thisSystem.get()}; + for (auto & s : SourceExprCommand::getDefaultFlakeAttrPaths()) + res.push_back(s); + return res; + } + + Strings getDefaultFlakeAttrPathPrefixes() override + { + Strings res{"apps." + settings.thisSystem.get() + ".", "packages"}; + for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes()) + res.push_back(s); + return res; + } + + void run(ref store) override + { + auto evalState = getEvalState(); + + auto app = installable->toApp(*evalState); + store->buildPaths(app.context); + + auto [exporterFlakeRef, exporterName] = parseFlakeRefWithFragment(exporter, absPath(".")); + const flake::LockFlags lockFlags{ .writeLockFile = false }; + auto exporter = InstallableFlake( + evalState, std::move(exporterFlakeRef), + Strings{exporterName == "" ? ("defaultExporter." + settings.thisSystem.get()) : exporterName}, + Strings({"exporters." + settings.thisSystem.get() + "."}), lockFlags); + + Value * arg = evalState->allocValue(); + evalState->mkAttrs(*arg, 1); + + PathSet context; + for (auto & i : app.context) + context.insert("=" + store->printStorePath(i.path)); + mkString(*evalState->allocAttr(*arg, evalState->symbols.create("program")), app.program, context); + + auto vRes = evalState->allocValue(); + evalState->callFunction(*exporter.toValue(*evalState).first, *arg, *vRes, noPos); + + if (!evalState->isDerivation(*vRes)) + throw Error("the exporter '%s' does not produce a derivation", exporter.what()); + + Bindings::iterator i = vRes->attrs->find(evalState->sDrvPath); + if (i == vRes->attrs->end()) + throw Error("the exporter '%s' does not produce a derivation", exporter.what()); + + PathSet context2; + StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + + i = vRes->attrs->find(evalState->sOutPath); + if (i == vRes->attrs->end()) + throw Error("the exporter '%s' does not produce a derivation", exporter.what()); + + StorePath outPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + + store->buildPaths({{drvPath}}); + + auto accessor = store->getFSAccessor(); + auto outPathS = store->printStorePath(outPath); + if (accessor->stat(outPathS).type != FSAccessor::tRegular) + throw Error("'%s' is not a file; an exporter must only create a single file", outPathS); + + auto info = store->queryPathInfo(outPath); + if (!info->references.empty()) + throw Error("'%s' has references; an exporter must not leave any references", outPathS); + + if (outLink == "") + outLink = baseNameOf(app.program); + + store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(outLink), true); + } +}; + +static auto r2 = registerCommand("export"); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 027a9871e..db3ebdc2a 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -368,6 +368,21 @@ struct CmdFlakeCheck : FlakeCommand } }; + auto checkExporter = [&](const std::string & attrPath, Value & v, const Pos & pos) { + try { + state->forceValue(v, pos); + if (v.type != tLambda) + throw Error("exporter must be a function"); + if (!v.lambda.fun->formals || + v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end() || + v.lambda.fun->formals->argNames.find(state->symbols.create("args")) == v.lambda.fun->formals->argNames.end()) + throw Error("exporter must take formal arguments 'program' and 'args'"); + } catch (Error & e) { + e.addTrace(pos, hintfmt("while checking the template '%s'", attrPath)); + throw; + } + }; + { Activity act(*logger, lvlInfo, actUnknown, "evaluating flake"); @@ -490,6 +505,16 @@ struct CmdFlakeCheck : FlakeCommand *attr.value, *attr.pos); } + else if (name == "defaultExporter") + checkExporter(name, vOutput, pos); + + else if (name == "exporters") { + state->forceAttrs(vOutput, pos); + for (auto & attr : *vOutput.attrs) + checkExporter(fmt("%s.%s", name, attr.name), + *attr.value, *attr.pos); + } + else warn("unknown flake output '%s'", name); -- cgit v1.2.3 From 5d04a4db9b3d8cbfbaacbc48a587d21d90844871 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 11:45:47 -0500 Subject: Handle exporters checking correctly --- src/nix/flake.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/nix') diff --git a/src/nix/flake.cc b/src/nix/flake.cc index db3ebdc2a..cf7e4b7f5 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -374,9 +374,8 @@ struct CmdFlakeCheck : FlakeCommand if (v.type != tLambda) throw Error("exporter must be a function"); if (!v.lambda.fun->formals || - v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end() || - v.lambda.fun->formals->argNames.find(state->symbols.create("args")) == v.lambda.fun->formals->argNames.end()) - throw Error("exporter must take formal arguments 'program' and 'args'"); + v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end()) + throw Error("exporter must take formal argument 'program'"); } catch (Error & e) { e.addTrace(pos, hintfmt("while checking the template '%s'", attrPath)); throw; @@ -506,13 +505,21 @@ struct CmdFlakeCheck : FlakeCommand } else if (name == "defaultExporter") - checkExporter(name, vOutput, pos); + for (auto & attr : *vOutput.attrs) { + checkSystemName(attr.name, *attr.pos); + checkExporter(fmt("%s.%s", name, attr.name), *attr.value, *attr.pos); + } else if (name == "exporters") { state->forceAttrs(vOutput, pos); - for (auto & attr : *vOutput.attrs) - checkExporter(fmt("%s.%s", name, attr.name), - *attr.value, *attr.pos); + for (auto & attr : *vOutput.attrs) { + checkSystemName(attr.name, *attr.pos); + state->forceAttrs(*attr.value, *attr.pos); + for (auto & attr2 : *attr.value->attrs) + checkExporter( + fmt("%s.%s.%s", name, attr.name, attr2.name), + *attr2.value, *attr2.pos); + } } else -- cgit v1.2.3 From 52407f83a133ba605a1f0891c3812fa89038bba8 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 15:03:57 -0500 Subject: exporter -> bundler --- src/nix/bundle.cc | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nix/export.cc | 126 ------------------------------------------------------ src/nix/flake.cc | 14 +++--- 3 files changed, 133 insertions(+), 133 deletions(-) create mode 100644 src/nix/bundle.cc delete mode 100644 src/nix/export.cc (limited to 'src/nix') diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc new file mode 100644 index 000000000..e7338262b --- /dev/null +++ b/src/nix/bundle.cc @@ -0,0 +1,126 @@ +#include "command.hh" +#include "common-args.hh" +#include "shared.hh" +#include "store-api.hh" +#include "fs-accessor.hh" + +using namespace nix; + +struct CmdBundle : InstallableCommand +{ + std::string bundler = "github:matthewbauer/nix-bundle"; + Path outLink; + + CmdBundle() + { + addFlag({ + .longName = "bundler", + .description = "use custom bundler", + .labels = {"flake-url"}, + .handler = {&bundler}, + .completer = {[&](size_t, std::string_view prefix) { + completeFlakeRef(getStore(), prefix); + }} + }); + + addFlag({ + .longName = "out-link", + .shortName = 'o', + .description = "path of the symlink to the build result", + .labels = {"path"}, + .handler = {&outLink}, + .completer = completePath + }); + } + + std::string description() override + { + return "bundle an application so that it works outside of the Nix store"; + } + + Examples examples() override + { + return { + Example{ + "To bundle Hello:", + "nix bundle hello" + }, + }; + } + + Strings getDefaultFlakeAttrPaths() override + { + Strings res{"defaultApp." + settings.thisSystem.get()}; + for (auto & s : SourceExprCommand::getDefaultFlakeAttrPaths()) + res.push_back(s); + return res; + } + + Strings getDefaultFlakeAttrPathPrefixes() override + { + Strings res{"apps." + settings.thisSystem.get() + ".", "packages"}; + for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes()) + res.push_back(s); + return res; + } + + void run(ref store) override + { + auto evalState = getEvalState(); + + auto app = installable->toApp(*evalState); + store->buildPaths(app.context); + + auto [bundlerFlakeRef, bundlerName] = parseFlakeRefWithFragment(bundler, absPath(".")); + const flake::LockFlags lockFlags{ .writeLockFile = false }; + auto bundler = InstallableFlake( + evalState, std::move(bundlerFlakeRef), + Strings{bundlerName == "" ? ("defaultBundler." + settings.thisSystem.get()) : bundlerName}, + Strings({"bundlers." + settings.thisSystem.get() + "."}), lockFlags); + + Value * arg = evalState->allocValue(); + evalState->mkAttrs(*arg, 1); + + PathSet context; + for (auto & i : app.context) + context.insert("=" + store->printStorePath(i.path)); + mkString(*evalState->allocAttr(*arg, evalState->symbols.create("program")), app.program, context); + + auto vRes = evalState->allocValue(); + evalState->callFunction(*bundler.toValue(*evalState).first, *arg, *vRes, noPos); + + if (!evalState->isDerivation(*vRes)) + throw Error("the bundler '%s' does not produce a derivation", bundler.what()); + + Bindings::iterator i = vRes->attrs->find(evalState->sDrvPath); + if (i == vRes->attrs->end()) + throw Error("the bundler '%s' does not produce a bderivation", bundler.what()); + + PathSet context2; + StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + + i = vRes->attrs->find(evalState->sOutPath); + if (i == vRes->attrs->end()) + throw Error("the bundler '%s' does not produce a derivation", bundler.what()); + + StorePath outPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + + store->buildPaths({{drvPath}}); + + auto accessor = store->getFSAccessor(); + auto outPathS = store->printStorePath(outPath); + if (accessor->stat(outPathS).type != FSAccessor::tRegular) + throw Error("'%s' is not a file; a bundler must only create a single file", outPathS); + + auto info = store->queryPathInfo(outPath); + if (!info->references.empty()) + throw Error("'%s' has references; a bundler must not leave any references", outPathS); + + if (outLink == "") + outLink = baseNameOf(app.program); + + store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(outLink), true); + } +}; + +static auto r2 = registerCommand("bundle"); diff --git a/src/nix/export.cc b/src/nix/export.cc deleted file mode 100644 index 9e7816605..000000000 --- a/src/nix/export.cc +++ /dev/null @@ -1,126 +0,0 @@ -#include "command.hh" -#include "common-args.hh" -#include "shared.hh" -#include "store-api.hh" -#include "fs-accessor.hh" - -using namespace nix; - -struct CmdExport : InstallableCommand -{ - std::string exporter = "github:matthewbauer/nix-bundle"; - Path outLink; - - CmdExport() - { - addFlag({ - .longName = "exporter", - .description = "use custom exporter", - .labels = {"flake-url"}, - .handler = {&exporter}, - .completer = {[&](size_t, std::string_view prefix) { - completeFlakeRef(getStore(), prefix); - }} - }); - - addFlag({ - .longName = "out-link", - .shortName = 'o', - .description = "path of the symlink to the build result", - .labels = {"path"}, - .handler = {&outLink}, - .completer = completePath - }); - } - - std::string description() override - { - return "export an application out of the Nix store"; - } - - Examples examples() override - { - return { - Example{ - "To export Hello:", - "nix export hello" - }, - }; - } - - Strings getDefaultFlakeAttrPaths() override - { - Strings res{"defaultApp." + settings.thisSystem.get()}; - for (auto & s : SourceExprCommand::getDefaultFlakeAttrPaths()) - res.push_back(s); - return res; - } - - Strings getDefaultFlakeAttrPathPrefixes() override - { - Strings res{"apps." + settings.thisSystem.get() + ".", "packages"}; - for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes()) - res.push_back(s); - return res; - } - - void run(ref store) override - { - auto evalState = getEvalState(); - - auto app = installable->toApp(*evalState); - store->buildPaths(app.context); - - auto [exporterFlakeRef, exporterName] = parseFlakeRefWithFragment(exporter, absPath(".")); - const flake::LockFlags lockFlags{ .writeLockFile = false }; - auto exporter = InstallableFlake( - evalState, std::move(exporterFlakeRef), - Strings{exporterName == "" ? ("defaultExporter." + settings.thisSystem.get()) : exporterName}, - Strings({"exporters." + settings.thisSystem.get() + "."}), lockFlags); - - Value * arg = evalState->allocValue(); - evalState->mkAttrs(*arg, 1); - - PathSet context; - for (auto & i : app.context) - context.insert("=" + store->printStorePath(i.path)); - mkString(*evalState->allocAttr(*arg, evalState->symbols.create("program")), app.program, context); - - auto vRes = evalState->allocValue(); - evalState->callFunction(*exporter.toValue(*evalState).first, *arg, *vRes, noPos); - - if (!evalState->isDerivation(*vRes)) - throw Error("the exporter '%s' does not produce a derivation", exporter.what()); - - Bindings::iterator i = vRes->attrs->find(evalState->sDrvPath); - if (i == vRes->attrs->end()) - throw Error("the exporter '%s' does not produce a derivation", exporter.what()); - - PathSet context2; - StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); - - i = vRes->attrs->find(evalState->sOutPath); - if (i == vRes->attrs->end()) - throw Error("the exporter '%s' does not produce a derivation", exporter.what()); - - StorePath outPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); - - store->buildPaths({{drvPath}}); - - auto accessor = store->getFSAccessor(); - auto outPathS = store->printStorePath(outPath); - if (accessor->stat(outPathS).type != FSAccessor::tRegular) - throw Error("'%s' is not a file; an exporter must only create a single file", outPathS); - - auto info = store->queryPathInfo(outPath); - if (!info->references.empty()) - throw Error("'%s' has references; an exporter must not leave any references", outPathS); - - if (outLink == "") - outLink = baseNameOf(app.program); - - store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(outLink), true); - } -}; - -static auto r2 = registerCommand("export"); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index cf7e4b7f5..1190d7997 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -368,14 +368,14 @@ struct CmdFlakeCheck : FlakeCommand } }; - auto checkExporter = [&](const std::string & attrPath, Value & v, const Pos & pos) { + auto checkBundler = [&](const std::string & attrPath, Value & v, const Pos & pos) { try { state->forceValue(v, pos); if (v.type != tLambda) - throw Error("exporter must be a function"); + throw Error("bundler must be a function"); if (!v.lambda.fun->formals || v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end()) - throw Error("exporter must take formal argument 'program'"); + throw Error("bundler must take formal argument 'program'"); } catch (Error & e) { e.addTrace(pos, hintfmt("while checking the template '%s'", attrPath)); throw; @@ -504,19 +504,19 @@ struct CmdFlakeCheck : FlakeCommand *attr.value, *attr.pos); } - else if (name == "defaultExporter") + else if (name == "defaultBundler") for (auto & attr : *vOutput.attrs) { checkSystemName(attr.name, *attr.pos); - checkExporter(fmt("%s.%s", name, attr.name), *attr.value, *attr.pos); + checkBundler(fmt("%s.%s", name, attr.name), *attr.value, *attr.pos); } - else if (name == "exporters") { + else if (name == "bundlers") { state->forceAttrs(vOutput, pos); for (auto & attr : *vOutput.attrs) { checkSystemName(attr.name, *attr.pos); state->forceAttrs(*attr.value, *attr.pos); for (auto & attr2 : *attr.value->attrs) - checkExporter( + checkBundler( fmt("%s.%s.%s", name, attr.name, attr2.name), *attr2.value, *attr2.pos); } -- cgit v1.2.3 From 1a705637ce96c30424409d74cb3411554ae2847e Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 15:05:51 -0500 Subject: Remove single file restriction for bundler --- src/nix/bundle.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nix') diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc index e7338262b..677d42520 100644 --- a/src/nix/bundle.cc +++ b/src/nix/bundle.cc @@ -107,10 +107,7 @@ struct CmdBundle : InstallableCommand store->buildPaths({{drvPath}}); - auto accessor = store->getFSAccessor(); auto outPathS = store->printStorePath(outPath); - if (accessor->stat(outPathS).type != FSAccessor::tRegular) - throw Error("'%s' is not a file; a bundler must only create a single file", outPathS); auto info = store->queryPathInfo(outPath); if (!info->references.empty()) -- cgit v1.2.3 From 22fcfdf18af84bbbbc1bd416a9eed37a64e26eb5 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 15:18:48 -0500 Subject: Address misc review --- src/nix/bundle.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/nix') diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc index 677d42520..95aed5269 100644 --- a/src/nix/bundle.cc +++ b/src/nix/bundle.cc @@ -9,7 +9,7 @@ using namespace nix; struct CmdBundle : InstallableCommand { std::string bundler = "github:matthewbauer/nix-bundle"; - Path outLink; + std::optional outLink; CmdBundle() { @@ -92,18 +92,18 @@ struct CmdBundle : InstallableCommand if (!evalState->isDerivation(*vRes)) throw Error("the bundler '%s' does not produce a derivation", bundler.what()); - Bindings::iterator i = vRes->attrs->find(evalState->sDrvPath); - if (i == vRes->attrs->end()) - throw Error("the bundler '%s' does not produce a bderivation", bundler.what()); + auto attr1 = vRes->attrs->find(evalState->sDrvPath); + if (!attr1) + throw Error("the bundler '%s' does not produce a derivation", bundler.what()); PathSet context2; - StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + StorePath drvPath = store->parseStorePath(evalState->coerceToPath(*attr1->pos, *attr1->value, context2)); - i = vRes->attrs->find(evalState->sOutPath); - if (i == vRes->attrs->end()) + auto attr2 = vRes->attrs->find(evalState->sOutPath); + if (!attr2) throw Error("the bundler '%s' does not produce a derivation", bundler.what()); - StorePath outPath = store->parseStorePath(evalState->coerceToPath(*i->pos, *i->value, context2)); + StorePath outPath = store->parseStorePath(evalState->coerceToPath(*attr2->pos, *attr2->value, context2)); store->buildPaths({{drvPath}}); @@ -113,10 +113,10 @@ struct CmdBundle : InstallableCommand if (!info->references.empty()) throw Error("'%s' has references; a bundler must not leave any references", outPathS); - if (outLink == "") + if (!outLink) outLink = baseNameOf(app.program); - store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(outLink), true); + store.dynamic_pointer_cast()->addPermRoot(outPath, absPath(*outLink), true); } }; -- cgit v1.2.3 From fa2d1fb36e2ee92622379b9716f5b06e73aae72e Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 30 Jul 2020 15:37:05 -0500 Subject: Pass system to bundler --- src/nix/bundle.cc | 10 +++++++--- src/nix/flake.cc | 21 +++++++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'src/nix') diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc index 95aed5269..f2b78eea5 100644 --- a/src/nix/bundle.cc +++ b/src/nix/bundle.cc @@ -75,17 +75,21 @@ struct CmdBundle : InstallableCommand const flake::LockFlags lockFlags{ .writeLockFile = false }; auto bundler = InstallableFlake( evalState, std::move(bundlerFlakeRef), - Strings{bundlerName == "" ? ("defaultBundler." + settings.thisSystem.get()) : bundlerName}, - Strings({"bundlers." + settings.thisSystem.get() + "."}), lockFlags); + Strings{bundlerName == "" ? "defaultBundler" : bundlerName}, + Strings({"bundlers."}), lockFlags); Value * arg = evalState->allocValue(); - evalState->mkAttrs(*arg, 1); + evalState->mkAttrs(*arg, 2); PathSet context; for (auto & i : app.context) context.insert("=" + store->printStorePath(i.path)); mkString(*evalState->allocAttr(*arg, evalState->symbols.create("program")), app.program, context); + mkString(*evalState->allocAttr(*arg, evalState->symbols.create("system")), settings.thisSystem.get()); + + arg->attrs->sort(); + auto vRes = evalState->allocValue(); evalState->callFunction(*bundler.toValue(*evalState).first, *arg, *vRes, noPos); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 1190d7997..80d8654bc 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -374,8 +374,9 @@ struct CmdFlakeCheck : FlakeCommand if (v.type != tLambda) throw Error("bundler must be a function"); if (!v.lambda.fun->formals || - v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end()) - throw Error("bundler must take formal argument 'program'"); + v.lambda.fun->formals->argNames.find(state->symbols.create("program")) == v.lambda.fun->formals->argNames.end() || + v.lambda.fun->formals->argNames.find(state->symbols.create("system")) == v.lambda.fun->formals->argNames.end()) + throw Error("bundler must take formal arguments 'program' and 'system'"); } catch (Error & e) { e.addTrace(pos, hintfmt("while checking the template '%s'", attrPath)); throw; @@ -505,21 +506,13 @@ struct CmdFlakeCheck : FlakeCommand } else if (name == "defaultBundler") - for (auto & attr : *vOutput.attrs) { - checkSystemName(attr.name, *attr.pos); - checkBundler(fmt("%s.%s", name, attr.name), *attr.value, *attr.pos); - } + checkBundler(name, vOutput, pos); else if (name == "bundlers") { state->forceAttrs(vOutput, pos); - for (auto & attr : *vOutput.attrs) { - checkSystemName(attr.name, *attr.pos); - state->forceAttrs(*attr.value, *attr.pos); - for (auto & attr2 : *attr.value->attrs) - checkBundler( - fmt("%s.%s.%s", name, attr.name, attr2.name), - *attr2.value, *attr2.pos); - } + for (auto & attr : *vOutput.attrs) + checkBundler(fmt("%s.%s", name, attr.name), + *attr.value, *attr.pos); } else -- cgit v1.2.3