From be1f0697468bd6c0f2be4f7e058270c161098e9f Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Fri, 4 Mar 2022 05:04:47 +0100 Subject: Add error context for most basic coercions --- src/libexpr/primops/fetchTree.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 9c2da2178..a40eddfca 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,7 +102,7 @@ static void fetchTree( state.forceValue(*args[0], pos); if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos); + state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree"); fetchers::Attrs attrs; @@ -112,7 +112,7 @@ static void fetchTree( .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos }); - type = state.forceStringNoCtx(*aType->value, *aType->pos); + type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree"); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), @@ -195,16 +195,14 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos); - for (auto & attr : *args[0]->attrs) { std::string n(attr.name); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos); + url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch"); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch"), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos); + name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch"); else throw EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), @@ -218,7 +216,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, .errPos = pos }); } else - url = state.forceStringNoCtx(*args[0], pos); + url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch"); url = resolveUri(*url); -- cgit v1.2.3 From 3a5855353e5dc2986c38bb66eaff5538dea70da1 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Fri, 4 Mar 2022 21:47:58 +0100 Subject: Add detailed error mesage for coerceTo{String,Path} --- src/libexpr/primops/fetchTree.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index a40eddfca..2baa272cb 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -125,7 +125,7 @@ static void fetchTree( if (attr.name == state.sType) continue; state.forceValue(*attr.value, *attr.pos); if (attr.value->type() == nPath || attr.value->type() == nString) { - auto s = state.coerceToString(*attr.pos, *attr.value, context, false, false).toOwned(); + auto s = state.coerceToString(*attr.pos, *attr.value, context, false, false, "").toOwned(); attrs.emplace(attr.name, attr.name == "url" ? type == "git" @@ -151,7 +151,7 @@ static void fetchTree( input = fetchers::Input::fromAttrs(std::move(attrs)); } else { - auto url = state.coerceToString(pos, *args[0], context, false, false).toOwned(); + auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher").toOwned(); if (type == "git") { fetchers::Attrs attrs; -- cgit v1.2.3 From 13c4dc65327c9654c47e6d80c0f4e1797b999f97 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Mon, 7 Mar 2022 11:33:03 +0100 Subject: more fixes --- src/libexpr/primops/fetchTree.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 2baa272cb..31a8907f1 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,7 +102,7 @@ static void fetchTree( state.forceValue(*args[0], pos); if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree"); + state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree: "); fetchers::Attrs attrs; @@ -112,7 +112,7 @@ static void fetchTree( .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos }); - type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree"); + type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree: "); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), @@ -151,7 +151,7 @@ static void fetchTree( input = fetchers::Input::fromAttrs(std::move(attrs)); } else { - auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher").toOwned(); + auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher: ").toOwned(); if (type == "git") { fetchers::Attrs attrs; @@ -198,11 +198,11 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, for (auto & attr : *args[0]->attrs) { std::string n(attr.name); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch"); + url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch: "); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch"), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch: "), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch"); + name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch: "); else throw EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), @@ -216,7 +216,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, .errPos = pos }); } else - url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch"); + url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch: "); url = resolveUri(*url); -- cgit v1.2.3 From eaecaaa00ba79b05f49a908f2c96c6507d3a2d7b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 14 Mar 2022 11:39:53 -0600 Subject: more debug_throw coverage of EvalErrors --- src/libexpr/primops/fetchTree.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index d09e2d9e1..c9fcbb8f5 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -108,16 +108,16 @@ static void fetchTree( if (auto aType = args[0]->attrs->get(state.sType)) { if (type) - throw Error({ + state.debug_throw(EvalError({ .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos - }); + })); type = state.forceStringNoCtx(*aType->value, *aType->pos); } else if (!type) - throw Error({ + state.debug_throw(EvalError({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), .errPos = pos - }); + })); attrs.emplace("type", type.value()); @@ -138,16 +138,16 @@ static void fetchTree( else if (attr.value->type() == nInt) attrs.emplace(attr.name, uint64_t(attr.value->integer)); else - throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - attr.name, showType(*attr.value)); + state.debug_throw(TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", + attr.name, showType(*attr.value))); } if (!params.allowNameArgument) if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) - throw Error({ + state.debug_throw(EvalError({ .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"), .errPos = pos - }); + })); input = fetchers::Input::fromAttrs(std::move(attrs)); } else { @@ -167,7 +167,7 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (evalSettings.pureEval && !input.isImmutable()) - throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input, at %s", pos); + state.debug_throw(EvalError("in pure evaluation mode, 'fetchTree' requires an immutable input, at %s", pos)); auto [tree, input2] = input.fetch(state.store); @@ -206,17 +206,17 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError({ + state.debug_throw(EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), .errPos = *attr.pos - }); + })); } if (!url) - throw EvalError({ + state.debug_throw(EvalError({ .msg = hintfmt("'url' argument required"), .errPos = pos - }); + })); } else url = state.forceStringNoCtx(*args[0], pos); @@ -228,7 +228,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, name = baseNameOf(*url); if (evalSettings.pureEval && !expectedHash) - throw Error("in pure evaluation mode, '%s' requires a 'sha256' argument", who); + state.debug_throw(EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who)); auto storePath = unpack @@ -240,8 +240,8 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, ? state.store->queryPathInfo(storePath)->narHash : hashFile(htSHA256, state.store->toRealPath(storePath)); if (hash != *expectedHash) - throw Error((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", - *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); + state.debug_throw(EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", + *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true))); } state.allowPath(storePath); -- cgit v1.2.3 From 1942fed6d9cee95775046c5ad3d253ab2e8ab210 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Fri, 18 Mar 2022 01:10:04 +0100 Subject: Revert extra colon at end os strings --- src/libexpr/primops/fetchTree.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 31a8907f1..2baa272cb 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,7 +102,7 @@ static void fetchTree( state.forceValue(*args[0], pos); if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree: "); + state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree"); fetchers::Attrs attrs; @@ -112,7 +112,7 @@ static void fetchTree( .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos }); - type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree: "); + type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree"); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), @@ -151,7 +151,7 @@ static void fetchTree( input = fetchers::Input::fromAttrs(std::move(attrs)); } else { - auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher: ").toOwned(); + auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher").toOwned(); if (type == "git") { fetchers::Attrs attrs; @@ -198,11 +198,11 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, for (auto & attr : *args[0]->attrs) { std::string n(attr.name); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch: "); + url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch"); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch: "), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch"), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch: "); + name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch"); else throw EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), @@ -216,7 +216,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, .errPos = pos }); } else - url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch: "); + url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch"); url = resolveUri(*url); -- cgit v1.2.3 From b8b8ec710160cfd343a8fce33ec8734e23c98444 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 12:34:27 -0600 Subject: move throw to preverve Error type; turn off debugger for tryEval --- src/libexpr/primops/fetchTree.cc | 74 +++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 19 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index bae0fb1e4..131cc87dc 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -108,16 +108,25 @@ static void fetchTree( if (auto aType = args[0]->attrs->get(state.sType)) { if (type) - state.debug_throw(EvalError({ + { + auto e = EvalError({ .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos - })); + }); + state.debugLastTrace(e); + throw e; + + } type = state.forceStringNoCtx(*aType->value, *aType->pos); } else if (!type) - state.debug_throw(EvalError({ + { + auto e = EvalError({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), .errPos = pos - })); + }); + state.debugLastTrace(e); + throw e; + } attrs.emplace("type", type.value()); @@ -138,16 +147,24 @@ static void fetchTree( else if (attr.value->type() == nInt) attrs.emplace(attr.name, uint64_t(attr.value->integer)); else - state.debug_throw(TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - attr.name, showType(*attr.value))); + { + auto e = TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", + attr.name, showType(*attr.value)); + state.debugLastTrace(e); + throw e; + } } if (!params.allowNameArgument) if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) - state.debug_throw(EvalError({ + { + auto e = EvalError({ .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"), .errPos = pos - })); + }); + state.debugLastTrace(e); + throw e; + } input = fetchers::Input::fromAttrs(std::move(attrs)); } else { @@ -167,7 +184,11 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (evalSettings.pureEval && !input.isLocked()) - state.debug_throw(EvalError("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", pos)); + { + auto e = EvalError("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", pos); + state.debugLastTrace(e); + throw e; + } auto [tree, input2] = input.fetch(state.store); @@ -205,18 +226,25 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); - else - state.debug_throw(EvalError({ - .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), - .errPos = *attr.pos - })); + else { + auto e = EvalError({ + .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), + .errPos = *attr.pos + }); + state.debugLastTrace(e); + throw e; } + } if (!url) - state.debug_throw(EvalError({ + { + auto e = EvalError({ .msg = hintfmt("'url' argument required"), .errPos = pos - })); + }); + state.debugLastTrace(e); + throw e; + } } else url = state.forceStringNoCtx(*args[0], pos); @@ -228,7 +256,11 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, name = baseNameOf(*url); if (evalSettings.pureEval && !expectedHash) - state.debug_throw(EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who)); + { + auto e = EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who); + state.debugLastTrace(e); + throw e; + } // early exit if pinned and already in the store if (expectedHash && expectedHash->type == htSHA256) { @@ -255,8 +287,12 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, ? state.store->queryPathInfo(storePath)->narHash : hashFile(htSHA256, state.store->toRealPath(storePath)); if (hash != *expectedHash) - state.debug_throw(EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", - *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true))); + { + auto e = EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", + *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); + state.debugLastTrace(e); + throw e; + } } state.allowAndSetStorePathString(storePath, v); -- cgit v1.2.3 From 27d45f9eb3c151afed8a20f1adc1d4dd1a200f09 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 15:46:12 -0600 Subject: minor cleanup --- src/libexpr/primops/fetchTree.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 131cc87dc..c7b73b83d 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -226,13 +226,14 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); - else { - auto e = EvalError({ - .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), - .errPos = *attr.pos - }); - state.debugLastTrace(e); - throw e; + else + { + auto e = EvalError({ + .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), + .errPos = *attr.pos + }); + state.debugLastTrace(e); + throw e; } } -- cgit v1.2.3 From 6526d1676ba5a645f65d751e7529ccd273579017 Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 4 Mar 2022 19:31:59 +0100 Subject: replace most Pos objects/ptrs with indexes into a position table Pos objects are somewhat wasteful as they duplicate the origin file name and input type for each object. on files that produce more than one Pos when parsed this a sizeable waste of memory (one pointer per Pos). the same goes for ptr on 64 bit machines: parsing enough source to require 8 bytes to locate a position would need at least 8GB of input and 64GB of expression memory. it's not likely that we'll hit that any time soon, so we can use a uint32_t index to locate positions instead. --- src/libexpr/primops/fetchTree.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 42c98e312..cdcae97b6 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -90,7 +90,7 @@ struct FetchTreeParams { static void fetchTree( EvalState & state, - const Pos & pos, + const PosIdx pos, Value * * args, Value & v, std::optional type, @@ -110,22 +110,22 @@ static void fetchTree( if (type) throw Error({ .msg = hintfmt("unexpected attribute 'type'"), - .errPos = pos + .errPos = state.positions[pos] }); - type = state.forceStringNoCtx(*aType->value, *aType->pos); + type = state.forceStringNoCtx(*aType->value, aType->pos); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), - .errPos = pos + .errPos = state.positions[pos] }); attrs.emplace("type", type.value()); for (auto & attr : *args[0]->attrs) { if (attr.name == state.sType) continue; - state.forceValue(*attr.value, *attr.pos); + state.forceValue(*attr.value, attr.pos); if (attr.value->type() == nPath || attr.value->type() == nString) { - auto s = state.coerceToString(*attr.pos, *attr.value, context, false, false).toOwned(); + auto s = state.coerceToString(attr.pos, *attr.value, context, false, false).toOwned(); attrs.emplace(attr.name, attr.name == "url" ? type == "git" @@ -146,7 +146,7 @@ static void fetchTree( if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) throw Error({ .msg = hintfmt("attribute 'name' isn't supported in call to 'fetchTree'"), - .errPos = pos + .errPos = state.positions[pos] }); input = fetchers::Input::fromAttrs(std::move(attrs)); @@ -167,7 +167,7 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (evalSettings.pureEval && !input.isLocked()) - throw Error("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", pos); + throw Error("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", state.positions[pos]); auto [tree, input2] = input.fetch(state.store); @@ -176,7 +176,7 @@ static void fetchTree( emitTreeAttrs(state, tree, input2, v, params.emptyRevFallback, false); } -static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchTree(EvalState & state, const PosIdx pos, Value * * args, Value & v) { settings.requireExperimentalFeature(Xp::Flakes); fetchTree(state, pos, args, v, std::nullopt, FetchTreeParams { .allowNameArgument = false }); @@ -185,7 +185,7 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V // FIXME: document static RegisterPrimOp primop_fetchTree("fetchTree", 1, prim_fetchTree); -static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, +static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v, const std::string & who, bool unpack, std::string name) { std::optional url; @@ -200,22 +200,22 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, for (auto & attr : *args[0]->attrs) { std::string n(attr.name); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos); + url = state.forceStringNoCtx(*attr.value, attr.pos); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos); + name = state.forceStringNoCtx(*attr.value, attr.pos); else throw EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), - .errPos = *attr.pos + .errPos = state.positions[attr.pos] }); } if (!url) throw EvalError({ .msg = hintfmt("'url' argument required"), - .errPos = pos + .errPos = state.positions[pos] }); } else url = state.forceStringNoCtx(*args[0], pos); @@ -262,7 +262,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, state.allowAndSetStorePathString(storePath, v); } -static void prim_fetchurl(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchurl(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetch(state, pos, args, v, "fetchurl", false, ""); } @@ -278,7 +278,7 @@ static RegisterPrimOp primop_fetchurl({ .fun = prim_fetchurl, }); -static void prim_fetchTarball(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchTarball(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetch(state, pos, args, v, "fetchTarball", true, "source"); } @@ -329,7 +329,7 @@ static RegisterPrimOp primop_fetchTarball({ .fun = prim_fetchTarball, }); -static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Value & v) +static void prim_fetchGit(EvalState & state, const PosIdx pos, Value * * args, Value & v) { fetchTree(state, pos, args, v, "git", FetchTreeParams { .emptyRevFallback = true, .allowNameArgument = true }); } -- cgit v1.2.3 From 8775be33931ec3b1cad97035ff3d5370a97178a1 Mon Sep 17 00:00:00 2001 From: pennae Date: Sat, 5 Mar 2022 14:40:24 +0100 Subject: store Symbols in a table as well, like positions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this slightly increases the amount of memory used for any given symbol, but this increase is more than made up for if the symbol is referenced more than once in the EvalState that holds it. on average every symbol should be referenced at least twice (once to introduce a binding, once to use it), so we expect no increase in memory on average. symbol tables are limited to 2³² entries like position tables, and similar arguments apply to why overflow is not likely: 2³² symbols would require as many string instances (at 24 bytes each) and map entries (at 24 bytes or more each, assuming that the map holds on average at most one item per bucket as the docs say). a full symbol table would require at least 192GB of memory just for symbols, which is well out of reach. (an ofborg eval of nixpks today creates less than a million symbols!) --- src/libexpr/primops/fetchTree.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index cdcae97b6..d7c3c9918 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -126,20 +126,20 @@ static void fetchTree( state.forceValue(*attr.value, attr.pos); if (attr.value->type() == nPath || attr.value->type() == nString) { auto s = state.coerceToString(attr.pos, *attr.value, context, false, false).toOwned(); - attrs.emplace(attr.name, - attr.name == "url" + attrs.emplace(state.symbols[attr.name], + state.symbols[attr.name] == "url" ? type == "git" ? fixURIForGit(s, state) : fixURI(s, state) : s); } else if (attr.value->type() == nBool) - attrs.emplace(attr.name, Explicit{attr.value->boolean}); + attrs.emplace(state.symbols[attr.name], Explicit{attr.value->boolean}); else if (attr.value->type() == nInt) - attrs.emplace(attr.name, uint64_t(attr.value->integer)); + attrs.emplace(state.symbols[attr.name], uint64_t(attr.value->integer)); else throw TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - attr.name, showType(*attr.value)); + state.symbols[attr.name], showType(*attr.value)); } if (!params.allowNameArgument) @@ -198,7 +198,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v state.forceAttrs(*args[0], pos); for (auto & attr : *args[0]->attrs) { - std::string n(attr.name); + std::string_view n(state.symbols[attr.name]); if (n == "url") url = state.forceStringNoCtx(*attr.value, attr.pos); else if (n == "sha256") @@ -207,7 +207,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v name = state.forceStringNoCtx(*attr.value, attr.pos); else throw EvalError({ - .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), + .msg = hintfmt("unsupported argument '%s' to '%s'", n, who), .errPos = state.positions[attr.pos] }); } -- cgit v1.2.3 From acf990c9ea9de913a500cf2b7a7492eef3bcd7b5 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Thu, 28 Apr 2022 12:54:14 +0200 Subject: fix errors case and wording --- src/libexpr/primops/fetchTree.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 2baa272cb..25fb8d939 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,7 +102,7 @@ static void fetchTree( state.forceValue(*args[0], pos); if (args[0]->type() == nAttrs) { - state.forceAttrs(*args[0], pos, "While evaluating the argument passed to builtins.fetchTree"); + state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.fetchTree"); fetchers::Attrs attrs; @@ -112,7 +112,7 @@ static void fetchTree( .msg = hintfmt("unexpected attribute 'type'"), .errPos = pos }); - type = state.forceStringNoCtx(*aType->value, *aType->pos, "While evaluating the `type` attribute passed to builtins.fetchTree"); + type = state.forceStringNoCtx(*aType->value, *aType->pos, "while evaluating the `type` attribute passed to builtins.fetchTree"); } else if (!type) throw Error({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), @@ -151,7 +151,7 @@ static void fetchTree( input = fetchers::Input::fromAttrs(std::move(attrs)); } else { - auto url = state.coerceToString(pos, *args[0], context, false, false, "While evaluating the first argument passed to the fetcher").toOwned(); + auto url = state.coerceToString(pos, *args[0], context, false, false, "while evaluating the first argument passed to the fetcher").toOwned(); if (type == "git") { fetchers::Attrs attrs; @@ -198,11 +198,11 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, for (auto & attr : *args[0]->attrs) { std::string n(attr.name); if (n == "url") - url = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the url we should fetch"); + url = state.forceStringNoCtx(*attr.value, *attr.pos, "while evaluating the url we should fetch"); else if (n == "sha256") - expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the sha256 of the content we should fetch"), htSHA256); + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos, "while evaluating the sha256 of the content we should fetch"), htSHA256); else if (n == "name") - name = state.forceStringNoCtx(*attr.value, *attr.pos, "While evaluating the name of the content we should fetch"); + name = state.forceStringNoCtx(*attr.value, *attr.pos, "while evaluating the name of the content we should fetch"); else throw EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), @@ -216,7 +216,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, .errPos = pos }); } else - url = state.forceStringNoCtx(*args[0], pos, "While evaluating the url we should fetch"); + url = state.forceStringNoCtx(*args[0], pos, "while evaluating the url we should fetch"); url = resolveUri(*url); -- cgit v1.2.3 From 2c9fafdc9e43f6da39c289888dedbbbf0ea0b208 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 6 May 2022 08:47:21 -0600 Subject: trying debugThrow --- src/libexpr/primops/fetchTree.cc | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 55fe7da24..e4fa3c5f9 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -113,8 +113,7 @@ static void fetchTree( .msg = hintfmt("unexpected attribute 'type'"), .errPos = state.positions[pos] }); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } type = state.forceStringNoCtx(*aType->value, aType->pos); } else if (!type) @@ -123,8 +122,7 @@ static void fetchTree( .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), .errPos = state.positions[pos] }); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } attrs.emplace("type", type.value()); @@ -149,8 +147,7 @@ static void fetchTree( { auto e = TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", state.symbols[attr.name], showType(*attr.value)); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } } @@ -161,8 +158,7 @@ static void fetchTree( .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"), .errPos = state.positions[pos] }); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } input = fetchers::Input::fromAttrs(std::move(attrs)); @@ -185,8 +181,7 @@ static void fetchTree( if (evalSettings.pureEval && !input.isLocked()) { auto e = EvalError("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", state.positions[pos]); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } auto [tree, input2] = input.fetch(state.store); @@ -231,8 +226,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v .msg = hintfmt("unsupported argument '%s' to '%s'", n, who), .errPos = state.positions[attr.pos] }); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } } @@ -242,8 +236,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v .msg = hintfmt("'url' argument required"), .errPos = state.positions[pos] }); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } } else url = state.forceStringNoCtx(*args[0], pos); @@ -258,8 +251,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v if (evalSettings.pureEval && !expectedHash) { auto e = EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } // early exit if pinned and already in the store @@ -290,8 +282,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v { auto e = EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); - state.debugLastTrace(e); - throw e; + state.debugThrowLastTrace(e); } } -- cgit v1.2.3 From 91b7d5373acdc5d9b3f2c13d16b9850ab5fc9e9d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 25 May 2022 12:32:22 +0200 Subject: Style tweaks --- src/libexpr/primops/fetchTree.cc | 59 +++++++++++----------------------------- 1 file changed, 16 insertions(+), 43 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index e4fa3c5f9..e5eeea520 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -108,22 +108,16 @@ static void fetchTree( if (auto aType = args[0]->attrs->get(state.sType)) { if (type) - { - auto e = EvalError({ + state.debugThrowLastTrace(EvalError({ .msg = hintfmt("unexpected attribute 'type'"), .errPos = state.positions[pos] - }); - state.debugThrowLastTrace(e); - } + })); type = state.forceStringNoCtx(*aType->value, aType->pos); } else if (!type) - { - auto e = EvalError({ + state.debugThrowLastTrace(EvalError({ .msg = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), .errPos = state.positions[pos] - }); - state.debugThrowLastTrace(e); - } + })); attrs.emplace("type", type.value()); @@ -144,22 +138,16 @@ static void fetchTree( else if (attr.value->type() == nInt) attrs.emplace(state.symbols[attr.name], uint64_t(attr.value->integer)); else - { - auto e = TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", - state.symbols[attr.name], showType(*attr.value)); - state.debugThrowLastTrace(e); - } + state.debugThrowLastTrace(TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected", + state.symbols[attr.name], showType(*attr.value))); } if (!params.allowNameArgument) if (auto nameIter = attrs.find("name"); nameIter != attrs.end()) - { - auto e = EvalError({ + state.debugThrowLastTrace(EvalError({ .msg = hintfmt("attribute 'name' isn’t supported in call to 'fetchTree'"), .errPos = state.positions[pos] - }); - state.debugThrowLastTrace(e); - } + })); input = fetchers::Input::fromAttrs(std::move(attrs)); } else { @@ -179,10 +167,7 @@ static void fetchTree( input = lookupInRegistries(state.store, input).first; if (evalSettings.pureEval && !input.isLocked()) - { - auto e = EvalError("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", state.positions[pos]); - state.debugThrowLastTrace(e); - } + state.debugThrowLastTrace(EvalError("in pure evaluation mode, 'fetchTree' requires a locked input, at %s", state.positions[pos])); auto [tree, input2] = input.fetch(state.store); @@ -221,23 +206,17 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v else if (n == "name") name = state.forceStringNoCtx(*attr.value, attr.pos); else - { - auto e = EvalError({ + state.debugThrowLastTrace(EvalError({ .msg = hintfmt("unsupported argument '%s' to '%s'", n, who), .errPos = state.positions[attr.pos] - }); - state.debugThrowLastTrace(e); - } + })); } if (!url) - { - auto e = EvalError({ + state.debugThrowLastTrace(EvalError({ .msg = hintfmt("'url' argument required"), .errPos = state.positions[pos] - }); - state.debugThrowLastTrace(e); - } + })); } else url = state.forceStringNoCtx(*args[0], pos); @@ -249,10 +228,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v name = baseNameOf(*url); if (evalSettings.pureEval && !expectedHash) - { - auto e = EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who); - state.debugThrowLastTrace(e); - } + state.debugThrowLastTrace(EvalError("in pure evaluation mode, '%s' requires a 'sha256' argument", who)); // early exit if pinned and already in the store if (expectedHash && expectedHash->type == htSHA256) { @@ -279,11 +255,8 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v ? state.store->queryPathInfo(storePath)->narHash : hashFile(htSHA256, state.store->toRealPath(storePath)); if (hash != *expectedHash) - { - auto e = EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", - *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); - state.debugThrowLastTrace(e); - } + state.debugThrowLastTrace(EvalError((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s", + *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true))); } state.allowAndSetStorePathString(storePath, v); -- cgit v1.2.3 From e8109cf405d672c50b1e5a25c632ddcb1d517233 Mon Sep 17 00:00:00 2001 From: Guillaume Girol Date: Sun, 26 Jun 2022 12:00:00 +0000 Subject: fetchGit: document `shallow` argument --- src/libexpr/primops/fetchTree.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index e5eeea520..84e7f5c02 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -364,6 +364,10 @@ static RegisterPrimOp primop_fetchGit({ A Boolean parameter that specifies whether submodules should be checked out. Defaults to `false`. + - shallow\ + A Boolean parameter that specifies whether fetching a shallow clone + is allowed. Defaults to `false`. + - allRefs\ Whether to fetch all refs of the repository. With this argument being true, it's possible to load a `rev` from *any* `ref` (by default only -- cgit v1.2.3 From ae5f62a894190e0075eb60ae4537ba81ca2a0a8d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 12 Sep 2022 15:37:09 +0200 Subject: Move isUri() and resolveUri() out of filetransfer.cc These are purely related to NIX_PATH / -I command line parsing, so put them in libexpr. --- src/libexpr/primops/fetchTree.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libexpr/primops/fetchTree.cc') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 84e7f5c02..680446787 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -220,8 +220,6 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v } else url = state.forceStringNoCtx(*args[0], pos); - url = resolveUri(*url); - state.checkURI(*url); if (name == "") -- cgit v1.2.3