Skip to content

Commit

Permalink
export index / import index
Browse files Browse the repository at this point in the history
  • Loading branch information
myrrc committed Jul 8, 2023
1 parent 7ece4e0 commit e0ea725
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 12 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ STRING(TOLOWER "${ARCH_NAME}" ARCH_NAME)

set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD "17")
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Expand Down
1 change: 0 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ add_library(reapack OBJECT
xml_$<IF:$<BOOL:${LIBXML2_FOUND}>,libxml2,tinyxml2>.cpp
)

target_compile_features(reapack PUBLIC cxx_std_17)
target_include_directories(reapack PRIVATE
${CMAKE_SOURCE_DIR}/vendor ${CMAKE_SOURCE_DIR}/vendor/reaper-sdk/sdk
${CMAKE_CURRENT_BINARY_DIR}
Expand Down
31 changes: 23 additions & 8 deletions src/archive_tasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "transaction.hpp"

#include <iomanip>
#include <fstream>
#include <sstream>

static const Path ARCHIVE_TOC("toc");
Expand Down Expand Up @@ -54,16 +55,11 @@ bool ExportTask::start()

std::vector<FileCompressor *> jobs;

for(const Remote &remote : g_reapack->config()->remotes.getEnabled()) {
bool addedRemote = false;
for(const Remote &remote : g_reapack->config()->remotes) {
toc << "REPO " << remote.toString() << '\n';
jobs.push_back(new FileCompressor(Index::pathFor(remote.name()), writer));

for(const Registry::Entry &entry : tx()->registry()->getEntries(remote.name())) {
if(!addedRemote) {
toc << "REPO " << remote.toString() << '\n';
jobs.push_back(new FileCompressor(Index::pathFor(remote.name()), writer));
addedRemote = true;
}

toc << "PACK "
<< quoted(entry.category) << '\x20'
<< quoted(entry.package) << '\x20'
Expand Down Expand Up @@ -107,3 +103,22 @@ void ExportTask::rollback()
{
FS::remove(m_path.temp());
}

void ExportIndexTask::commit()
{
std::ofstream index{m_path, std::ios::out | std::ios::trunc};
if (!index.good())
return tx()->receipt()->addError({"Error opening index file", m_path});

for(const Remote &remote : g_reapack->config()->remotes) {
index << "REPO " << remote.toString() << '\n';

for(const Registry::Entry &entry : tx()->registry()->getEntries(remote.name())) {
index << "PACK "
<< quoted(entry.category) << '\x20'
<< quoted(entry.package) << '\x20'
<< quoted(entry.version.toString()) << '\x20'
<< entry.flags << '\n';
}
}
}
34 changes: 34 additions & 0 deletions src/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,37 @@ void InstallTask::rollback()

m_fail = true;
}

InstallFromIndexTask::InstallFromIndexTask(PackageFromIndex&& pkg_, Transaction *tx)
: Task(tx), pkg(std::move(pkg_)) { }

bool InstallFromIndexTask::start()
{
const IndexPtr index = tx()->loadIndex({pkg.remote});
if(!index) return false;

const ErrorInfo err = {
String::format("%s/%s/%s v%s",
pkg.remote.name().c_str(), pkg.category.c_str(), pkg.name.c_str(), pkg.version.c_str()),
"Package cannot be found or is incompatible with your operating system"};

const Package *const pkg_handle = [&]() -> const Package * {
for(const Package *other : index->packages())
if(other->name() == pkg.name && other->category()->name() == pkg.category)
return other;
return nullptr;
}();

if(!pkg_handle) {
tx()->receipt()->addError(err);
return false;
} else if(version = pkg_handle->findVersion({pkg.version}); !version) {
tx()->receipt()->addError(err);
return false;
}
return true;
}

void InstallFromIndexTask::commit() {
tx()->install(version, pkg.flags);
}
83 changes: 80 additions & 3 deletions src/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,23 @@
#include "transaction.hpp"
#include "win32.hpp"

#include <fstream>
#include <iomanip>

static const Win32::char_type *ARCHIVE_FILTER =
L("ReaPack Offline Archive (*.ReaPackArchive)\0*.ReaPackArchive\0");
static const Win32::char_type *ARCHIVE_EXT = L("ReaPackArchive");
static const Win32::char_type *INDEX_FILTER =
L("ReaPack Index (*.txt)\0*.txt\0");
static const Win32::char_type *INDEX_EXT = L("txt");

enum {
ACTION_UNINSTALL = 80, ACTION_ABOUT, ACTION_REFRESH, ACTION_COPYURL,
ACTION_SELECT, ACTION_UNSELECT, ACTION_AUTOINSTALL_GLOBAL,
ACTION_AUTOINSTALL_OFF, ACTION_AUTOINSTALL_ON, ACTION_AUTOINSTALL,
ACTION_BLEEDINGEDGE, ACTION_PROMPTOBSOLETE, ACTION_SYNONYMS, ACTION_NETCONFIG,
ACTION_RESETCONFIG, ACTION_IMPORT_REPO, ACTION_IMPORT_ARCHIVE,
ACTION_EXPORT_ARCHIVE,
ACTION_EXPORT_ARCHIVE, ACTION_IMPORT_INDEX, ACTION_EXPORT_INDEX
};

enum { TIMER_ABOUT = 1, };
Expand Down Expand Up @@ -150,6 +156,13 @@ void Manager::onCommand(const int id, int)
case ACTION_EXPORT_ARCHIVE:
exportArchive();
break;
case ACTION_IMPORT_INDEX:
importIndex();
refresh();
break;
case ACTION_EXPORT_INDEX:
exportIndex();
break;
case ACTION_AUTOINSTALL:
toggle(m_autoInstall, g_reapack->config()->install.autoInstall);
break;
Expand Down Expand Up @@ -470,6 +483,9 @@ void Manager::importExport()
Menu menu;
menu.addAction("Import &repositories...", ACTION_IMPORT_REPO);
menu.addSeparator();
menu.addAction("Import index", ACTION_IMPORT_INDEX);
menu.addAction("Export index", ACTION_EXPORT_INDEX);
menu.addSeparator();
menu.addAction("Import offline archive...", ACTION_IMPORT_ARCHIVE);
menu.addAction("&Export offline archive...", ACTION_EXPORT_ARCHIVE);

Expand All @@ -492,7 +508,7 @@ void Manager::importArchive()
{
const char *title = "Import offline archive";

const std::string &path = FileDialog::getOpenFileName(handle(), instance(),
const std::string path = FileDialog::getOpenFileName(handle(), instance(),
title, Path::DATA.prependRoot(), ARCHIVE_FILTER, ARCHIVE_EXT);

if(path.empty())
Expand All @@ -510,7 +526,7 @@ void Manager::importArchive()

void Manager::exportArchive()
{
const std::string &path = FileDialog::getSaveFileName(handle(), instance(),
const std::string path = FileDialog::getSaveFileName(handle(), instance(),
"Export offline archive", Path::DATA.prependRoot(), ARCHIVE_FILTER, ARCHIVE_EXT);

if(!path.empty()) {
Expand All @@ -521,6 +537,67 @@ void Manager::exportArchive()
}
}

void Manager::importIndex()
{
Transaction * const tx = g_reapack->setupTransaction();
if(!tx) return;
Receipt * const receipt = tx->receipt();

const std::string path = FileDialog::getOpenFileName(handle(), instance(),
"Import index", Path::root(), INDEX_FILTER, INDEX_EXT);

std::ifstream index{path};
if(!index.good()) {
receipt->addError({"Error opening index file", path});
tx->runTasks();
return;
}

Remote remote;
std::string line;
std::vector<PackageFromIndex> packages;

while(std::getline(index, line)) {
switch(line[0]) {
case 'R':
if(remote = Remote::fromString(line.substr(5)); remote.isNull())
receipt->addError({"Error adding remote", remote.toString()});
else {
g_reapack->addSetRemote(remote);
// strange but above function doesn't fetch index files despite issuing same SynchronizeTask
tx->fetchIndexes({remote}, true);
}
break;
case 'P': {
auto& ref = packages.emplace_back(PackageFromIndex{remote});
std::istringstream{line.substr(5)}
>> quoted(ref.category) >> quoted(ref.name) >> quoted(ref.version)
>> ref.flags;
break;
}
default:
receipt->addError({line, "Invalid index entry"});
}
}

g_reapack->commitConfig(true); // runs tx

for(PackageFromIndex& pkg : packages)
tx->installFromIndex(std::move(pkg));
tx->runTasks();
}

void Manager::exportIndex()
{
const std::string path = FileDialog::getSaveFileName(handle(), instance(),
"Export index", Path::root(), INDEX_FILTER, INDEX_EXT);

if(Transaction *tx = g_reapack->setupTransaction()) {
tx->exportIndex(path);
tx->runTasks();
}
}

void Manager::launchBrowser()
{
const auto promptApply = [this] {
Expand Down
2 changes: 2 additions & 0 deletions src/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class Manager : public Dialog {
void setupNetwork();
void importArchive();
void exportArchive();
void importIndex();
void exportIndex();
void aboutRepo(bool focus = true);

void setChange(int);
Expand Down
27 changes: 27 additions & 0 deletions src/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,24 @@ class InstallTask : public Task {
std::unordered_set<ThreadTask *> m_waiting;
};

struct PackageFromIndex {
Remote remote;
std::string name, category, version;
int flags;
};

class InstallFromIndexTask : public Task {
public:
InstallFromIndexTask(PackageFromIndex &&, Transaction *);

bool start() override;
void commit() override;

private:
PackageFromIndex pkg;
const Version * version = nullptr;
};

class UninstallTask : public Task {
public:
UninstallTask(const Registry::Entry &, Transaction *);
Expand Down Expand Up @@ -142,4 +160,13 @@ class ExportTask : public Task {
TempPath m_path;
};

class ExportIndexTask : public Task {
public:
inline ExportIndexTask(std::string_view path, Transaction *tx): Task(tx), m_path(path) {}

protected:
void commit() final;
std::string m_path;
};

#endif
10 changes: 10 additions & 0 deletions src/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ void Transaction::install(const Version *ver, const Registry::Entry &oldEntry,
m_nextQueue.push(std::make_shared<InstallTask>(ver, flags, oldEntry, reader, this));
}

void Transaction::installFromIndex(PackageFromIndex&& pkg)
{
m_nextQueue.push(std::make_shared<InstallFromIndexTask>(std::move(pkg), this));
}

void Transaction::setFlags(const Registry::Entry &entry, const int flags)
{
m_nextQueue.push(std::make_shared<FlagsTask>(entry, flags, this));
Expand Down Expand Up @@ -142,6 +147,11 @@ void Transaction::exportArchive(const std::string &path)
m_nextQueue.push(std::make_shared<ExportTask>(path, this));
}

void Transaction::exportIndex(std::string_view path)
{
m_nextQueue.push(std::make_shared<ExportIndexTask>(path, this));
}

bool Transaction::runTasks()
{
do {
Expand Down
3 changes: 3 additions & 0 deletions src/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ class Transaction {
void install(const Version *, int flags = 0, const ArchiveReaderPtr & = nullptr);
void install(const Version *, const Registry::Entry &oldEntry,
int flags = false, const ArchiveReaderPtr & = nullptr);
void installFromIndex(PackageFromIndex&& pkg);
void setFlags(const Registry::Entry &, int flags);
void uninstall(const Remote &);
void uninstall(const Registry::Entry &);
void exportArchive(const std::string &path);
void exportIndex(std::string_view path);
bool runTasks();

bool isCancelled() const { return m_isCancelled; }
Expand All @@ -75,6 +77,7 @@ class Transaction {
protected:
friend SynchronizeTask;
friend InstallTask;
friend InstallFromIndexTask;
friend UninstallTask;

IndexPtr loadIndex(const Remote &);
Expand Down

0 comments on commit e0ea725

Please sign in to comment.