Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport SourcePath from the lazy-trees branch #8172

Merged
merged 6 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,27 +153,27 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
for (auto & i : autoArgs) {
auto v = state.allocValue();
if (i.second[0] == 'E')
state.mkThunk_(*v, state.parseExprFromString(i.second.substr(1), absPath(".")));
state.mkThunk_(*v, state.parseExprFromString(i.second.substr(1), state.rootPath(CanonPath::fromCwd())));
else
v->mkString(((std::string_view) i.second).substr(1));
res.insert(state.symbols.create(i.first), v);
}
return res.finish();
}

Path lookupFileArg(EvalState & state, std::string_view s)
SourcePath lookupFileArg(EvalState & state, std::string_view s)
{
if (EvalSettings::isPseudoUrl(s)) {
auto storePath = fetchers::downloadTarball(
state.store, EvalSettings::resolvePseudoUrl(s), "source", false).first.storePath;
return state.store->toRealPath(storePath);
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
}

else if (hasPrefix(s, "flake:")) {
experimentalFeatureSettings.require(Xp::Flakes);
auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
return state.store->toRealPath(storePath);
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
}

else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
Expand All @@ -182,7 +182,7 @@ Path lookupFileArg(EvalState & state, std::string_view s)
}

else
return absPath(std::string(s));
return state.rootPath(CanonPath::fromCwd(s));
}

}
3 changes: 2 additions & 1 deletion src/libcmd/common-eval-args.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace nix {
class Store;
class EvalState;
class Bindings;
struct SourcePath;

struct MixEvalArgs : virtual Args
{
Expand All @@ -25,6 +26,6 @@ private:
std::map<std::string, std::string> autoArgs;
};

Path lookupFileArg(EvalState & state, std::string_view s);
SourcePath lookupFileArg(EvalState & state, std::string_view s);

}
7 changes: 5 additions & 2 deletions src/libcmd/editor-for.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

namespace nix {

Strings editorFor(const Path & file, uint32_t line)
Strings editorFor(const SourcePath & file, uint32_t line)
{
auto path = file.getPhysicalPath();
if (!path)
throw Error("cannot open '%s' in an editor because it has no physical path", file);
auto editor = getEnv("EDITOR").value_or("cat");
auto args = tokenizeString<Strings>(editor);
if (line > 0 && (
Expand All @@ -13,7 +16,7 @@ Strings editorFor(const Path & file, uint32_t line)
editor.find("vim") != std::string::npos ||
editor.find("kak") != std::string::npos))
args.push_back(fmt("+%d", line));
args.push_back(file);
args.push_back(path->abs());
return args;
}

Expand Down
3 changes: 2 additions & 1 deletion src/libcmd/editor-for.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
///@file

#include "types.hh"
#include "input-accessor.hh"

namespace nix {

/**
* Helper function to generate args that invoke $EDITOR on
* filename:lineno.
*/
Strings editorFor(const Path & file, uint32_t line);
Strings editorFor(const SourcePath & file, uint32_t line);

}
3 changes: 1 addition & 2 deletions src/libcmd/installable-flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
auto v = attr->forceValue();

if (v.type() == nPath) {
NixStringContext context;
auto storePath = state->copyPathToStore(context, Path(v.path));
auto storePath = v.path().fetchToStore(state->store);
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
Expand Down
2 changes: 1 addition & 1 deletion src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ Installables SourceExprCommand::parseInstallables(
else if (file)
state->evalFile(lookupFileArg(*state, *file), *vFile);
else {
auto e = state->parseExprFromString(*expr, absPath("."));
auto e = state->parseExprFromString(*expr, state->rootPath(CanonPath::fromCwd()));
state->eval(e, *vFile);
}

Expand Down
12 changes: 4 additions & 8 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ struct NixRepl
, gc
#endif
{
std::string curDir;

size_t debugTraceIndex;

Strings loadedFiles;
Expand Down Expand Up @@ -114,7 +112,6 @@ NixRepl::NixRepl(const Strings & searchPath, nix::ref<Store> store, ref<EvalStat
, staticEnv(new StaticEnv(false, state->staticBaseEnv.get()))
, historyFile(getDataDir() + "/nix/repl-history")
{
curDir = absPath(".");
}


Expand Down Expand Up @@ -594,14 +591,14 @@ bool NixRepl::processLine(std::string line)
Value v;
evalString(arg, v);

const auto [path, line] = [&] () -> std::pair<Path, uint32_t> {
const auto [path, line] = [&] () -> std::pair<SourcePath, uint32_t> {
if (v.type() == nPath || v.type() == nString) {
NixStringContext context;
auto path = state->coerceToPath(noPos, v, context, "while evaluating the filename to edit");
return {path, 0};
} else if (v.isLambda()) {
auto pos = state->positions[v.lambda.fun->pos];
if (auto path = std::get_if<Path>(&pos.origin))
if (auto path = std::get_if<SourcePath>(&pos.origin))
return {*path, pos.line};
else
throw Error("'%s' cannot be shown in an editor", pos);
Expand Down Expand Up @@ -876,8 +873,7 @@ void NixRepl::addVarToScope(const Symbol name, Value & v)

Expr * NixRepl::parseString(std::string s)
{
Expr * e = state->parseExprFromString(std::move(s), curDir, staticEnv);
return e;
return state->parseExprFromString(std::move(s), state->rootPath(CanonPath::fromCwd()), staticEnv);
}


Expand Down Expand Up @@ -925,7 +921,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
break;

case nPath:
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
str << ANSI_GREEN << v.path().to_string() << ANSI_NORMAL; // !!! escaping?
break;

case nNull:
Expand Down
26 changes: 15 additions & 11 deletions src/libexpr/attr-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::strin
}


std::pair<std::string, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what)
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what)
{
Value * v2;
try {
Expand All @@ -118,21 +118,25 @@ std::pair<std::string, uint32_t> findPackageFilename(EvalState & state, Value &

// FIXME: is it possible to extract the Pos object instead of doing this
// toString + parsing?
auto pos = state.forceString(*v2, noPos, "while evaluating the 'meta.position' attribute of a derivation");
NixStringContext context;
auto path = state.coerceToPath(noPos, *v2, context, "while evaluating the 'meta.position' attribute of a derivation");

auto colon = pos.rfind(':');
if (colon == std::string::npos)
throw ParseError("cannot parse meta.position attribute '%s'", pos);
auto fn = path.path.abs();

auto fail = [fn]() {
throw ParseError("cannot parse 'meta.position' attribute '%s'", fn);
};

std::string filename(pos, 0, colon);
unsigned int lineno;
try {
lineno = std::stoi(std::string(pos, colon + 1, std::string::npos));
auto colon = fn.rfind(':');
if (colon == std::string::npos) fail();
std::string filename(fn, 0, colon);
auto lineno = std::stoi(std::string(fn, colon + 1, std::string::npos));
return {CanonPath(fn.substr(0, colon)), lineno};
} catch (std::invalid_argument & e) {
throw ParseError("cannot parse line number '%s'", pos);
fail();
abort();
}

return { std::move(filename), lineno };
}


Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/attr-path.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ std::pair<Value *, PosIdx> findAlongAttrPath(
/**
* Heuristic to find the filename and lineno or a nix value.
*/
std::pair<std::string, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what);
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what);

std::vector<Symbol> parseAttrPath(EvalState & state, std::string_view s);

Expand Down
10 changes: 6 additions & 4 deletions src/libexpr/eval-cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,10 @@ Value & AttrCursor::forceValue()
if (v.type() == nString)
cachedValue = {root->db->setString(getKey(), v.string.s, v.string.context),
string_t{v.string.s, {}}};
else if (v.type() == nPath)
cachedValue = {root->db->setString(getKey(), v.path), string_t{v.path, {}}};
else if (v.type() == nPath) {
auto path = v.path().path;
cachedValue = {root->db->setString(getKey(), path.abs()), string_t{path.abs(), {}}};
}
else if (v.type() == nBool)
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
else if (v.type() == nInt)
Expand Down Expand Up @@ -580,7 +582,7 @@ std::string AttrCursor::getString()
if (v.type() != nString && v.type() != nPath)
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();

return v.type() == nString ? v.string.s : v.path;
return v.type() == nString ? v.string.s : v.path().to_string();
}

string_t AttrCursor::getStringWithContext()
Expand Down Expand Up @@ -624,7 +626,7 @@ string_t AttrCursor::getStringWithContext()
copyContext(v, context);
return {v.string.s, std::move(context)};
} else if (v.type() == nPath)
return {v.path, {}};
return {v.path().to_string(), {}};
else
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();
}
Expand Down