reapack

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

commit b2fe87815a72a78fd4b09089ab5173b6a92ed9c4
parent 230439917489e68eb4131d90a9664d61889ae2d4
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sat, 28 Nov 2015 16:07:38 -0500

refactor package target location

Diffstat:
Msrc/database.cpp | 42------------------------------------------
Msrc/database.hpp | 36+-----------------------------------
Asrc/package.cpp | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/package.hpp | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/reapack.cpp | 24++++--------------------
Msrc/reapack.hpp | 9---------
Mtest/database.cpp | 50--------------------------------------------------
Atest/package.cpp | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 237 insertions(+), 156 deletions(-)

diff --git a/src/database.cpp b/src/database.cpp @@ -59,45 +59,3 @@ void Category::addPackage(PackagePtr pack) pack->setCategory(this); m_packages.push_back(pack); } - -Package::Type Package::convertType(const char *type) -{ - if(!strcmp(type, "script")) - return ScriptType; - else - return UnknownType; -} - -Package::Package(const Type type, - const std::string &name, const std::string &author) - : m_category(0), m_type(type), m_name(name), m_author(author) -{ - if(m_name.empty()) - throw reapack_error("empty package name"); - - if(m_author.empty()) - throw reapack_error("empty package author"); -} - -void Package::addVersion(VersionPtr ver) -{ - if(ver->sources().empty()) - return; - - m_versions.insert(ver); -} - -VersionPtr Package::version(const int index) const -{ - auto it = m_versions.begin(); - - for(int i = 0; i < index; i++) - it++; - - return *it; -} - -VersionPtr Package::lastVersion() const -{ - return *prev(m_versions.end()); -} diff --git a/src/database.hpp b/src/database.hpp @@ -5,7 +5,7 @@ #include <string> #include <vector> -#include "version.hpp" +#include "package.hpp" class TiXmlElement; @@ -15,9 +15,6 @@ typedef std::shared_ptr<Database> DatabasePtr; class Category; typedef std::shared_ptr<Category> CategoryPtr; -class Package; -typedef std::shared_ptr<Package> PackagePtr; - class Database { public: static DatabasePtr load(const char *); @@ -50,35 +47,4 @@ private: std::vector<PackagePtr> m_packages; }; -class Package { -public: - enum Type { - UnknownType, - ScriptType, - }; - - static Type convertType(const char *); - - Package(const Type, const std::string &name, const std::string &author); - - void setCategory(Category *cat) { m_category = cat; } - Category *category() const { return m_category; } - - Type type() const { return m_type; } - const std::string &name() const { return m_name; } - const std::string &author() const { return m_author; } - - void addVersion(VersionPtr ver); - const VersionSet &versions() const { return m_versions; } - VersionPtr version(const int i) const; - VersionPtr lastVersion() const; - -private: - Category *m_category; - Type m_type; - std::string m_name; - std::string m_author; - VersionSet m_versions; -}; - #endif diff --git a/src/package.cpp b/src/package.cpp @@ -0,0 +1,56 @@ +#include "package.hpp" + +#include "database.hpp" +#include "errors.hpp" + +Package::Type Package::convertType(const char *type) +{ + if(!strcmp(type, "script")) + return ScriptType; + else + return UnknownType; +} + +Package::Package(const Type type, + const std::string &name, const std::string &author) + : m_category(0), m_type(type), m_name(name), m_author(author) +{ + if(m_name.empty()) + throw reapack_error("empty package name"); + + if(m_author.empty()) + throw reapack_error("empty package author"); +} + +void Package::addVersion(VersionPtr ver) +{ + if(ver->sources().empty()) + return; + + m_versions.insert(ver); +} + +VersionPtr Package::version(const int index) const +{ + auto it = m_versions.begin(); + + for(int i = 0; i < index; i++) + it++; + + return *it; +} + +VersionPtr Package::lastVersion() const +{ + return *prev(m_versions.end()); +} + +InstallLocation Package::targetLocation() const +{ + switch(m_type) { + case ScriptType: + return {"/Scripts/ReaScripts/" + category()->name(), name()}; + default: + throw reapack_error("unsupported package type"); + } +} diff --git a/src/package.hpp b/src/package.hpp @@ -0,0 +1,71 @@ +#ifndef REAPACK_PACKAGE_HPP +#define REAPACK_PACKAGE_HPP + +#include "version.hpp" + +class Package; +typedef std::shared_ptr<Package> PackagePtr; + +class Category; + +class InstallLocation { +public: + InstallLocation(const std::string &d, const std::string &f) + : m_directory(d), m_filename(f) + {} + + void setPrefix(const std::string &p) { m_directory.insert(0, p); } + const std::string directory() const { return m_directory; } + const std::string filename() const { return m_filename; } + + std::string fullPath() const { return m_directory + "/" + m_filename; } + + bool operator==(const InstallLocation &o) const + { + return m_directory == o.directory() && m_filename == o.filename(); + } + + bool operator!=(const InstallLocation &o) const + { + return !(*this == o); + } + +private: + std::string m_directory; + std::string m_filename; +}; + +class Package { +public: + enum Type { + UnknownType, + ScriptType, + }; + + static Type convertType(const char *); + + Package(const Type, const std::string &name, const std::string &author); + + void setCategory(Category *cat) { m_category = cat; } + Category *category() const { return m_category; } + + Type type() const { return m_type; } + const std::string &name() const { return m_name; } + const std::string &author() const { return m_author; } + + void addVersion(VersionPtr ver); + const VersionSet &versions() const { return m_versions; } + VersionPtr version(const int i) const; + VersionPtr lastVersion() const; + + InstallLocation targetLocation() const; + +private: + Category *m_category; + Type m_type; + std::string m_name; + std::string m_author; + VersionSet m_versions; +}; + +#endif diff --git a/src/reapack.cpp b/src/reapack.cpp @@ -72,18 +72,12 @@ void ReaPack::installPackage(PackagePtr pkg) return; } + InstallLocation loc = pkg->targetLocation(); + loc.setPrefix(m_resourcePath); - const Location loc = scriptLocation(pkg); - switch(pkg->type()) { - case Package::ScriptType: - break; - default: - return; - }; - - RecursiveCreateDirectory(loc.directory.c_str(), 0); + RecursiveCreateDirectory(loc.directory().c_str(), 0); - ofstream file(loc.path()); + ofstream file(loc.fullPath()); if(file.bad()) { ShowMessageBox(strerror(errno), pkg->name().c_str(), 0); return; @@ -94,16 +88,6 @@ void ReaPack::installPackage(PackagePtr pkg) }); } -Location ReaPack::scriptLocation(PackagePtr pkg) -{ - string path = string(m_resourcePath) - .append("/Scripts/ReaScripts") - .append("/" + pkg->category()->name()) - ; - - return {path, pkg->name()}; -} - void ReaPack::queuedDownload(const char *url, DownloadCallback cb) { Download *download = new Download(url); diff --git a/src/reapack.hpp b/src/reapack.hpp @@ -10,13 +10,6 @@ #include "reaper_plugin.h" -struct Location { - std::string path() const { return directory + "/" + filename; } - - std::string directory; - std::string filename; -}; - typedef std::function<void()> ActionCallback; class ReaPack { @@ -36,8 +29,6 @@ public: void queuedDownload(const char *url, DownloadCallback cb); private: - Location scriptLocation(PackagePtr pkg); - std::map<int, ActionCallback> m_actions; DatabasePtr m_database; std::queue<Download *> m_downloadQueue; diff --git a/test/database.cpp b/test/database.cpp @@ -136,53 +136,3 @@ TEST_CASE("empty category name", M) { REQUIRE(string(e.what()) == "empty category name"); } } - -TEST_CASE("empty package name", M) { - try { - Package pack(Package::ScriptType, string(), "a"); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "empty package name"); - } -} - -TEST_CASE("empty package author", M) { - try { - Package pack(Package::ScriptType, "a", string()); - FAIL(); - } - catch(const reapack_error &e) { - REQUIRE(string(e.what()) == "empty package author"); - } -} - -TEST_CASE("package versions are sorted", M) { - Package pack(Package::ScriptType, "a", "b"); - CHECK(pack.versions().size() == 0); - - SourcePtr source = make_shared<Source>(Source::GenericPlatform, "google.com"); - - VersionPtr final = make_shared<Version>("1"); - final->addSource(source); - - VersionPtr alpha = make_shared<Version>("0.1"); - alpha->addSource(source); - - pack.addVersion(final); - CHECK(pack.versions().size() == 1); - - pack.addVersion(alpha); - CHECK(pack.versions().size() == 2); - - REQUIRE(pack.version(0) == alpha); - REQUIRE(pack.version(1) == final); - REQUIRE(pack.lastVersion() == final); -} - -TEST_CASE("drop empty version", M) { - Package pack(Package::ScriptType, "a", "b"); - pack.addVersion(make_shared<Version>("1")); - - REQUIRE(pack.versions().empty()); -} diff --git a/test/package.cpp b/test/package.cpp @@ -0,0 +1,105 @@ +#include <catch.hpp> + +#include <database.hpp> +#include <errors.hpp> +#include <package.hpp> + +#include <string> + +using namespace std; + +static const char *M = "[package]"; + +TEST_CASE("empty package name", M) { + try { + Package pack(Package::ScriptType, string(), "a"); + FAIL(); + } + catch(const reapack_error &e) { + REQUIRE(string(e.what()) == "empty package name"); + } +} + +TEST_CASE("empty package author", M) { + try { + Package pack(Package::ScriptType, "a", string()); + FAIL(); + } + catch(const reapack_error &e) { + REQUIRE(string(e.what()) == "empty package author"); + } +} + +TEST_CASE("package versions are sorted", M) { + Package pack(Package::ScriptType, "a", "b"); + CHECK(pack.versions().size() == 0); + + SourcePtr source = make_shared<Source>(Source::GenericPlatform, "google.com"); + + VersionPtr final = make_shared<Version>("1"); + final->addSource(source); + + VersionPtr alpha = make_shared<Version>("0.1"); + alpha->addSource(source); + + pack.addVersion(final); + CHECK(pack.versions().size() == 1); + + pack.addVersion(alpha); + CHECK(pack.versions().size() == 2); + + REQUIRE(pack.version(0) == alpha); + REQUIRE(pack.version(1) == final); + REQUIRE(pack.lastVersion() == final); +} + +TEST_CASE("drop empty version", M) { + Package pack(Package::ScriptType, "a", "b"); + pack.addVersion(make_shared<Version>("1")); + + REQUIRE(pack.versions().empty()); +} + +TEST_CASE("different install location", M) { + const InstallLocation a{"/hello", "/world"}; + const InstallLocation b{"/chunky", "/bacon"}; + + REQUIRE_FALSE(a == b); +} + +TEST_CASE("set install location prefix", M) { + InstallLocation loc{"/hello", "world"}; + + REQUIRE(loc.directory() == "/hello"); + REQUIRE(loc.filename() == "world"); + REQUIRE(loc.fullPath() == "/hello/world"); + + loc.setPrefix("/root"); + + REQUIRE(loc.directory() == "/root/hello"); + REQUIRE(loc.filename() == "world"); + REQUIRE(loc.fullPath() == "/root/hello/world"); +} + +TEST_CASE("unknown target location", M) { + Package pack(Package::UnknownType, "a", "b"); + + try { + pack.targetLocation(); + FAIL(); + } + catch(const reapack_error &e) { + REQUIRE(string(e.what()) == "unsupported package type"); + } +} + +TEST_CASE("script target location", M) { + Category cat("Category Name"); + + Package pack(Package::ScriptType, "file.name", "author"); + pack.setCategory(&cat); + + const InstallLocation loc = pack.targetLocation(); + REQUIRE(loc == + InstallLocation("/Scripts/ReaScripts/Category Name", "file.name")); +}