mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
normalizeCLIPathForVFS(): Add an option for resolving symlinks
This commit is contained in:
@@ -111,7 +111,10 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
}
|
||||
}
|
||||
|
||||
boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::path const& _path)
|
||||
boost::filesystem::path FileReader::normalizeCLIPathForVFS(
|
||||
boost::filesystem::path const& _path,
|
||||
SymlinkResolution _symlinkResolution
|
||||
)
|
||||
{
|
||||
// Detailed normalization rules:
|
||||
// - Makes the path either be absolute or have slash as root (note that on Windows paths with
|
||||
@@ -125,7 +128,8 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::pa
|
||||
// path to the current working directory.
|
||||
//
|
||||
// Also note that this function:
|
||||
// - Does NOT resolve symlinks (except for symlinks in the path to the current working directory).
|
||||
// - Does NOT resolve symlinks (except for symlinks in the path to the current working directory)
|
||||
// unless explicitly requested.
|
||||
// - Does NOT check if the path refers to a file or a directory. If the path ends with a slash,
|
||||
// the slash is preserved even if it's a file.
|
||||
// - The only exception are paths where the file name is a dot (e.g. '.' or 'a/b/.'). These
|
||||
@@ -139,9 +143,27 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS(boost::filesystem::pa
|
||||
// Windows it does not. To get consistent results we resolve them on all platforms.
|
||||
boost::filesystem::path absolutePath = boost::filesystem::absolute(_path, canonicalWorkDir);
|
||||
|
||||
// NOTE: boost path preserves certain differences that are ignored by its operator ==.
|
||||
// E.g. "a//b" vs "a/b" or "a/b/" vs "a/b/.". lexically_normal() does remove these differences.
|
||||
boost::filesystem::path normalizedPath = absolutePath.lexically_normal();
|
||||
boost::filesystem::path normalizedPath;
|
||||
if (_symlinkResolution == SymlinkResolution::Enabled)
|
||||
{
|
||||
// NOTE: weakly_canonical() will not convert a relative path into an absolute one if no
|
||||
// directory included in the path actually exists.
|
||||
normalizedPath = boost::filesystem::weakly_canonical(absolutePath);
|
||||
|
||||
// The three corner cases in which lexically_normal() includes a trailing slash in the
|
||||
// normalized path but weakly_canonical() does not. Note that the trailing slash is not
|
||||
// ignored when comparing paths with ==.
|
||||
if ((_path == "." || _path == "./" || _path == "../") && !boost::ends_with(normalizedPath.generic_string(), "/"))
|
||||
normalizedPath = normalizedPath.parent_path() / (normalizedPath.filename().string() + "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(_symlinkResolution == SymlinkResolution::Disabled, "");
|
||||
|
||||
// NOTE: boost path preserves certain differences that are ignored by its operator ==.
|
||||
// E.g. "a//b" vs "a/b" or "a/b/" vs "a/b/.". lexically_normal() does remove these differences.
|
||||
normalizedPath = absolutePath.lexically_normal();
|
||||
}
|
||||
solAssert(normalizedPath.is_absolute() || normalizedPath.root_path() == "/", "");
|
||||
|
||||
// If the path is on the same drive as the working dir, for portability we prefer not to
|
||||
|
||||
@@ -39,6 +39,11 @@ public:
|
||||
using PathMap = std::map<SourceUnitName, boost::filesystem::path>;
|
||||
using FileSystemPathSet = std::set<boost::filesystem::path>;
|
||||
|
||||
enum SymlinkResolution {
|
||||
Disabled, ///< Do not resolve symbolic links in the path.
|
||||
Enabled, ///< Follow symbolic links. The path should contain no symlinks.
|
||||
};
|
||||
|
||||
/// Constructs a FileReader with a base path and a set of allowed directories that
|
||||
/// will be used when requesting files from this file reader instance.
|
||||
explicit FileReader(
|
||||
@@ -90,11 +95,16 @@ public:
|
||||
|
||||
/// Normalizes a filesystem path to make it include all components up to the filesystem root,
|
||||
/// remove small, inconsequential differences that do not affect the meaning and make it look
|
||||
/// the same on all platforms (if possible). Symlinks in the path are not resolved.
|
||||
/// the same on all platforms (if possible).
|
||||
/// The resulting path uses forward slashes as path separators, has no redundant separators,
|
||||
/// has no redundant . or .. segments and has no root name if removing it does not change the meaning.
|
||||
/// The path does not have to actually exist.
|
||||
static boost::filesystem::path normalizeCLIPathForVFS(boost::filesystem::path const& _path);
|
||||
/// @param _path Path to normalize.
|
||||
/// @param _symlinkResolution If @a Disabled, any symlinks present in @a _path are preserved.
|
||||
static boost::filesystem::path normalizeCLIPathForVFS(
|
||||
boost::filesystem::path const& _path,
|
||||
SymlinkResolution _symlinkResolution = SymlinkResolution::Disabled
|
||||
);
|
||||
|
||||
/// @returns true if all the path components of @a _prefix are present at the beginning of @a _path.
|
||||
/// Both paths must be absolute (or have slash as root) and normalized (no . or .. segments, no
|
||||
|
||||
Reference in New Issue
Block a user