reapack

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

commit b16f81abb030c8a8863574f43b8c34ec3bbb79aa
parent c0949154fb4b271a12ecd78fb87e7732b35a0208
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Thu, 19 May 2016 13:55:47 -0400

support multiple main files per package

Diffstat:
Msrc/index_v1.cpp | 4++++
Msrc/registry.cpp | 37++++++++++++++++++-------------------
Msrc/registry.hpp | 5++---
Msrc/source.cpp | 3++-
Msrc/source.hpp | 5+++--
Msrc/transaction.cpp | 3+--
Msrc/version.cpp | 8++++----
Msrc/version.hpp | 4++--
Mtest/index_v1.cpp | 20+++++++++++++++-----
Mtest/indexes/v1/ReaPack/valid_index.xml | 3++-
Mtest/registry.cpp | 18++++++++++++------
Mtest/source.cpp | 12++++--------
Mtest/version.cpp | 21++++++++++++++-------
13 files changed, 83 insertions(+), 60 deletions(-)

diff --git a/src/index_v1.cpp b/src/index_v1.cpp @@ -174,5 +174,9 @@ void LoadSourceV1(TiXmlElement *node, Version *ver) Source *src = new Source(file, url, ver); src->setPlatform(platform); src->setTypeOverride(Package::getType(type)); + + if(node->Attribute("main")) + src->setMain(true); + ver->addSource(src); } diff --git a/src/registry.cpp b/src/registry.cpp @@ -57,13 +57,10 @@ Registry::Registry(const Path &path) // file queries m_getFiles = m_db.prepare("SELECT path FROM files WHERE entry = ?"); - m_getMainFile = m_db.prepare( - "SELECT path FROM files WHERE main = 1 AND entry = ? LIMIT 1" + m_getMainFiles = m_db.prepare( + "SELECT path FROM files WHERE main = 1 AND entry = ?" ); - m_setMainFile = m_db.prepare( - "UPDATE files SET main = 1 WHERE path = ? AND entry = ?" - ); - m_insertFile = m_db.prepare("INSERT INTO files VALUES(NULL, ?, ?, NULL)"); + m_insertFile = m_db.prepare("INSERT INTO files VALUES(NULL, ?, ?, ?)"); m_clearFiles = m_db.prepare( "DELETE FROM files WHERE entry = (" " SELECT id FROM entries WHERE remote = ? AND category = ? AND package = ?" @@ -155,9 +152,14 @@ auto Registry::push(const Version *ver, vector<Path> *conflicts) -> Entry } // register files - for(const Path &path : ver->files()) { + const auto &sources = ver->sources(); + for(auto it = sources.begin(); it != sources.end();) { + const Path &path = it->first; + const Source *src = it->second; + m_insertFile->bind(1, entryId); m_insertFile->bind(2, path.join('/')); + m_insertFile->bind(3, src->isMain()); try { m_insertFile->exec(); @@ -172,12 +174,9 @@ auto Registry::push(const Version *ver, vector<Path> *conflicts) -> Entry throw; } } - } - if(ver->mainSource()) { - m_setMainFile->bind(1, ver->mainSource()->targetPath().join('/')); - m_setMainFile->bind(2, entryId); - m_setMainFile->exec(); + // skip duplicate files + do { it++; } while(it != sources.end() && path == it->first); } if(hasConflicts) { @@ -268,20 +267,20 @@ set<Path> Registry::getFiles(const Entry &entry) const return list; } -string Registry::getMainFile(const Entry &entry) const +vector<string> Registry::getMainFiles(const Entry &entry) const { if(!entry) return {}; - string mainFile; + vector<string> files; - m_getMainFile->bind(1, entry.id); - m_getMainFile->exec([&] { - mainFile = m_getMainFile->stringColumn(0); - return false; + m_getMainFiles->bind(1, entry.id); + m_getMainFiles->exec([&] { + files.push_back(m_getMainFiles->stringColumn(0)); + return true; }); - return mainFile; + return files; } void Registry::forget(const Entry &entry) diff --git a/src/registry.hpp b/src/registry.hpp @@ -49,7 +49,7 @@ public: Entry getEntry(const Package *) const; std::vector<Entry> getEntries(const std::string &) const; std::set<Path> getFiles(const Entry &) const; - std::string getMainFile(const Entry &) const; + std::vector<std::string> getMainFiles(const Entry &) const; Entry push(const Version *, std::vector<Path> *conflicts = nullptr); void setPinned(const Entry &, bool pinned); void forget(const Entry &); @@ -70,8 +70,7 @@ private: Statement *m_forgetEntry; Statement *m_getFiles; - Statement *m_getMainFile; - Statement *m_setMainFile; + Statement *m_getMainFiles; Statement *m_insertFile; Statement *m_clearFiles; Statement *m_forgetFiles; diff --git a/src/source.cpp b/src/source.cpp @@ -23,7 +23,8 @@ using namespace std; Source::Source(const string &file, const string &url, const Version *ver) - : m_type(Package::UnknownType), m_file(file), m_url(url), m_version(ver) + : m_type(Package::UnknownType), m_file(file), m_url(url), m_main(false), + m_version(ver) { if(m_url.empty()) throw reapack_error("empty source url"); diff --git a/src/source.hpp b/src/source.hpp @@ -35,10 +35,10 @@ public: void setTypeOverride(Package::Type t) { m_type = t; } Package::Type typeOverride() const { return m_type; } - - bool isMain() const { return m_file.empty(); } const std::string &file() const; const std::string &url() const { return m_url; } + void setMain(bool main) { m_main = main; } + bool isMain() const { return m_main; } const Version *version() const { return m_version; } const Package *package() const; @@ -51,6 +51,7 @@ private: Package::Type m_type; std::string m_file; std::string m_url; + bool m_main; const Version *m_version; }; diff --git a/src/transaction.cpp b/src/transaction.cpp @@ -361,8 +361,7 @@ bool Transaction::runTasks() void Transaction::registerInHost(const bool add, const Registry::Entry &entry) { // don't actually do anything until commit() – which will calls registerQueued - const string &mainFile = m_registry->getMainFile(entry); - if(!mainFile.empty()) + for(const string &mainFile : m_registry->getMainFiles(entry)) m_regQueue.push({add, entry, mainFile}); } diff --git a/src/version.cpp b/src/version.cpp @@ -28,12 +28,12 @@ using namespace std; Version::Version() - : m_stable(true), m_time(), m_package(nullptr), m_mainSource(nullptr) + : m_stable(true), m_time(), m_package(nullptr) { } Version::Version(const string &str, const Package *pkg) - : m_time(), m_package(pkg), m_mainSource(nullptr) + : m_time(), m_package(pkg) { parse(str); } @@ -41,7 +41,7 @@ Version::Version(const string &str, const Package *pkg) Version::Version(const Version &o, const Package *pkg) : m_name(o.m_name), m_segments(o.m_segments), m_stable(o.m_stable), m_author(o.m_author), m_changelog(o.m_changelog), m_time(o.m_time), - m_package(pkg), m_mainSource(nullptr) + m_package(pkg) { } @@ -125,7 +125,7 @@ void Version::addSource(Source *source) m_sources.insert({path, source}); if(source->isMain()) - m_mainSource = source; + m_mainSources.push_back(source); } void Version::setChangelog(const string &changelog) diff --git a/src/version.hpp b/src/version.hpp @@ -64,7 +64,7 @@ public: void addSource(Source *source); const SourceMap &sources() const { return m_sources; } const Source *source(size_t) const; - const Source *mainSource() const { return m_mainSource; } + const SourceList &mainSources() const { return m_mainSources; } const std::set<Path> &files() const { return m_files; } @@ -91,7 +91,7 @@ private: std::tm m_time; const Package *m_package; - const Source *m_mainSource; + SourceList m_mainSources; SourceMap m_sources; std::set<Path> m_files; diff --git a/test/index_v1.cpp b/test/index_v1.cpp @@ -168,13 +168,23 @@ TEST_CASE("full index", M) { const Version *ver = pack->version(0); REQUIRE(ver->name() == "1.0"); - REQUIRE(ver->sources().size() == 1); + REQUIRE(ver->sources().size() == 2); REQUIRE(ver->changelog() == "Fixed a division by zero error."); - const Source *source = ver->source(0); - REQUIRE(source->platform() == Platform::GenericPlatform); - REQUIRE(source->file() == "test.lua"); - REQUIRE(source->url() == "https://google.com/"); + const Source *source1 = ver->source(1); + REQUIRE(source1->platform() == Platform::GenericPlatform); + REQUIRE(source1->file() == "test.lua"); + REQUIRE(source1->isMain()); + REQUIRE(source1->url() == "https://google.com/"); + + const Source *source2 = ver->source(0); + REQUIRE(source2->platform() == Platform::GenericPlatform); + REQUIRE(source2->file() == "background.png"); + REQUIRE_FALSE(source2->isMain()); + REQUIRE(source2->url() == "http://cfillion.tk/"); + + REQUIRE(ver->mainSources().size() == 1); + REQUIRE(ver->mainSources()[0] == source1); } TEST_CASE("read index metadata", M) { diff --git a/test/indexes/v1/ReaPack/valid_index.xml b/test/indexes/v1/ReaPack/valid_index.xml @@ -2,7 +2,8 @@ <category name="Category Name"> <reapack name="Hello World.lua" type="script"> <version name="1.0"> - <source platform="all" file="test.lua">https://google.com/</source> + <source platform="all" file="test.lua" main="true">https://google.com/</source> + <source platform="all" file="background.png">http://cfillion.tk/</source> <changelog>Fixed a division by zero error.</changelog> </version> </reapack> diff --git a/test/registry.cpp b/test/registry.cpp @@ -90,7 +90,6 @@ TEST_CASE("get file list", M) { reg.push(ver); const set<Path> &files = reg.getFiles(reg.getEntry(&pkg)); - REQUIRE(files == ver->files()); } @@ -162,17 +161,24 @@ TEST_CASE("file conflicts", M) { REQUIRE(reg.getEntry(&pkg).id == 0); // never installed } -TEST_CASE("get main file", M) { +TEST_CASE("get main files", M) { MAKE_PACKAGE Registry reg; - REQUIRE((reg.getMainFile({})).empty()); + REQUIRE((reg.getMainFiles({})).empty()); + + Source *main1 = new Source({}, "url", ver); + main1->setMain(true); + ver->addSource(main1); - Source *main = new Source({}, "url", ver); - ver->addSource(main); + Source *main2 = new Source({}, "url", ver); // duplicate file + main2->setMain(true); + ver->addSource(main2); const Registry::Entry &entry = reg.push(ver); - REQUIRE(reg.getMainFile(entry) == main->targetPath().join('/')); + + const vector<string> expected{main1->targetPath().join('/')}; + REQUIRE(reg.getMainFiles(entry) == expected); } TEST_CASE("pin registry entry", M) { diff --git a/test/source.cpp b/test/source.cpp @@ -42,15 +42,11 @@ TEST_CASE("empty file name and no package", M) { } TEST_CASE("main source", M) { - SECTION("with file name") { - const Source source("filename", "url"); - REQUIRE_FALSE(source.isMain()); - } + Source source("filename", "url"); + REQUIRE_FALSE(source.isMain()); - SECTION("without file name") { - const Source source({}, "url"); - REQUIRE(source.isMain()); - } + source.setMain(true); + REQUIRE(source.isMain()); } TEST_CASE("empty source url", M) { diff --git a/test/version.cpp b/test/version.cpp @@ -25,7 +25,7 @@ TEST_CASE("construct null version", M) { REQUIRE(ver.isStable()); REQUIRE(ver.displayTime().empty()); REQUIRE(ver.package() == nullptr); - REQUIRE(ver.mainSource() == nullptr); + REQUIRE(ver.mainSources().empty()); } TEST_CASE("parse version", M) { @@ -211,8 +211,8 @@ TEST_CASE("add source", M) { Source *src = new Source("a", "b", &ver); ver.addSource(src); - CHECK(ver.mainSource() == nullptr); CHECK(ver.sources().size() == 1); + CHECK(ver.mainSources().empty()); REQUIRE(src->version() == &ver); REQUIRE(ver.source(0) == src); @@ -234,13 +234,20 @@ TEST_CASE("add owned source", M) { } } -TEST_CASE("add main source", M) { +TEST_CASE("add main sources", M) { MAKE_VERSION - Source *src = new Source({}, "b", &ver); - ver.addSource(src); + Source *src1 = new Source({}, "b", &ver); + src1->setMain(true); + ver.addSource(src1); + + Source *src2 = new Source({}, "b", &ver); + src2->setMain(true); + ver.addSource(src2); - REQUIRE(ver.mainSource() == src); + REQUIRE(ver.mainSources().size() == 2); + REQUIRE(ver.mainSources()[0] == src1); + REQUIRE(ver.mainSources()[1] == src2); } TEST_CASE("duplicate sources", M) { @@ -330,7 +337,7 @@ TEST_CASE("copy version constructor", M) { REQUIRE(copy1.changelog() == original.changelog()); REQUIRE(copy1.displayTime() == original.displayTime()); REQUIRE(copy1.package() == nullptr); - REQUIRE(copy1.mainSource() == nullptr); + REQUIRE(copy1.mainSources().empty()); REQUIRE(copy1.sources().empty()); const Version copy2(original, &pkg);