reapack

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

commit e365a384f402b5d569fde4bd394031edbd929b8a
parent 7bb71a637f10e24b827c28b84e8d2b680cf9c0ca
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sun, 20 Dec 2015 13:27:30 -0500

rename PkgTransaction → Task

Diffstat:
Dsrc/pkgtransaction.cpp | 148-------------------------------------------------------------------------------
Dsrc/pkgtransaction.hpp | 64----------------------------------------------------------------
Asrc/task.cpp | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/task.hpp | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/transaction.cpp | 26+++++++++++++-------------
Msrc/transaction.hpp | 6+++---
6 files changed, 228 insertions(+), 228 deletions(-)

diff --git a/src/pkgtransaction.cpp b/src/pkgtransaction.cpp @@ -1,148 +0,0 @@ -/* ReaPack: Package manager for REAPER - * Copyright (C) 2015 Christian Fillion - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "pkgtransaction.hpp" - -#include "encoding.hpp" -#include "path.hpp" -#include "transaction.hpp" - -#include <cerrno> -#include <cstdio> - -using namespace std; - -PackageTransaction::PackageTransaction(Transaction *transaction) - : m_transaction(transaction), m_isCancelled(false) -{ -} - -void PackageTransaction::install(Version *ver) -{ - const auto &sources = ver->sources(); - - for(auto it = sources.begin(); it != sources.end();) { - const Path &path = it->first; - Source *src = it->second; - - Download *dl = new Download(src->fullName(), src->url()); - dl->onFinish(bind(&PackageTransaction::saveSource, this, dl, src)); - - m_remaining.push_back(dl); - m_transaction->downloadQueue()->push(dl); - - // executing finish after the download is deleted - // prevents the download queue from being deleted before the download is - dl->onFinish(bind(&PackageTransaction::finish, this)); - - // skip duplicate files - do { it++; } while(it != sources.end() && path == it->first); - } -} - -void PackageTransaction::saveSource(Download *dl, Source *src) -{ - m_remaining.erase(remove(m_remaining.begin(), m_remaining.end(), dl)); - - if(m_isCancelled) - return; - - const Path targetPath = src->targetPath(); - Path tmpPath = targetPath; - tmpPath[tmpPath.size() - 1] += ".new"; - - m_files.push_back({tmpPath, targetPath}); - - const Path path = m_transaction->prefixPath(tmpPath); - - if(!m_transaction->saveFile(dl, path)) { - cancel(); - return; - } -} - -void PackageTransaction::finish() -{ - if(!m_remaining.empty()) - return; - - m_onFinish(); -} - -void PackageTransaction::cancel() -{ - m_isCancelled = true; - - for(Download *dl : m_remaining) - dl->abort(); - - rollback(); -} - -void PackageTransaction::commit() -{ - if(m_isCancelled) - return; - - for(const PathPair &paths : m_files) { - const string tempPath = m_transaction->prefixPath(paths.first).join(); - const string targetPath = m_transaction->prefixPath(paths.second).join(); - - RemoveFile(targetPath); - - if(RenameFile(tempPath, targetPath)) { - m_transaction->addError(strerror(errno), tempPath); - - // it's a bit late to rollback here as some files might already have been - // overwritten. at least we can delete the temporary files - rollback(); - return; - } - } - - m_files.clear(); - m_onCommit(); -} - -void PackageTransaction::rollback() -{ - for(const PathPair &paths : m_files) { - const string tempPath = m_transaction->prefixPath(paths.first).join(); - - RemoveFile(tempPath); - } - - m_files.clear(); -} - -int PackageTransaction::RemoveFile(const std::string &path) -{ -#ifdef _WIN32 - return _wremove(make_autostring(path).c_str()); -#else - return remove(path.c_str()); -#endif -} - -int PackageTransaction::RenameFile(const std::string &from, const std::string &to) -{ -#ifdef _WIN32 - return _wrename(make_autostring(from).c_str(), make_autostring(to).c_str()); -#else - return rename(from.c_str(), to.c_str()); -#endif -} diff --git a/src/pkgtransaction.hpp b/src/pkgtransaction.hpp @@ -1,64 +0,0 @@ -/* ReaPack: Package manager for REAPER - * Copyright (C) 2015 Christian Fillion - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef REAPACK_PKG_TRANSACTION_HPP -#define REAPACK_PKG_TRANSACTION_HPP - -#include <boost/signals2.hpp> -#include <vector> - -class Download; -class Source; -class Transaction; -class Path; -class Version; - -class PackageTransaction { -public: - typedef boost::signals2::signal<void ()> Signal; - typedef Signal::slot_type Callback; - - PackageTransaction(Transaction *parent); - - void onCommit(const Callback &callback) { m_onCommit.connect(callback); } - void onFinish(const Callback &callback) { m_onFinish.connect(callback); } - - void install(Version *ver); - void commit(); - void cancel(); - -private: - static int RemoveFile(const std::string &); - static int RenameFile(const std::string &, const std::string &); - - typedef std::pair<Path, Path> PathPair; - - void finish(); - void rollback(); - - void saveSource(Download *, Source *); - - Transaction *m_transaction; - bool m_isCancelled; - std::vector<Download *> m_remaining; - std::vector<PathPair> m_files; - - Signal m_onCommit; - Signal m_onFinish; -}; - -#endif diff --git a/src/task.cpp b/src/task.cpp @@ -0,0 +1,148 @@ +/* ReaPack: Package manager for REAPER + * Copyright (C) 2015 Christian Fillion + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "task.hpp" + +#include "encoding.hpp" +#include "path.hpp" +#include "transaction.hpp" + +#include <cerrno> +#include <cstdio> + +using namespace std; + +Task::Task(Transaction *transaction) + : m_transaction(transaction), m_isCancelled(false) +{ +} + +void Task::install(Version *ver) +{ + const auto &sources = ver->sources(); + + for(auto it = sources.begin(); it != sources.end();) { + const Path &path = it->first; + Source *src = it->second; + + Download *dl = new Download(src->fullName(), src->url()); + dl->onFinish(bind(&Task::saveSource, this, dl, src)); + + m_remaining.push_back(dl); + m_transaction->downloadQueue()->push(dl); + + // executing finish after the download is deleted + // prevents the download queue from being deleted before the download is + dl->onFinish(bind(&Task::finish, this)); + + // skip duplicate files + do { it++; } while(it != sources.end() && path == it->first); + } +} + +void Task::saveSource(Download *dl, Source *src) +{ + m_remaining.erase(remove(m_remaining.begin(), m_remaining.end(), dl)); + + if(m_isCancelled) + return; + + const Path targetPath = src->targetPath(); + Path tmpPath = targetPath; + tmpPath[tmpPath.size() - 1] += ".new"; + + m_files.push_back({tmpPath, targetPath}); + + const Path path = m_transaction->prefixPath(tmpPath); + + if(!m_transaction->saveFile(dl, path)) { + cancel(); + return; + } +} + +void Task::finish() +{ + if(!m_remaining.empty()) + return; + + m_onFinish(); +} + +void Task::cancel() +{ + m_isCancelled = true; + + for(Download *dl : m_remaining) + dl->abort(); + + rollback(); +} + +void Task::commit() +{ + if(m_isCancelled) + return; + + for(const PathPair &paths : m_files) { + const string tempPath = m_transaction->prefixPath(paths.first).join(); + const string targetPath = m_transaction->prefixPath(paths.second).join(); + + RemoveFile(targetPath); + + if(RenameFile(tempPath, targetPath)) { + m_transaction->addError(strerror(errno), tempPath); + + // it's a bit late to rollback here as some files might already have been + // overwritten. at least we can delete the temporary files + rollback(); + return; + } + } + + m_files.clear(); + m_onCommit(); +} + +void Task::rollback() +{ + for(const PathPair &paths : m_files) { + const string tempPath = m_transaction->prefixPath(paths.first).join(); + + RemoveFile(tempPath); + } + + m_files.clear(); +} + +int Task::RemoveFile(const std::string &path) +{ +#ifdef _WIN32 + return _wremove(make_autostring(path).c_str()); +#else + return remove(path.c_str()); +#endif +} + +int Task::RenameFile(const std::string &from, const std::string &to) +{ +#ifdef _WIN32 + return _wrename(make_autostring(from).c_str(), make_autostring(to).c_str()); +#else + return rename(from.c_str(), to.c_str()); +#endif +} diff --git a/src/task.hpp b/src/task.hpp @@ -0,0 +1,64 @@ +/* ReaPack: Package manager for REAPER + * Copyright (C) 2015 Christian Fillion + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef REAPACK_TASK_HPP +#define REAPACK_TASK_HPP + +#include <boost/signals2.hpp> +#include <vector> + +class Download; +class Source; +class Transaction; +class Path; +class Version; + +class Task { +public: + typedef boost::signals2::signal<void ()> Signal; + typedef Signal::slot_type Callback; + + Task(Transaction *parent); + + void onCommit(const Callback &callback) { m_onCommit.connect(callback); } + void onFinish(const Callback &callback) { m_onFinish.connect(callback); } + + void install(Version *ver); + void commit(); + void cancel(); + +private: + static int RemoveFile(const std::string &); + static int RenameFile(const std::string &, const std::string &); + + typedef std::pair<Path, Path> PathPair; + + void finish(); + void rollback(); + + void saveSource(Download *, Source *); + + Transaction *m_transaction; + bool m_isCancelled; + std::vector<Download *> m_remaining; + std::vector<PathPair> m_files; + + Signal m_onCommit; + Signal m_onFinish; +}; + +#endif diff --git a/src/transaction.cpp b/src/transaction.cpp @@ -19,7 +19,7 @@ #include "encoding.hpp" #include "errors.hpp" -#include "pkgtransaction.hpp" +#include "task.hpp" #include <fstream> @@ -37,8 +37,8 @@ Transaction::Transaction(Registry *reg, const Path &root) Transaction::~Transaction() { - for(PackageTransaction *tr : m_transactions) - delete tr; + for(Task *task : m_tasks) + delete task; for(Database *db : m_databases) delete db; @@ -114,11 +114,11 @@ void Transaction::run() Package *pkg = entry.first; const Registry::QueryResult regEntry = entry.second; - PackageTransaction *tr = new PackageTransaction(this); + Task *task = new Task(this); try { - tr->install(entry.first->lastVersion()); - tr->onCommit([=] { + task->install(entry.first->lastVersion()); + task->onCommit([=] { if(regEntry.status == Registry::UpdateAvailable) m_updates.push_back(entry); else @@ -126,13 +126,13 @@ void Transaction::run() m_registry->push(pkg); }); - tr->onFinish(bind(&Transaction::finish, this)); + task->onFinish(bind(&Transaction::finish, this)); - m_transactions.push_back(tr); + m_tasks.push_back(task); } catch(const reapack_error &e) { addError(e.what(), pkg->fullName()); - delete tr; + delete task; } } } @@ -141,8 +141,8 @@ void Transaction::cancel() { m_isCancelled = true; - for(PackageTransaction *tr : m_transactions) - tr->cancel(); + for(Task *task : m_tasks) + task->cancel(); m_queue.abort(); } @@ -176,8 +176,8 @@ void Transaction::finish() return; if(!m_isCancelled) { - for(PackageTransaction *tr : m_transactions) - tr->commit(); + for(Task *task : m_tasks) + task->commit(); } m_onFinish(); diff --git a/src/transaction.hpp b/src/transaction.hpp @@ -26,7 +26,7 @@ #include <boost/signals2.hpp> -class PackageTransaction; +class Task; class Transaction { public: @@ -63,7 +63,7 @@ public: const ErrorList &errors() const { return m_errors; } private: - friend PackageTransaction; + friend Task; void prepare(); void finish(); @@ -88,7 +88,7 @@ private: PackageEntryList m_updates; ErrorList m_errors; - std::vector<PackageTransaction *> m_transactions; + std::vector<Task *> m_tasks; std::set<Path> m_files; bool m_hasConflicts;