mirror of https://github.com/KLayout/klayout.git
A helper class for parsing Salt Grain URLs into protocol, branch, subfolder
This commit is contained in:
parent
2ed44e27ad
commit
bd785279ef
|
|
@ -33,6 +33,7 @@ HEADERS = \
|
|||
layResourceHelpProvider.h \
|
||||
layRuntimeErrorForm.h \
|
||||
layReaderErrorForm.h \
|
||||
laySaltParsedURL.h \
|
||||
laySearchReplaceConfigPage.h \
|
||||
laySearchReplaceDialog.h \
|
||||
laySearchReplacePropertiesWidgets.h \
|
||||
|
|
@ -144,6 +145,7 @@ SOURCES = \
|
|||
layResourceHelpProvider.cc \
|
||||
layRuntimeErrorForm.cc \
|
||||
layReaderErrorForm.cc \
|
||||
laySaltParsedURL.cc \
|
||||
laySearchReplaceConfigPage.cc \
|
||||
laySearchReplaceDialog.cc \
|
||||
laySearchReplacePlugin.cc \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "laySaltParsedURL.h"
|
||||
#include "laySaltGrain.h"
|
||||
#include "tlString.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
static void
|
||||
parse_git_url (tl::Extractor &ex, std::string &url, std::string &branch, std::string &subfolder)
|
||||
{
|
||||
const char *org_str = ex.get ();
|
||||
|
||||
std::string w;
|
||||
// protocol (http:)
|
||||
ex.try_read_word (w, "") && ex.test (":");
|
||||
while (! ex.at_end () && ex.test ("/")) {
|
||||
;
|
||||
}
|
||||
// server ("www.klayout.de")
|
||||
while (! ex.at_end () && (*ex != '/' && *ex != '+')) {
|
||||
++ex;
|
||||
}
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
++ex;
|
||||
|
||||
const char *c1 = ex.get ();
|
||||
while (! ex.at_end () && (*ex != '/' && *ex != '+' && *ex != '[')) {
|
||||
++ex;
|
||||
}
|
||||
const char *c2 = ex.get ();
|
||||
|
||||
std::string comp (c1, c2 - c1);
|
||||
|
||||
if ((! ex.at_end () && *ex == '+') || comp.find (".git") == comp.size () - 4) {
|
||||
// subfolder starts here
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
url = std::string (org_str, ex.get () - org_str);
|
||||
|
||||
if (ex.at_end ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ex == '/') {
|
||||
while (! ex.at_end () && *ex == '/') {
|
||||
++ex;
|
||||
}
|
||||
} else if (*ex == '+') {
|
||||
++ex;
|
||||
}
|
||||
|
||||
{
|
||||
const char *c1 = ex.get ();
|
||||
while (! ex.at_end () && *ex != '[') {
|
||||
++ex;
|
||||
}
|
||||
const char *c2 = ex.get ();
|
||||
subfolder = std::string (c1, c2 - c1);
|
||||
}
|
||||
|
||||
if (! ex.at_end () && *ex == '[') {
|
||||
|
||||
// explicit branch
|
||||
++ex;
|
||||
const char *c1 = ex.get ();
|
||||
while (! ex.at_end () && *ex != ']') {
|
||||
++ex;
|
||||
}
|
||||
const char *c2 = ex.get ();
|
||||
branch = std::string (c1, c2 - c1);
|
||||
|
||||
} else if (! subfolder.empty ()) {
|
||||
|
||||
// SVN emulation
|
||||
|
||||
auto parts = tl::split (subfolder, "/");
|
||||
if (parts.size () >= 1 && parts.back () == "trunk") {
|
||||
|
||||
branch = "HEAD";
|
||||
parts.pop_back ();
|
||||
subfolder = tl::join (parts, "/");
|
||||
|
||||
} else if (parts.size () >= 2 && parts[parts.size () - 2] == "tags") {
|
||||
|
||||
branch = "refs/tags/" + parts.back ();
|
||||
parts.pop_back ();
|
||||
parts.pop_back ();
|
||||
subfolder = tl::join (parts, "/");
|
||||
|
||||
} else if (parts.size () >= 2 && parts[parts.size () - 2] == "branches") {
|
||||
|
||||
branch = "refs/heads/" + parts.back ();
|
||||
parts.pop_back ();
|
||||
parts.pop_back ();
|
||||
subfolder = tl::join (parts, "/");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SaltParsedURL::SaltParsedURL (const std::string &url)
|
||||
: m_protocol (lay::DefaultProtocol)
|
||||
{
|
||||
tl::Extractor ex (url.c_str ());
|
||||
if (ex.test ("svn") && ex.test ("+")) {
|
||||
m_protocol = lay::WebDAV;
|
||||
m_url = ex.get ();
|
||||
return;
|
||||
}
|
||||
|
||||
ex = tl::Extractor (url.c_str ());
|
||||
if (ex.test ("git") && ex.test ("+")) {
|
||||
m_protocol = lay::Git;
|
||||
parse_git_url (ex, m_url, m_branch, m_subfolder);
|
||||
return;
|
||||
}
|
||||
|
||||
m_url = url;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_laySaltParsedURL
|
||||
#define HDR_laySaltParsedURL
|
||||
|
||||
#include "layCommon.h"
|
||||
#include "laySaltGrain.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A class representing a SaltGrain URL
|
||||
*
|
||||
* The URL is parsed into protocol, branch, URL and subfolder if applicable.
|
||||
* Some heuristics is applied to decompose parts.
|
||||
*
|
||||
* SVN URLs:
|
||||
* https://server.com/repo/trunk -> protocol=DefaultProtocol, url="https://server.com/repo/trunk", branch="", subfolder=""
|
||||
* svn+https://server.com/repo/trunk -> protocol=WebDAV, url="https://server.com/repo/trunk", branch="", subfolder=""
|
||||
*
|
||||
* Git URL heuristics:
|
||||
* git+https://server.com/repo.git -> protocol=Git, url="https://server.com/repo.git", branch="", subfolder=""
|
||||
* git+https://server.com/repo.git/sub/folder -> protocol=Git, url="https://server.com/repo.git", branch="", subfolder="sub/folder"
|
||||
* git+https://server.com/repo+sub/folder -> protocol=Git, url="https://server.com/repo", branch="", subfolder="sub/folder"
|
||||
* git+https://server.com/repo.git[v1.0] -> protocol=Git, url="https://server.com/repo.git", branch="v1.0", subfolder=""
|
||||
* git+https://server.com/repo.git/sub/folder[refs/tags/1.0] -> protocol=Git, url="https://server.com/repo.git", branch="refs/tags/1.0", subfolder="sub/folder"
|
||||
* git+https://server.com/repo.git/trunk -> protocol=Git, url="https://server.com/repo.git", branch="HEAD", subfolder=""
|
||||
* git+https://server.com/repo.git/sub/folder/trunk -> protocol=Git, url="https://server.com/repo.git", branch="HEAD", subfolder="sub/folder"
|
||||
* git+https://server.com/repo.git/branches/release -> protocol=Git, url="https://server.com/repo.git", branch="refs/heads/release", subfolder=""
|
||||
* git+https://server.com/repo.git/tags/1.9 -> protocol=Git, url="https://server.com/repo.git", branch="refs/tags/1.9", subfolder=""
|
||||
* git+https://server.com/repo.git/sub/folder/tags/1.9 -> protocol=Git, url="https://server.com/repo.git", branch="refs/tags/1.9", subfolder="sub/folder"
|
||||
*/
|
||||
|
||||
class LAY_PUBLIC SaltParsedURL
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor: creates an URL from the given generic URL string
|
||||
*
|
||||
* This will decompose the URL into the parts and fill protocol, branch and subfolder fields.
|
||||
*/
|
||||
SaltParsedURL (const std::string &url);
|
||||
|
||||
/**
|
||||
* @brief Gets the basic URL
|
||||
*/
|
||||
const std::string &url () const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the subfolder string
|
||||
*/
|
||||
const std::string &subfolder () const
|
||||
{
|
||||
return m_subfolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the branch string
|
||||
*/
|
||||
const std::string &branch () const
|
||||
{
|
||||
return m_branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the protocol
|
||||
*/
|
||||
lay::Protocol protocol () const
|
||||
{
|
||||
return m_protocol;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_url;
|
||||
std::string m_branch;
|
||||
std::string m_subfolder;
|
||||
lay::Protocol m_protocol;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "laySaltParsedURL.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST (1_Basic)
|
||||
{
|
||||
lay::SaltParsedURL purl ("https://server.com/repo/trunk");
|
||||
EXPECT_EQ (purl.protocol () == lay::DefaultProtocol, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo/trunk");
|
||||
EXPECT_EQ (purl.branch (), "");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (2_SVN)
|
||||
{
|
||||
lay::SaltParsedURL purl ("svn+https://server.com/repo/trunk");
|
||||
EXPECT_EQ (purl.protocol () == lay::WebDAV, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo/trunk");
|
||||
EXPECT_EQ (purl.branch (), "");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (10_GitBasic)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (11_GitSubFolder)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/sub/folder");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "");
|
||||
EXPECT_EQ (purl.subfolder (), "sub/folder");
|
||||
}
|
||||
|
||||
TEST (12_GitExplicitBranch)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git[v1.0]");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "v1.0");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (13_GitExplicitBranchAndSubFolder)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/sub/folder[refs/tags/1.0]");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "refs/tags/1.0");
|
||||
EXPECT_EQ (purl.subfolder (), "sub/folder");
|
||||
}
|
||||
|
||||
TEST (14_GitExplicitBranchAndExplicitSubFolder)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo+sub/folder[refs/tags/1.0]");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo");
|
||||
EXPECT_EQ (purl.branch (), "refs/tags/1.0");
|
||||
EXPECT_EQ (purl.subfolder (), "sub/folder");
|
||||
}
|
||||
|
||||
TEST (15_GitSVNEmulationTrunk)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/trunk");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "HEAD");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (16_GitSVNEmulationTrunkWithSubFolder)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/sub/folder/trunk");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "HEAD");
|
||||
EXPECT_EQ (purl.subfolder (), "sub/folder");
|
||||
}
|
||||
|
||||
TEST (17_GitSVNEmulationBranch)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/branches/xyz");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "refs/heads/xyz");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (18_GitSVNEmulationTag)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/tags/1.9");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "refs/tags/1.9");
|
||||
EXPECT_EQ (purl.subfolder (), "");
|
||||
}
|
||||
|
||||
TEST (19_GitSVNEmulationTagWithSubFolder)
|
||||
{
|
||||
lay::SaltParsedURL purl ("git+https://server.com/repo.git/sub/folder/tags/1.9");
|
||||
EXPECT_EQ (purl.protocol () == lay::Git, true);
|
||||
EXPECT_EQ (purl.url (), "https://server.com/repo.git");
|
||||
EXPECT_EQ (purl.branch (), "refs/tags/1.9");
|
||||
EXPECT_EQ (purl.subfolder (), "sub/folder");
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ include($$PWD/../../lib_ut.pri)
|
|||
SOURCES = \
|
||||
laySalt.cc \
|
||||
layHelpIndexTest.cc \
|
||||
laySaltParsedURLTests.cc \
|
||||
laySessionTests.cc
|
||||
|
||||
INCLUDEPATH += $$LAY_INC $$TL_INC $$LAYBASIC_INC $$LAYUI_INC $$LAYVIEW_INC $$DB_INC $$GSI_INC $$ANT_INC $$IMG_INC $$RDB_INC
|
||||
|
|
|
|||
Loading…
Reference in New Issue