blob: 6375b7fc619c8ece042eafd4800a74cab028dfa4 [file] [log] [blame]
//
// Copyright (c) 2011 Kevin Sawicki <kevinsawicki@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
// Copyright (C) 2017 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.googlesource.gerrit.plugins.analytics.test
import java.io.File
import java.io.PrintWriter
import java.text.MessageFormat
import java.util.Date
import java.util
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.api.MergeResult
import org.eclipse.jgit.api.errors.GitAPIException
import org.eclipse.jgit.lib.Constants
import org.eclipse.jgit.lib.PersonIdent
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.notes.Note
import org.eclipse.jgit.revwalk.RevCommit
import org.gitective.core.CommitUtils
import org.scalatest.{BeforeAndAfterEach, Suite}
/**
* Base test case with utilities for common Git operations performed during
* testing
*/
trait GitTestCase extends BeforeAndAfterEach {
self: Suite =>
/**
* Test repository .git directory
*/
protected var testRepo: File = null
/**
* Author used for commits
*/
protected val author = new PersonIdent("Test Author", "author@test.com")
def newPersonIdent(name: String = "Test Person", email: String = "person@test.com", ts: Date = new Date()) =
new PersonIdent(new PersonIdent(name, email), ts)
/**
* Committer used for commits
*/
protected val committer = new PersonIdent("Test Committer", "committer@test.com")
/**
* Set up method that initializes git repository
*
*
*/
override def beforeEach = {
testRepo = initRepo
}
/**
* Initialize a new repo in a new directory
*
* @return created .git folder
* @throws GitAPIException
*/
protected def initRepo: File = {
val tmpDir = System.getProperty("java.io.tmpdir")
assert(tmpDir != null, "java.io.tmpdir was null")
val dir = new File(tmpDir, "git-test-case-" + System.nanoTime)
assert(dir.mkdir)
Git.init.setDirectory(dir).setBare(false).call
val repo = new File(dir, Constants.DOT_GIT)
assert(repo.exists)
repo.deleteOnExit()
repo
}
/**
* Create branch with name and checkout
*
* @param name
* @return branch ref
*
*/
protected def branch(name: String): Ref = branch(testRepo, name)
/**
* Create branch with name and checkout
*
* @param repo
* @param name
* @return branch ref
*
*/
protected def branch(repo: File, name: String): Ref = {
val git = Git.open(repo)
git.branchCreate.setName(name).call
checkout(repo, name)
}
/**
* Checkout branch
*
* @param name
* @return branch ref
*
*/
protected def checkout(name: String): Ref = checkout(testRepo, name)
/**
* Checkout branch
*
* @param repo
* @param name
* @return branch ref
*
*/
@throws[Exception]
protected def checkout(repo: File, name: String): Ref = {
val git = Git.open(repo)
val ref = git.checkout.setName(name).call
assert(ref != null)
ref
}
/**
* Create tag with name
*
* @param name
* @return tag ref
*
*/
protected def tag(name: String): Ref = tag(testRepo, name)
/**
* Create tag with name
*
* @param repo
* @param name
* @return tag ref
*
*/
protected def tag(repo: File, name: String): Ref = {
val git = Git.open(repo)
git.tag.setName(name).setMessage(name).call
val tagRef = git.getRepository.getTags.get(name)
assert(tagRef != null)
tagRef
}
/**
* Add file to test repository
*
* @param path
* @param content
* @return commit
*
*/
protected def add(path: String, content: String, author: PersonIdent = author, committer: PersonIdent = committer): RevCommit = add(testRepo, path, content, author, committer)
/**
* Add file to test repository
*
* @param repo
* @param path
* @param content
* @return commit
*
*/
protected def add(repo: File, path: String, content: String, author: PersonIdent, committer: PersonIdent): RevCommit = {
val message = MessageFormat.format("Committing {0} at {1}", path, new Date)
add(repo, path, content, message, author, committer)
}
/**
* Add file to test repository
*
* @param repo
* @param path
* @param content
* @param message
* @return commit
*
*/
protected def add(repo: File, path: String, content: String, message: String, author: PersonIdent, committer: PersonIdent): RevCommit = {
val file = new File(repo.getParentFile, path)
if (!file.getParentFile.exists) assert(file.getParentFile.mkdirs)
if (!file.exists) assert(file.createNewFile)
val writer = new PrintWriter(file)
try
writer.print(Option(content).fold("")(identity))
finally writer.close()
val git = Git.open(repo)
git.add.addFilepattern(path).call
val commit = git.commit.setOnly(path).setMessage(message).setAuthor(author).setCommitter(committer).call
assert(null != commit)
commit
}
/**
* Move file in test repository
*
* @param from
* @param to
* @return commit
*
*/
protected def mv(from: String, to: String): RevCommit = mv(testRepo, from, to, MessageFormat.format("Moving {0} to {1} at {2}", from, to, new Date))
/**
* Move file in test repository
*
* @param from
* @param to
* @param message
* @return commit
*
*/
protected def mv(from: String, to: String, message: String): RevCommit = mv(testRepo, from, to, message)
/**
* Move file in test repository
*
* @param repo
* @param from
* @param to
* @param message
* @return commit
*
*/
protected def mv(repo: File, from: String, to: String, message: String): RevCommit = {
val file = new File(repo.getParentFile, from)
file.renameTo(new File(repo.getParentFile, to))
val git = Git.open(repo)
git.rm.addFilepattern(from)
git.add.addFilepattern(to).call
val commit = git.commit.setAll(true).setMessage(message).setAuthor(author).setCommitter(committer).call
assert(null != commit)
commit
}
/**
* Add files to test repository
*
* @param paths
* @param contents
* @return commit
*
*/
protected def add(paths: util.List[String], contents: util.List[String]): RevCommit = add(testRepo, paths, contents, "Committing multiple files")
/**
* Add files to test repository
*
* @param repo
* @param paths
* @param contents
* @param message
* @return commit
*
*/
protected def add(repo: File, paths: util.List[String], contents: util.List[String], message: String): RevCommit = {
val git = Git.open(repo)
var i = 0
while ( {
i < paths.size
}) {
val path = paths.get(i)
var content = contents.get(i)
val file = new File(repo.getParentFile, path)
if (!file.getParentFile.exists) assert(file.getParentFile.mkdirs)
if (!file.exists) assert(file.createNewFile)
val writer = new PrintWriter(file)
if (content == null) content = ""
try
writer.print(content)
finally writer.close()
git.add.addFilepattern(path).call
{
i += 1;
i - 1
}
}
val commit = git.commit.setMessage(message).setAuthor(author).setCommitter(committer).call
assert(null != commit)
commit
}
/**
* Merge ref into current branch
*
* @param ref
* @return result
*
*/
protected def merge(ref: String): MergeResult = {
val git = Git.open(testRepo)
git.merge.setStrategy(MergeStrategy.RESOLVE).include(CommitUtils.getCommit(git.getRepository, ref)).call
}
/**
* Add note to latest commit with given content
*
* @param content
* @return note
*
*/
protected def note(content: String): Note = note(content, "commits")
/**
* Add note to latest commit with given content
*
* @param content
* @param ref
* @return note
*
*/
protected def note(content: String, ref: String): Note = {
val git = Git.open(testRepo)
val note = git.notesAdd.setMessage(content).setNotesRef(Constants.R_NOTES + ref).setObjectId(CommitUtils.getHead(git.getRepository)).call
assert(null != note)
note
}
/**
* Delete and commit file at path
*
* @param path
* @return commit
*
*/
protected def delete(path: String): RevCommit = {
val message = MessageFormat.format("Committing {0} at {1}", path, new Date)
val git = Git.open(testRepo)
git.rm.addFilepattern(path).call
val commit = git.commit.setOnly(path).setMessage(message).setAuthor(author).setCommitter(committer).call
assert(null != commit)
commit
}
}