Using parsed URLs for packages

This commit is contained in:
Matthias Koefferlein 2023-10-29 16:04:12 +01:00
parent bd785279ef
commit 6dec3b0348
13 changed files with 98 additions and 205 deletions

View File

@ -21,6 +21,7 @@
*/
#include "laySalt.h"
#include "laySaltParsedURL.h"
#include "tlString.h"
#include "tlFileUtils.h"
@ -492,16 +493,18 @@ Salt::create_grain (const SaltGrain &templ, SaltGrain &target, double timeout, t
// otherwise download from the URL using Git or SVN
if (templ.protocol () == Git) {
lay::SaltParsedURL purl (templ.url ());
if (purl.protocol () == Git) {
#if defined(HAVE_GIT2)
tl::info << QObject::tr ("Downloading package from '%1' to '%2' using Git protocol ..").arg (tl::to_qstring (templ.url ())).arg (tl::to_qstring (target.path ()));
res = tl::GitObject::download (templ.url (), target.path (), templ.branch (), timeout, callback);
res = tl::GitObject::download (templ.url (), target.path (), purl.subfolder (), purl.branch (), timeout, callback);
#else
throw tl::Exception (tl::to_string (QObject::tr ("Unable to install package '%1' - git protocol not compiled in").arg (tl::to_qstring (target.name ()))));
#endif
} else if (templ.protocol () == WebDAV || templ.protocol () == DefaultProtocol) {
} else if (purl.protocol () == WebDAV || purl.protocol () == DefaultProtocol) {
tl::info << QObject::tr ("Downloading package from '%1' to '%2' using SVN/WebDAV protocol ..").arg (tl::to_qstring (templ.url ())).arg (tl::to_qstring (target.path ()));
res = tl::WebDAVObject::download (templ.url (), target.path (), timeout, callback);

View File

@ -23,6 +23,7 @@
#include "laySaltController.h"
#include "laySaltManagerDialog.h"
#include "laySaltDownloadManager.h"
#include "laySaltParsedURL.h"
#include "layConfig.h"
#include "layMainWindow.h"
#include "layQtTools.h"
@ -202,40 +203,18 @@ SaltController::install_packages (const std::vector<std::string> &packages, bool
}
}
if (n.find ("http:") == 0 || n.find ("https:") == 0 || n.find ("file:") == 0 || n[0] == '/' || n[0] == '\\') {
lay::SaltParsedURL purl (n);
const std::string &url = purl.url ();
if (url.find ("http:") == 0 || url.find ("https:") == 0 || url.find ("file:") == 0 || url[0] == '/' || url[0] == '\\') {
// its a URL
manager.register_download (std::string (), std::string (), n, DefaultProtocol, std::string (), v);
} else if (n.find ("git@") == 0) {
// git protocol:
// "git@<url>"
// "git@<url>[<branch>]"
std::string url (n, 4);
size_t br = url.find ("[");
std::string branch;
if (br != std::string::npos && url.back () == ']') {
branch = std::string (url, br + 1, url.size () - br - 2);
url = std::string (url, 0, br);
}
manager.register_download (std::string (), std::string (), url, Git, branch, v);
} else if (n.find ("svn@") == 0) {
// svn protocol:
// "svn@<url>"
std::string url (n, 4);
// its a URL
manager.register_download (std::string (), std::string (), url, WebDAV, std::string (), v);
manager.register_download (std::string (), std::string (), n, v);
} else {
// its a plain name
manager.register_download (n, std::string (), std::string (), DefaultProtocol, std::string (), v);
manager.register_download (n, std::string (), std::string (), v);
}

View File

@ -58,7 +58,7 @@ ConfirmationDialog::ConfirmationDialog (QWidget *parent)
}
void
ConfirmationDialog::add_info (const std::string &name, bool update, const std::string &version, const std::string &url, Protocol protocol, const std::string &branch)
ConfirmationDialog::add_info (const std::string &name, bool update, const std::string &version, const std::string &url)
{
QTreeWidgetItem *item = new QTreeWidgetItem (list);
m_items_by_name.insert (std::make_pair (name, item));
@ -68,18 +68,7 @@ ConfirmationDialog::add_info (const std::string &name, bool update, const std::s
item->setText (0, tl::to_qstring (name));
item->setText (1, update ? tr ("UPDATE") : tr ("INSTALL"));
item->setText (2, tl::to_qstring (version));
if (protocol == WebDAV) {
item->setText (3, tl::to_qstring ("svn@" + url));
} else if (protocol == Git) {
if (branch.empty ()) {
item->setText (3, tl::to_qstring ("git@" + url));
} else {
item->setText (3, tl::to_qstring ("git@" + url + "[" + branch + "]"));
}
} else {
item->setText (3, tl::to_qstring (url));
}
item->setText (3, tl::to_qstring (url));
for (int column = 0; column < list->colorCount (); ++column) {
item->setData (column, Qt::ForegroundRole, QVariant (QBrush (update ? QColor (Qt::blue) : QColor (Qt::black))));
@ -180,9 +169,9 @@ SaltDownloadManager::SaltDownloadManager ()
}
void
SaltDownloadManager::register_download (const std::string &name, const std::string &token, const std::string &url, Protocol protocol, const std::string &branch, const std::string &version)
SaltDownloadManager::register_download (const std::string &name, const std::string &token, const std::string &url, const std::string &version)
{
m_registry.push_back (Descriptor (name, token, url, protocol, branch, version));
m_registry.push_back (Descriptor (name, token, url, version));
}
void
@ -255,7 +244,7 @@ SaltDownloadManager::compute_list (const lay::Salt &salt, const lay::Salt &salt_
if (tl::verbosity() >= 20) {
tl::log << "Considering for update as dependency: " << d->name << " (" << d->version << ") with URL " << d->url;
}
m_registry.push_back (Descriptor (d->name, std::string (), d->url, d->protocol, d->branch, d->version));
m_registry.push_back (Descriptor (d->name, std::string (), d->url, d->version));
} else {
if (tl::verbosity() >= 20) {
@ -268,7 +257,7 @@ SaltDownloadManager::compute_list (const lay::Salt &salt, const lay::Salt &salt_
if (tl::verbosity() >= 20) {
tl::log << "Considering for download as dependency: " << d->name << " (" << d->version << ") with URL " << d->url;
}
m_registry.push_back (Descriptor (d->name, std::string (), d->url, d->protocol, d->branch, d->version));
m_registry.push_back (Descriptor (d->name, std::string (), d->url, d->version));
}
@ -341,7 +330,8 @@ SaltDownloadManager::fetch_missing (const lay::Salt &salt, const lay::Salt &salt
}
try {
p->grain = SaltGrain::from_url (p->url, p->protocol, p->branch);
// @@@ Take from repo index for Git protocol?
p->grain = SaltGrain::from_url (p->url);
} catch (tl::Exception &ex) {
throw tl::Exception (tl::to_string (QObject::tr ("Error fetching spec file for package '%1': %2").arg (tl::to_qstring (p->name)).arg (tl::to_qstring (ex.msg ()))));
}
@ -398,7 +388,7 @@ SaltDownloadManager::make_confirmation_dialog (QWidget *parent, const lay::Salt
const lay::SaltGrain *g = salt.grain_by_name (p->name);
if (g) {
// \342\206\222 is UTF-8 "right arrow"
dialog->add_info (p->name, true, g->version () + " \342\206\222 " + p->version, p->url, p->protocol, p->branch);
dialog->add_info (p->name, true, g->version () + " \342\206\222 " + p->version, p->url);
}
}
@ -406,7 +396,7 @@ SaltDownloadManager::make_confirmation_dialog (QWidget *parent, const lay::Salt
for (std::vector<Descriptor>::const_iterator p = m_registry.begin (); p != m_registry.end (); ++p) {
const lay::SaltGrain *g = salt.grain_by_name (p->name);
if (!g) {
dialog->add_info (p->name, false, p->version, p->url, p->protocol, p->branch);
dialog->add_info (p->name, false, p->version, p->url);
}
}

View File

@ -53,7 +53,7 @@ Q_OBJECT
public:
ConfirmationDialog (QWidget *parent);
void add_info (const std::string &name, bool update, const std::string &version, const std::string &url, Protocol protocol, const std::string &branch);
void add_info (const std::string &name, bool update, const std::string &version, const std::string &url);
bool is_confirmed () const { return m_confirmed; }
bool is_cancelled () const { return m_cancelled; }
@ -108,7 +108,7 @@ public:
*
* The target directory can be empty. In this case, the downloader will pick an appropriate one.
*/
void register_download (const std::string &name, const std::string &token, const std::string &url, Protocol protocol, const std::string &branch, const std::string &version);
void register_download (const std::string &name, const std::string &token, const std::string &url, const std::string &version);
/**
* @brief Computes the dependencies after all required packages have been registered
@ -145,8 +145,8 @@ public:
private:
struct Descriptor
{
Descriptor (const std::string &_name, const std::string &_token, const std::string &_url, Protocol _protocol, const std::string &_branch, const std::string &_version)
: name (_name), token (_token), url (_url), protocol (_protocol), branch (_branch), version (_version), downloaded (false)
Descriptor (const std::string &_name, const std::string &_token, const std::string &_url, const std::string &_version)
: name (_name), token (_token), url (_url), version (_version), downloaded (false)
{ }
bool operator< (const Descriptor &other) const
@ -170,8 +170,6 @@ private:
std::string name;
std::string token;
std::string url;
Protocol protocol;
std::string branch;
std::string version;
bool downloaded;
lay::SaltGrain grain;

View File

@ -22,6 +22,7 @@
#include "laySaltGrain.h"
#include "laySaltController.h"
#include "laySaltParsedURL.h"
#include "tlString.h"
#include "tlXMLParser.h"
#include "tlHttpStream.h"
@ -44,7 +45,7 @@ namespace lay
static const std::string grain_filename = "grain.xml";
SaltGrain::SaltGrain ()
: m_protocol (DefaultProtocol), m_hidden (false)
: m_hidden (false)
{
// .. nothing yet ..
}
@ -68,9 +69,7 @@ SaltGrain::operator== (const SaltGrain &other) const
m_license == other.m_license &&
m_hidden == other.m_hidden &&
m_authored_time == other.m_authored_time &&
m_installed_time == other.m_installed_time &&
m_protocol == other.m_protocol &&
m_branch == other.m_branch
m_installed_time == other.m_installed_time
;
}
@ -116,18 +115,6 @@ SaltGrain::set_url (const std::string &u)
m_url = u;
}
void
SaltGrain::set_branch (const std::string &b)
{
m_branch = b;
}
void
SaltGrain::set_protocol (const Protocol &p)
{
m_protocol = p;
}
void
SaltGrain::set_title (const std::string &t)
{
@ -410,30 +397,6 @@ struct ImageConverter
}
};
struct ProtocolConverter
{
std::string to_string (const Protocol &protocol) const
{
if (protocol == lay::WebDAV) {
return std::string ("svn");
} else if (protocol == lay::Git) {
return std::string ("git");
} else {
return std::string ();
}
}
void from_string (const std::string &s, Protocol &res) const
{
res = lay::DefaultProtocol;
if (s == "svn" || s == "SVN" || s == "WebDAV") {
res = lay::WebDAV;
} else if (s == "git" || s == "Git" || s == "GIT") {
res = lay::Git;
}
}
};
static tl::XMLElementList *sp_xml_elements = 0;
tl::XMLElementList &
@ -450,8 +413,6 @@ SaltGrain::xml_elements ()
tl::make_member (&SaltGrain::doc, &SaltGrain::set_doc, "doc") +
tl::make_member (&SaltGrain::doc_url, &SaltGrain::set_doc_url, "doc-url") +
tl::make_member (&SaltGrain::url, &SaltGrain::set_url, "url") +
tl::make_member (&SaltGrain::branch, &SaltGrain::set_branch, "branch") +
tl::make_member (&SaltGrain::protocol, &SaltGrain::set_protocol, "protocol", ProtocolConverter ()) +
tl::make_member (&SaltGrain::license, &SaltGrain::set_license, "license") +
tl::make_member (&SaltGrain::author, &SaltGrain::set_author, "author") +
tl::make_member (&SaltGrain::author_contact, &SaltGrain::set_author_contact, "author-contact") +
@ -462,8 +423,6 @@ SaltGrain::xml_elements ()
tl::make_element (&SaltGrain::begin_dependencies, &SaltGrain::end_dependencies, &SaltGrain::add_dependency, "depends",
tl::make_member (&SaltGrainDependency::name, "name") +
tl::make_member (&SaltGrainDependency::url, "url") +
tl::make_member (&SaltGrainDependency::protocol, "protocol", ProtocolConverter ()) +
tl::make_member (&SaltGrainDependency::branch, "branch") +
tl::make_member (&SaltGrainDependency::version, "version")
)
);
@ -550,14 +509,17 @@ SaltGrain::from_path (const std::string &path)
}
tl::InputStream *
SaltGrain::stream_from_url (std::string &url, Protocol protocol, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
SaltGrain::stream_from_url (std::string &generic_url, double timeout, tl::InputHttpStreamCallback *callback)
{
if (url.empty ()) {
if (generic_url.empty ()) {
throw tl::Exception (tl::to_string (QObject::tr ("No download link available")));
}
lay::SaltParsedURL purl (generic_url);
const std::string &url = purl.url ();
// base relative URL's on the salt mine URL
if (url.find ("http:") != 0 && url.find ("https:") != 0 && url.find ("file:") != 0 && !url.empty() && url[0] != '/' && url[0] != '\\' && lay::SaltController::instance ()) {
if (purl.protocol () == lay::DefaultProtocol && url.find ("http:") != 0 && url.find ("https:") != 0 && url.find ("file:") != 0 && !url.empty() && url[0] != '/' && url[0] != '\\' && lay::SaltController::instance ()) {
// replace the last component ("repository.xml") by the given path
QUrl sami_url (tl::to_qstring (lay::SaltController::instance ()->salt_mine_url ()));
@ -567,15 +529,16 @@ SaltGrain::stream_from_url (std::string &url, Protocol protocol, const std::stri
}
sami_url.setPath (path_comp.join (QString::fromUtf8 ("/")));
url = tl::to_string (sami_url.toString ());
// return the full path as a file path, not an URL
generic_url = tl::to_string (sami_url.toString ());
}
if (url.find ("http:") == 0 || url.find ("https:") == 0) {
if (protocol == lay::Git) {
if (purl.protocol () == lay::Git) {
#if defined(HAVE_GIT2)
return tl::GitObject::download_item (url, SaltGrain::spec_file (), branch, timeout, callback);
return tl::GitObject::download_item (url, SaltGrain::spec_file (), purl.subfolder (), purl.branch (), timeout, callback);
#else
throw tl::Exception (tl::to_string (QObject::tr ("Cannot download from Git - Git support not compiled in")));
#endif
@ -591,10 +554,10 @@ SaltGrain::stream_from_url (std::string &url, Protocol protocol, const std::stri
}
SaltGrain
SaltGrain::from_url (const std::string &url_in, Protocol protocol, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
SaltGrain::from_url (const std::string &url_in, double timeout, tl::InputHttpStreamCallback *callback)
{
std::string url = url_in;
std::unique_ptr<tl::InputStream> stream (stream_from_url (url, protocol, branch, timeout, callback));
std::unique_ptr<tl::InputStream> stream (stream_from_url (url, timeout, callback));
SaltGrain g;
g.load (*stream);

View File

@ -39,15 +39,6 @@ namespace tl
namespace lay
{
/**
* @brief An enum describing the protocol to use for download
*/
enum Protocol {
DefaultProtocol = 0,
WebDAV = 1,
Git = 2
};
/**
* @brief A descriptor for one dependency
* A dependency can be specified either through a name (see name property)
@ -59,13 +50,10 @@ enum Protocol {
struct SaltGrainDependency
{
SaltGrainDependency ()
: protocol (DefaultProtocol)
{ }
std::string name;
std::string url;
Protocol protocol;
std::string branch;
std::string version;
bool operator== (const SaltGrainDependency &other) const
@ -356,32 +344,6 @@ public:
*/
void set_url (const std::string &u);
/**
* @brief Gets the download protocol
*/
const Protocol &protocol () const
{
return m_protocol;
}
/**
* @brief Sets the download protocol
*/
void set_protocol (const Protocol &p);
/**
* @brief Gets the Git branch
*/
const std::string &branch () const
{
return m_branch;
}
/**
* @brief Sets the Git branch
*/
void set_branch (const std::string &b);
/**
* @brief Gets a value indicating whether the grain is hidden
* A grain can be hidden (in Salt.Mine) if it's a pure dependency package
@ -507,18 +469,16 @@ public:
* This method will return a grain constructed from the downloaded data.
* The data is read from "URL/grain.xml". This method will throw an
* exception if an error occurs during reading.
* protocol is the protocol to use and branch the Git branch.
*/
static SaltGrain from_url (const std::string &url, Protocol protocol, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
static SaltGrain from_url (const std::string &url, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
/**
* @brief Returns a stream prepared for downloading the grain
* The stream is a new'd object and needs to be deleted by the caller.
* "url" is the download URL on input and gets modified to match the
* actual URL if it is a relative one.
* protocol is the protocol to use and branch the Git branch.
*/
static tl::InputStream *stream_from_url (std::string &url, Protocol protocol, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
static tl::InputStream *stream_from_url (std::string &url, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
/**
* @brief Gets the name of the spec file ("grain.xml")
@ -542,8 +502,6 @@ private:
std::string m_author;
std::string m_author_contact;
std::string m_license;
Protocol m_protocol;
std::string m_branch;
bool m_hidden;
QDateTime m_authored_time, m_installed_time;
QImage m_icon, m_screenshot;

View File

@ -305,6 +305,7 @@ SaltGrainDetailsTextWidget::details_text ()
if (! d->url.empty ()) {
stream << " - ";
stream << "[" << tl::to_qstring (tl::escaped_to_html (d->url)) << "]<br/>";
// @@@ TODO: protocol and branch
}
}
stream << "</p>";

View File

@ -178,6 +178,7 @@ SaltGrainPropertiesDialog::update_controls ()
dependency_changed (item, 0);
item->setData (1, Qt::UserRole, tl::to_qstring (d->version));
dependency_changed (item, 1);
// @@@ TODO: protocol and branch?
item->setData (2, Qt::UserRole, tl::to_qstring (d->url));
dependency_changed (item, 2);
@ -244,6 +245,7 @@ SaltGrainPropertiesDialog::update_data ()
dep.name = tl::to_string (name);
dep.version = tl::to_string (version);
dep.url = tl::to_string (url);
// @@@ TODO: set protocol and branch
m_grain.dependencies ().push_back (dep);
}
@ -584,9 +586,10 @@ SaltGrainPropertiesDialog::accept ()
}
if (!d->url.empty ()) {
// @@@ TODO: only do for SVN repo
SaltGrain gdep;
try {
gdep = SaltGrain::from_url (d->url, d->protocol, d->branch);
gdep = SaltGrain::from_url (d->url);
if (gdep.name () != d->name) {
dependencies_alert->error () << tr ("Package name obtained from download URL is not the expected name.") << tl::endl
<< tr ("Downloaded name: ") << gdep.name () << tl::endl

View File

@ -683,7 +683,7 @@ BEGIN_PROTECTED
SaltGrain *g = model->grain_from_index (index);
// NOTE: checking for valid_name prevents bad entries inside the download list
if (g && model->is_marked (g->name ()) && SaltGrain::valid_name (g->name ())) {
manager.register_download (g->name (), g->token (), g->url (), g->protocol (), g->branch (), g->version ());
manager.register_download (g->name (), g->token (), g->url (), g->version ());
any = true;
}
}
@ -1190,17 +1190,13 @@ SaltManagerDialog::get_remote_grain_info (lay::SaltGrain *g, SaltGrainDetailsTex
details->setHtml (html);
std::string url = g->url ();
Protocol protocol = g->protocol ();
std::string branch = g->branch ();
m_downloaded_grain.reset (new SaltGrain ());
m_downloaded_grain->set_url (url);
m_downloaded_grain->set_protocol (protocol);
m_downloaded_grain->set_branch (branch);
// NOTE: stream_from_url may modify the URL, hence we set it again
ProcessEventCallback callback;
m_downloaded_grain_reader.reset (SaltGrain::stream_from_url (url, protocol, branch, 60.0, &callback));
m_downloaded_grain_reader.reset (SaltGrain::stream_from_url (url, 60.0, &callback));
m_downloaded_grain->set_url (url);
tl::InputHttpStream *http = dynamic_cast<tl::InputHttpStream *> (m_downloaded_grain_reader->base ());

View File

@ -29,6 +29,15 @@
namespace lay
{
/**
* @brief An enum describing the protocol to use for download
*/
enum Protocol {
DefaultProtocol = 0,
WebDAV = 1,
Git = 2
};
/**
* @brief A class representing a SaltGrain URL
*

View File

@ -243,26 +243,17 @@ checkout_branch (git_repository *repo, git_remote *remote, const git_checkout_op
}
void
GitObject::read (const std::string &org_url, const std::string &org_filter, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
GitObject::read (const std::string &org_url, const std::string &org_filter, const std::string &subfolder, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
{
std::string url = org_url;
std::string filter = org_filter;
std::string subdir;
std::string url_terminator (".git/");
size_t url_end = url.find (url_terminator);
if (url_end != std::string::npos) {
subdir = std::string (url, url_end + url_terminator.size ());
url = std::string (url, 0, url_end + url_terminator.size () - 1);
if (! subfolder.empty ()) {
if (filter.empty ()) {
filter = subdir + "/**";
filter = subfolder + "/**";
} else {
filter = subdir + "/" + filter;
filter = subfolder + "/" + filter;
}
}
// @@@ use callback, timeout?
@ -343,9 +334,9 @@ GitObject::read (const std::string &org_url, const std::string &org_filter, cons
}
// pull subfolder files to target path level
if (! subdir.empty ()) {
if (! subfolder.empty ()) {
std::string pp = tl::combine_path (m_local_path, subdir);
std::string pp = tl::combine_path (m_local_path, subfolder);
if (! tl::is_dir (pp)) {
throw tl::Exception (tl::to_string (tr ("Error cloning Git repo - failed to fetch subdirectory: ")) + pp);
}
@ -358,7 +349,7 @@ GitObject::read (const std::string &org_url, const std::string &org_filter, cons
break;
}
}
auto pc = tl::split (subdir, "/");
auto pc = tl::split (subfolder, "/");
if (! tl::rename_file (tl::combine_path (m_local_path, pc.front ()), tmp_dir)) {
throw tl::Exception (tl::to_string (tr ("Error cloning Git repo - failed to rename temp folder")));
}
@ -372,18 +363,18 @@ GitObject::read (const std::string &org_url, const std::string &org_filter, cons
}
bool
GitObject::download (const std::string &url, const std::string &target, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
GitObject::download (const std::string &url, const std::string &target, const std::string &subfolder, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
{
GitObject obj (target);
obj.read (url, std::string (), branch, timeout, callback);
obj.read (url, std::string (), subfolder, branch, timeout, callback);
return false;
}
tl::InputStream *
GitObject::download_item (const std::string &url, const std::string &file, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
GitObject::download_item (const std::string &url, const std::string &file, const std::string &subfolder, const std::string &branch, double timeout, tl::InputHttpStreamCallback *callback)
{
GitObject obj;
obj.read (url, file, branch, timeout, callback);
obj.read (url, file, subfolder, branch, timeout, callback);
// extract the file and return a memory blob, so we can delete the temp folder

View File

@ -65,7 +65,7 @@ public:
* "filter" can be a top-level file to download. If filter is non-empty,
* sparse mode is chosen.
*/
void read (const std::string &url, const std::string &filter, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
void read (const std::string &url, const std::string &filter, const std::string &subfolder, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
/**
* @brief Downloads the collection or file with the given URL
@ -85,7 +85,7 @@ public:
* "branch" is the remote ref to use. This can be a branch name, a tag name,
* a remote ref such as "refs/heads/master" or a symbolic name such as "HEAD".
*/
static bool download (const std::string &url, const std::string &target, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
static bool download (const std::string &url, const std::string &target, const std::string &subfolder, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
/**
* @brief Gets a stream object for downloading the single item of the given URL
@ -93,7 +93,7 @@ public:
* The file needs to be a top-level object.
* The stream object returned needs to be deleted by the caller.
*/
static tl::InputStream *download_item (const std::string &url, const std::string &file, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
static tl::InputStream *download_item (const std::string &url, const std::string &file, const std::string &subfolder, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);
private:
std::string m_local_path;

View File

@ -32,7 +32,7 @@ TEST(1_plain)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url, std::string (), std::string ());
repo.read (test_url, std::string (), std::string (), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "LICENSE")), true);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".gitignore")), true);
@ -41,11 +41,24 @@ TEST(1_plain)
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "src/macros/xsection.lym")), true);
}
TEST(2_pathspecs)
TEST(2_subdir)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url, std::string ("src/**"), std::string ());
repo.read (test_url, std::string (), std::string ("src"), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "LICENSE")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".gitignore")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "macros/xsection.lym")), true);
}
TEST(3_subdir_as_filter)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url, std::string ("src/**"), std::string (), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "LICENSE")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".gitignore")), false);
@ -54,22 +67,11 @@ TEST(2_pathspecs)
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "src/macros/xsection.lym")), true);
}
TEST(3_subdir)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string (), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "macros/xsection.lym")), true);
}
TEST(4_single_file)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url, std::string ("LICENSE"), std::string ());
repo.read (test_url, std::string ("LICENSE"), std::string (), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "LICENSE")), true);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".gitignore")), false);
@ -81,7 +83,7 @@ TEST(5_single_file_from_subdir)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string ("grain.xml"), std::string ());
repo.read (test_url, std::string ("grain.xml"), std::string ("src"), std::string ());
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
@ -103,7 +105,7 @@ TEST(6_branch)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string ("grain.xml"), std::string ("wip"));
repo.read (test_url, std::string ("grain.xml"), std::string ("src"), std::string ("wip"));
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
@ -125,7 +127,7 @@ TEST(7_tag)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string ("grain.xml"), std::string ("1.2"));
repo.read (test_url, std::string ("grain.xml"), std::string ("src"), std::string ("1.2"));
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
@ -147,7 +149,7 @@ TEST(8_refspec)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string ("grain.xml"), std::string ("refs/tags/1.5"));
repo.read (test_url, std::string ("grain.xml"), std::string ("src"), std::string ("refs/tags/1.5"));
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
@ -169,7 +171,7 @@ TEST(9_HEAD)
{
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
repo.read (test_url + "/src", std::string ("grain.xml"), std::string ("HEAD"));
repo.read (test_url, std::string ("grain.xml"), std::string ("src"), std::string ("HEAD"));
EXPECT_EQ (tl::file_exists (tl::combine_path (path, ".git")), false);
EXPECT_EQ (tl::file_exists (tl::combine_path (path, "grain.xml")), true);
@ -192,7 +194,7 @@ TEST(10_invalid_branch)
std::string path = tl::TestBase::tmp_file ("repo");
tl::GitObject repo (path);
try {
repo.read (test_url, std::string (), std::string ("brxxx"));
repo.read (test_url, std::string (), std::string (), std::string ("brxxx"));
EXPECT_EQ (true, false);
} catch (tl::Exception &ex) {
EXPECT_EQ (ex.msg (), "Git checkout - Unable to resolve reference name: brxxx");