Package org.eclipse.egit.core.test

Source Code of org.eclipse.egit.core.test.TestRepository

/*******************************************************************************
* Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
* Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
* Copyright (C) 2012, Robin Stocker <robin@nibor.org>
* Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.egit.core.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Collections;
import java.util.regex.Pattern;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.op.BranchOperation;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.egit.core.op.DisconnectProviderOperation;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.api.errors.NoMessageException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.UnmergedPathException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.FileUtils;

/**
* Helper class for creating and filling a test repository
*
*/
public class TestRepository {

  Repository repository;

  String workdirPrefix;

  /**
   * Creates a new test repository
   *
   * @param gitDir
   * @throws IOException
   */
  public TestRepository(File gitDir) throws IOException {
    Repository tmpRepository = FileRepositoryBuilder.create(gitDir);
    tmpRepository.create();
    tmpRepository.close();
    // use repository instance from RepositoryCache!
    repository = Activator.getDefault().getRepositoryCache().lookupRepository(gitDir);
    try {
      workdirPrefix = repository.getWorkTree().getCanonicalPath();
    } catch (IOException err) {
      workdirPrefix = repository.getWorkTree().getAbsolutePath();
    }
    workdirPrefix = workdirPrefix.replace('\\', '/');
    if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
      workdirPrefix += "/"; //$NON-NLS-1$
  }

  /**
   * Creates a test repository from an existing Repository
   *
   * @param repository
   * @throws IOException
   */
  public TestRepository(Repository repository) throws IOException {
    this.repository = repository;
    try {
      workdirPrefix = repository.getWorkTree().getCanonicalPath();
    } catch (IOException err) {
      workdirPrefix = repository.getWorkTree().getAbsolutePath();
    }
    workdirPrefix = workdirPrefix.replace('\\', '/');
    if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
      workdirPrefix += "/"; //$NON-NLS-1$
  }

  /**
   * @return the wrapped repository
   */
  public Repository getRepository() {
    return repository;
  }

  /**
   * create an initial commit containing a file "dummy" in the
   *
   * @param message
   *            commit message
   * @return commit object
   * @throws IOException
   * @throws JGitInternalException
   * @throws GitAPIException
   * @throws NoFilepatternException
   */
  public RevCommit createInitialCommit(String message) throws IOException,
      JGitInternalException, NoFilepatternException, GitAPIException {
    String repoPath = repository.getWorkTree().getAbsolutePath();
    File file = new File(repoPath, "dummy");
    if (!file.exists())
      FileUtils.createNewFile(file);
    track(file);
    return commit(message);
  }

  /**
   * Create a file or get an existing one
   *
   * @param project
   *            instance of project inside with file will be created
   * @param name
   *            name of file
   * @return nearly created file
   * @throws IOException
   */
  public File createFile(IProject project, String name) throws IOException {
    String path = project.getLocation().append(name).toOSString();
    int lastSeparator = path.lastIndexOf(File.separator);
    FileUtils.mkdirs(new File(path.substring(0, lastSeparator)), true);

    File file = new File(path);
    if (!file.exists())
      FileUtils.createNewFile(file);

    return file;
  }

  /**
   * Track, add to index and finally commit given file
   *
   * @param project
   * @param file
   * @param commitMessage
   * @return commit object
   * @throws Exception
   */
  public RevCommit addAndCommit(IProject project, File file, String commitMessage)
      throws Exception {
    track(file);
    addToIndex(project, file);

    return commit(commitMessage);
  }

  /**
   * Appends file content to given file, then track, add to index and finally
   * commit it.
   *
   * @param project
   * @param file
   * @param content
   * @param commitMessage
   * @return commit object
   * @throws Exception
   */
  public RevCommit appendContentAndCommit(IProject project, File file,
      byte[] content, String commitMessage) throws Exception {
    return appendContentAndCommit(project, file, new String(content,
        "UTF-8"), commitMessage);
  }

  /**
   * Appends file content to given file, then track, add to index and finally
   * commit it.
   *
   * @param project
   * @param file
   * @param content
   * @param commitMessage
   * @return commit object
   * @throws Exception
   */
  public RevCommit appendContentAndCommit(IProject project, File file,
      String content, String commitMessage) throws Exception {
    appendFileContent(file, content);
    track(file);
    addToIndex(project, file);

    return commit(commitMessage);
  }

  /**
   * Commits the current index
   *
   * @param message
   *            commit message
   * @return commit object
   *
   * @throws NoHeadException
   * @throws NoMessageException
   * @throws UnmergedPathException
   * @throws ConcurrentRefUpdateException
   * @throws JGitInternalException
   * @throws GitAPIException
   * @throws WrongRepositoryStateException
   */
  public RevCommit commit(String message) throws NoHeadException,
      NoMessageException, UnmergedPathException,
      ConcurrentRefUpdateException, JGitInternalException,
      WrongRepositoryStateException, GitAPIException {
    Git git = new Git(repository);
    CommitCommand commitCommand = git.commit();
    commitCommand.setAuthor("J. Git", "j.git@egit.org");
    commitCommand.setCommitter(commitCommand.getAuthor());
    commitCommand.setMessage(message);
    return commitCommand.call();
  }

  /**
   * Adds file to version control
   *
   * @param file
   * @throws IOException
   * @throws GitAPIException
   * @throws NoFilepatternException
   */
  public void track(File file) throws IOException, NoFilepatternException, GitAPIException {
    String repoPath = getRepoRelativePath(new Path(file.getPath())
        .toString());
    new Git(repository).add().addFilepattern(repoPath).call();
  }

  /**
   * Adds all project files to version control
   *
   * @param project
   * @throws CoreException
   */
  public void trackAllFiles(IProject project) throws CoreException {
    project.accept(new IResourceVisitor() {

      public boolean visit(IResource resource) throws CoreException {
        if (resource instanceof IFile) {
          try {
            track(EFS.getStore(resource.getLocationURI())
                    .toLocalFile(0, null));
          } catch (Exception e) {
            throw new CoreException(Activator.error(e.getMessage(),
                e));
          }
        }
        return true;
      }
    });
  }

  /**
   * Removes file from version control
   *
   * @param file
   * @throws IOException
   */
  public void untrack(File file) throws IOException {
    String repoPath = getRepoRelativePath(new Path(file.getPath())
        .toString());
    try {
      new Git(repository).rm().addFilepattern(repoPath).call();
    } catch (GitAPIException e) {
      throw new IOException(e.getMessage());
    }
  }

  /**
   * Creates a new branch and immediately checkout it.
   *
   * @param refName
   *            starting point for the new branch
   * @param newRefName
   * @throws Exception
   */
  public void createAndCheckoutBranch(String refName, String newRefName) throws Exception {
    createBranch(refName, newRefName);
    checkoutBranch(newRefName);
  }

  /**
   * Creates a new branch
   *
   * @param refName
   *            starting point for the new branch
   * @param newRefName
   * @throws IOException
   */
  public void createBranch(String refName, String newRefName)
      throws IOException {
    RefUpdate updateRef;
    updateRef = repository.updateRef(newRefName);
    Ref startRef = repository.getRef(refName);
    ObjectId startAt = repository.resolve(refName);
    String startBranch;
    if (startRef != null)
      startBranch = refName;
    else
      startBranch = startAt.name();
    startBranch = Repository.shortenRefName(startBranch);
    updateRef.setNewObjectId(startAt);
    updateRef
        .setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
    updateRef.update();
  }

  /**
   * Checkouts branch
   *
   * @param refName
   *            full name of branch
   * @throws CoreException
   */
  public void checkoutBranch(String refName) throws CoreException {
    new BranchOperation(repository, refName).execute(null);
  }

  /**
   * Adds the given file to the index
   *
   * @param project
   * @param file
   * @throws Exception
   */
  public void addToIndex(IProject project, File file) throws Exception {
    IFile iFile = getIFile(project, file);
    addToIndex(iFile);
  }


  /**
   * Adds the given resource to the index
   *
   * @param resource
   * @throws CoreException
   * @throws IOException
   * @throws GitAPIException
   * @throws NoFilepatternException
   */
  public void addToIndex(IResource resource) throws CoreException, IOException, NoFilepatternException, GitAPIException {
    String repoPath = getRepoRelativePath(resource.getLocation().toString());
    new Git(repository).add().addFilepattern(repoPath).call();
  }

  /**
   * Appends content to end of given file.
   *
   * @param file
   * @param content
   * @throws IOException
   */
  public void appendFileContent(File file, byte[] content) throws IOException {
    appendFileContent(file, new String(content, "UTF-8"), true);
  }

  /**
   * Appends content to end of given file.
   *
   * @param file
   * @param content
   * @throws IOException
   */
  public void appendFileContent(File file, String content) throws IOException {
    appendFileContent(file, content, true);
  }

  /**
   * Appends content to given file.
   *
   * @param file
   * @param content
   * @param append
   *            if true, then bytes will be written to the end of the file
   *            rather than the beginning
   * @throws IOException
   */
  public void appendFileContent(File file, byte[] content, boolean append)
      throws IOException {
    appendFileContent(file, new String(content, "UTF-8"), append);
  }

  /**
   * Appends content to given file.
   *
   * @param file
   * @param content
   * @param append
   *            if true, then bytes will be written to the end of the file
   *            rather than the beginning
   * @throws IOException
   */
  public void appendFileContent(File file, String content, boolean append)
      throws IOException {
    Writer fw = null;
    try {
      fw = new OutputStreamWriter(new FileOutputStream(file, append),
          "UTF-8");
      fw.append(content);
    } finally {
      if (fw != null)
        fw.close();
    }
  }

  /**
   * Checks if a file with the given path exists in the HEAD tree
   *
   * @param path
   * @return true if the file exists
   * @throws IOException
   */
  public boolean inHead(String path) throws IOException {
    ObjectId headId = repository.resolve(Constants.HEAD);
    RevWalk rw = new RevWalk(repository);
    TreeWalk tw = null;
    try {
      tw = TreeWalk.forPath(repository, path, rw.parseTree(headId));
      return tw != null;
    } finally {
      rw.release();
      rw.dispose();
      if (tw != null)
        tw.release();
    }
  }

  public boolean inIndex(String absolutePath) throws IOException {
    return getDirCacheEntry(absolutePath) != null;
  }

  public boolean removedFromIndex(String absolutePath) throws IOException {
    DirCacheEntry dc = getDirCacheEntry(absolutePath);
    if (dc == null)
      return true;

    Ref ref = repository.getRef(Constants.HEAD);
    RevCommit c = new RevWalk(repository).parseCommit(ref.getObjectId());
    TreeWalk tw = TreeWalk.forPath(repository, getRepoRelativePath(absolutePath), c.getTree());

    return tw == null || dc.getObjectId().equals(tw.getObjectId(0));
  }

  public long lastModifiedInIndex(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath).getLastModified();
  }

  public int getDirCacheEntryLength(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath).getLength();
  }

  public String getRepoRelativePath(String path) {
    final int pfxLen = workdirPrefix.length();
    final int pLen = path.length();
    if (pLen > pfxLen)
      return path.substring(pfxLen);
    else if (path.length() == pfxLen - 1)
      return ""; //$NON-NLS-1$
    return null;
  }

  public IFile getIFile(IProject project, File file) throws CoreException {
    String relativePath = getRepoRelativePath(file.getAbsolutePath());

    String quotedProjectName = Pattern.quote(project.getName());
    relativePath = relativePath.replaceFirst(quotedProjectName, "");

    IFile iFile = project.getFile(relativePath);
    iFile.refreshLocal(0, null);

    return iFile;
  }

  public void dispose() {
    if (repository != null) {
      repository.close();
      repository = null;
    }
  }

  /**
   * Connect a project to this repository
   *
   * @param project
   * @throws CoreException
   */
  public void connect(IProject project) throws CoreException {
    ConnectProviderOperation op = new ConnectProviderOperation(project,
        this.getRepository().getDirectory());
    op.execute(null);
  }

  /**
   * Disconnects provider from project
   *
   * @param project
   * @throws CoreException
   */
  public void disconnect(IProject project) throws CoreException {
    Collection<IProject> projects = Collections.singleton(project
        .getProject());
    DisconnectProviderOperation disconnect = new DisconnectProviderOperation(
        projects);
    disconnect.execute(null);
  }

  public URIish getUri() throws URISyntaxException {
    return new URIish("file:///" + repository.getDirectory().toString());
  }

  private DirCacheEntry getDirCacheEntry(String path) throws IOException {
    String repoPath = getRepoRelativePath(path);
    DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());

    return dc.getEntry(repoPath);
  }
}
TOP

Related Classes of org.eclipse.egit.core.test.TestRepository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.