reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 53f57fcb41509539f51fe7e5de16b68198e80bfd
parent d72d67d3419629eeeefde51ff02614008a91a84c
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Mon, 25 Jan 2016 16:29:28 -0500

centralize path generation and ensure the cache directory always exists

Diffstat:
Msrc/path.cpp | 13+++++++++++++
Msrc/path.hpp | 20++++++++++++++++++++
Msrc/reapack.cpp | 12+++++++-----
Msrc/reapack.hpp | 2+-
Msrc/task.cpp | 30++++++++++++++----------------
Msrc/task.hpp | 6+++---
Msrc/transaction.cpp | 26+++++---------------------
Msrc/transaction.hpp | 7++-----
Mtest/path.cpp | 25+++++++++++++++++++++++++
9 files changed, 90 insertions(+), 51 deletions(-)

diff --git a/src/path.cpp b/src/path.cpp @@ -28,6 +28,8 @@ static const char SEPARATOR = '/'; static const char SEPARATOR = '\\'; #endif +Path Path::s_root; + static vector<string> Split(const string &input) { vector<string> list; @@ -172,3 +174,14 @@ const string &Path::operator[](const size_t index) const { return at(index); } + +UseRootPath::UseRootPath(const std::string &path) + : m_backup(move(Path::s_root)) +{ + Path::s_root = path; +} + +UseRootPath::~UseRootPath() +{ + Path::s_root = move(m_backup); +} diff --git a/src/path.hpp b/src/path.hpp @@ -21,8 +21,16 @@ #include <string> #include <list> +class UseRootPath; + class Path { public: + static Path prefix(const Path &p) { return s_root + p; } + static Path configFile() { return s_root + "reapack.ini"; } + static Path cacheDir() { return s_root + "ReaPack"; } + static Path cache(const std::string &p) { return cacheDir() + p; } + static Path registry() { return cacheDir() + "registry.db"; } + Path(const std::string &path = std::string()); void prepend(const std::string &part); @@ -46,9 +54,21 @@ public: const std::string &operator[](const size_t index) const; private: + static Path s_root; + friend UseRootPath; + const std::string &at(const size_t) const; std::list<std::string> m_parts; }; +class UseRootPath { +public: + UseRootPath(const std::string &); + ~UseRootPath(); + +private: + Path m_backup; +}; + #endif diff --git a/src/reapack.cpp b/src/reapack.cpp @@ -32,10 +32,12 @@ ReaPack::ReaPack(REAPER_PLUGIN_HINSTANCE instance) : m_transaction(nullptr), m_instance(instance) { m_mainWindow = GetMainHwnd(); - m_resourcePath.append(GetResourcePath()); + m_useRootPath = new UseRootPath(GetResourcePath()); + + RecursiveCreateDirectory(Path::cacheDir().join().c_str(), 0); m_config = new Config; - m_config->read(m_resourcePath + "reapack.ini"); + m_config->read(Path::configFile()); m_progress = Dialog::Create<Progress>(m_instance, m_mainWindow); m_manager = Dialog::Create<Manager>(m_instance, m_mainWindow, this); @@ -45,8 +47,6 @@ ReaPack::ReaPack(REAPER_PLUGIN_HINSTANCE instance) ReaPack::~ReaPack() { - // for some reasons ~ReaPack() is called many times during startup - // and two times during shutdown on osx... cleanup() is called only once m_config->write(); delete m_config; @@ -54,6 +54,8 @@ ReaPack::~ReaPack() Dialog::Destroy(m_manager); Download::Cleanup(); + + delete m_useRootPath; } int ReaPack::setupAction(const char *name, const ActionCallback &callback) @@ -238,7 +240,7 @@ Transaction *ReaPack::createTransaction() } try { - m_transaction = new Transaction(m_resourcePath); + m_transaction = new Transaction; } catch(const reapack_error &e) { ShowMessageBox(e.what(), "ReaPack – Fatal Error", 0); diff --git a/src/reapack.hpp b/src/reapack.hpp @@ -67,7 +67,7 @@ private: REAPER_PLUGIN_HINSTANCE m_instance; HWND m_mainWindow; - Path m_resourcePath; + UseRootPath *m_useRootPath; }; #endif diff --git a/src/task.cpp b/src/task.cpp @@ -59,10 +59,10 @@ void Task::rollback() doRollback(); } -bool Task::renameFile(const Path &from, const Path &to) const +bool Task::RenameFile(const Path &from, const Path &to) { - const string &fullFrom = m_transaction->prefixPath(from).join(); - const string &fullTo = m_transaction->prefixPath(to).join(); + const string &fullFrom = Path::prefix(from).join(); + const string &fullTo = Path::prefix(to).join(); #ifdef _WIN32 return !_wrename(make_autostring(fullFrom).c_str(), @@ -72,10 +72,10 @@ bool Task::renameFile(const Path &from, const Path &to) const #endif } -bool Task::removeFile(const Path &path) const +bool Task::RemoveFile(const Path &path) { const auto_string &fullPath = - make_autostring(m_transaction->prefixPath(path).join()); + make_autostring(Path::prefix(path).join()); #ifdef _WIN32 if(GetFileAttributes(fullPath.c_str()) & FILE_ATTRIBUTE_DIRECTORY) @@ -87,9 +87,9 @@ bool Task::removeFile(const Path &path) const #endif } -bool Task::removeFileRecursive(const Path &file) const +bool Task::RemoveFileRecursive(const Path &file) { - if(!removeFile(file)) + if(!RemoveFile(file)) return false; Path dir = file; @@ -98,7 +98,7 @@ bool Task::removeFileRecursive(const Path &file) const while(dir.size() > 2) { dir.removeLast(); - if(!removeFile(dir)) + if(!RemoveFile(dir)) break; } @@ -144,9 +144,7 @@ void InstallTask::saveSource(Download *dl, Source *src) if(old != m_oldFiles.end()) m_oldFiles.erase(old); - const Path &path = transaction()->prefixPath(tmpPath); - - if(!transaction()->saveFile(dl, path)) { + if(!transaction()->saveFile(dl, Path::prefix(tmpPath))) { rollback(); return; } @@ -155,12 +153,12 @@ void InstallTask::saveSource(Download *dl, Source *src) bool InstallTask::doCommit() { for(const Path &path : m_oldFiles) - removeFile(path); + RemoveFile(path); for(const PathPair &paths : m_newFiles) { - removeFile(paths.second); + RemoveFile(paths.second); - if(!renameFile(paths.first, paths.second)) { + if(!RenameFile(paths.first, paths.second)) { transaction()->addError(strerror(errno), paths.first.join()); // it's a bit late to rollback here as some files might already have been @@ -176,7 +174,7 @@ bool InstallTask::doCommit() void InstallTask::doRollback() { for(const PathPair &paths : m_newFiles) - removeFileRecursive(paths.first); + RemoveFileRecursive(paths.first); m_newFiles.clear(); } @@ -189,7 +187,7 @@ RemoveTask::RemoveTask(const vector<Path> &files, Transaction *t) bool RemoveTask::doCommit() { for(const Path &path : m_files) { - if(removeFileRecursive(path)) + if(RemoveFileRecursive(path)) m_removedFiles.insert(path); else transaction()->addError(strerror(errno), path.join()); diff --git a/src/task.hpp b/src/task.hpp @@ -44,9 +44,9 @@ public: void rollback(); protected: - bool renameFile(const Path &, const Path &) const; - bool removeFile(const Path &) const; - bool removeFileRecursive(const Path &) const; + static bool RenameFile(const Path &, const Path &); + static bool RemoveFile(const Path &); + static bool RemoveFileRecursive(const Path &); Transaction *transaction() const { return m_transaction; } diff --git a/src/transaction.cpp b/src/transaction.cpp @@ -29,12 +29,10 @@ using namespace std; -Transaction::Transaction(const Path &root) - : m_root(root), m_isCancelled(false) +Transaction::Transaction() + : m_isCancelled(false) { - m_dbPath = m_root + "ReaPack"; - - m_registry = new Registry(m_dbPath + "registry.db"); + m_registry = new Registry(Path::registry()); m_downloadQueue.onDone([=](void *) { if(m_installQueue.empty()) @@ -42,8 +40,6 @@ Transaction::Transaction(const Path &root) else install(); }); - - RecursiveCreateDirectory(m_dbPath.join().c_str(), 0); } Transaction::~Transaction() @@ -71,7 +67,7 @@ void Transaction::synchronize(const Remote &remote) void Transaction::upgradeAll(Download *dl) { - const Path path = m_dbPath + ("remote_" + dl->name() + ".xml"); + const Path path = Path::cache("remote_" + dl->name() + ".xml"); if(!saveFile(dl, path)) return; @@ -145,13 +141,6 @@ void Transaction::install() const set<Path> &removedFiles = task->removedFiles(); m_removals.insert(removedFiles.begin(), removedFiles.end()); - - if(!m_registry->addToREAPER(ver, m_root)) { - addError( - "Cannot register the package in REAPER. " - "Are you using REAPER v5.12 or more recent?", ver->fullName() - ); - } }); addTask(task); @@ -245,15 +234,10 @@ void Transaction::addError(const string &message, const string &title) m_errors.push_back({message, title}); } -Path Transaction::prefixPath(const Path &input) const -{ - return m_root + input; -} - bool Transaction::allFilesExists(const set<Path> &list) const { for(const Path &path : list) { - if(!file_exists(prefixPath(path).join().c_str())) + if(!file_exists(Path::prefix(path).join().c_str())) return false; } diff --git a/src/transaction.hpp b/src/transaction.hpp @@ -46,7 +46,7 @@ public: typedef std::vector<const Error> ErrorList; - Transaction(const Path &root); + Transaction(); ~Transaction(); void onFinish(const Callback &callback) { m_onFinish.connect(callback); } @@ -79,11 +79,8 @@ private: bool allFilesExists(const std::set<Path> &) const; void addTask(Task *); - Registry *m_registry; - - Path m_root; - Path m_dbPath; bool m_isCancelled; + Registry *m_registry; std::set<Remote> m_remotes; std::vector<RemoteIndex *> m_remoteIndexes; diff --git a/test/path.cpp b/test/path.cpp @@ -163,3 +163,28 @@ TEST_CASE("remove last component of path", M) { REQUIRE(a.size() == 1); REQUIRE(a[0] == "a"); } + +TEST_CASE("path collection", M) { + const Path path("world"); + + REQUIRE(Path::prefix(path) == Path("world")); + + { + UseRootPath root("hello"); + (void)root; + + REQUIRE(Path::prefix(path) == Path("hello/world")); + } + + REQUIRE(Path::prefix(path) == Path("world")); +} + +TEST_CASE("standard paths", M) { + UseRootPath root("root"); + (void)root; + + REQUIRE(Path::configFile() == Path("root/reapack.ini")); + REQUIRE(Path::cacheDir() == Path("root/ReaPack")); + REQUIRE(Path::cache("test") == Path("root/ReaPack/test")); + REQUIRE(Path::registry() == Path("root/ReaPack/registry.db")); +}