10#include <system_error>
12#include <wx/filename.h>
19 return std::filesystem::path( aPath.ToStdWstring() );
21 return std::filesystem::path( aPath.utf8_string() );
28 return wxString( aPath.wstring() );
30 return wxString::FromUTF8( aPath.string() );
36 if( aOutput.IsEmpty() )
38 aError =
_(
"An output path is required. Use --output." );
42 wxFileName output( aOutput );
45 if( !output.MakeAbsolute() )
47 aError =
_(
"The output path is not accessible." );
51 std::error_code error;
52 auto status = std::filesystem::symlink_status(
DowngradeNativePath( output.GetFullPath() ), error );
54 if( ( error && error != std::errc::no_such_file_or_directory )
55 || status.type() != std::filesystem::file_type::not_found )
57 aError =
_(
"The output path already exists or is inaccessible. Choose a new destination." );
66 wxFileName file( aPath );
68 || file.GetFullName().Contains( wxT(
".downgrade_tmp." ) )
69 || file.GetFullName().Contains( wxT(
".downgrade_backup." ) );
74 std::error_code error;
77 if( error || !std::filesystem::is_directory(
source, error ) || error )
79 aError =
_(
"The library folder is not accessible." );
83 std::filesystem::recursive_directory_iterator iterator(
source, error );
84 const std::filesystem::recursive_directory_iterator
end;
86 while( !error && iterator !=
end )
88 const auto& entry = *iterator;
93 iterator.disable_recursion_pending();
95 else if( entry.is_symlink( error ) && entry.is_directory( error ) )
97 aError =
_(
"Library folders containing directory links cannot be copied safely." );
100 else if( !error && !entry.is_directory( error ) && !entry.is_regular_file( error ) )
102 aError =
_(
"The library folder contains an inaccessible or unsupported file." );
107 iterator.increment( error );
112 aError =
_(
"The library folder could not be read completely." );
126 std::error_code error;
128 auto destination = std::filesystem::weakly_canonical(
DowngradeNativePath( aDestination ), error );
132 aError =
_(
"The output path is not accessible." );
136 auto relative = destination.lexically_relative(
source );
138 if( destination ==
source || ( !relative.empty() && *relative.begin() !=
".." ) )
140 aError =
_(
"The library output must be outside the source library folder." );
161 std::error_code error;
164 std::filesystem::remove_all( it->first, error );
166 std::filesystem::remove( it->first, error );
170 bool Create(
const wxString& aDirectory,
bool aOwnContents =
false )
172 std::error_code error;
178 std::vector<std::filesystem::path> missing;
182 if( error ||
path.empty() ||
path ==
path.parent_path() )
185 missing.push_back(
path );
188 if( error || ( aOwnContents && missing.empty() ) )
191 for(
auto it = missing.rbegin(); it != missing.rend(); ++it )
193 if( !std::filesystem::create_directory( *it, error ) || error )
199 return std::filesystem::is_directory(
directory, error ) && !error;
205 std::vector<std::pair<std::filesystem::path, bool>>
m_created;
211 std::error_code error;
215 return wxEmptyString;
226 if( !aDirectories.
Create( aDestination,
true ) )
228 aError =
_(
"Could not create the library output folder." );
232 std::error_code error;
234 std::filesystem::recursive_directory_iterator iterator(
source, error );
235 const std::filesystem::recursive_directory_iterator
end;
237 while( !error && iterator !=
end )
239 const auto& entry = *iterator;
243 iterator.disable_recursion_pending();
249 if( entry.is_directory( error ) )
250 std::filesystem::create_directory( destination, error );
252 std::filesystem::copy_file( entry.path(), destination, error );
256 iterator.increment( error );
261 aError =
_(
"Could not copy the library folder." );
std::vector< std::pair< std::filesystem::path, bool > > m_created
DOWNGRADE_OUTPUT_DIRECTORIES(const DOWNGRADE_OUTPUT_DIRECTORIES &)=delete
DOWNGRADE_OUTPUT_DIRECTORIES()=default
~DOWNGRADE_OUTPUT_DIRECTORIES()
DOWNGRADE_OUTPUT_DIRECTORIES & operator=(const DOWNGRADE_OUTPUT_DIRECTORIES &)=delete
bool Create(const wxString &aDirectory, bool aOwnContents=false)
wxString DowngradeWxPath(const std::filesystem::path &aPath)
wxString DowngradeLibraryCopyPath(const wxString &aLibrary, const wxString &aOutputDirectory)
bool IsDowngradeLibraryWorkingArtifact(const wxString &aPath)
bool ValidateDowngradeLibrarySource(const wxString &aSource, wxString &aError)
bool ValidateDowngradeLibraryCopy(const wxString &aSource, const wxString &aDestination, wxString &aError)
bool ValidateFreshDowngradeOutput(const wxString &aOutput, wxString &aError)
bool CopyDowngradeLibraryDirectory(const wxString &aSource, const wxString &aDestination, DOWNGRADE_OUTPUT_DIRECTORIES &aDirectories, wxString &aError)
std::filesystem::path DowngradeNativePath(const wxString &aPath)
bool IsDowngradeWorkingArtifact(const wxString &aPath)
Editor working state (autosaves, local history, backups) holds current-format copies nothing downgrad...