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:
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);