Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symlink to file:// repos by adding ?symlink suffix #58

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/download.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <cassert>

#include <boost/algorithm/string/replace.hpp>
#include <reaper_plugin_functions.h>

static const int DOWNLOAD_TIMEOUT = 15;
Expand Down Expand Up @@ -212,7 +213,13 @@ bool FileDownload::save()
return FS::remove(m_path.temp());
}

std::ostream *FileDownload::openStream()
CopyFileDownload::CopyFileDownload(const Path &target, const std::string &url,
const NetworkOpts &opts, int flags)
: FileDownload(target, url, opts, flags)
{
}

std::ostream *CopyFileDownload::openStream()
{
if(FS::open(m_stream, m_path.temp()))
return &m_stream;
Expand All @@ -222,7 +229,25 @@ std::ostream *FileDownload::openStream()
}
}

void FileDownload::closeStream()
void CopyFileDownload::closeStream()
{
m_stream.close();
}

SymlinkFileDownload::SymlinkFileDownload(const Path &target, const std::string &url,
const NetworkOpts &opts, int flags)
: FileDownload(target, url, opts, flags)
{
}

bool SymlinkFileDownload::run()
{
std::string local_path = m_url;
boost::algorithm::replace_all(local_path, "file://", "");
return FS::symlink(Path(local_path), m_path.temp());
}

std::ostream *SymlinkFileDownload::openStream()
{
return nullptr;
}
24 changes: 22 additions & 2 deletions src/download.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class Download : public ThreadTask {
virtual std::ostream *openStream() = 0;
virtual void closeStream() {}

std::string m_url;

private:
struct WriteContext {
std::ostream *stream;
Expand All @@ -77,7 +79,6 @@ class Download : public ThreadTask {
static size_t WriteData(char *, size_t, size_t, void *);
static int UpdateProgress(void *, double, double, double, double);

std::string m_url;
std::string m_expectedChecksum;
NetworkOpts m_opts;
int m_flags;
Expand All @@ -104,13 +105,32 @@ class FileDownload : public Download {
const TempPath &path() const { return m_path; }
bool save();

protected:
TempPath m_path;
};

class CopyFileDownload : public FileDownload {
public:
CopyFileDownload(const Path &target, const std::string &url,
const NetworkOpts &, int flags = 0);

protected:
std::ostream *openStream() override;
void closeStream() override;

private:
TempPath m_path;
std::ofstream m_stream;
};

class SymlinkFileDownload : public FileDownload {
public:
SymlinkFileDownload(const Path &target, const std::string &url,
const NetworkOpts &, int flags = 0);

bool run() override;

protected:
std::ostream *openStream() override;
};

#endif
14 changes: 14 additions & 0 deletions src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,20 @@ bool FS::rename(const Path &from, const Path &to)
return !func(nativePath(from).c_str(), nativePath(to).c_str());
}

bool FS::symlink(const Path &target, const Path &link)
{
mkdir(link.dirname());

const auto &nativeTarget = nativePath(target);
const auto &nativeLink = nativePath(link);

#ifdef _WIN32
return CreateSymbolicLink(nativeLink.c_str(), nativeTarget.c_str(), 0x0);
#else
return !::symlink(nativeTarget.c_str(), nativeLink.c_str());
#endif
}

bool FS::remove(const Path &path)
{
const auto &fullPath = nativePath(path);
Expand Down
1 change: 1 addition & 0 deletions src/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace FS {
bool write(const Path &, const std::string &);
bool rename(const TempPath &);
bool rename(const Path &, const Path &);
bool symlink(const Path &, const Path &);
bool remove(const Path &);
bool removeRecursive(const Path &);
bool mtime(const Path &, time_t *);
Expand Down
8 changes: 4 additions & 4 deletions src/index_v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

static void LoadMetadataV1(XmlNode , Metadata *);
static void LoadCategoryV1(XmlNode , Index *);
static void LoadPackageV1(XmlNode , Category *);
static void LoadPackageV1(XmlNode , Category *, Index *);
static void LoadVersionV1(XmlNode , Package *);
static void LoadSourceV1(XmlNode , Version *);

Expand Down Expand Up @@ -75,18 +75,18 @@ void LoadCategoryV1(XmlNode catNode, Index *ri)

for(XmlNode packNode = catNode.firstChild("reapack");
packNode; packNode = packNode.nextSibling("reapack"))
LoadPackageV1(packNode, cat);
LoadPackageV1(packNode, cat, ri);

if(ri->addCategory(cat))
ptr.release();
}

void LoadPackageV1(XmlNode packNode, Category *cat)
void LoadPackageV1(XmlNode packNode, Category *cat, Index *ri)
{
const XmlString &type = packNode.attribute("type"),
&name = packNode.attribute("name");

Package *pack = new Package(Package::getType(type.value_or("")), name.value_or(""), cat);
Package *pack = new Package(Package::getType(type.value_or("")), name.value_or(""), cat, ri->name());
std::unique_ptr<Package> ptr(pack);

if(const XmlString &desc = packNode.attribute("desc"))
Expand Down
18 changes: 16 additions & 2 deletions src/install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@
#include "filesystem.hpp"
#include "index.hpp"
#include "reapack.hpp"
#include "remote.hpp"
#include "transaction.hpp"

#include <boost/algorithm/string/predicate.hpp>

InstallTask::InstallTask(const Version *ver, const int flags,
const Registry::Entry &re, const ArchiveReaderPtr &reader, Transaction *tx)
: Task(tx), m_version(ver), m_flags(flags), m_oldEntry(std::move(re)), m_reader(reader),
m_fail(false), m_index(ver->package()->category()->index()->shared_from_this())
{
Remote r = g_reapack->remote(ver->package()->remote());
this->m_symlink = boost::algorithm::starts_with(r.url(), "file://")
&& boost::algorithm::ends_with(r.url(), "?symlink");
}

bool InstallTask::start()
Expand Down Expand Up @@ -71,8 +77,16 @@ bool InstallTask::start()
}
else {
const NetworkOpts &opts = g_reapack->config()->network;
FileDownload *dl = new FileDownload(targetPath, src->url(), opts);
dl->setExpectedChecksum(src->checksum());
FileDownload *dl;

if(m_symlink) {
dl = new SymlinkFileDownload(targetPath, src->url(), opts);
}
else {
dl = new CopyFileDownload(targetPath, src->url(), opts);
dl->setExpectedChecksum(src->checksum());
}

push(dl, dl->path());
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ const std::string &Package::displayName(const std::string &name, const std::stri
return desc.empty() ? name : desc;
}

Package::Package(const Type type, const std::string &name, const Category *cat)
: m_category(cat), m_type(type), m_name(name)
Package::Package(const Type type, const std::string &name, const Category *cat, const std::string &remote)
: m_category(cat), m_type(type), m_name(name), m_remote(remote)
{
if(m_name.empty())
throw reapack_error("empty package name");
Expand Down
4 changes: 3 additions & 1 deletion src/package.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ class Package {
static const char *displayType(Type);
static const std::string &displayName(const std::string &name, const std::string &desc);

Package(const Type, const std::string &name, const Category *);
Package(const Type, const std::string &name, const Category *, const std::string &remote);
~Package();

const Category *category() const { return m_category; }
Type type() const { return m_type; }
std::string displayType() const { return displayType(m_type); }
const std::string &name() const { return m_name; }
const std::string &remote() const { return m_remote; }
std::string fullName() const;
void setDescription(const std::string &d) { m_desc = d; }
const std::string &description() const { return m_desc; }
Expand Down Expand Up @@ -80,6 +81,7 @@ class Package {
Type m_type;
std::string m_name;
std::string m_desc;
std::string m_remote;
Metadata m_metadata;
std::set<const Version *, CompareVersion> m_versions;

Expand Down
2 changes: 1 addition & 1 deletion src/reapack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ void ReaPack::registerSelf()
// hard-coding galore!
Index ri("ReaPack");
Category cat("Extensions", &ri);
Package pkg(Package::ExtensionType, "ReaPack.ext", &cat);
Package pkg(Package::ExtensionType, "ReaPack.ext", &cat, "ReaPack");
Version ver(REAPACK_VERSION, &pkg);
ver.setAuthor("cfillion");
ver.addSource(new Source(REAPACK_FILENAME, "dummy url", &ver));
Expand Down
2 changes: 1 addition & 1 deletion src/synchronize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ bool SynchronizeTask::start()
if(!m_stale && mtime && (!threshold || mtime > now - threshold))
return true;

auto dl = new FileDownload(m_indexPath, m_remote.url(),
auto dl = new CopyFileDownload(m_indexPath, m_remote.url(),
netConfig, Download::NoCacheFlag);
dl->setName(m_remote.name());

Expand Down
1 change: 1 addition & 0 deletions src/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class InstallTask : public Task {
int m_flags;
Registry::Entry m_oldEntry;
ArchiveReaderPtr m_reader;
bool m_symlink;

bool m_fail;
IndexPtr m_index; // keep in memory
Expand Down
12 changes: 6 additions & 6 deletions test/index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ TEST_CASE("future version", M) {
TEST_CASE("add a category", M) {
Index ri("a");
Category *cat = new Category("a", &ri);
Package *pack = new Package(Package::ScriptType, "name", cat);
Package *pack = new Package(Package::ScriptType, "name", cat, "remote");
Version *ver = new Version("1", pack);
Source *source = new Source({}, "google.com", ver);

Expand Down Expand Up @@ -134,7 +134,7 @@ TEST_CASE("drop empty category", M) {
TEST_CASE("add a package", M) {
Index ri("a");
Category cat("a", &ri);
Package *pack = new Package(Package::ScriptType, "name", &cat);
Package *pack = new Package(Package::ScriptType, "name", &cat, "remote");
Version *ver = new Version("1", pack);
ver->addSource(new Source({}, "google.com", ver));
pack->addVersion(ver);
Expand All @@ -151,7 +151,7 @@ TEST_CASE("add a package", M) {

TEST_CASE("add owned package", M) {
Category cat1("a", nullptr);
Package *pack = new Package(Package::ScriptType, "name", &cat1);
Package *pack = new Package(Package::ScriptType, "name", &cat1, "remote");

try {
Category cat2("b", nullptr);
Expand All @@ -166,14 +166,14 @@ TEST_CASE("add owned package", M) {

TEST_CASE("drop empty package", M) {
Category cat("a", nullptr);
const Package pkg(Package::ScriptType, "name", &cat);
const Package pkg(Package::ScriptType, "name", &cat, "remote");
REQUIRE_FALSE(cat.addPackage(&pkg));
REQUIRE(cat.packages().empty());
}

TEST_CASE("drop unknown package", M) {
Category cat("a", nullptr);
const Package pkg(Package::UnknownType, "name", &cat);
const Package pkg(Package::UnknownType, "name", &cat, "remote");
REQUIRE_FALSE(cat.addPackage(&pkg));
REQUIRE(cat.packages().size() == 0);
}
Expand Down Expand Up @@ -217,7 +217,7 @@ TEST_CASE("set index name", M) {
TEST_CASE("find package", M) {
Index ri("index name");
Category *cat = new Category("cat", &ri);
Package *pack = new Package(Package::ScriptType, "pkg", cat);
Package *pack = new Package(Package::ScriptType, "pkg", cat, "remote");
Version *ver = new Version("1", pack);
Source *source = new Source({}, "google.com", ver);

Expand Down
Loading