reapack

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

commit 5a2a2cd165f7bbe8d995e7a787c0039c930eecc9
parent 9b0fe4248b2c92756de56152ed9aa1b1ff48ebe6
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Fri, 18 Dec 2015 19:51:16 -0500

ensure the package tree cannot be jumbled with another tree

Diffstat:
Msrc/database.cpp | 16++++++++++------
Msrc/database.hpp | 4+---
Msrc/database_v1.cpp | 2+-
Msrc/package.cpp | 4+++-
Msrc/package.hpp | 2--
Msrc/source.cpp | 5+++--
Msrc/source.hpp | 4++--
Msrc/version.cpp | 3++-
Msrc/version.hpp | 2--
Mtest/database.cpp | 64++++++++++++++++++++++++++++++++++++++++++++++------------------
Mtest/package.cpp | 62++++++++++++++++++++++++++++++++++++++------------------------
Mtest/registry.cpp | 10++++------
Mtest/source.cpp | 21++++++---------------
Mtest/version.cpp | 102+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
14 files changed, 182 insertions(+), 119 deletions(-)

diff --git a/src/database.cpp b/src/database.cpp @@ -65,10 +65,12 @@ Database::~Database() void Database::addCategory(Category *cat) { + if(cat->database() != this) + throw reapack_error("category belongs to another database"); + if(cat->packages().empty()) return; - cat->setDatabase(this); m_categories.push_back(cat); m_packages.insert(m_packages.end(), @@ -93,13 +95,15 @@ string Category::fullName() const return m_database ? m_database->name() + "/" + m_name : m_name; } -void Category::addPackage(Package *pack) +void Category::addPackage(Package *pkg) { - if(pack->type() == Package::UnknownType) + if(pkg->category() != this) + throw reapack_error("package belongs to another category"); + + if(pkg->type() == Package::UnknownType) return; // silently discard unknown package types - else if(pack->versions().empty()) + else if(pkg->versions().empty()) return; - pack->setCategory(this); - m_packages.push_back(pack); + m_packages.push_back(pkg); } diff --git a/src/database.hpp b/src/database.hpp @@ -60,12 +60,10 @@ public: Category(const std::string &name, Database * = nullptr); ~Category(); + Database *database() const { return m_database; } const std::string &name() const { return m_name; } std::string fullName() const; - void setDatabase(Database *db) { m_database = db; } - Database *database() const { return m_database; } - void addPackage(Package *pack); const PackageList &packages() const { return m_packages; } Package *package(const size_t i) const { return m_packages[i]; } diff --git a/src/database_v1.cpp b/src/database_v1.cpp @@ -114,7 +114,7 @@ void LoadVersionV1(TiXmlElement *verNode, Package *pkg) const char *url = node->GetText(); if(!url) url = ""; - ver->addSource(new Source(Source::ConvertPlatform(platform), file, url)); + ver->addSource(new Source(Source::ConvertPlatform(platform), file, url, ver)); node = node->NextSiblingElement("source"); } diff --git a/src/package.cpp b/src/package.cpp @@ -52,10 +52,12 @@ Package::~Package() void Package::addVersion(Version *ver) { + if(ver->package() != this) + throw reapack_error("version belongs to another package"); + if(ver->sources().empty()) return; - ver->setPackage(this); m_versions.insert(ver); } diff --git a/src/package.hpp b/src/package.hpp @@ -38,9 +38,7 @@ public: Package(const Type, const std::string &name, Category * = nullptr); ~Package(); - 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; } std::string fullName() const; diff --git a/src/source.cpp b/src/source.cpp @@ -43,8 +43,9 @@ Source::Platform Source::ConvertPlatform(const char *platform) return UnknownPlatform; } -Source::Source(const Platform platform, const string &file, const string &url) - : m_platform(platform), m_file(file), m_url(url), m_version(nullptr) +Source::Source(const Platform platform, const string &file, + const string &url, Version *ver) + : m_platform(platform), m_file(file), m_url(url), m_version(ver) { if(m_url.empty()) throw reapack_error("empty source url"); diff --git a/src/source.hpp b/src/source.hpp @@ -48,13 +48,13 @@ public: static Platform ConvertPlatform(const char *); - Source(const Platform, const std::string &file, const std::string &url); + Source(const Platform, const std::string &file, + const std::string &url, Version * = nullptr); Platform platform() const { return m_platform; } const std::string &file() const; const std::string &url() const { return m_url; } - void setVersion(Version *ver) { m_version = ver; } Version *version() const { return m_version; } Package *package() const; diff --git a/src/version.cpp b/src/version.cpp @@ -93,7 +93,8 @@ void Version::addSource(Source *source) #endif #endif - source->setVersion(this); + if(source->version() != this) + throw reapack_error("source belongs to another version"); const Path path = source->targetPath(); m_files.insert(path); diff --git a/src/version.hpp b/src/version.hpp @@ -36,9 +36,7 @@ public: std::string fullName() const; uint64_t code() const { return m_code; } - void setPackage(Package *pkg) { m_package = pkg; } Package *package() const { return m_package; } - void setChangelog(const std::string &); const std::string &changelog() const { return m_changelog; } diff --git a/test/database.cpp b/test/database.cpp @@ -81,8 +81,8 @@ TEST_CASE("add category", M) { Database db("a"); Category *cat = new Category("a", &db); Package *pack = new Package(Package::ScriptType, "name", cat); - Source *source = new Source(Source::GenericPlatform, string(), "google.com"); Version *ver = new Version("1", pack); + Source *source = new Source(Source::GenericPlatform, {}, "google.com", ver); ver->addSource(source); pack->addVersion(ver); @@ -96,49 +96,77 @@ TEST_CASE("add category", M) { REQUIRE(db.packages() == cat->packages()); } +TEST_CASE("add owned category", M) { + Database db1("a"); + Database db2("b"); + + Category *cat = new Category("name", &db1); + + try { + db2.addCategory(cat); + FAIL(); + } + catch(const reapack_error &e) { + delete cat; + REQUIRE(string(e.what()) == "category belongs to another database"); + } +} + TEST_CASE("drop empty category", M) { Database db("a"); - db.addCategory(new Category("a")); + db.addCategory(new Category("a", &db)); REQUIRE(db.categories().empty()); } TEST_CASE("add a package", M) { Database db("a"); - Category cat1("a", &db); - Package *pack = new Package(Package::ScriptType, "name", &cat1); + Category cat("a", &db); + Package *pack = new Package(Package::ScriptType, "name", &cat); Version *ver = new Version("1", pack); - ver->addSource(new Source(Source::GenericPlatform, string(), "google.com")); + ver->addSource(new Source(Source::GenericPlatform, {}, "google.com", ver)); pack->addVersion(ver); - CHECK(pack->category() == &cat1); + CHECK(cat.packages().size() == 0); - Category cat2("b"); - CHECK(cat2.packages().size() == 0); + cat.addPackage(pack); - cat2.addPackage(pack); + REQUIRE(cat.packages().size() == 1); + REQUIRE(pack->category() == &cat); +} - REQUIRE(cat2.packages().size() == 1); - REQUIRE(pack->category() == &cat2); +TEST_CASE("add owned package", M) { + Category cat1("a"); + Package *pack = new Package(Package::ScriptType, "name", &cat1); + + try { + Category cat2("b"); + cat2.addPackage(pack); + FAIL(); + } + catch(const reapack_error &e) { + delete pack; + REQUIRE(string(e.what()) == "package belongs to another category"); + } } TEST_CASE("drop empty package", M) { Category cat("a"); - cat.addPackage(new Package(Package::ScriptType, "name")); + cat.addPackage(new Package(Package::ScriptType, "name", &cat)); REQUIRE(cat.packages().empty()); } TEST_CASE("drop unknown package", M) { Category cat("a"); - cat.addPackage(new Package(Package::UnknownType, "name")); + cat.addPackage(new Package(Package::UnknownType, "name", &cat)); REQUIRE(cat.packages().size() == 0); } TEST_CASE("empty category name", M) { try { - Category cat{string()}; + Category cat{string(), nullptr}; FAIL(); } catch(const reapack_error &e) { @@ -147,10 +175,10 @@ TEST_CASE("empty category name", M) { } TEST_CASE("category full name", M) { - Category cat("Category Name"); - REQUIRE(cat.fullName() == "Category Name"); + Category cat1("Category Name"); + REQUIRE(cat1.fullName() == "Category Name"); Database db("Database Name"); - cat.setDatabase(&db); - REQUIRE(cat.fullName() == "Database Name/Category Name"); + Category cat2("Category Name", &db); + REQUIRE(cat2.fullName() == "Database Name/Category Name"); } diff --git a/test/package.cpp b/test/package.cpp @@ -39,14 +39,11 @@ TEST_CASE("package versions are sorted", M) { Package pack(Package::ScriptType, "a", &cat); CHECK(pack.versions().size() == 0); - Source *sourceA = new Source(Source::GenericPlatform, string(), "google.com"); - Source *sourceB = new Source(Source::GenericPlatform, string(), "google.com"); - Version *final = new Version("1", &pack); - final->addSource(sourceA); + final->addSource(new Source(Source::GenericPlatform, {}, "google.com", final)); Version *alpha = new Version("0.1", &pack); - alpha->addSource(sourceB); + alpha->addSource(new Source(Source::GenericPlatform, {}, "google.com", alpha)); pack.addVersion(final); REQUIRE(final->package() == &pack); @@ -62,19 +59,33 @@ TEST_CASE("package versions are sorted", M) { TEST_CASE("drop empty version", M) { Package pack(Package::ScriptType, "a"); - pack.addVersion(new Version("1")); + pack.addVersion(new Version("1", &pack)); REQUIRE(pack.versions().empty()); REQUIRE(pack.lastVersion() == nullptr); } +TEST_CASE("add owned version", M) { + Package pack1(Package::ScriptType, "a"); + Package pack2(Package::ScriptType, "a"); + + Version *ver = new Version("1", &pack1); + + try { + pack2.addVersion(ver); + FAIL(); + } + catch(const reapack_error &e) { + delete ver; + REQUIRE(string(e.what()) == "version belongs to another package"); + } +} + TEST_CASE("unknown target path", M) { Database db("name"); - Category cat("name"); - cat.setDatabase(&db); + Category cat("name", &db); - Package pack(Package::UnknownType, "a"); - pack.setCategory(&cat); + Package pack(Package::UnknownType, "a", &cat); try { pack.targetPath(); @@ -87,12 +98,9 @@ TEST_CASE("unknown target path", M) { TEST_CASE("script target path", M) { Database db("Database Name"); + Category cat("Category Name", &db); - Category cat("Category Name"); - cat.setDatabase(&db); - - Package pack(Package::ScriptType, "file.name"); - pack.setCategory(&cat); + Package pack(Package::ScriptType, "file.name", &cat); Path expected; expected.append("Scripts"); @@ -115,16 +123,22 @@ TEST_CASE("script target path without category", M) { } TEST_CASE("full name", M) { - Database db("Database Name"); - - Category cat("Category Name"); + SECTION("no category") { + Package pack(Package::ScriptType, "file.name"); + REQUIRE(pack.fullName() == "file.name"); + } - Package pack(Package::ScriptType, "file.name"); - REQUIRE(pack.fullName() == "file.name"); + SECTION("with category") { + Category cat("Category Name"); + Package pack(Package::ScriptType, "file.name", &cat); + REQUIRE(pack.fullName() == "Category Name/file.name"); + } - pack.setCategory(&cat); - REQUIRE(pack.fullName() == "Category Name/file.name"); + SECTION("with database") { + Database db("Database Name"); + Category cat("Category Name", &db); + Package pack(Package::ScriptType, "file.name", &cat); - cat.setDatabase(&db); - REQUIRE(pack.fullName() == "Database Name/Category Name/file.name"); + REQUIRE(pack.fullName() == "Database Name/Category Name/file.name"); + } } diff --git a/test/registry.cpp b/test/registry.cpp @@ -10,11 +10,10 @@ static const char *M = "[registry]"; #define MAKE_PACKAGE \ Database db("Hello"); \ - Category cat("Hello"); \ - cat.setDatabase(&db); \ + Category cat("Hello", &db); \ Package pkg(Package::ScriptType, "Hello", &cat); \ Version *ver = new Version("1.0", &pkg); \ - Source *src = new Source(Source::GenericPlatform, "file", "url"); \ + Source *src = new Source(Source::GenericPlatform, "file", "url", ver); \ ver->addSource(src); \ pkg.addVersion(ver); @@ -42,9 +41,8 @@ TEST_CASE("query up to date pacakge", M) { TEST_CASE("bump version", M) { MAKE_PACKAGE - Version *ver2 = new Version("2.0"); - ver2->setPackage(&pkg); - ver2->addSource(new Source(Source::GenericPlatform, "file", "url")); + Version *ver2 = new Version("2.0", &pkg); + ver2->addSource(new Source(Source::GenericPlatform, "file", "url", ver2)); Registry reg; reg.push(&pkg); diff --git a/test/source.cpp b/test/source.cpp @@ -87,16 +87,14 @@ TEST_CASE("full name without version", M) { TEST_CASE("full name with version", M) { SECTION("with source name") { Version ver("1.0"); - Source source(Source::UnknownPlatform, "a", "b"); - source.setVersion(&ver); + Source source(Source::UnknownPlatform, "a", "b", &ver); REQUIRE(source.fullName() == "v1.0 (a)"); } SECTION("with source name") { Version ver("1.0"); - Source source(Source::UnknownPlatform, string(), "b"); - source.setVersion(&ver); + Source source(Source::UnknownPlatform, string(), "b", &ver); REQUIRE(source.fullName() == ver.fullName()); } @@ -104,18 +102,11 @@ TEST_CASE("full name with version", M) { TEST_CASE("source target path", M) { Database db("Database Name"); + Category cat("Category Name", &db); + Package pack(Package::ScriptType, "package name", &cat); + Version ver("1.0", &pack); - Category cat("Category Name"); - cat.setDatabase(&db); - - Package pack(Package::ScriptType, "package name"); - pack.setCategory(&cat); - - Version ver("1.0"); - ver.setPackage(&pack); - - Source source(Source::GenericPlatform, "file.name", "https://google.com"); - source.setVersion(&ver); + Source source(Source::GenericPlatform, "file.name", "url", &ver); Path expected; expected.append("Scripts"); diff --git a/test/version.cpp b/test/version.cpp @@ -84,20 +84,34 @@ TEST_CASE("version with 5 components", M) { } TEST_CASE("version full name", M) { - Version ver("1.0"); - REQUIRE(ver.fullName() == "v1.0"); + SECTION("no package") { + Version ver("1.0"); + REQUIRE(ver.fullName() == "v1.0"); + } + + SECTION("with package") { + Package pkg(Package::UnknownType, "file.name"); + Version ver("1.0", &pkg); - Package pkg(Package::UnknownType, "file.name"); - ver.setPackage(&pkg); - REQUIRE(ver.fullName() == "file.name v1.0"); + REQUIRE(ver.fullName() == "file.name v1.0"); + } - Category cat("Category Name"); - pkg.setCategory(&cat); - REQUIRE(ver.fullName() == "Category Name/file.name v1.0"); + SECTION("with category") { + Category cat("Category Name"); + Package pkg(Package::UnknownType, "file.name", &cat); + Version ver("1.0", &pkg); + + REQUIRE(ver.fullName() == "Category Name/file.name v1.0"); + } - Database db("Database Name"); - cat.setDatabase(&db); - REQUIRE(ver.fullName() == "Database Name/Category Name/file.name v1.0"); + SECTION("with database") { + Database db("Database Name"); + Category cat("Category Name", &db); + Package pkg(Package::UnknownType, "file.name", &cat); + Version ver("1.0", &pkg); + + REQUIRE(ver.fullName() == "Database Name/Category Name/file.name v1.0"); + } } TEST_CASE("add source", M) { @@ -105,7 +119,7 @@ TEST_CASE("add source", M) { CHECK(ver.sources().size() == 0); - Source *src = new Source(Source::GenericPlatform, "a", "b"); + Source *src = new Source(Source::GenericPlatform, "a", "b", &ver); ver.addSource(src); CHECK(ver.sources().size() == 1); @@ -114,10 +128,26 @@ TEST_CASE("add source", M) { REQUIRE(ver.source(0) == src); } +TEST_CASE("add owned source", M) { + MAKE_VERSION + + Version ver2("1"); + Source *src = new Source(Source::GenericPlatform, "a", "b", &ver2); + + try { + ver.addSource(src); + FAIL(); + } + catch(const reapack_error &e) { + delete src; + REQUIRE(string(e.what()) == "source belongs to another version"); + } +} + TEST_CASE("list files", M) { MAKE_VERSION - Source *src1 = new Source(Source::GenericPlatform, "file", "url"); + Source *src1 = new Source(Source::GenericPlatform, "file", "url", &ver); ver.addSource(src1); Path path1; @@ -132,7 +162,7 @@ TEST_CASE("list files", M) { TEST_CASE("drop sources for unknown platforms", M) { MAKE_VERSION - ver.addSource(new Source(Source::UnknownPlatform, "a", "b")); + ver.addSource(new Source(Source::UnknownPlatform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -141,9 +171,9 @@ TEST_CASE("drop sources for unknown platforms", M) { TEST_CASE("drop windows sources on os x", M) { MAKE_VERSION - ver.addSource(new Source(Source::WindowsPlatform, "a", "b")); - ver.addSource(new Source(Source::Win32Platform, "a", "b")); - ver.addSource(new Source(Source::Win64Platform, "a", "b")); + ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver)); + ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -151,7 +181,7 @@ TEST_CASE("drop windows sources on os x", M) { #ifdef __x86_64__ TEST_CASE("drop 32-bit sources on os x 64-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::Darwin32Platform, "a", "b")); + ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -159,16 +189,16 @@ TEST_CASE("drop 32-bit sources on os x 64-bit", M) { TEST_CASE("valid sources for os x 64-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::GenericPlatform, "a", "b")); - ver.addSource(new Source(Source::DarwinPlatform, "a", "b")); - ver.addSource(new Source(Source::Darwin64Platform, "a", "b")); + ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 3); } #else TEST_CASE("drop 64-bit sources on os x 32-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::Darwin64Platform, "a", "b")); + ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -176,9 +206,9 @@ TEST_CASE("drop 64-bit sources on os x 32-bit", M) { TEST_CASE("valid sources for os x 32-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::GenericPlatform, "a", "b")); - ver.addSource(new Source(Source::DarwinPlatform, "a", "b")); - ver.addSource(new Source(Source::Darwin32Platform, "a", "b")); + ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 3); } @@ -188,9 +218,9 @@ TEST_CASE("valid sources for os x 32-bit", M) { TEST_CASE("drop os x sources on windows", M) { MAKE_VERSION - ver.addSource(new Source(Source::DarwinPlatform, "a", "b")); - ver.addSource(new Source(Source::Darwin32Platform, "a", "b")); - ver.addSource(new Source(Source::Darwin64Platform, "a", "b")); + ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver)); + ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -198,7 +228,7 @@ TEST_CASE("drop os x sources on windows", M) { #ifdef _WIN64 TEST_CASE("drop 32-bit sources on windows 64-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::Win32Platform, "a", "b")); + ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -206,16 +236,16 @@ TEST_CASE("drop 32-bit sources on windows 64-bit", M) { TEST_CASE("valid sources for windows 64-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::GenericPlatform, "a", "b")); - ver.addSource(new Source(Source::WindowsPlatform, "a", "b")); - ver.addSource(new Source(Source::Win64Platform, "a", "b")); + ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 3); } #else TEST_CASE("drop 64-bit sources on windows 32-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::Win64Platform, "a", "b")); + ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 0); } @@ -223,9 +253,9 @@ TEST_CASE("drop 64-bit sources on windows 32-bit", M) { TEST_CASE("valid sources for windows 32-bit", M) { MAKE_VERSION - ver.addSource(new Source(Source::GenericPlatform, "a", "b")); - ver.addSource(new Source(Source::WindowsPlatform, "a", "b")); - ver.addSource(new Source(Source::Win32Platform, "a", "b")); + ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver)); + ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver)); REQUIRE(ver.sources().size() == 3); }