jetbrains.buildServer.buildTriggers.vcs.git.submodules.TeamCitySubmoduleResolver.java Source code

Java tutorial

Introduction

Here is the source code for jetbrains.buildServer.buildTriggers.vcs.git.submodules.TeamCitySubmoduleResolver.java

Source

/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * 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 jetbrains.buildServer.buildTriggers.vcs.git.submodules;

import com.intellij.openapi.diagnostic.Logger;
import jetbrains.buildServer.buildTriggers.vcs.git.GitUtils;
import jetbrains.buildServer.buildTriggers.vcs.git.OperationContext;
import jetbrains.buildServer.vcs.VcsException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.URIish;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;

/**
 * The resolver for submodules that uses TeamCity repository mapping.
 */
public class TeamCitySubmoduleResolver extends SubmoduleResolver {

    private static Logger LOG = Logger.getInstance(TeamCitySubmoduleResolver.class.getName());
    /**
     * Path from the root of the first repository.
     * For root repository = "".
     * For submodule repository = path of submodule.
     * For sub-submodules = path of submodule/path of sub-submodule in submodule repository.
     */
    private final String myPathFromRoot;
    private final OperationContext myContext;

    public TeamCitySubmoduleResolver(@NotNull final OperationContext context, Repository db, RevCommit commit) {
        this(context, db, commit, "");
    }

    private TeamCitySubmoduleResolver(@NotNull final OperationContext context, Repository db, RevCommit commit,
            String basePath) {
        super(context.getSupport(), db, commit);
        myContext = context;
        myPathFromRoot = basePath;
    }

    protected Repository resolveRepository(String path, String submoduleUrl)
            throws IOException, VcsException, URISyntaxException {
        LOG.debug("Resolve repository for URL: " + submoduleUrl);
        final URIish uri = resolveUrl(submoduleUrl);
        Repository r = myContext.getRepositoryFor(uri);
        LOG.debug("Repository dir for submodule " + submoduleUrl + " is " + r.getDirectory().getAbsolutePath());
        return r;
    }

    @Override
    protected void fetch(Repository r, String submodulePath, String submoduleUrl)
            throws VcsException, URISyntaxException, IOException {
        if (LOG.isDebugEnabled())
            LOG.debug("Fetching submodule " + submoduleUrl + " used at " + submodulePath + " for "
                    + myContext.getGitRoot().debugInfo());
        URIish uri = resolveUrl(submoduleUrl);
        myGitSupport.fetch(r, uri,
                Arrays.asList(new RefSpec("+refs/heads/*:refs/heads/*"), new RefSpec("+refs/tags/*:refs/tags/*")),
                myContext.getGitRoot().getAuthSettings());
    }

    private boolean isRelative(String url) {
        return url.startsWith(".");
    }

    private URIish resolveUrl(String url) throws URISyntaxException {
        String uri = isRelative(url) ? resolveRelativeUrl(url) : url;
        return new URIish(uri);
    }

    private String resolveRelativeUrl(String relativeUrl) throws URISyntaxException {
        String baseUrl = getRepository().getConfig().getString("teamcity", null, "remote");
        URIish u = new URIish(baseUrl);
        String newPath = u.getPath();
        if (newPath.length() == 0) {
            newPath = relativeUrl;
        } else {
            newPath = GitUtils.normalizePath(newPath + '/' + relativeUrl);
        }
        return u.setPath(newPath).toPrivateString();
    }

    public SubmoduleResolver getSubResolver(RevCommit commit, String path) {
        Repository db = null;
        try {
            db = resolveRepository(path, getSubmoduleUrl(path));
        } catch (Exception e) {
            //exception means path does not contain submodule, use current repository
            db = getRepository();
        }
        return new TeamCitySubmoduleResolver(myContext, db, commit, fullPath(path));
    }

    /**
     * Get full path using from local path
     *
     * @param path the path to examine
     * @return the full including the base path
     */
    private String fullPath(String path) {
        return myPathFromRoot.length() == 0 ? path : myPathFromRoot + "/" + path;
    }
}