Git: Add new class GitRemote

Allows to split a remote URL and performs
some validation checks on the elements.

Change-Id: I048373076b1a1553fdd7bed2986a41cc087138b0
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Andre Hartmann
2017-03-09 19:13:38 +01:00
committed by André Hartmann
parent 6e7d2a4001
commit b0ac6435b3
3 changed files with 55 additions and 22 deletions

View File

@@ -113,39 +113,27 @@ QString GerritServer::url(UrlType urlType) const
bool GerritServer::fillFromRemote(const QString &remote, const GerritParameters &parameters) bool GerritServer::fillFromRemote(const QString &remote, const GerritParameters &parameters)
{ {
static const QRegularExpression remotePattern( const GitRemote r(remote);
"^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)" if (!r.isValid)
"(?::(?<port>\\d+))?:?(?<path>/.*)$"); return false;
// Skip local remotes (refer to the root or relative path) if (r.protocol == "https")
if (remote.isEmpty() || remote.startsWith('/') || remote.startsWith('.'))
return false;
// On Windows, local paths typically starts with <drive>:
if (HostOsInfo::isWindowsHost() && remote[1] == ':')
return false;
QRegularExpressionMatch match = remotePattern.match(remote);
if (!match.hasMatch())
return false;
const QString protocol = match.captured("protocol");
if (protocol == "https")
type = GerritServer::Https; type = GerritServer::Https;
else if (protocol == "http") else if (r.protocol == "http")
type = GerritServer::Http; type = GerritServer::Http;
else if (protocol.isEmpty() || protocol == "ssh") else if (r.protocol.isEmpty() || r.protocol == "ssh")
type = GerritServer::Ssh; type = GerritServer::Ssh;
else else
return false; return false;
const QString userName = match.captured("user");
user.userName = userName.isEmpty() ? parameters.server.user.userName : userName; user.userName = r.userName.isEmpty() ? parameters.server.user.userName : r.userName;
host = match.captured("host"); if (r.host.contains("github.com")) // Clearly not gerrit
port = match.captured("port").toUShort();
if (host.contains("github.com")) // Clearly not gerrit
return false; return false;
if (type != GerritServer::Ssh) { if (type != GerritServer::Ssh) {
curlBinary = parameters.curl; curlBinary = parameters.curl;
if (curlBinary.isEmpty() || !QFile::exists(curlBinary)) if (curlBinary.isEmpty() || !QFile::exists(curlBinary))
return false; return false;
rootPath = match.captured("path"); rootPath = r.path;
// Strip the last part of the path, which is always the repo name // Strip the last part of the path, which is always the repo name
// The rest of the path needs to be inspected to find the root path // The rest of the path needs to be inspected to find the root path
// (can be http://example.net/review) // (can be http://example.net/review)

View File

@@ -3191,6 +3191,39 @@ void GitClient::StashInfo::end()
m_stashResult = NotStashed; m_stashResult = NotStashed;
} }
// GitRemote
GitRemote::GitRemote(const QString &url)
{
static const QRegularExpression remotePattern(
"^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)"
"(?::(?<port>\\d+))?:?(?<path>/.*)$");
if (url.isEmpty())
return;
// Check for local remotes (refer to the root or relative path)
// On Windows, local paths typically starts with <drive>:
if (url.startsWith('/') || url.startsWith('.')
|| (HostOsInfo::isWindowsHost() && url[1] == ':')) {
protocol = "file";
path = QDir::fromNativeSeparators(url);
isValid = QDir(path).exists() || QDir(path + ".git").exists();
return;
}
const QRegularExpressionMatch match = remotePattern.match(url);
if (!match.hasMatch())
return;
protocol = match.captured("protocol");
userName = match.captured("user");
host = match.captured("host");
port = match.captured("port").toUShort();
path = match.captured("path");
isValid = true;
}
} // namespace Internal } // namespace Internal
} // namespace Git } // namespace Git

View File

@@ -380,5 +380,17 @@ private:
QFutureSynchronizer<void> m_synchronizer; // for commit updates QFutureSynchronizer<void> m_synchronizer; // for commit updates
}; };
class GitRemote {
public:
GitRemote(const QString &url);
QString protocol;
QString userName;
QString host;
QString path;
quint16 port = 0;
bool isValid = false;
};
} // namespace Internal } // namespace Internal
} // namespace Git } // namespace Git