    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.release.plugin.mojos;
    018
    019import org.apache.commons.lang3.StringUtils;
    020import org.apache.commons.release.plugin.SharedFunctions;
    021import org.apache.maven.plugin.AbstractMojo;
    022import org.apache.maven.plugin.MojoExecutionException;
    023import org.apache.maven.plugin.MojoFailureException;
    024import org.apache.maven.plugins.annotations.Component;
    025import org.apache.maven.plugins.annotations.LifecyclePhase;
    026import org.apache.maven.plugins.annotations.Mojo;
    027import org.apache.maven.plugins.annotations.Parameter;
    028import org.apache.maven.project.MavenProject;
    029import org.apache.maven.scm.ScmException;
    030import org.apache.maven.scm.ScmFileSet;
    031import org.apache.maven.scm.command.checkin.CheckInScmResult;
    032import org.apache.maven.scm.command.checkout.CheckOutScmResult;
    033import org.apache.maven.scm.command.remove.RemoveScmResult;
    034import org.apache.maven.scm.manager.BasicScmManager;
    035import org.apache.maven.scm.manager.ScmManager;
    036import org.apache.maven.scm.provider.ScmProvider;
    037import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
    038import org.apache.maven.scm.provider.svn.svnexe.SvnExeScmProvider;
    039import org.apache.maven.scm.repository.ScmRepository;
    040import org.apache.maven.settings.Settings;
    041import org.apache.maven.settings.crypto.SettingsDecrypter;
    042
    043import java.io.File;
    044import java.util.Arrays;
    045import java.util.List;
    046
    047/**
    048 * This class checks out the dev distribution location, checks whether anything exists in the
    049 * distribution location, and if it is non-empty it deletes all the resources there.
    050 *
    051 * @since 1.6
    052 */
    053@Mojo(name = "clean-staging",
    054        defaultPhase = LifecyclePhase.POST_CLEAN,
    055        threadSafe = true,
    056        aggregator = true)
    057public class CommonsStagingCleanupMojo extends AbstractMojo {
    058
    059    /**
    060     * The {@link MavenProject} object is essentially the context of the maven build at
    061     * a given time.
    062     */
    063    @Parameter(defaultValue = "${project}", required = true)
    064    private MavenProject project;
    065
    066    /**
    067     * The main working directory for the plugin, namely <code>target/commons-release-plugin</code>, but
    068     * that assumes that we're using the default maven <code>${project.build.directory}</code>.
    069     */
    070    @Parameter(defaultValue = "${project.build.directory}/commons-release-plugin", property = "commons.outputDirectory")
    071    private File workingDirectory;
    072
    073    /**
    074     * The location to which to checkout the dist subversion repository under our working directory, which
    075     * was given above. We then do an SVN delete on all the directories in this repository.
    076     */
    077    @Parameter(defaultValue = "${project.build.directory}/commons-release-plugin/scm-cleanup",
    078            property = "commons.distCleanupDirectory")
    079    private File distCleanupDirectory;
    080
    081    /**
    082     * A boolean that determines whether or not we actually commit the files up to the subversion repository.
    083     * If this is set to {@code true}, we do all but make the commits. We do checkout the repository in question
    084     * though.
    085     */
    086    @Parameter(property = "commons.release.dryRun", defaultValue = "false")
    087    private Boolean dryRun;
    088
    089    /**
    090     * The url of the subversion repository to which we wish the artifacts to be staged. Typically this would need to
    091     * be of the form: <code>scm:svn:https://dist.apache.org/repos/dist/dev/commons/foo/version-RC#</code>. Note. that
    092     * the prefix to the substring <code>https</code> is a requirement.
    093     */
    094    @Parameter(defaultValue = "", property = "commons.distSvnStagingUrl")
    095    private String distSvnStagingUrl;
    096
    097    /**
    098     * A parameter to generally avoid running unless it is specifically turned on by the consuming module.
    099     */
    100    @Parameter(defaultValue = "false", property = "commons.release.isDistModule")
    101    private Boolean isDistModule;
    102
    103    /**
    104     * The ID of the server (specified in settings.xml) which should be used for dist authentication.
    105     * This will be used in preference to {@link #username}/{@link #password}.
    106     */
    107    @Parameter(property = "commons.distServer")
    108    private String distServer;
    109
    110    /**
    111     * The username for the distribution subversion repository. This is typically your Apache id.
    112     */
    113    @Parameter(property = "user.name")
    114    private String username;
    115
    116    /**
    117     * The password associated with {@link CommonsDistributionStagingMojo#username}.
    118     */
    119    @Parameter(property = "user.password")
    120    private String password;
    121
    122    /**
    123     * Maven {@link Settings}.
    124     */
    125    @Parameter(defaultValue = "${settings}", readonly = true, required = true)
    126    private Settings settings;
    127
    128    /**
    129     * Maven {@link SettingsDecrypter} component.
    130     */
    131    @Component
    132    private SettingsDecrypter settingsDecrypter;
    133
    134    @Override
    135    public void execute() throws MojoExecutionException, MojoFailureException {
    136        if (!isDistModule) {
    137            getLog().info("This module is marked as a non distribution "
    138                    + "or assembly module, and the plugin will not run.");
    139            return;
    140        }
    141        if (StringUtils.isEmpty(distSvnStagingUrl)) {
    142            getLog().warn("commons.distSvnStagingUrl is not set, the commons-release-plugin will not run.");
    143            return;
    144        }
    145        if (!workingDirectory.exists()) {
    146            SharedFunctions.initDirectory(getLog(), workingDirectory);
    147        }
    148        try {
    149            final ScmManager scmManager = new BasicScmManager();
    150            scmManager.setScmProvider("svn", new SvnExeScmProvider());
    151            final ScmRepository repository = scmManager.makeScmRepository(distSvnStagingUrl);
    152            final ScmProvider provider = scmManager.getProviderByRepository(repository);
    153            final SvnScmProviderRepository providerRepository = (SvnScmProviderRepository) repository
    154                    .getProviderRepository();
    155            SharedFunctions.setAuthentication(
    156                    providerRepository,
    157                    distServer,
    158                    settings,
    159                    settingsDecrypter,
    160                    username,
    161                    password
    162            );
    163            getLog().info("Checking out dist from: " + distSvnStagingUrl);
    164            final ScmFileSet scmFileSet = new ScmFileSet(distCleanupDirectory);
    165            final CheckOutScmResult checkOutResult = provider.checkOut(repository, scmFileSet);
    166            if (!checkOutResult.isSuccess()) {
    167                throw new MojoExecutionException("Failed to checkout files from SCM: "
    168                        + checkOutResult.getProviderMessage() + " [" + checkOutResult.getCommandOutput() + "]");
    169            }
    170            final List<File> filesToRemove = Arrays.asList(distCleanupDirectory.listFiles());
    171            if (filesToRemove.size() == 1) {
    172                getLog().info("No files to delete");
    173                return;
    174            }
    175            if (!dryRun) {
    176                final ScmFileSet fileSet = new ScmFileSet(distCleanupDirectory, filesToRemove);
    177                final RemoveScmResult removeScmResult = provider.remove(repository, fileSet,
    178                        "Cleaning up staging area");
    179                if (!removeScmResult.isSuccess()) {
    180                    throw new MojoFailureException("Failed to remove files from SCM: "
    181                            + removeScmResult.getProviderMessage()
    182                            + " [" + removeScmResult.getCommandOutput() + "]");
    183                }
    184                getLog().info("Cleaning distribution area for: " + project.getArtifactId());
    185                final CheckInScmResult checkInResult = provider.checkIn(
    186                        repository,
    187                        fileSet,
    188                        "Cleaning distribution area for: " + project.getArtifactId()
    189                );
    190                if (!checkInResult.isSuccess()) {
    191                    throw new MojoFailureException("Failed to commit files: " + removeScmResult.getProviderMessage()
    192                            + " [" + removeScmResult.getCommandOutput() + "]");
    193                }
    194            } else {
    195                getLog().info("Would have attempted to delete files from: " + distSvnStagingUrl);
    196            }
    197        } catch (final ScmException e) {
    198            throw new MojoFailureException(e.getMessage());
    199        }
    200
    201    }
    202}