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

org.apache.maven.scm.plugin.AbstractScmMojo Maven / Gradle / Ivy

Go to download

Kuali version of the maven-scm-plugin that supports removing files from SCM. The 1.6-SNAPSHOT version of the maven-scm-plugin at Apache has this ability but their 1.6-SNAPSHOT version hasn't been released yet. As soon as they do, the Kuali version of this plugin can be abandoned in favor of the one from Apache

The newest version!
package org.apache.maven.scm.plugin;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.scm.ScmBranch;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.ScmResult;
import org.apache.maven.scm.ScmRevision;
import org.apache.maven.scm.ScmTag;
import org.apache.maven.scm.ScmVersion;
import org.apache.maven.scm.manager.ScmManager;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
import org.apache.maven.scm.repository.ScmRepository;
import org.apache.maven.scm.repository.ScmRepositoryException;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.model.fileset.FileSet;
import org.apache.maven.shared.model.fileset.util.FileSetManager;
import org.codehaus.plexus.util.StringUtils;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;

/**
 * @author Emmanuel Venisse
 * @author Olivier Lamy
 * @version $Id: AbstractScmMojo.java 1069361 2011-02-10 12:38:18Z bentmann $
 */
public abstract class AbstractScmMojo
    extends AbstractMojo
{
    /**
     * The SCM connection URL.
     *
     * @parameter expression="${connectionUrl}" default-value="${project.scm.connection}"
     */
    private String connectionUrl;

    /**
     * The SCM connection URL for developers.
     *
     * @parameter expression="${connectionUrl}" default-value="${project.scm.developerConnection}"
     */
    private String developerConnectionUrl;

    /**
     * The type of connection to use (connection or developerConnection).
     *
     * @parameter expression="${connectionType}" default-value="connection"
     */
    private String connectionType;

    /**
     * The working directory.
     *
     * @parameter expression="${workingDirectory}"
     */
    private File workingDirectory;

    /**
     * The user name (used by svn, starteam and perforce protocol).
     *
     * @parameter expression="${username}"
     */
    private String username;

    /**
     * The user password (used by svn, starteam and perforce protocol).
     *
     * @parameter expression="${password}"
     */
    private String password;

    /**
     * The private key (used by java svn).
     *
     * @parameter expression="${privateKey}"
     */
    private String privateKey;

    /**
     * The passphrase (used by java svn).
     *
     * @parameter expression="${passphrase}"
     */
    private String passphrase;

    /**
     * The url of tags base directory (used by svn protocol). It is not
     * necessary to set it if you use the standard svn layout
     * (branches/tags/trunk).
     *
     * @parameter expression="${tagBase}"
     */
    private String tagBase;

    /**
     * Comma separated list of includes file pattern.
     *
     * @parameter expression="${includes}"
     */
    private String includes;

    /**
     * Comma separated list of excludes file pattern.
     *
     * @parameter expression="${excludes}"
     */
    private String excludes;

    /**
     * @component
     */
    private ScmManager manager;

    /**
     * When this plugin requires Maven 3.0 as minimum, this component can be removed and o.a.m.s.c.SettingsDecrypter be
     * used instead.
     * 
     * @component roleHint="mng-4384"
     */
    private SecDispatcher secDispatcher;

    /**
     * The base directory.
     *
     * @parameter expression="${basedir}"
     * @required
     */
    private File basedir;

    /**
     * @parameter default-value="${settings}"
     * @required
     * @readonly
     */
    private Settings settings;

    /**
     * List of System properties to pass to the JUnit tests.
     *
     * @parameter
     */
    private Properties systemProperties;

    /**
     * List of provider implementations.
     *
     * @parameter
     */
    private Map providerImplementations;
    
    /**
     * Should distributed changes be pushed to the central repository?
     * For many distributed SCMs like Git, a change like a commit 
     * is only stored in your local copy of the repository.  Pushing
     * the change allows your to more easily share it with other users.
     * 
     * @parameter expression="${pushChanges}" default-value="true"
     * @since 1.4
     */
    private boolean pushChanges;

    /** {@inheritDoc} */
    public void execute()
        throws MojoExecutionException
    {
        if ( systemProperties != null )
        {
            // Add all system properties configured by the user
            Iterator iter = systemProperties.keySet().iterator();

            while ( iter.hasNext() )
            {
                String key = (String) iter.next();

                String value = systemProperties.getProperty( key );

                System.setProperty( key, value );
            }
        }

        if ( providerImplementations != null && !providerImplementations.isEmpty() )
        {
            for ( Entry entry : providerImplementations.entrySet() )
            {
                String providerType = entry.getKey();
                String providerImplementation = entry.getValue();
                getLog().info(
                               "Change the default '" + providerType + "' provider implementation to '"
                                   + providerImplementation + "'." );
                getScmManager().setScmProviderImplementation( providerType, providerImplementation );
            }
        }
    }

    protected void setConnectionType( String connectionType )
    {
        this.connectionType = connectionType;
    }

    public String getConnectionUrl()
    {
        boolean requireDeveloperConnection = !"connection".equals( connectionType.toLowerCase() );
        if ( StringUtils.isNotEmpty( connectionUrl ) && !requireDeveloperConnection )
        {
            return connectionUrl;
        }
        else if ( StringUtils.isNotEmpty( developerConnectionUrl ) )
        {
            return developerConnectionUrl;
        }
        if ( requireDeveloperConnection )
        {
            throw new NullPointerException( "You need to define a developerConnectionUrl parameter" );
        }
        else
        {
            throw new NullPointerException( "You need to define a connectionUrl parameter" );
        }
    }

    public void setConnectionUrl( String connectionUrl )
    {
        this.connectionUrl = connectionUrl;
    }

    public File getWorkingDirectory()
    {
        if ( workingDirectory == null )
        {
            return basedir;
        }

        return workingDirectory;
    }

    public void setWorkingDirectory( File workingDirectory )
    {
        this.workingDirectory = workingDirectory;
    }

    public ScmManager getScmManager()
    {
        return manager;
    }

    public ScmFileSet getFileSet()
        throws IOException
    {
        if ( includes != null || excludes != null )
        {
            return new ScmFileSet( getWorkingDirectory(), includes, excludes );
        }
        else
        {
            return new ScmFileSet( getWorkingDirectory() );
        }
    }

    public ScmRepository getScmRepository()
        throws ScmException
    {
        ScmRepository repository;

        try
        {
            repository = getScmManager().makeScmRepository( getConnectionUrl() );

            ScmProviderRepository providerRepo = repository.getProviderRepository();
            
            providerRepo.setPushChanges( pushChanges );

            if ( !StringUtils.isEmpty( username ) )
            {
                providerRepo.setUser( username );
            }

            if ( !StringUtils.isEmpty( password ) )
            {
                providerRepo.setPassword( password );
            }

            if ( repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost )
            {
                ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHost) repository.getProviderRepository();

                loadInfosFromSettings( repo );

                if ( !StringUtils.isEmpty( username ) )
                {
                    repo.setUser( username );
                }

                if ( !StringUtils.isEmpty( password ) )
                {
                    repo.setPassword( password );
                }

                if ( !StringUtils.isEmpty( privateKey ) )
                {
                    repo.setPrivateKey( privateKey );
                }

                if ( !StringUtils.isEmpty( passphrase ) )
                {
                    repo.setPassphrase( passphrase );
                }
            }

            if ( !StringUtils.isEmpty( tagBase ) && repository.getProvider().equals( "svn" ) )
            {
                SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();

                svnRepo.setTagBase( tagBase );
            }
        }
        catch ( ScmRepositoryException e )
        {
            if ( !e.getValidationMessages().isEmpty() )
            {
                for ( String message : e.getValidationMessages() )
                {
                    getLog().error( message );
                }
            }

            throw new ScmException( "Can't load the scm provider.", e );
        }
        catch ( Exception e )
        {
            throw new ScmException( "Can't load the scm provider.", e );
        }

        return repository;
    }

    /**
     * Load username password from settings if user has not set them in JVM properties
     *
     * @param repo not null
     */
    private void loadInfosFromSettings( ScmProviderRepositoryWithHost repo )
    {
        if ( username == null || password == null )
        {
            String host = repo.getHost();

            int port = repo.getPort();

            if ( port > 0 )
            {
                host += ":" + port;
            }

            Server server = this.settings.getServer( host );

            if ( server != null )
            {
                if ( username == null )
                {
                    username = server.getUsername();
                }

                if ( password == null )
                {
                    password = decrypt( server.getPassword(), host );
                }

                if ( privateKey == null )
                {
                    privateKey = server.getPrivateKey();
                }

                if ( passphrase == null )
                {
                    passphrase = decrypt( server.getPassphrase(), host );
                }
            }
        }
    }

    private String decrypt( String str, String server )
    {
        try
        {
            return secDispatcher.decrypt( str );
        }
        catch ( SecDispatcherException e )
        {
            getLog().warn( "Failed to decrypt password/passphrase for server " + server + ", using auth token as is" );
            return str;
        }
    }

    public void checkResult( ScmResult result )
        throws MojoExecutionException
    {
        if ( !result.isSuccess() )
        {
            getLog().error( "Provider message:" );

            getLog().error( result.getProviderMessage() == null ? "" : result.getProviderMessage() );

            getLog().error( "Command output:" );

            getLog().error( result.getCommandOutput() == null ? "" : result.getCommandOutput() );

            throw new MojoExecutionException(
                "Command failed." + StringUtils.defaultString( result.getProviderMessage() ) );
        }
    }

    public String getIncludes()
    {
        return includes;
    }

    public void setIncludes( String includes )
    {
        this.includes = includes;
    }

    public String getExcludes()
    {
        return excludes;
    }

    public void setExcludes( String excludes )
    {
        this.excludes = excludes;
    }

    public ScmVersion getScmVersion( String versionType, String version )
        throws MojoExecutionException
    {
        if ( StringUtils.isEmpty( versionType ) && StringUtils.isNotEmpty( version ) )
        {
            throw new MojoExecutionException( "You must specify the version type." );
        }

        if ( StringUtils.isEmpty( version ) )
        {
            return null;
        }

        if ( "branch".equals( versionType ) )
        {
            return new ScmBranch( version );
        }

        if ( "tag".equals( versionType ) )
        {
            return new ScmTag( version );
        }

        if ( "revision".equals( versionType ) )
        {
            return new ScmRevision( version );
        }

        throw new MojoExecutionException( "Unknown '" + versionType + "' version type." );
    }
    
    protected void handleExcludesIncludesAfterCheckoutAndExport( File checkoutDirectory )
        throws MojoExecutionException
    {
        List includes = new ArrayList();

        if ( ! StringUtils.isBlank( this.getIncludes() ) )
        {
            String[] tokens = StringUtils.split( this.getIncludes(), "," );
            for ( int i = 0; i < tokens.length; ++i )
            {
                includes.add( tokens[i] );
            }
        }

        List excludes = new ArrayList();

        if ( ! StringUtils.isBlank( this.getExcludes() ) )
        {
            String[] tokens = StringUtils.split( this.getExcludes(), "," );
            for ( int i = 0; i < tokens.length; ++i )
            {
                excludes.add( tokens[i] );
            }
        }
        
        if ( includes.isEmpty() &&  excludes.isEmpty() )
        {
            return;
        }

        FileSetManager fileSetManager = new FileSetManager();

        FileSet fileset = new FileSet();
        fileset.setDirectory( checkoutDirectory.getAbsolutePath() );
        fileset.setIncludes( excludes );//revert the order to do the delete
        fileset.setExcludes( includes );
        fileset.setUseDefaultExcludes( false );

        try
        {
            fileSetManager.delete( fileset );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error found while cleaning up output directory base on excludes/includes configurations.", e );
        }

    }
}