mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Switch from boost::filesystem to std::filesystem
This commit mostly just swaps namespaces. Boost and std handle character encoding changes differently, so additional changes and tests will be required. Other than namespace swapping, changes were made to resolve the following issues causing compilation or test failures: - std parent_path() doesn't throw if the path is empty, so some thrown exceptions have changed type - std path doesn't throw if it's an invalid path, so some thrown exceptions have changed type - there is no std unique_path(), so I'm using Boost.UUID to generate something unique instead. A std-only solution is possible but messier - last_write_time() doesn't work with time_t, but std::chrono clocks instead - Removing the owner_write permission is now insufficient, but setting permissions to be only owner_read works - Junction links in Windows no longer appear as directories, and calling is_directory() on a symlink throws an exception. - Creating symlink directories expects an absolute link path or the link will be created but will be unresolvable.
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ install:
|
||||
- export CXX="g++-8" CC="gcc-8"
|
||||
# Build Boost.
|
||||
- wget https://raw.githubusercontent.com/WrinklyNinja/ci-scripts/1.5.0/install_boost.py
|
||||
- python install_boost.py --directory ~ --boost-version 1.67.0 -a 64 -t gcc-8 filesystem locale system thread
|
||||
- python install_boost.py --directory ~ --boost-version 1.67.0 -a 64 -t gcc-8 locale system
|
||||
# Install packages for generating documentation
|
||||
- pip install --user -r docs/requirements.txt
|
||||
# Add sphinx-build to PATH
|
||||
|
||||
+3
-2
@@ -63,7 +63,7 @@ ELSE ()
|
||||
set(RUST_TARGET x86_64-unknown-linux-gnu)
|
||||
ENDIF ()
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS filesystem locale system)
|
||||
find_package(Boost REQUIRED COMPONENTS locale system)
|
||||
|
||||
ExternalProject_Add(GTest
|
||||
PREFIX "external"
|
||||
@@ -335,7 +335,8 @@ IF (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
icuuc
|
||||
icui18n
|
||||
ssh2
|
||||
http_parser)
|
||||
http_parser
|
||||
stdc++fs)
|
||||
|
||||
IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set (LOOT_LIBS ${LOOT_LIBS} supc++)
|
||||
|
||||
+6
-8
@@ -24,22 +24,21 @@
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
#include <boost/locale.hpp>
|
||||
|
||||
#include "api/game/game.h"
|
||||
#include "api/helpers/logging.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace loot {
|
||||
std::string ResolvePath(const std::string& path) {
|
||||
// NTFS junction links show up as symlinks and directories, but resolving
|
||||
// them just appends their target path.
|
||||
if (path.empty() || !fs::is_symlink(path) || fs::is_directory(path))
|
||||
return path;
|
||||
if (fs::is_symlink(path))
|
||||
return fs::read_symlink(path).string();
|
||||
|
||||
return fs::read_symlink(path).string();
|
||||
return path;
|
||||
}
|
||||
|
||||
LOOT_API void SetLoggingCallback(
|
||||
@@ -63,7 +62,6 @@ LOOT_API bool IsCompatible(const unsigned int versionMajor,
|
||||
|
||||
LOOT_API void InitialiseLocale(const std::string& id) {
|
||||
std::locale::global(boost::locale::generator().generate(id));
|
||||
boost::filesystem::path::imbue(std::locale());
|
||||
}
|
||||
|
||||
LOOT_API std::shared_ptr<GameInterface> CreateGameHandle(
|
||||
|
||||
+11
-11
@@ -36,7 +36,7 @@
|
||||
|
||||
namespace loot {
|
||||
ApiDatabase::ApiDatabase(const GameType gameType,
|
||||
const boost::filesystem::path& dataPath,
|
||||
const std::filesystem::path& dataPath,
|
||||
std::shared_ptr<GameCache> gameCache,
|
||||
std::shared_ptr<LoadOrderHandler> loadOrderHandler) :
|
||||
gameCache_(gameCache),
|
||||
@@ -52,7 +52,7 @@ void ApiDatabase::LoadLists(const std::string& masterlistPath,
|
||||
MetadataList userTemp;
|
||||
|
||||
if (!masterlistPath.empty()) {
|
||||
if (boost::filesystem::exists(masterlistPath)) {
|
||||
if (std::filesystem::exists(masterlistPath)) {
|
||||
temp.Load(masterlistPath);
|
||||
} else {
|
||||
throw FileAccessError("The given masterlist path does not exist: " +
|
||||
@@ -61,7 +61,7 @@ void ApiDatabase::LoadLists(const std::string& masterlistPath,
|
||||
}
|
||||
|
||||
if (!userlistPath.empty()) {
|
||||
if (boost::filesystem::exists(userlistPath)) {
|
||||
if (std::filesystem::exists(userlistPath)) {
|
||||
userTemp.Load(userlistPath);
|
||||
} else {
|
||||
throw FileAccessError("The given userlist path does not exist: " +
|
||||
@@ -75,11 +75,11 @@ void ApiDatabase::LoadLists(const std::string& masterlistPath,
|
||||
|
||||
void ApiDatabase::WriteUserMetadata(const std::string& outputFile,
|
||||
const bool overwrite) const {
|
||||
if (!boost::filesystem::exists(
|
||||
boost::filesystem::path(outputFile).parent_path()))
|
||||
if (!std::filesystem::exists(
|
||||
std::filesystem::path(outputFile).parent_path()))
|
||||
throw std::invalid_argument("Output directory does not exist.");
|
||||
|
||||
if (boost::filesystem::exists(outputFile) && !overwrite)
|
||||
if (std::filesystem::exists(outputFile) && !overwrite)
|
||||
throw FileAccessError(
|
||||
"Output file exists but overwrite is not set to true.");
|
||||
|
||||
@@ -93,8 +93,8 @@ void ApiDatabase::WriteUserMetadata(const std::string& outputFile,
|
||||
bool ApiDatabase::UpdateMasterlist(const std::string& masterlistPath,
|
||||
const std::string& remoteURL,
|
||||
const std::string& remoteBranch) {
|
||||
if (!boost::filesystem::is_directory(
|
||||
boost::filesystem::path(masterlistPath).parent_path()))
|
||||
if (!std::filesystem::is_directory(
|
||||
std::filesystem::path(masterlistPath).parent_path()))
|
||||
throw std::invalid_argument("Given masterlist path \"" + masterlistPath +
|
||||
"\" does not have a valid parent directory.");
|
||||
|
||||
@@ -250,11 +250,11 @@ void ApiDatabase::DiscardAllUserMetadata() { userlist_.Clear(); }
|
||||
// will only be overwritten if overwrite is true.
|
||||
void ApiDatabase::WriteMinimalList(const std::string& outputFile,
|
||||
const bool overwrite) const {
|
||||
if (!boost::filesystem::exists(
|
||||
boost::filesystem::path(outputFile).parent_path()))
|
||||
if (!std::filesystem::exists(
|
||||
std::filesystem::path(outputFile).parent_path()))
|
||||
throw std::invalid_argument("Output directory does not exist.");
|
||||
|
||||
if (boost::filesystem::exists(outputFile) && !overwrite)
|
||||
if (std::filesystem::exists(outputFile) && !overwrite)
|
||||
throw FileAccessError(
|
||||
"Output file exists but overwrite is not set to true.");
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
namespace loot {
|
||||
struct ApiDatabase : public DatabaseInterface {
|
||||
ApiDatabase(const GameType gameType,
|
||||
const boost::filesystem::path& dataPath,
|
||||
const std::filesystem::path& dataPath,
|
||||
std::shared_ptr<GameCache> gameCache,
|
||||
std::shared_ptr<LoadOrderHandler> loadOrderHandler);
|
||||
|
||||
|
||||
@@ -53,12 +53,10 @@ using std::string;
|
||||
using std::thread;
|
||||
using std::vector;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace loot {
|
||||
Game::Game(const GameType gameType,
|
||||
const boost::filesystem::path& gamePath,
|
||||
const boost::filesystem::path& localDataPath) :
|
||||
const std::filesystem::path& gamePath,
|
||||
const std::filesystem::path& localDataPath) :
|
||||
type_(gameType),
|
||||
gamePath_(gamePath),
|
||||
cache_(std::make_shared<GameCache>()),
|
||||
@@ -78,7 +76,7 @@ Game::Game(const GameType gameType,
|
||||
|
||||
GameType Game::Type() const { return type_; }
|
||||
|
||||
boost::filesystem::path Game::DataPath() const { return gamePath_ / "Data"; }
|
||||
std::filesystem::path Game::DataPath() const { return gamePath_ / "Data"; }
|
||||
|
||||
std::shared_ptr<GameCache> Game::GetCache() { return cache_; }
|
||||
|
||||
@@ -246,8 +244,8 @@ void Game::SetLoadOrder(const std::vector<std::string>& loadOrder) {
|
||||
void Game::CacheArchives() {
|
||||
const auto archiveFileExtension = GetArchiveFileExtension(Type());
|
||||
|
||||
for (boost::filesystem::directory_iterator it(DataPath());
|
||||
it != boost::filesystem::directory_iterator();
|
||||
for (std::filesystem::directory_iterator it(DataPath());
|
||||
it != std::filesystem::directory_iterator();
|
||||
++it) {
|
||||
// Check if the path is an archive by checking if replacing its
|
||||
// file extension with the archive extension resolves to the same file.
|
||||
|
||||
+5
-6
@@ -25,10 +25,9 @@
|
||||
#ifndef LOOT_API_GAME_GAME
|
||||
#define LOOT_API_GAME_GAME
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "api/game/game_cache.h"
|
||||
#include "api/game/load_order_handler.h"
|
||||
#include "loot/game_interface.h"
|
||||
@@ -37,14 +36,14 @@ namespace loot {
|
||||
class Game : public GameInterface {
|
||||
public:
|
||||
Game(const GameType gameType,
|
||||
const boost::filesystem::path& gamePath,
|
||||
const boost::filesystem::path& gameLocalDataPath = "");
|
||||
const std::filesystem::path& gamePath,
|
||||
const std::filesystem::path& gameLocalDataPath = "");
|
||||
|
||||
// Internal Methods //
|
||||
//////////////////////
|
||||
|
||||
GameType Type() const;
|
||||
boost::filesystem::path DataPath() const;
|
||||
std::filesystem::path DataPath() const;
|
||||
|
||||
std::shared_ptr<GameCache> GetCache();
|
||||
std::shared_ptr<LoadOrderHandler> GetLoadOrderHandler();
|
||||
@@ -85,7 +84,7 @@ private:
|
||||
std::shared_ptr<DatabaseInterface> database_;
|
||||
|
||||
const GameType type_;
|
||||
const boost::filesystem::path gamePath_;
|
||||
const std::filesystem::path gamePath_;
|
||||
|
||||
std::string masterFile_;
|
||||
};
|
||||
|
||||
@@ -117,12 +117,12 @@ void GameCache::AddPlugin(const Plugin&& plugin) {
|
||||
std::make_shared<Plugin>(std::move(plugin)));
|
||||
}
|
||||
|
||||
std::set<boost::filesystem::path> GameCache::GetArchivePaths() const
|
||||
std::set<std::filesystem::path> GameCache::GetArchivePaths() const
|
||||
{
|
||||
return archivePaths_;
|
||||
}
|
||||
|
||||
void GameCache::CacheArchivePath(const boost::filesystem::path& path)
|
||||
void GameCache::CacheArchivePath(const std::filesystem::path& path)
|
||||
{
|
||||
lock_guard<mutex> lock(mutex_);
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ public:
|
||||
const std::string& pluginName) const;
|
||||
void AddPlugin(const Plugin&& plugin);
|
||||
|
||||
std::set<boost::filesystem::path> GetArchivePaths() const;
|
||||
void CacheArchivePath(const boost::filesystem::path& path);
|
||||
std::set<std::filesystem::path> GetArchivePaths() const;
|
||||
void CacheArchivePath(const std::filesystem::path& path);
|
||||
|
||||
void ClearCachedConditions();
|
||||
void ClearCachedPlugins();
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
std::unordered_map<std::string, bool> conditions_;
|
||||
std::unordered_map<std::string, uint32_t> crcs_;
|
||||
std::unordered_map<std::string, std::shared_ptr<const Plugin>> plugins_;
|
||||
std::set<boost::filesystem::path> archivePaths_;
|
||||
std::set<std::filesystem::path> archivePaths_;
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
};
|
||||
|
||||
@@ -58,8 +58,8 @@ LoadOrderHandler::LoadOrderHandler() : gh_(nullptr) {}
|
||||
LoadOrderHandler::~LoadOrderHandler() { lo_destroy_handle(gh_); }
|
||||
|
||||
void LoadOrderHandler::Init(const GameType& gameType,
|
||||
const boost::filesystem::path& gamePath,
|
||||
const boost::filesystem::path& gameLocalAppData) {
|
||||
const std::filesystem::path& gamePath,
|
||||
const std::filesystem::path& gameLocalAppData) {
|
||||
if (gamePath.empty()) {
|
||||
throw std::invalid_argument("Game path is not initialised.");
|
||||
}
|
||||
@@ -138,7 +138,7 @@ std::vector<std::string> LoadOrderHandler::GetImplicitlyActivePlugins() const {
|
||||
lo_get_implicitly_active_plugins(gh_, &pluginArr, &pluginArrSize);
|
||||
|
||||
HandleError("get implicitly active plugins", ret);
|
||||
|
||||
|
||||
std::vector<string> loadOrder(pluginArr, pluginArr + pluginArrSize);
|
||||
lo_free_string_array(pluginArr, pluginArrSize);
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
#ifndef LOOT_API_GAME_LOAD_ORDER_HANDLER
|
||||
#define LOOT_API_GAME_LOAD_ORDER_HANDLER
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <libloadorder.hpp>
|
||||
|
||||
#include "loot/enum/game_type.h"
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
~LoadOrderHandler();
|
||||
|
||||
void Init(const GameType& game,
|
||||
const boost::filesystem::path& gamePath,
|
||||
const boost::filesystem::path& gameLocalAppData = "");
|
||||
const std::filesystem::path& gamePath,
|
||||
const std::filesystem::path& gameLocalAppData = "");
|
||||
|
||||
void LoadCurrentState();
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
|
||||
#include "api/helpers/crc.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include "api/helpers/logging.h"
|
||||
|
||||
@@ -46,14 +47,14 @@ size_t GetStreamSize(std::istream& stream) {
|
||||
}
|
||||
|
||||
// Calculate the CRC of the given file for comparison purposes.
|
||||
uint32_t GetCrc32(const boost::filesystem::path& filename) {
|
||||
uint32_t GetCrc32(const std::filesystem::path& filename) {
|
||||
try {
|
||||
auto logger = getLogger();
|
||||
if (logger) {
|
||||
logger->trace("Calculating CRC for: {}", filename.string());
|
||||
}
|
||||
|
||||
boost::filesystem::ifstream ifile(filename, std::ios::binary);
|
||||
std::ifstream ifile(filename, std::ios::binary);
|
||||
ifile.exceptions(std::ios_base::badbit | std::ios_base::failbit);
|
||||
|
||||
static const size_t bufferSize = 8192;
|
||||
|
||||
@@ -26,11 +26,10 @@
|
||||
#define LOOT_API_HELPERS_CRC
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace loot {
|
||||
uint32_t GetCrc32(const boost::filesystem::path& filename);
|
||||
uint32_t GetCrc32(const std::filesystem::path& filename);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,13 +27,17 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
#include "api/helpers/logging.h"
|
||||
#include "loot/exception/error_categories.h"
|
||||
#include "loot/exception/git_state_error.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace loot {
|
||||
GitHelper::GitHelper() : logger_(getLogger()) {}
|
||||
@@ -105,7 +109,7 @@ void GitHelper::InitialiseOptions(const std::string& branch,
|
||||
data_.clone_options.checkout_branch = branch.c_str();
|
||||
}
|
||||
|
||||
void GitHelper::Open(const boost::filesystem::path& repoRoot) {
|
||||
void GitHelper::Open(const std::filesystem::path& repoRoot) {
|
||||
if (logger_) {
|
||||
logger_->info("Attempting to open Git repository at: {}",
|
||||
repoRoot.string());
|
||||
@@ -144,7 +148,7 @@ void GitHelper::Call(int error_code) {
|
||||
throw std::system_error(error_code, libgit2_category(), message);
|
||||
}
|
||||
|
||||
bool GitHelper::IsRepository(const boost::filesystem::path& path) {
|
||||
bool GitHelper::IsRepository(const std::filesystem::path& path) {
|
||||
return git_repository_open_ext(NULL,
|
||||
path.string().c_str(),
|
||||
GIT_REPOSITORY_OPEN_NO_SEARCH,
|
||||
@@ -171,7 +175,7 @@ int GitHelper::DiffFileCallback(const git_diff_delta* delta,
|
||||
}
|
||||
|
||||
// Clones a repository and opens it.
|
||||
void GitHelper::Clone(const boost::filesystem::path& path,
|
||||
void GitHelper::Clone(const std::filesystem::path& path,
|
||||
const std::string& url) {
|
||||
if (data_.repo != nullptr)
|
||||
throw GitStateError(
|
||||
@@ -191,7 +195,8 @@ void GitHelper::Clone(const boost::filesystem::path& path,
|
||||
if (logger_) {
|
||||
logger_->trace("Target repo path not empty, cloning into temporary directory.");
|
||||
}
|
||||
auto directory = "LOOT-" + path.filename().string() + "-" + fs::unique_path().string();
|
||||
auto directory = "LOOT-" + path.filename().string() + "-" +
|
||||
boost::lexical_cast<std::string>((boost::uuids::random_generator())());
|
||||
repoPath = fs::temp_directory_path() / directory;
|
||||
|
||||
// Remove path in case it already exists.
|
||||
@@ -218,7 +223,7 @@ void GitHelper::Clone(const boost::filesystem::path& path,
|
||||
"Target repo path not empty, moving cloned files in.");
|
||||
}
|
||||
|
||||
std::vector<boost::filesystem::path> filenamesToMove;
|
||||
std::vector<std::filesystem::path> filenamesToMove;
|
||||
for (fs::directory_iterator it(repoPath);
|
||||
it != fs::directory_iterator();
|
||||
++it) {
|
||||
@@ -570,7 +575,7 @@ std::string GitHelper::GetHeadCommitDate() {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
bool GitHelper::IsFileDifferent(const boost::filesystem::path& repoRoot,
|
||||
bool GitHelper::IsFileDifferent(const std::filesystem::path& repoRoot,
|
||||
const std::string& filename) {
|
||||
auto logger = getLogger();
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
#ifndef LOOT_API_HELPERS_GIT_HELPER
|
||||
#define LOOT_API_HELPERS_GIT_HELPER
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#include <git2.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace loot {
|
||||
class GitHelper {
|
||||
@@ -38,14 +38,14 @@ public:
|
||||
|
||||
void InitialiseOptions(const std::string& branch,
|
||||
const std::string& filenameToCheckout);
|
||||
void Open(const boost::filesystem::path& repoRoot);
|
||||
void Open(const std::filesystem::path& repoRoot);
|
||||
void SetRemoteUrl(const std::string& remote, const std::string& url);
|
||||
|
||||
static bool IsRepository(const boost::filesystem::path& path);
|
||||
static bool IsFileDifferent(const boost::filesystem::path& repoRoot,
|
||||
static bool IsRepository(const std::filesystem::path& path);
|
||||
static bool IsFileDifferent(const std::filesystem::path& repoRoot,
|
||||
const std::string& filename);
|
||||
|
||||
void Clone(const boost::filesystem::path& path, const std::string& url);
|
||||
void Clone(const std::filesystem::path& path, const std::string& url);
|
||||
void Fetch(const std::string& remote);
|
||||
|
||||
void CheckoutNewBranch(const std::string& remote, const std::string& branch);
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
|
||||
// Removes the read-only flag from some files in git repositories
|
||||
// created by libgit2.
|
||||
void GrantWritePermissions(const boost::filesystem::path& path);
|
||||
void GrantWritePermissions(const std::filesystem::path& path);
|
||||
|
||||
void Call(int error_code);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ Version::Version(const std::string& ver) {
|
||||
}
|
||||
}
|
||||
|
||||
Version::Version(const boost::filesystem::path& file) {
|
||||
Version::Version(const std::filesystem::path& file) {
|
||||
#ifdef _WIN32
|
||||
DWORD dummy = 0;
|
||||
DWORD size = GetFileVersionInfoSize(ToWinWide(file.string()).c_str(), &dummy);
|
||||
|
||||
@@ -25,18 +25,17 @@
|
||||
#ifndef LOOT_API_HELPERS_VERSION
|
||||
#define LOOT_API_HELPERS_VERSION
|
||||
|
||||
#include <filesystem>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace loot {
|
||||
// Version class for more robust version comparisons.
|
||||
class Version {
|
||||
public:
|
||||
Version();
|
||||
Version(const std::string& ver);
|
||||
Version(const boost::filesystem::path& file);
|
||||
Version(const std::filesystem::path& file);
|
||||
|
||||
std::string AsString() const;
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace loot {
|
||||
MasterlistInfo Masterlist::GetInfo(const boost::filesystem::path& path,
|
||||
MasterlistInfo Masterlist::GetInfo(const std::filesystem::path& path,
|
||||
bool shortID) {
|
||||
// Compare HEAD and working copy, and get revision info.
|
||||
GitHelper git;
|
||||
@@ -71,7 +71,7 @@ MasterlistInfo Masterlist::GetInfo(const boost::filesystem::path& path,
|
||||
return info;
|
||||
}
|
||||
|
||||
bool Masterlist::IsLatest(const boost::filesystem::path& path,
|
||||
bool Masterlist::IsLatest(const std::filesystem::path& path,
|
||||
const std::string& repoBranch) {
|
||||
if (repoBranch.empty())
|
||||
throw std::invalid_argument("Repository branch must not be empty.");
|
||||
@@ -96,7 +96,7 @@ bool Masterlist::IsLatest(const boost::filesystem::path& path,
|
||||
git.IsBranchCheckedOut(repoBranch);
|
||||
}
|
||||
|
||||
bool Masterlist::Update(const boost::filesystem::path& path,
|
||||
bool Masterlist::Update(const std::filesystem::path& path,
|
||||
const std::string& repoUrl,
|
||||
const std::string& repoBranch) {
|
||||
GitHelper git;
|
||||
@@ -104,8 +104,8 @@ bool Masterlist::Update(const boost::filesystem::path& path,
|
||||
fs::path repoPath = path.parent_path();
|
||||
string filename = path.filename().string();
|
||||
|
||||
if (repoUrl.empty() || repoBranch.empty())
|
||||
throw std::invalid_argument("Repository URL and branch must not be empty.");
|
||||
if (path.empty() || repoUrl.empty() || repoBranch.empty())
|
||||
throw std::invalid_argument("Repository path, URL and branch must not be empty.");
|
||||
|
||||
if (logger) {
|
||||
logger->debug("Setting up checkout options.");
|
||||
|
||||
@@ -25,24 +25,23 @@
|
||||
#ifndef LOOT_API_MASTERLIST
|
||||
#define LOOT_API_MASTERLIST
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "api/metadata_list.h"
|
||||
#include "loot/struct/masterlist_info.h"
|
||||
|
||||
namespace loot {
|
||||
class Masterlist : public MetadataList {
|
||||
public:
|
||||
bool Update(const boost::filesystem::path& path,
|
||||
bool Update(const std::filesystem::path& path,
|
||||
const std::string& repoURL,
|
||||
const std::string& repoBranch);
|
||||
|
||||
static MasterlistInfo GetInfo(const boost::filesystem::path& path,
|
||||
static MasterlistInfo GetInfo(const std::filesystem::path& path,
|
||||
bool shortID);
|
||||
|
||||
static bool IsLatest(const boost::filesystem::path& path,
|
||||
static bool IsLatest(const std::filesystem::path& path,
|
||||
const std::string& repoBranch);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ ConditionEvaluator::ConditionEvaluator() :
|
||||
loadOrderHandler_(nullptr) {}
|
||||
ConditionEvaluator::ConditionEvaluator(
|
||||
const GameType gameType,
|
||||
const boost::filesystem::path& dataPath,
|
||||
const std::filesystem::path& dataPath,
|
||||
std::shared_ptr<GameCache> gameCache,
|
||||
std::shared_ptr<LoadOrderHandler> loadOrderHandler) :
|
||||
gameType_(gameType),
|
||||
@@ -163,10 +163,10 @@ bool ConditionEvaluator::fileExists(const std::string& filePath) const {
|
||||
|
||||
// Not a loaded plugin, check the filesystem.
|
||||
if (hasPluginFileExtension(filePath, gameType_))
|
||||
return boost::filesystem::exists(dataPath_ / filePath) ||
|
||||
boost::filesystem::exists(dataPath_ / (filePath + ".ghost"));
|
||||
return std::filesystem::exists(dataPath_ / filePath) ||
|
||||
std::filesystem::exists(dataPath_ / (filePath + ".ghost"));
|
||||
else
|
||||
return boost::filesystem::exists(dataPath_ / filePath);
|
||||
return std::filesystem::exists(dataPath_ / filePath);
|
||||
}
|
||||
|
||||
bool ConditionEvaluator::regexMatchExists(
|
||||
@@ -261,13 +261,13 @@ bool ConditionEvaluator::compareVersions(const std::string& filePath,
|
||||
(comparator == ">=" && trueVersion >= givenVersion));
|
||||
}
|
||||
|
||||
void ConditionEvaluator::validatePath(const boost::filesystem::path& path) {
|
||||
void ConditionEvaluator::validatePath(const std::filesystem::path& path) {
|
||||
auto logger = getLogger();
|
||||
if (logger) {
|
||||
logger->trace("Checking to see if the path \"{}\" is safe.", path.string());
|
||||
}
|
||||
|
||||
boost::filesystem::path temp;
|
||||
std::filesystem::path temp;
|
||||
for (const auto& component : path) {
|
||||
if (component == ".")
|
||||
continue;
|
||||
@@ -288,14 +288,14 @@ void ConditionEvaluator::validateRegex(const std::string& regexString) {
|
||||
}
|
||||
}
|
||||
|
||||
boost::filesystem::path ConditionEvaluator::getRegexParentPath(
|
||||
std::filesystem::path ConditionEvaluator::getRegexParentPath(
|
||||
const std::string& regexString) {
|
||||
size_t pos = regexString.rfind('/');
|
||||
|
||||
if (pos == std::string::npos)
|
||||
return boost::filesystem::path();
|
||||
return std::filesystem::path();
|
||||
|
||||
return boost::filesystem::path(regexString.substr(0, pos));
|
||||
return std::filesystem::path(regexString.substr(0, pos));
|
||||
}
|
||||
|
||||
std::string ConditionEvaluator::getRegexFilename(
|
||||
@@ -308,7 +308,7 @@ std::string ConditionEvaluator::getRegexFilename(
|
||||
return regexString.substr(pos + 1);
|
||||
}
|
||||
|
||||
std::pair<boost::filesystem::path, std::regex> ConditionEvaluator::splitRegex(
|
||||
std::pair<std::filesystem::path, std::regex> ConditionEvaluator::splitRegex(
|
||||
const std::string& regexString) {
|
||||
// Can't support a regex string where all path components may be regex, since
|
||||
// this could lead to massive scanning if an unfortunately-named directory is
|
||||
@@ -318,7 +318,7 @@ std::pair<boost::filesystem::path, std::regex> ConditionEvaluator::splitRegex(
|
||||
validateRegex(regexString);
|
||||
|
||||
std::string filename = getRegexFilename(regexString);
|
||||
boost::filesystem::path parent = getRegexParentPath(regexString);
|
||||
std::filesystem::path parent = getRegexParentPath(regexString);
|
||||
|
||||
validatePath(parent);
|
||||
|
||||
@@ -330,19 +330,19 @@ std::pair<boost::filesystem::path, std::regex> ConditionEvaluator::splitRegex(
|
||||
"\": " + e.what());
|
||||
}
|
||||
|
||||
return std::pair<boost::filesystem::path, std::regex>(parent, reg);
|
||||
return std::pair<std::filesystem::path, std::regex>(parent, reg);
|
||||
}
|
||||
|
||||
bool ConditionEvaluator::isGameSubdirectory(
|
||||
const boost::filesystem::path& path) const {
|
||||
boost::filesystem::path parentPath = dataPath_ / path;
|
||||
const std::filesystem::path& path) const {
|
||||
std::filesystem::path parentPath = dataPath_ / path;
|
||||
|
||||
return boost::filesystem::exists(parentPath) &&
|
||||
boost::filesystem::is_directory(parentPath);
|
||||
return std::filesystem::exists(parentPath) &&
|
||||
std::filesystem::is_directory(parentPath);
|
||||
}
|
||||
|
||||
bool ConditionEvaluator::isRegexMatchInDataDirectory(
|
||||
const std::pair<boost::filesystem::path, std::regex>& pathRegex,
|
||||
const std::pair<std::filesystem::path, std::regex>& pathRegex,
|
||||
const std::function<bool(const std::string&)> condition) const {
|
||||
// Now we have a valid parent path and a regex filename. Check that the
|
||||
// parent path exists and is a directory.
|
||||
@@ -356,9 +356,9 @@ bool ConditionEvaluator::isRegexMatchInDataDirectory(
|
||||
}
|
||||
|
||||
return std::any_of(
|
||||
boost::filesystem::directory_iterator(dataPath_ / pathRegex.first),
|
||||
boost::filesystem::directory_iterator(),
|
||||
[&](const boost::filesystem::directory_entry& entry) {
|
||||
std::filesystem::directory_iterator(dataPath_ / pathRegex.first),
|
||||
std::filesystem::directory_iterator(),
|
||||
[&](const std::filesystem::directory_entry& entry) {
|
||||
const std::string filename = entry.path().filename().string();
|
||||
return std::regex_match(filename, pathRegex.second) &&
|
||||
condition(filename);
|
||||
@@ -366,7 +366,7 @@ bool ConditionEvaluator::isRegexMatchInDataDirectory(
|
||||
}
|
||||
|
||||
bool ConditionEvaluator::areRegexMatchesInDataDirectory(
|
||||
const std::pair<boost::filesystem::path, std::regex>& pathRegex,
|
||||
const std::pair<std::filesystem::path, std::regex>& pathRegex,
|
||||
const std::function<bool(const std::string&)> condition) const {
|
||||
bool foundOneFile = false;
|
||||
|
||||
@@ -405,7 +405,7 @@ bool ConditionEvaluator::parseCondition(const std::string& condition) const {
|
||||
}
|
||||
Version ConditionEvaluator::getVersion(const std::string& filePath) const {
|
||||
if (filePath == "LOOT")
|
||||
return Version(boost::filesystem::absolute("LOOT.exe"));
|
||||
return Version(std::filesystem::absolute("LOOT.exe"));
|
||||
else {
|
||||
// If the file is a plugin, its version needs to be extracted
|
||||
// from its description field. Try getting an entry from the
|
||||
@@ -440,7 +440,7 @@ uint32_t ConditionEvaluator::getCrc(const std::string & file) const {
|
||||
}
|
||||
|
||||
if (file == "LOOT") {
|
||||
crc = GetCrc32(boost::filesystem::absolute("LOOT.exe"));
|
||||
crc = GetCrc32(std::filesystem::absolute("LOOT.exe"));
|
||||
gameCache_->CacheCrc(file, crc);
|
||||
return crc;
|
||||
}
|
||||
@@ -453,11 +453,11 @@ uint32_t ConditionEvaluator::getCrc(const std::string & file) const {
|
||||
|
||||
// Otherwise calculate it from the file.
|
||||
if (crc == 0) {
|
||||
if (boost::filesystem::exists(dataPath_ / file)) {
|
||||
if (std::filesystem::exists(dataPath_ / file)) {
|
||||
crc = GetCrc32(dataPath_ / file);
|
||||
}
|
||||
else if (hasPluginFileExtension(file, gameType_) &&
|
||||
boost::filesystem::exists(dataPath_ / (file + ".ghost"))) {
|
||||
std::filesystem::exists(dataPath_ / (file + ".ghost"))) {
|
||||
crc = GetCrc32(dataPath_ / (file + ".ghost"));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user