diff --git a/src/lay/lay/laySalt.cc b/src/lay/lay/laySalt.cc index 4f5f428b7..2abf3c519 100644 --- a/src/lay/lay/laySalt.cc +++ b/src/lay/lay/laySalt.cc @@ -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); diff --git a/src/lay/lay/laySaltController.cc b/src/lay/lay/laySaltController.cc index 2a10a8894..efd85a58e 100644 --- a/src/lay/lay/laySaltController.cc +++ b/src/lay/lay/laySaltController.cc @@ -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 &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@" - // "git@[]" - - 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@" - - 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); } diff --git a/src/lay/lay/laySaltDownloadManager.cc b/src/lay/lay/laySaltDownloadManager.cc index 4d9032f6c..cc0b625d7 100644 --- a/src/lay/lay/laySaltDownloadManager.cc +++ b/src/lay/lay/laySaltDownloadManager.cc @@ -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::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); } } diff --git a/src/lay/lay/laySaltDownloadManager.h b/src/lay/lay/laySaltDownloadManager.h index 04c3ef2b5..a81e0f973 100644 --- a/src/lay/lay/laySaltDownloadManager.h +++ b/src/lay/lay/laySaltDownloadManager.h @@ -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; diff --git a/src/lay/lay/laySaltGrain.cc b/src/lay/lay/laySaltGrain.cc index b956e11a0..e887066e7 100644 --- a/src/lay/lay/laySaltGrain.cc +++ b/src/lay/lay/laySaltGrain.cc @@ -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 stream (stream_from_url (url, protocol, branch, timeout, callback)); + std::unique_ptr stream (stream_from_url (url, timeout, callback)); SaltGrain g; g.load (*stream); diff --git a/src/lay/lay/laySaltGrain.h b/src/lay/lay/laySaltGrain.h index 1919e98ab..58e429ffa 100644 --- a/src/lay/lay/laySaltGrain.h +++ b/src/lay/lay/laySaltGrain.h @@ -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; diff --git a/src/lay/lay/laySaltGrainDetailsTextWidget.cc b/src/lay/lay/laySaltGrainDetailsTextWidget.cc index 28eb81c6a..1992b20c9 100644 --- a/src/lay/lay/laySaltGrainDetailsTextWidget.cc +++ b/src/lay/lay/laySaltGrainDetailsTextWidget.cc @@ -305,6 +305,7 @@ SaltGrainDetailsTextWidget::details_text () if (! d->url.empty ()) { stream << " - "; stream << "[" << tl::to_qstring (tl::escaped_to_html (d->url)) << "]
"; + // @@@ TODO: protocol and branch } } stream << "

"; diff --git a/src/lay/lay/laySaltGrainPropertiesDialog.cc b/src/lay/lay/laySaltGrainPropertiesDialog.cc index 200bce4eb..fa6321f6e 100644 --- a/src/lay/lay/laySaltGrainPropertiesDialog.cc +++ b/src/lay/lay/laySaltGrainPropertiesDialog.cc @@ -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 diff --git a/src/lay/lay/laySaltManagerDialog.cc b/src/lay/lay/laySaltManagerDialog.cc index 4e135e266..98f084ab7 100644 --- a/src/lay/lay/laySaltManagerDialog.cc +++ b/src/lay/lay/laySaltManagerDialog.cc @@ -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 (m_downloaded_grain_reader->base ()); diff --git a/src/lay/lay/laySaltParsedURL.h b/src/lay/lay/laySaltParsedURL.h index bc076f76b..770395a64 100644 --- a/src/lay/lay/laySaltParsedURL.h +++ b/src/lay/lay/laySaltParsedURL.h @@ -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 * diff --git a/src/tl/tl/tlGit.cc b/src/tl/tl/tlGit.cc index 3279bef16..eb2336b7f 100644 --- a/src/tl/tl/tlGit.cc +++ b/src/tl/tl/tlGit.cc @@ -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 diff --git a/src/tl/tl/tlGit.h b/src/tl/tl/tlGit.h index 68a1db83a..a5d22e342 100644 --- a/src/tl/tl/tlGit.h +++ b/src/tl/tl/tlGit.h @@ -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; diff --git a/src/tl/unit_tests/tlGitTests.cc b/src/tl/unit_tests/tlGitTests.cc index cd9c5fd9e..82d62dacc 100644 --- a/src/tl/unit_tests/tlGitTests.cc +++ b/src/tl/unit_tests/tlGitTests.cc @@ -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");