io.fabric8.itests.basic.git.GitUtils.java Source code

Java tutorial

Introduction

Here is the source code for io.fabric8.itests.basic.git.GitUtils.java

Source

/**
 *  Copyright 2005-2014 Red Hat, Inc.
 *
 *  Red Hat licenses this file to you 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 io.fabric8.itests.basic.git;

import static io.fabric8.zookeeper.utils.ZooKeeperUtils.getSubstitutedData;
import io.fabric8.api.ContainerRegistration;
import io.fabric8.api.ServiceLocator;
import io.fabric8.git.GitNode;
import io.fabric8.groups.Group;
import io.fabric8.groups.GroupListener;
import io.fabric8.groups.internal.ZooKeeperGroup;
import io.fabric8.zookeeper.ZkPath;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.osgi.framework.BundleContext;

import com.google.common.base.Objects;

public class GitUtils {

    public static final CredentialsProvider DEFAULT_CREDENTIALS_PROVIDER = new UsernamePasswordCredentialsProvider(
            "admin", "admin");

    /**
     * Waits until the master url becomes available & returns it.
     */
    public static String getMasterUrl(BundleContext bundleContext, CuratorFramework curator)
            throws InterruptedException, URISyntaxException {
        ServiceLocator.awaitService(bundleContext, ContainerRegistration.class);
        Group<GitNode> group = new ZooKeeperGroup<GitNode>(curator, ZkPath.GIT.getPath(), GitNode.class);
        final CountDownLatch latch = new CountDownLatch(1);

        group.add(new GroupListener<GitNode>() {
            @Override
            public void groupEvent(Group<GitNode> group, GroupEvent event) {
                if (group.master() != null && group.master().getUrl() != null) {
                    latch.countDown();
                }
            }
        });
        group.start();
        latch.await(10, TimeUnit.SECONDS);
        return getSubstitutedData(curator, group.master().getUrl());
    }

    /**
     * Wait until the version znode gets updated (indicating that entries has been bridge from/to git).
     * @param curator       The {@link CuratorFramework} instance to use for looking up the registry.
     * @param branch        The name of the branch/version.
     * @throws Exception
     */
    public static void waitForBranchUpdate(CuratorFramework curator, String branch) throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        final Watcher watcher = new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                latch.countDown();
            }
        };

        for (int i = 0; curator.checkExists().usingWatcher(watcher)
                .forPath(ZkPath.CONFIG_VERSION.getPath(branch)) == null && i < 3; i++) {
            Thread.sleep(1000);
        }

        latch.await(10, TimeUnit.SECONDS);
    }

    public static void configureBranch(Git git, String remote, String remoteUrl, String branch) {
        if (git != null && remoteUrl != null && !remoteUrl.isEmpty()) {
            Repository repository = git.getRepository();
            if (repository != null) {
                StoredConfig config = repository.getConfig();
                config.setString("remote", remote, "url", remoteUrl);
                config.setString("remote", remote, "fetch", "+refs/heads/*:refs/remotes/" + branch + "/*");
                config.setString("branch", branch, "merge", "refs/heads/" + branch);
                config.setString("branch", branch, "remote", "origin");
                try {
                    config.save();
                } catch (IOException e) {
                    //Ignore
                }
            }
        }
    }

    /**
     * Returns the name of the current branch.
     * @param git
     * @return
     */
    public static String currentBranch(Git git) {
        try {
            return git.getRepository().getBranch();
        } catch (IOException e) {
            return null;
        }
    }

    public static void checkoutBranch(Git git, String remote, String branch) throws GitAPIException {
        checkoutBranch(git, DEFAULT_CREDENTIALS_PROVIDER, remote, branch);
    }

    public static void checkoutBranch(Git git, CredentialsProvider credentialsProvider, String remote,
            String branch) throws GitAPIException {
        String current = currentBranch(git);
        if (Objects.equal(current, branch)) {
            return;
        }
        boolean localExists = localBranchExists(git, branch);
        boolean remoteExists = remoteBranchExists(git, remote, branch);
        if (localExists) {
            git.checkout().setName(branch).call();
        } else if (remoteExists) {
            git.checkout().setName(branch).setCreateBranch(true).setForce(true)
                    .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
                    .setStartPoint(remote + "/" + branch).call();
        } else {
            git.branchCreate().setName(branch).setForce(true).call();
            git.checkout().setName(branch).call();
            git.push().setCredentialsProvider(credentialsProvider).setRemote(remote)
                    .setRefSpecs(new RefSpec(branch)).setForce(true).call();
        }
        configureBranch(git, remote, getRemote(git, remote), branch);
    }

    public static String getRemote(Git git, String remote) throws GitAPIException {
        StoredConfig config = git.getRepository().getConfig();
        return config.getString("remote", remote, "url");
    }

    /**
     * Checks if a local branch exists.
     * @param git       The git object to use.
     * @param branch    The name of the local branch.
     * @return
     * @throws GitAPIException
     */
    public static boolean localBranchExists(Git git, String branch) throws GitAPIException {
        List<Ref> list = git.branchList().call();
        String fullName = "refs/heads/" + branch;
        boolean exists = false;
        for (Ref ref : list) {
            String name = ref.getName();
            if (Objects.equal(name, fullName)) {
                exists = true;
            }
        }
        return exists;
    }

    /**
     * Checks if a remote branch exists.
     * @param git       The git object to use.
     * @param remote    The name of the remote repo to check.
     * @param branch    The name of the local branch.
     * @return
     * @throws GitAPIException
     */
    public static boolean remoteBranchExists(Git git, String remote, String branch) throws GitAPIException {
        List<Ref> list = git.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call();
        String fullName = "refs/remotes/" + remote + "/" + branch;
        boolean exists = false;
        for (Ref ref : list) {
            String name = ref.getName();
            if (Objects.equal(name, fullName)) {
                exists = true;
            }
        }
        return exists;
    }
}