Replaced `fs::u8path` long-path support on windows by enabling it explicitly.

This commit is contained in:
Joël Lamotte (Klaim) 2022-05-31 12:53:34 +02:00
parent efc7773a50
commit a6a1251c10
9 changed files with 31 additions and 49 deletions

View File

@ -120,6 +120,7 @@ foreach(script ${SHELL_SCRIPTS})
endforeach()
set(LIBMAMBA_SOURCES
longpath.manifest
${LIBMAMBA_SOURCE_DIR}/version.cpp
# Core API (low-level)
${LIBMAMBA_SOURCE_DIR}/core/singletons.cpp

View File

@ -101,66 +101,56 @@ namespace fs
u8path(const std::filesystem::path& path)
: m_path(path)
{
check_long_path();
}
u8path& operator=(const std::filesystem::path& path)
{
m_path = path;
check_long_path();
return *this;
}
u8path& operator=(std::filesystem::path&& path)
{
m_path = std::move(path);
check_long_path();
return *this;
}
u8path(std::string_view u8string)
: m_path(from_utf8(u8string))
{
check_long_path();
}
u8path& operator=(std::string_view u8string)
{
m_path = from_utf8(u8string);
check_long_path();
return *this;
}
u8path(const char* u8string)
: m_path(from_utf8(u8string))
{
check_long_path();
}
u8path& operator=(const char* u8string)
{
m_path = from_utf8(u8string);
check_long_path();
return *this;
}
u8path(const std::string& u8string)
: m_path(from_utf8(u8string))
{
check_long_path();
}
u8path& operator=(const std::string& u8string)
{
m_path = from_utf8(u8string);
check_long_path();
return *this;
}
u8path& operator=(std::string&& u8string)
{
m_path = from_utf8(std::move(u8string));
check_long_path();
return *this;
}
@ -169,33 +159,28 @@ namespace fs
u8path(const wchar_t* wstr)
: m_path(wstr)
{
check_long_path();
}
u8path& operator=(const wchar_t* wstr)
{
m_path = wstr;
check_long_path();
return *this;
}
u8path(const std::wstring& wstr)
: m_path(wstr)
{
check_long_path();
}
u8path& operator=(const std::wstring& wstr)
{
m_path = wstr;
check_long_path();
return *this;
}
u8path& operator=(std::wstring&& wstr)
{
m_path = std::move(wstr);
check_long_path();
return *this;
}
@ -241,81 +226,70 @@ namespace fs
return m_path / wstr;
}
template<typename T>
template <typename T>
u8path& operator/=(T&& some_string)
{
*this = *this / std::forward<T>(some_string);
check_long_path();
return *this;
}
u8path& operator+=(const u8path& to_append)
{
m_path += to_append.m_path;
check_long_path();
return *this;
}
u8path& operator+=(const std::filesystem::path& to_append)
{
m_path += to_append;
check_long_path();
return *this;
}
u8path& operator+=(std::string_view to_append)
{
m_path = from_utf8(this->string() + std::string(to_append));
check_long_path();
return *this;
}
u8path& operator+=(std::wstring_view to_append)
{
m_path += to_append;
check_long_path();
return *this;
}
u8path& operator+=(const char* to_append)
{
m_path = from_utf8(this->string() + to_append);
check_long_path();
return *this;
}
u8path& operator+=(const wchar_t* to_append)
{
m_path += to_append;
check_long_path();
return *this;
}
u8path& operator+=(const std::string& to_append)
{
m_path = from_utf8(this->string() + to_append);
check_long_path();
return *this;
}
u8path& operator+=(const std::wstring& to_append)
{
m_path += to_append;
check_long_path();
return *this;
}
u8path& operator+=(char to_append)
{
m_path = from_utf8(this->string() + to_append);
check_long_path();
return *this;
}
u8path& operator+=(wchar_t to_append)
{
m_path += to_append;
check_long_path();
return *this;
}
@ -411,14 +385,12 @@ namespace fs
u8path& replace_filename(const u8path replacement)
{
m_path.replace_filename(replacement.m_path);
check_long_path();
return *this;
}
u8path& replace_extension(const u8path replacement = u8path())
{
m_path.replace_extension(replacement.m_path);
check_long_path();
return *this;
}
@ -541,7 +513,7 @@ namespace fs
{
return m_path.is_relative();
}
bool has_root_path() const
{
return m_path.has_root_path();
@ -602,7 +574,6 @@ namespace fs
std::string raw_input;
in >> std::quoted(raw_input);
path.m_path = from_utf8(raw_input);
path.check_long_path();
return in;
}
@ -618,20 +589,6 @@ namespace fs
private:
std::filesystem::path m_path;
void check_long_path()
{
#if defined(_WIN32)
// When we have long paths on windows, we need to mark the path so that if the system is set to allow long paths, we handle them properly.
// To achieve this we need to prefix long paths with a marker. This is one of windows weirderies.
if (is_absolute()
&& m_path.native().size() >= 248 // MAX_PATH - 12 (but MAX_PATH is not necessarilly available here - it's set to 260)
&& !m_path.native()._Starts_with(LR"(\\?\)")) // TODO: replace by std::basic_string::starts_with() in C++20
{
m_path = LR"(\\?\)" + m_path.native();
}
#endif
}
};
class directory_entry : public std::filesystem::directory_entry

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>

View File

@ -6,6 +6,7 @@ find_package(Threads REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS} SYSTEM)
set(TEST_SRCS
../longpath.manifest
test_activation.cpp
test_channel.cpp
test_configuration.cpp

View File

@ -78,14 +78,11 @@ namespace mamba
TEST(u8path, long_paths)
{
const auto tmp_dir = fs::temp_directory_path() / "mamba_fs_long_path";
EXPECT_FALSE(starts_with(tmp_dir.string(), u8R"(\\?\)"));
fs::u8path long_path = tmp_dir;
for (int i = 0; i < 42; ++i)
long_path /= u8"some_very_long_prefix";
#if defined(_WIN32)
EXPECT_TRUE(starts_with(long_path.string(), u8R"(\\?\)"));
#endif
fs::create_directories(long_path);
}

View File

@ -19,6 +19,7 @@ endif ()
pybind11_add_module(bindings
src/main.cpp
longpath.manifest
)
target_link_libraries(bindings PUBLIC pybind11::pybind11 libmamba)
set_property(TARGET bindings PROPERTY CXX_STANDARD 17)

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>

View File

@ -21,6 +21,7 @@ set(MICROMAMBA_LINKAGE "DYNAMIC" CACHE STRING "micromamba linkage against librar
# ============
set(MICROMAMBA_SRCS
longpath.manifest
${CMAKE_CURRENT_SOURCE_DIR}/src/activate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/clean.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/config.cpp

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>