/* * Copyright 2000-2016 Vaadin Ltd. * * 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.vaadin.tests.tb3; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.eclipse.jgit.api.DiffCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.diff.RawTextComparator; import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; 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.util.io.DisabledOutputStream; /** * * @since * @author Vaadin Ltd */ public class ChangedTB3TestLocator extends TB3TestLocator { @Override protected <T> List<Class<? extends T>> findClasses(Class<T> baseClass, String basePackage, String[] ignoredPackages) throws IOException { return getChangedTestClasses(baseClass); } protected List<String> getChangedFilePaths() { List<String> filePaths = new ArrayList<>(); for (DiffEntry diff : getDiffs()) { if (diff.getChangeType() != ChangeType.DELETE) { filePaths.add(diff.getNewPath()); System.out.println("Using changed file: " + diff.getNewPath()); } } return filePaths; } private List<DiffEntry> getDiffs() { try { FileRepositoryBuilder builder = new FileRepositoryBuilder(); Repository repository = builder.setWorkTree(new File(".")) .readEnvironment() // scan environment GIT_* variables .findGitDir() // scan up the file system tree .build(); List<DiffEntry> diffsInWorkingTree = getDiffsInWorkingTree( repository); if (diffsInWorkingTree.isEmpty()) { return getDiffsInHead(repository); } return diffsInWorkingTree; } catch (IOException e) { e.printStackTrace(); } catch (NoWorkTreeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (GitAPIException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private List<DiffEntry> getDiffsInWorkingTree(Repository repository) throws GitAPIException { Git git = new Git(repository); DiffCommand diffCommand = git.diff(); List<DiffEntry> diffsInWorkingTree = new ArrayList<>(); for (DiffEntry diff : diffCommand.call()) { if (pathIsExcluded(diff.getNewPath())) { continue; } diffsInWorkingTree.add(diff); } return diffsInWorkingTree; } private boolean pathIsExcluded(String path) { // Exclude temporary junit files and screenshots. return path.startsWith("uitest/junit") || getScreenshotDirectory().contains(path); } private String getScreenshotDirectory() { return PrivateTB3Configuration .getProperty(PrivateTB3Configuration.SCREENSHOT_DIRECTORY); } private List<DiffEntry> getDiffsInHead(Repository repository) throws AmbiguousObjectException, IncorrectObjectTypeException, IOException, MissingObjectException { RevWalk rw = new RevWalk(repository); ObjectId head = repository.resolve(Constants.HEAD); RevCommit commit = rw.parseCommit(head); RevCommit parent = rw.parseCommit(commit.getParent(0).getId()); DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE); df.setRepository(repository); df.setDiffComparator(RawTextComparator.DEFAULT); df.setDetectRenames(true); List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree()); return diffs; } private <T> List<Class<? extends T>> getChangedTestClasses( Class<T> baseClass) { List<String> changedTestFilePaths = getTestFilePaths(); List<Class<? extends T>> testClasses = new ArrayList<>(); for (String filePath : changedTestFilePaths) { String path = filePath.replace("uitest/src/", "").replace(".java", ""); String className = path.replace("/", "."); addClassIfMatches(testClasses, className, baseClass); } return testClasses; } private List<String> getTestFilePaths() { List<String> changedTestFilePaths = new ArrayList<>(); for (String filePath : getChangedFilePaths()) { if (filePath.toLowerCase().startsWith("uitest") && filePath.toLowerCase().endsWith(".java")) { changedTestFilePaths.add(filePath); } } return changedTestFilePaths; } }