diff options
Diffstat (limited to 'java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java')
-rw-r--r-- | java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java b/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java new file mode 100644 index 0000000000..f05d1d774b --- /dev/null +++ b/java/com/google/gerrit/server/util/git/SubmoduleSectionParser.java @@ -0,0 +1,145 @@ +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.util.git; + +import com.google.gerrit.reviewdb.client.Branch; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.client.SubmoduleSubscription; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashSet; +import java.util.Set; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.Constants; + +/** + * It parses from a configuration file submodule sections. + * + * <p>Example of submodule sections: + * + * <pre> + * [submodule "project-a"] + * url = http://localhost/a + * path = a + * branch = . + * + * [submodule "project-b"] + * url = http://localhost/b + * path = b + * branch = refs/heads/test + * </pre> + */ +public class SubmoduleSectionParser { + + private final Config config; + private final String canonicalWebUrl; + private final Branch.NameKey superProjectBranch; + + public SubmoduleSectionParser( + Config config, String canonicalWebUrl, Branch.NameKey superProjectBranch) { + this.config = config; + this.canonicalWebUrl = canonicalWebUrl; + this.superProjectBranch = superProjectBranch; + } + + public Set<SubmoduleSubscription> parseAllSections() { + Set<SubmoduleSubscription> parsedSubscriptions = new HashSet<>(); + for (String id : config.getSubsections("submodule")) { + final SubmoduleSubscription subscription = parse(id); + if (subscription != null) { + parsedSubscriptions.add(subscription); + } + } + return parsedSubscriptions; + } + + private SubmoduleSubscription parse(String id) { + final String url = config.getString("submodule", id, "url"); + final String path = config.getString("submodule", id, "path"); + String branch = config.getString("submodule", id, "branch"); + + try { + if (url != null + && url.length() > 0 + && path != null + && path.length() > 0 + && branch != null + && branch.length() > 0) { + // All required fields filled. + String project; + + if (branch.equals(".")) { + branch = superProjectBranch.get(); + } + + // relative URL + if (url.startsWith("../")) { + // prefix with a slash for easier relative path walks + project = '/' + superProjectBranch.getParentKey().get(); + String hostPart = url; + while (hostPart.startsWith("../")) { + int lastSlash = project.lastIndexOf('/'); + if (lastSlash < 0) { + // too many levels up, ignore for now + return null; + } + project = project.substring(0, lastSlash); + hostPart = hostPart.substring(3); + } + project = project + "/" + hostPart; + + // remove leading '/' + project = project.substring(1); + } else { + // It is actually an URI. It could be ssh://localhost/project-a. + URI targetServerURI = new URI(url); + URI thisServerURI = new URI(canonicalWebUrl); + String thisHost = thisServerURI.getHost(); + String targetHost = targetServerURI.getHost(); + if (thisHost == null || targetHost == null || !targetHost.equalsIgnoreCase(thisHost)) { + return null; + } + String p1 = targetServerURI.getPath(); + String p2 = thisServerURI.getPath(); + if (!p1.startsWith(p2)) { + // When we are running the server at + // http://server/my-gerrit/ but the subscription is for + // http://server/other-teams-gerrit/ + return null; + } + // skip common part + project = p1.substring(p2.length()); + } + + while (project.startsWith("/")) { + project = project.substring(1); + } + + if (project.endsWith(Constants.DOT_GIT_EXT)) { + project = + project.substring( + 0, // + project.length() - Constants.DOT_GIT_EXT.length()); + } + Project.NameKey projectKey = new Project.NameKey(project); + return new SubmoduleSubscription( + superProjectBranch, new Branch.NameKey(projectKey, branch), path); + } + } catch (URISyntaxException e) { + // Error in url syntax (in fact it is uri syntax) + } + return null; + } +} |