Stripping base path from CLI paths (without CLI refactor)#11617
Stripping base path from CLI paths (without CLI refactor)#11617
Conversation
|
In case anyone is wondering why this is so much more complex than my initial PR, here's a non-exhaustive list of path-related weirdness it has to account for:
|
libsolidity/interface/FileReader.h
Outdated
| return [this](std::string const& _kind, std::string const& _path) { return readFile(_kind, _path); }; | ||
| } | ||
|
|
||
| /// Normalizes a filesystem path in a way that removes small, inconsequential differences. Specifically: |
There was a problem hiding this comment.
Maybe just sommarize in the header and put the full description in the cpp file?
There was a problem hiding this comment.
Sure. I thought the docstring would be a better place for this. It is a bit detailed but on the other hand it still describes the effects visible to the user of the function rather than implementation details.
|
Did not review the actual code. |
46ac037 to
a9c06fb
Compare
libsolidity/interface/FileReader.cpp
Outdated
| ); | ||
|
|
||
| string rootName = normalizedPath.root_name().string(); | ||
| boost::filesystem::path normalizedRootPath = |
There was a problem hiding this comment.
Is it really correct to define normalizedRootPath here again?
There was a problem hiding this comment.
Good catch. It should not be redeclared. Weird that it did not break any tests though.
There was a problem hiding this comment.
Fixed. The normalization from \\host and //host for UNC paths was broken because of this. Tests did not break because boost ignores slashes is comparisons. Slashes do not matter as long as we use generic_string() on the path before using it but better have it normalized in case someone uses native() instead.
0d67e71 to
6eaf232
Compare
leonardoalt
left a comment
There was a problem hiding this comment.
Some minor comments, looks good in general
| /// Paths are treated as case-sensitive. Does not require the path to actually exist in the | ||
| /// filesystem and does not follow symlinks. Only considers whole segments, e.g. /abc/d is not | ||
| /// considered a prefix of /abc/def. Both paths must be non-empty. | ||
| static bool isPathPrefix(boost::filesystem::path _prefix, boost::filesystem::path const& _path); |
There was a problem hiding this comment.
Any particular reason _prefix is not const&?
There was a problem hiding this comment.
I'm modifying it in place inside the function. I could add a local variable but it was just more convenient to modify the parameter.
| /// If @a _prefix is actually a prefix of @p _path, removes it from @a _path to make it relative. | ||
| /// Otherwise returns @a _path unchanged. | ||
| /// Returns '.' if @a _path and @_prefix are identical. | ||
| static boost::filesystem::path stripPrefixIfPresent(boost::filesystem::path _prefix, boost::filesystem::path const& _path); |
| _prefix.remove_filename(); | ||
|
|
||
| boost::filesystem::path strippedPath = _path.lexically_relative(_prefix); | ||
| solAssert(strippedPath.empty() || *strippedPath.begin() != "..", ""); |
There was a problem hiding this comment.
So each element of strippedPath is a string?
There was a problem hiding this comment.
It's actually path but strings are implicitly convertible to that type.
Boost let you iterate over path segments while skipping separators. E.g. in /a/bc/def.sol you can iterate over a, bc and def.sol.
| rootName.size() == 2 || | ||
| (rootName.size() > 2 && rootName[2] != rootName[1]) | ||
| ) && ( | ||
| (rootName[0] == '/' && rootName[1] == '/') |
There was a problem hiding this comment.
You mean "why both characters should be /" or "why both // and \\"?
If it's the former - this is meant to detect UNC paths of the form //host/a/bc/def.sol.
If the latter: Windows accepts both //host and \\host as UNC path root name. Outside of windows only the one starting with // is treated specially.
| BOOST_TEST(FileReader::normalizeCLIPathForVFS("/a/b/c/../") == "/a/b/"); | ||
|
|
||
| BOOST_TEST(FileReader::normalizeCLIPathForVFS("/a/b/c/../../..") == "/"); | ||
| BOOST_TEST(FileReader::normalizeCLIPathForVFS("/a/b/c/../../../") == "/"); |
There was a problem hiding this comment.
How about some error cases? Like /a/b/c/../../../../
There was a problem hiding this comment.
The function has no error cases :) The function is supposed to be able to normalize every possible path.
/a/b/c/../../../../ will reduce to /. I do have a test for that. In fact lots of tests - see normalizeCLIPathForVFS_path_beyond_root below. I grouped them together not to have monster test cases spanning half of the file :)
|
|
||
| // NOTE: If path to work dir contains symlinks (of then the case on macOS), boost might resolve | ||
| // them, making the path different from tempDirPath. | ||
| boost::filesystem::path expectedWorkDir = boost::filesystem::current_path().parent_path().parent_path().parent_path(); |
There was a problem hiding this comment.
Because the working directory is set to tempDir.path() / "x/y/z" and the paths I'm testing below sometimes go up a few levels so they do not always preserve the x/y/z part. So I basically want tempDir.path() but normalized the way a working directory would be (e.g. on MacOS the temp dir I get usually has a symlink in it that I need to resolve; on Windows it has a drive letter).
But I just realized that now it's no longer working dir so the name is a bit misleading so maybe that's what you meant. Renamed to expectedPrefix.
44b33eb to
f6fde4e
Compare
f6fde4e to
b8e7786
Compare
|
Similar to #11544 (comment), I'm adding some refactors and small changes from work on #11688 as fixups (previous fixups squashed). Again, functionality did not change and almost all the changes were just in tests:
|
|
I'm closing this in favor of #11545. The only point of this PR was to be able to merge it without having to review all the dependencies first. Now that the dependencies are already merged, there's no point in keeping it around. I kept these PRs in sync at all times so if you already reviewed this, the only extra thing to review in #11545 is |
Fixes #4702.
Implements the
solcpart of #11408.solc-jschanges will be submitted in that repo.This is a version of #11545 that does not depend on the CLI refactor PRs (#11518, #11520, #11544) and does not include test cases for the CLI.
Things that were not implemented or were implemented differently than specified in the issue: