All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gradle.api.plugins.buildcomparison.gradle.CompareGradleBuilds Maven / Gradle / Ivy

There is a newer version: 8.6
Show newest version
/*
 * Copyright 2012 the original author or authors.
 *
 * 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 org.gradle.api.plugins.buildcomparison.gradle;

import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Task;
import org.gradle.api.logging.Logger;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.buildcomparison.compare.internal.BuildComparisonResult;
import org.gradle.api.plugins.buildcomparison.gradle.internal.ComparableGradleBuildExecuter;
import org.gradle.api.plugins.buildcomparison.gradle.internal.DefaultGradleBuildInvocationSpec;
import org.gradle.api.plugins.buildcomparison.gradle.internal.GradleBuildComparison;
import org.gradle.api.plugins.buildcomparison.gradle.internal.MovableFileStore;
import org.gradle.api.plugins.buildcomparison.outcome.internal.archive.GeneratedArchiveBuildOutcome;
import org.gradle.api.plugins.buildcomparison.outcome.internal.archive.GeneratedArchiveBuildOutcomeComparator;
import org.gradle.api.plugins.buildcomparison.outcome.internal.archive.GeneratedArchiveBuildOutcomeComparisonResultHtmlRenderer;
import org.gradle.api.plugins.buildcomparison.outcome.internal.archive.GeneratedArchiveBuildOutcomeHtmlRenderer;
import org.gradle.api.plugins.buildcomparison.outcome.internal.unknown.UnknownBuildOutcome;
import org.gradle.api.plugins.buildcomparison.outcome.internal.unknown.UnknownBuildOutcomeComparator;
import org.gradle.api.plugins.buildcomparison.outcome.internal.unknown.UnknownBuildOutcomeComparisonResultHtmlRenderer;
import org.gradle.api.plugins.buildcomparison.outcome.internal.unknown.UnknownBuildOutcomeHtmlRenderer;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.VerificationTask;
import org.gradle.internal.file.PathToFileResolver;
import org.gradle.internal.logging.ConsoleRenderer;
import org.gradle.internal.logging.progress.ProgressLogger;
import org.gradle.internal.logging.progress.ProgressLoggerFactory;
import org.gradle.internal.resource.local.FileStore;
import org.gradle.internal.resource.local.FileStoreException;
import org.gradle.internal.resource.local.LocallyAvailableResource;
import org.gradle.internal.resource.local.PathNormalisingKeyFileStore;
import org.gradle.util.GFileUtils;
import org.gradle.util.GradleVersion;

import javax.inject.Inject;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Executes two Gradle builds (that can be the same build) with specified versions and compares the outcomes.
 *
 * Please see the “Comparing Builds” chapter of the Gradle User Manual for more information.
 */
@Deprecated
public class CompareGradleBuilds extends DefaultTask implements VerificationTask {

    public static final List DEFAULT_TASKS = Arrays.asList("clean", "assemble");

    private static final String TMP_FILESTORAGE_PREFIX = "tmp-filestorage";

    private final GradleBuildInvocationSpec sourceBuild;
    private final GradleBuildInvocationSpec targetBuild;
    private boolean ignoreFailures;
    private Object reportDir;

    public CompareGradleBuilds() {
        PathToFileResolver fileResolver = getFileResolver();
        ObjectFactory objectFactory = getObjectFactory();
        sourceBuild = objectFactory.newInstance(DefaultGradleBuildInvocationSpec.class, fileResolver, getProject().getRootDir());
        sourceBuild.setTasks(DEFAULT_TASKS);
        targetBuild = objectFactory.newInstance(DefaultGradleBuildInvocationSpec.class, fileResolver, getProject().getRootDir());
        targetBuild.setTasks(DEFAULT_TASKS);

        // Never up to date
        getOutputs().upToDateWhen(new Spec() {
            @Override
            public boolean isSatisfiedBy(Task element) {
                return false;
            }
        });
    }

    @Inject
    protected PathToFileResolver getFileResolver() {
        throw new UnsupportedOperationException();
    }

    @Inject
    protected ProgressLoggerFactory getProgressLoggerFactory() {
        throw new UnsupportedOperationException();
    }

    /**
     * Injects and returns an instance of {@link ObjectFactory}.
     *
     * @since 4.2
     */
    @Inject
    protected ObjectFactory getObjectFactory() {
        throw new UnsupportedOperationException();
    }

    /**
     * The specification of how to invoke the source build.
     *
     * Defaults to {@link org.gradle.api.Project#getRootDir() project.rootDir} with the current Gradle version
     * and the tasks “clean assemble”.
     *
     * The {@code projectDir} must be the project directory of the root project if this is a multi project build.
     *
     * @return The specification of how to invoke the source build.
     */
    @Nested
    public GradleBuildInvocationSpec getSourceBuild() {
        return sourceBuild;
    }

    /**
     * Configures the source build.
     *
     * A Groovy closure can be used as the action.
     * 
     * sourceBuild {
     *   gradleVersion = "1.1"
     * }
     * 
* * @param config The configuration action. */ @SuppressWarnings("UnusedDeclaration") public void sourceBuild(Action config) { config.execute(getSourceBuild()); } /** * The specification of how to invoke the target build. * * Defaults to {@link org.gradle.api.Project#getRootDir() project.rootDir} with the current Gradle version * and the tasks “clean assemble”. * * The {@code projectDir} must be the project directory of the root project if this is a multi project build. * * @return The specification of how to invoke the target build. */ @Nested public GradleBuildInvocationSpec getTargetBuild() { return targetBuild; } /** * Configures the target build. * * A Groovy closure can be used as the action. *
     * targetBuild {
     *   gradleVersion = "1.1"
     * }
     * 
* * @param config The configuration action. */ @SuppressWarnings("UnusedDeclaration") public void targetBuild(Action config) { config.execute(getTargetBuild()); } /** * Whether a comparison between non identical builds will fail the task execution. * * @return True if a comparison between non identical builds will fail the task execution, otherwise false. */ @Override public boolean getIgnoreFailures() { return ignoreFailures; } /** * Sets whether a comparison between non identical builds will fail the task execution. * * @param ignoreFailures false to fail the task on non identical builds, true to not fail the task. The default is false. */ @Override public void setIgnoreFailures(boolean ignoreFailures) { this.ignoreFailures = ignoreFailures; } /** * The directory that will contain the HTML comparison report and any other report files. * * @return The directory that will contain the HTML comparison report and any other report files. */ @OutputDirectory public File getReportDir() { return reportDir == null ? null : getFileResolver().resolve(reportDir); } /** * Sets the directory that will contain the HTML comparison report and any other report files. * * @param reportDir The directory that will contain the HTML comparison report and any other report files. * @since 4.0 */ public void setReportDir(File reportDir) { setReportDir((Object) reportDir); } /** * Sets the directory that will contain the HTML comparison report and any other report files. * * The value will be evaluated by {@link org.gradle.api.Project#file(Object) project.file()}. * * @param reportDir The directory that will contain the HTML comparison report and any other report files. */ @SuppressWarnings("UnusedDeclaration") public void setReportDir(Object reportDir) { if (reportDir == null) { throw new IllegalArgumentException("reportDir cannot be null"); } this.reportDir = reportDir; } @SuppressWarnings("UnusedDeclaration") @TaskAction void compare() { GradleBuildInvocationSpec sourceBuild = getSourceBuild(); GradleBuildInvocationSpec targetBuild = getTargetBuild(); if (sourceBuild.equals(targetBuild)) { getLogger().warn("The source build and target build are identical. Set '{}.targetBuild.gradleVersion' if you want to compare with a different Gradle version.", getName()); } ComparableGradleBuildExecuter sourceBuildExecuter = new ComparableGradleBuildExecuter(sourceBuild); ComparableGradleBuildExecuter targetBuildExecuter = new ComparableGradleBuildExecuter(targetBuild); Logger logger = getLogger(); ProgressLogger progressLogger = getProgressLoggerFactory().newOperation(getClass()); progressLogger.setDescription("Gradle Build Comparison"); GradleBuildComparison comparison = new GradleBuildComparison( sourceBuildExecuter, targetBuildExecuter, logger, progressLogger, getProject().getGradle() ); comparison.registerType( GeneratedArchiveBuildOutcome.class, new GeneratedArchiveBuildOutcomeComparator(), new GeneratedArchiveBuildOutcomeComparisonResultHtmlRenderer(), new GeneratedArchiveBuildOutcomeHtmlRenderer() ); comparison.registerType( UnknownBuildOutcome.class, new UnknownBuildOutcomeComparator(), new UnknownBuildOutcomeComparisonResultHtmlRenderer(), new UnknownBuildOutcomeHtmlRenderer() ); File fileStoreTmpBase = getFileResolver().resolve(String.format(TMP_FILESTORAGE_PREFIX + "-%s-%s", getName(), System.currentTimeMillis())); MovableFileStore fileStore = new Files(fileStoreTmpBase); Map hostAttributes = new LinkedHashMap(4); hostAttributes.put("Project", getProject().getRootDir().getAbsolutePath()); hostAttributes.put("Task", getPath()); hostAttributes.put("Gradle version", GradleVersion.current().getVersion()); hostAttributes.put("Executed at", new SimpleDateFormat().format(new Date())); BuildComparisonResult result = comparison.compare(fileStore, getReportDir(), hostAttributes); communicateResult(result); } private void communicateResult(BuildComparisonResult result) { File reportFile = new File(getReportDir(), GradleBuildComparison.HTML_REPORT_FILE_NAME); String reportUrl = new ConsoleRenderer().asClickableFileUrl(reportFile); if (result.isBuildsAreIdentical()) { getLogger().info("The build outcomes were found to be identical. See the report at: {}", reportUrl); } else { String message = String.format("The build outcomes were not found to be identical. See the report at: %s", reportUrl); if (getIgnoreFailures()) { getLogger().warn(message); } else { throw new GradleException(message); } } } private static class Files implements MovableFileStore { private final File baseDir; private final FileStore delegate; public Files(File baseDir) { this.baseDir = baseDir; this.delegate = new PathNormalisingKeyFileStore(baseDir); } @Override public void moveFileStore(File destination) { if (baseDir.isDirectory()) { GFileUtils.moveDirectory(baseDir, destination); } } @Override public LocallyAvailableResource move(String key, File source) throws FileStoreException { return delegate.move(key, source); } @Override public LocallyAvailableResource add(String key, Action addAction) throws FileStoreException { return delegate.add(key, addAction); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy