mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
Make 'nix edit' etc. work again
This commit is contained in:
parent
1790698a74
commit
bb4d35dcca
15 changed files with 108 additions and 82 deletions
|
@ -207,8 +207,11 @@ void StorePathCommand::run(ref<Store> store, std::vector<StorePath> && storePath
|
||||||
run(store, *storePaths.begin());
|
run(store, *storePaths.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
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 editor = getEnv("EDITOR").value_or("cat");
|
||||||
auto args = tokenizeString<Strings>(editor);
|
auto args = tokenizeString<Strings>(editor);
|
||||||
if (line > 0 && (
|
if (line > 0 && (
|
||||||
|
@ -217,7 +220,7 @@ Strings editorFor(const Path & file, uint32_t line)
|
||||||
editor.find("vim") != std::string::npos ||
|
editor.find("vim") != std::string::npos ||
|
||||||
editor.find("kak") != std::string::npos))
|
editor.find("kak") != std::string::npos))
|
||||||
args.push_back(fmt("+%d", line));
|
args.push_back(fmt("+%d", line));
|
||||||
args.push_back(file);
|
args.push_back(path->abs());
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
||||||
|
|
||||||
/* Helper function to generate args that invoke $EDITOR on
|
/* Helper function to generate args that invoke $EDITOR on
|
||||||
filename:lineno. */
|
filename:lineno. */
|
||||||
Strings editorFor(const Path & file, uint32_t line);
|
Strings editorFor(const SourcePath & file, uint32_t line);
|
||||||
|
|
||||||
struct MixProfile : virtual StoreCommand
|
struct MixProfile : virtual StoreCommand
|
||||||
{
|
{
|
||||||
|
|
|
@ -573,17 +573,17 @@ bool NixRepl::processLine(std::string line)
|
||||||
Value v;
|
Value v;
|
||||||
evalString(arg, v);
|
evalString(arg, v);
|
||||||
|
|
||||||
const auto [file, line] = [&] () -> std::pair<std::string, uint32_t> {
|
const auto [path, line] = [&] () -> std::pair<SourcePath, uint32_t> {
|
||||||
if (v.type() == nPath || v.type() == nString) {
|
if (v.type() == nPath || v.type() == nString) {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
auto filename = state->coerceToString(noPos, v, context).toOwned();
|
auto path = state->coerceToPath(noPos, v, context);
|
||||||
state->symbols.create(filename);
|
return {path, 0};
|
||||||
return {filename, 0};
|
|
||||||
} else if (v.isLambda()) {
|
} else if (v.isLambda()) {
|
||||||
auto pos = state->positions[v.lambda.fun->pos];
|
auto pos = state->positions[v.lambda.fun->pos];
|
||||||
// FIXME
|
if (auto path = std::get_if<SourcePath>(&pos.origin))
|
||||||
abort();
|
return {*path, pos.line};
|
||||||
//return {pos.file, pos.line};
|
else
|
||||||
|
throw Error("'%s' cannot be shown in an editor", pos);
|
||||||
} else {
|
} else {
|
||||||
// assume it's a derivation
|
// assume it's a derivation
|
||||||
return findPackageFilename(*state, v, arg);
|
return findPackageFilename(*state, v, arg);
|
||||||
|
@ -591,7 +591,7 @@ bool NixRepl::processLine(std::string line)
|
||||||
}();
|
}();
|
||||||
|
|
||||||
// Open in EDITOR
|
// Open in EDITOR
|
||||||
auto args = editorFor(file, line);
|
auto args = editorFor(path, line);
|
||||||
auto editor = args.front();
|
auto editor = args.front();
|
||||||
args.pop_front();
|
args.pop_front();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
Value * v2;
|
||||||
try {
|
try {
|
||||||
|
@ -120,19 +120,41 @@ std::pair<std::string, uint32_t> findPackageFilename(EvalState & state, Value &
|
||||||
// toString + parsing?
|
// toString + parsing?
|
||||||
auto pos = state.forceString(*v2);
|
auto pos = state.forceString(*v2);
|
||||||
|
|
||||||
auto colon = pos.rfind(':');
|
auto fail = [pos]() {
|
||||||
if (colon == std::string::npos)
|
throw ParseError("cannot parse 'meta.position' attribute '%s'", pos);
|
||||||
throw ParseError("cannot parse meta.position attribute '%s'", pos);
|
};
|
||||||
|
|
||||||
std::string filename(pos, 0, colon);
|
|
||||||
unsigned int lineno;
|
|
||||||
try {
|
try {
|
||||||
lineno = std::stoi(std::string(pos, colon + 1, std::string::npos));
|
std::string_view prefix = "/virtual/";
|
||||||
|
|
||||||
|
if (!hasPrefix(pos, prefix)) fail();
|
||||||
|
pos = pos.substr(prefix.size());
|
||||||
|
|
||||||
|
auto slash = pos.find('/');
|
||||||
|
if (slash == std::string::npos) fail();
|
||||||
|
size_t number = std::stoi(std::string(pos, 0, slash));
|
||||||
|
pos = pos.substr(slash);
|
||||||
|
|
||||||
|
std::shared_ptr<InputAccessor> accessor;
|
||||||
|
for (auto & i : state.inputAccessors)
|
||||||
|
if (i.second->number == number) {
|
||||||
|
accessor = i.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accessor) fail();
|
||||||
|
|
||||||
|
auto colon = pos.rfind(':');
|
||||||
|
if (colon == std::string::npos) fail();
|
||||||
|
std::string filename(pos, 0, colon);
|
||||||
|
auto lineno = std::stoi(std::string(pos, colon + 1, std::string::npos));
|
||||||
|
|
||||||
|
return {SourcePath{ref(accessor), CanonPath(filename)}, lineno};
|
||||||
|
|
||||||
} catch (std::invalid_argument & e) {
|
} catch (std::invalid_argument & e) {
|
||||||
throw ParseError("cannot parse line number '%s'", pos);
|
fail();
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { std::move(filename), lineno };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ std::pair<Value *, PosIdx> findAlongAttrPath(
|
||||||
Value & vIn);
|
Value & vIn);
|
||||||
|
|
||||||
/* Heuristic to find the filename and lineno or a nix value. */
|
/* 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);
|
std::vector<Symbol> parseAttrPath(EvalState & state, std::string_view s);
|
||||||
|
|
||||||
|
|
|
@ -1097,7 +1097,7 @@ void EvalState::mkPos(Value & v, PosIdx p)
|
||||||
auto pos = positions[p];
|
auto pos = positions[p];
|
||||||
if (auto path = std::get_if<SourcePath>(&pos.origin)) {
|
if (auto path = std::get_if<SourcePath>(&pos.origin)) {
|
||||||
auto attrs = buildBindings(3);
|
auto attrs = buildBindings(3);
|
||||||
attrs.alloc(sFile).mkString(path->path.abs());
|
attrs.alloc(sFile).mkString(fmt("/virtual/%d%s", path->accessor->number, path->path.abs()));
|
||||||
attrs.alloc(sLine).mkInt(pos.line);
|
attrs.alloc(sLine).mkInt(pos.line);
|
||||||
attrs.alloc(sColumn).mkInt(pos.column);
|
attrs.alloc(sColumn).mkInt(pos.column);
|
||||||
v.mkAttrs(attrs);
|
v.mkAttrs(attrs);
|
||||||
|
|
|
@ -431,10 +431,10 @@ LockedFlake lockFlake(
|
||||||
flakerefs relative to the parent flake. */
|
flakerefs relative to the parent flake. */
|
||||||
auto getInputFlake = [&]()
|
auto getInputFlake = [&]()
|
||||||
{
|
{
|
||||||
if (input.ref->input.isRelative()) {
|
if (auto relativePath = input.ref->input.isRelative()) {
|
||||||
SourcePath inputSourcePath {
|
SourcePath inputSourcePath {
|
||||||
overridenSourcePath.accessor,
|
overridenSourcePath.accessor,
|
||||||
CanonPath(*input.ref->input.getSourcePath(), *overridenSourcePath.path.parent())
|
*overridenSourcePath.path.parent() + *relativePath
|
||||||
};
|
};
|
||||||
return readFlake(state, *input.ref, *input.ref, *input.ref, inputSourcePath, inputPath);
|
return readFlake(state, *input.ref, *input.ref, *input.ref, inputSourcePath, inputPath);
|
||||||
} else
|
} else
|
||||||
|
@ -621,7 +621,7 @@ LockedFlake lockFlake(
|
||||||
auto diff = LockFile::diff(oldLockFile, newLockFile);
|
auto diff = LockFile::diff(oldLockFile, newLockFile);
|
||||||
|
|
||||||
if (lockFlags.writeLockFile) {
|
if (lockFlags.writeLockFile) {
|
||||||
if (auto sourcePath = topRef.input.getSourcePath()) {
|
if (auto sourcePath = topRef.input.getAccessor(state.store).first->root().getPhysicalPath()) {
|
||||||
if (auto unlockedInput = newLockFile.isUnlocked()) {
|
if (auto unlockedInput = newLockFile.isUnlocked()) {
|
||||||
if (fetchSettings.warnDirty)
|
if (fetchSettings.warnDirty)
|
||||||
warn("will not write lock file of flake '%s' because it has an unlocked input ('%s')", topRef, *unlockedInput);
|
warn("will not write lock file of flake '%s' because it has an unlocked input ('%s')", topRef, *unlockedInput);
|
||||||
|
@ -629,11 +629,13 @@ LockedFlake lockFlake(
|
||||||
if (!lockFlags.updateLockFile)
|
if (!lockFlags.updateLockFile)
|
||||||
throw Error("flake '%s' requires lock file changes but they're not allowed due to '--no-update-lock-file'", topRef);
|
throw Error("flake '%s' requires lock file changes but they're not allowed due to '--no-update-lock-file'", topRef);
|
||||||
|
|
||||||
auto relPath = (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock";
|
CanonPath flakeDir(*sourcePath);
|
||||||
|
|
||||||
auto path = *sourcePath + "/" + relPath;
|
auto relPath = flakeDir + "flake.lock";
|
||||||
|
|
||||||
bool lockFileExists = pathExists(path);
|
auto path = flakeDir + "flake.lock";
|
||||||
|
|
||||||
|
bool lockFileExists = pathExists(path.abs());
|
||||||
|
|
||||||
if (lockFileExists) {
|
if (lockFileExists) {
|
||||||
auto s = chomp(diff);
|
auto s = chomp(diff);
|
||||||
|
@ -644,7 +646,7 @@ LockedFlake lockFlake(
|
||||||
} else
|
} else
|
||||||
warn("creating lock file '%s'", path);
|
warn("creating lock file '%s'", path);
|
||||||
|
|
||||||
newLockFile.write(path);
|
newLockFile.write(path.abs());
|
||||||
|
|
||||||
std::optional<std::string> commitMessage = std::nullopt;
|
std::optional<std::string> commitMessage = std::nullopt;
|
||||||
if (lockFlags.commitLockFile) {
|
if (lockFlags.commitLockFile) {
|
||||||
|
|
|
@ -87,8 +87,9 @@ Attrs Input::toAttrs() const
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Input::isRelative() const
|
std::optional<CanonPath> Input::isRelative() const
|
||||||
{
|
{
|
||||||
|
assert(scheme);
|
||||||
return scheme->isRelative(*this);
|
return scheme->isRelative(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,12 +187,6 @@ void Input::clone(const Path & destDir) const
|
||||||
scheme->clone(*this, destDir);
|
scheme->clone(*this, destDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Path> Input::getSourcePath() const
|
|
||||||
{
|
|
||||||
assert(scheme);
|
|
||||||
return scheme->getSourcePath(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Input::markChangedFile(
|
void Input::markChangedFile(
|
||||||
std::string_view file,
|
std::string_view file,
|
||||||
std::optional<std::string> commitMsg) const
|
std::optional<std::string> commitMsg) const
|
||||||
|
@ -283,11 +278,6 @@ Input InputScheme::applyOverrides(
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Path> InputScheme::getSourcePath(const Input & input)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputScheme::markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg)
|
void InputScheme::markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg)
|
||||||
{
|
{
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
|
@ -54,7 +54,9 @@ public:
|
||||||
one that contains a commit hash or content hash. */
|
one that contains a commit hash or content hash. */
|
||||||
bool isLocked() const { return locked; }
|
bool isLocked() const { return locked; }
|
||||||
|
|
||||||
bool isRelative() const;
|
/* Only for relative path flakes, i.e. 'path:./foo', returns the
|
||||||
|
relative path, i.e. './foo'. */
|
||||||
|
std::optional<CanonPath> isRelative() const;
|
||||||
|
|
||||||
bool hasAllInfo() const;
|
bool hasAllInfo() const;
|
||||||
|
|
||||||
|
@ -77,8 +79,6 @@ public:
|
||||||
|
|
||||||
void clone(const Path & destDir) const;
|
void clone(const Path & destDir) const;
|
||||||
|
|
||||||
std::optional<Path> getSourcePath() const;
|
|
||||||
|
|
||||||
void markChangedFile(
|
void markChangedFile(
|
||||||
std::string_view file,
|
std::string_view file,
|
||||||
std::optional<std::string> commitMsg) const;
|
std::optional<std::string> commitMsg) const;
|
||||||
|
@ -130,8 +130,6 @@ struct InputScheme
|
||||||
|
|
||||||
virtual void clone(const Input & input, const Path & destDir);
|
virtual void clone(const Input & input, const Path & destDir);
|
||||||
|
|
||||||
virtual std::optional<Path> getSourcePath(const Input & input);
|
|
||||||
|
|
||||||
virtual void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg);
|
virtual void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg);
|
||||||
|
|
||||||
/* Note: the default implementations of fetchToStore() and
|
/* Note: the default implementations of fetchToStore() and
|
||||||
|
@ -142,8 +140,8 @@ struct InputScheme
|
||||||
|
|
||||||
virtual std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input);
|
virtual std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input);
|
||||||
|
|
||||||
virtual bool isRelative(const Input & input) const
|
virtual std::optional<CanonPath> isRelative(const Input & input) const
|
||||||
{ return false; }
|
{ return std::nullopt; }
|
||||||
|
|
||||||
virtual std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const
|
virtual std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const
|
||||||
{ return std::nullopt; }
|
{ return std::nullopt; }
|
||||||
|
|
|
@ -245,26 +245,17 @@ struct GitInputScheme : InputScheme
|
||||||
runProgram("git", true, args);
|
runProgram("git", true, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Path> getSourcePath(const Input & input) override
|
|
||||||
{
|
|
||||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
|
||||||
if (url.scheme == "file" && !input.getRef() && !input.getRev())
|
|
||||||
return url.path;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
||||||
{
|
{
|
||||||
auto sourcePath = getSourcePath(input);
|
auto repoInfo = getRepoInfo(input);
|
||||||
assert(sourcePath);
|
assert(repoInfo.isLocal);
|
||||||
auto gitDir = ".git";
|
|
||||||
|
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", *sourcePath, "--git-dir", gitDir, "add", "--force", "--intent-to-add", "--", std::string(file) });
|
{ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "add", "--force", "--intent-to-add", "--", std::string(file) });
|
||||||
|
|
||||||
if (commitMsg)
|
if (commitMsg)
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", *sourcePath, "--git-dir", gitDir, "commit", std::string(file), "-m", *commitMsg });
|
{ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "commit", std::string(file), "-m", *commitMsg });
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RepoInfo
|
struct RepoInfo
|
||||||
|
|
|
@ -104,6 +104,11 @@ std::string InputAccessor::showPath(const CanonPath & path)
|
||||||
return displayPrefix + path.abs() + displaySuffix;
|
return displayPrefix + path.abs() + displaySuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourcePath InputAccessor::root()
|
||||||
|
{
|
||||||
|
return {ref(shared_from_this()), CanonPath::root};
|
||||||
|
}
|
||||||
|
|
||||||
struct FSInputAccessorImpl : FSInputAccessor
|
struct FSInputAccessorImpl : FSInputAccessor
|
||||||
{
|
{
|
||||||
CanonPath root;
|
CanonPath root;
|
||||||
|
@ -211,6 +216,15 @@ struct FSInputAccessorImpl : FSInputAccessor
|
||||||
{
|
{
|
||||||
return (bool) allowedPaths;
|
return (bool) allowedPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<CanonPath> getPhysicalPath(const CanonPath & path) override
|
||||||
|
{
|
||||||
|
auto absPath = makeAbsPath(path);
|
||||||
|
if (isAllowed(absPath))
|
||||||
|
return absPath;
|
||||||
|
else
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ref<FSInputAccessor> makeFSInputAccessor(
|
ref<FSInputAccessor> makeFSInputAccessor(
|
||||||
|
|
|
@ -9,6 +9,8 @@ namespace nix {
|
||||||
|
|
||||||
MakeError(RestrictedPathError, Error);
|
MakeError(RestrictedPathError, Error);
|
||||||
|
|
||||||
|
struct SourcePath;
|
||||||
|
|
||||||
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
{
|
{
|
||||||
const size_t number;
|
const size_t number;
|
||||||
|
@ -50,6 +52,12 @@ struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
Sink & sink,
|
Sink & sink,
|
||||||
PathFilter & filter = defaultPathFilter);
|
PathFilter & filter = defaultPathFilter);
|
||||||
|
|
||||||
|
/* Return a corresponding path in the root filesystem, if
|
||||||
|
possible. This is only possible for inputs that are
|
||||||
|
materialized in the root filesystem. */
|
||||||
|
virtual std::optional<CanonPath> getPhysicalPath(const CanonPath & path)
|
||||||
|
{ return std::nullopt; }
|
||||||
|
|
||||||
bool operator == (const InputAccessor & x) const
|
bool operator == (const InputAccessor & x) const
|
||||||
{
|
{
|
||||||
return number == x.number;
|
return number == x.number;
|
||||||
|
@ -63,6 +71,8 @@ struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
void setPathDisplay(std::string displayPrefix, std::string displaySuffix = "");
|
void setPathDisplay(std::string displayPrefix, std::string displaySuffix = "");
|
||||||
|
|
||||||
virtual std::string showPath(const CanonPath & path);
|
virtual std::string showPath(const CanonPath & path);
|
||||||
|
|
||||||
|
SourcePath root();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FSInputAccessor : InputAccessor
|
struct FSInputAccessor : InputAccessor
|
||||||
|
@ -128,6 +138,9 @@ struct SourcePath
|
||||||
PathFilter & filter = defaultPathFilter) const
|
PathFilter & filter = defaultPathFilter) const
|
||||||
{ return accessor->dumpPath(path, sink, filter); }
|
{ return accessor->dumpPath(path, sink, filter); }
|
||||||
|
|
||||||
|
std::optional<CanonPath> getPhysicalPath() const
|
||||||
|
{ return accessor->getPhysicalPath(path); }
|
||||||
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{ return accessor->showPath(path); }
|
{ return accessor->showPath(path); }
|
||||||
|
|
||||||
|
|
|
@ -116,26 +116,18 @@ struct MercurialInputScheme : InputScheme
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Path> getSourcePath(const Input & input) override
|
|
||||||
{
|
|
||||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
|
||||||
if (url.scheme == "file" && !input.getRef() && !input.getRev())
|
|
||||||
return url.path;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
||||||
{
|
{
|
||||||
auto sourcePath = getSourcePath(input);
|
auto [isLocal, path] = getActualUrl(input);
|
||||||
assert(sourcePath);
|
assert(isLocal);
|
||||||
|
|
||||||
// FIXME: shut up if file is already tracked.
|
// FIXME: shut up if file is already tracked.
|
||||||
runHg(
|
runHg(
|
||||||
{ "add", *sourcePath + "/" + std::string(file) });
|
{ "add", path + "/" + file });
|
||||||
|
|
||||||
if (commitMsg)
|
if (commitMsg)
|
||||||
runHg(
|
runHg(
|
||||||
{ "commit", *sourcePath + "/" + std::string(file), "-m", *commitMsg });
|
{ "commit", path + "/" + file, "-m", *commitMsg });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, std::string> getActualUrl(const Input & input) const
|
std::pair<bool, std::string> getActualUrl(const Input & input) const
|
||||||
|
|
|
@ -66,9 +66,13 @@ struct PathInputScheme : InputScheme
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRelative(const Input & input) const override
|
std::optional<CanonPath> isRelative(const Input & input) const override
|
||||||
{
|
{
|
||||||
return !hasPrefix(*input.getSourcePath(), "/");
|
auto path = getStrAttr(input.attrs, "path");
|
||||||
|
if (hasPrefix(path, "/"))
|
||||||
|
return std::nullopt;
|
||||||
|
else
|
||||||
|
return CanonPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) override
|
||||||
|
@ -76,11 +80,6 @@ struct PathInputScheme : InputScheme
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Path> getSourcePath(const Input & input) override
|
|
||||||
{
|
|
||||||
return getStrAttr(input.attrs, "path");
|
|
||||||
}
|
|
||||||
|
|
||||||
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg) override
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
|
|
@ -558,7 +558,9 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
// chdir if installable is a flake of type git+file or path
|
// chdir if installable is a flake of type git+file or path
|
||||||
auto installableFlake = std::dynamic_pointer_cast<InstallableFlake>(installable);
|
auto installableFlake = std::dynamic_pointer_cast<InstallableFlake>(installable);
|
||||||
if (installableFlake) {
|
if (installableFlake) {
|
||||||
auto sourcePath = installableFlake->getLockedFlake()->flake.resolvedRef.input.getSourcePath();
|
auto sourcePath = installableFlake->getLockedFlake()
|
||||||
|
->flake.resolvedRef.input.getAccessor(store).first
|
||||||
|
->root().getPhysicalPath();
|
||||||
if (sourcePath) {
|
if (sourcePath) {
|
||||||
if (chdir(sourcePath->c_str()) == -1) {
|
if (chdir(sourcePath->c_str()) == -1) {
|
||||||
throw SysError("chdir to '%s' failed", *sourcePath);
|
throw SysError("chdir to '%s' failed", *sourcePath);
|
||||||
|
|
Loading…
Reference in a new issue