MPARTIFACT-75 : Allow to sign artifacts to deploy

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@528699 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
aheritier 2007-04-13 23:12:22 +00:00
parent f8eacd8b86
commit 98b46d4fba
8 changed files with 459 additions and 217 deletions

View File

@ -22,4 +22,10 @@ maven.artifact.manifest.extensions.add=false
maven.artifact.manifest.basedir=${plugin.dir}/plugin-resources/templates maven.artifact.manifest.basedir=${plugin.dir}/plugin-resources/templates
maven.artifact.manifest.template=manifest.vm maven.artifact.manifest.template=manifest.vm
maven.artifact.deploy.timestamps=true maven.artifact.deploy.timestamps=true
#GPG Settings
maven.artifact.gpg.skip=true
#maven.artifact.gpg.passphrase=
#maven.artifact.gpg.keyname=
maven.artifact.gpg.useagent=false

View File

@ -22,7 +22,7 @@
<pomVersion>3</pomVersion> <pomVersion>3</pomVersion>
<id>maven-artifact-plugin</id> <id>maven-artifact-plugin</id>
<name>Maven Artifact Plugin</name> <name>Maven Artifact Plugin</name>
<currentVersion>1.8.1-SNAPSHOT</currentVersion> <currentVersion>1.9-SNAPSHOT</currentVersion>
<description>Tools to manage artifacts and deployment. *WARNING*: This version of the artifact-plugin requires Maven 1.1. People using Maven 1.0 should NOT use this version of the plugin.</description> <description>Tools to manage artifacts and deployment. *WARNING*: This version of the artifact-plugin requires Maven 1.1. People using Maven 1.0 should NOT use this version of the plugin.</description>
<shortDescription>Tools to manage artifacts and deployment</shortDescription> <shortDescription>Tools to manage artifacts and deployment</shortDescription>
<versions> <versions>

View File

@ -16,22 +16,8 @@ package org.apache.maven.artifact.deployer;
* limitations under the License. * limitations under the License.
*/ */
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.maven.MavenConstants; import org.apache.maven.MavenConstants;
@ -52,24 +38,48 @@ import org.apache.maven.wagon.observers.ChecksumObserver;
import org.apache.maven.wagon.providers.file.FileWagon; import org.apache.maven.wagon.providers.file.FileWagon;
import org.apache.maven.wagon.providers.ftp.FtpWagon; import org.apache.maven.wagon.providers.ftp.FtpWagon;
import org.apache.maven.wagon.providers.http.HttpWagon; import org.apache.maven.wagon.providers.http.HttpWagon;
import org.apache.maven.wagon.providers.ssh.external.ScpExternalWagon;
import org.apache.maven.wagon.providers.ssh.jsch.ScpWagon; import org.apache.maven.wagon.providers.ssh.jsch.ScpWagon;
import org.apache.maven.wagon.providers.ssh.jsch.SftpWagon; import org.apache.maven.wagon.providers.ssh.jsch.SftpWagon;
import org.apache.maven.wagon.providers.ssh.external.ScpExternalWagon;
import org.apache.maven.wagon.repository.Repository; import org.apache.maven.wagon.repository.Repository;
import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.cli.DefaultConsumer;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
/** /**
* Default implementation of Artifact Deployer interface. * Default implementation of Artifact Deployer interface.
* *
* @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka</a> * @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka</a>
* @version $Id$ * @version $Id$
*/ */
public class DefaultArtifactDeployer public class DefaultArtifactDeployer implements ArtifactDeployer
implements ArtifactDeployer
{ {
protected static final String POM_TYPE = "pom"; protected static final String POM_TYPE = "pom";
public static final String SIGNATURE_EXTENSION = ".asc";
private static final ArtifactTypeHandler POM_ARTIFACT_TYPE_HANDLER = new DefaultArtifactTypeHandler(); private static final ArtifactTypeHandler POM_ARTIFACT_TYPE_HANDLER = new DefaultArtifactTypeHandler();
/** /**
@ -84,8 +94,8 @@ public class DefaultArtifactDeployer
/** /**
* @see ArtifactDeployer#deploy(String, String, Project, ArtifactTypeHandler) * @see ArtifactDeployer#deploy(String, String, Project, ArtifactTypeHandler)
*/ */
public void deploy( final String artifact, final String type, final Project project, final ArtifactTypeHandler handler ) public void deploy( final String artifact, final String type, final Project project,
throws MavenException final ArtifactTypeHandler handler ) throws MavenException
{ {
this.handleDeploy( type, project, project.getArtifactId(), artifact, handler, project.getCurrentVersion() ); this.handleDeploy( type, project, project.getArtifactId(), artifact, handler, project.getCurrentVersion() );
} }
@ -93,16 +103,30 @@ public class DefaultArtifactDeployer
/** /**
* @see DefaultArtifactDeployer#deploySnapshot(String, String, Project, ArtifactTypeHandler) * @see DefaultArtifactDeployer#deploySnapshot(String, String, Project, ArtifactTypeHandler)
*/ */
public void deploySnapshot( final String artifact, final String type, final Project project, final ArtifactTypeHandler handler ) public void deploySnapshot( final String artifact, final String type, final Project project,
throws MavenException final ArtifactTypeHandler handler ) throws MavenException
{ {
this.handleDeploy( type, project, project.getArtifactId(), artifact, handler, MavenConstants.SNAPSHOT_SIGNIFIER ); this.handleDeploy( type, project, project.getArtifactId(), artifact, handler, MavenConstants.SNAPSHOT_SIGNIFIER );
} }
protected void handleDeploy( final String type, final Project project, final String artifactId, final String artifact, protected void handleDeploy( final String type, final Project project, final String artifactId,
final ArtifactTypeHandler handler, final String version ) final String artifact, final ArtifactTypeHandler handler, final String version )
throws MavenException throws MavenException
{ {
Boolean gpgSkip = Boolean.valueOf( (String) project.getContext().getVariable( "maven.artifact.gpg.skip" ) );
String gpgPassphrase;
try
{
gpgPassphrase = getPassphrase( project );
}
catch ( IOException e )
{
throw new MavenException( "Error while retreiving the passphrase for gpg", e );
}
String gpgKeyname = (String) project.getContext().getVariable( "maven.artifact.gpg.keyname" );
Boolean gpgUseagent =
Boolean.valueOf( (String) project.getContext().getVariable( "maven.artifact.gpg.useagent" ) );
File file; File file;
if ( DefaultArtifactDeployer.POM_TYPE.equals( type ) ) if ( DefaultArtifactDeployer.POM_TYPE.equals( type ) )
{ {
@ -116,11 +140,17 @@ public class DefaultArtifactDeployer
// do not deploy POM twice // do not deploy POM twice
if ( !DefaultArtifactDeployer.POM_TYPE.equals( type ) ) if ( !DefaultArtifactDeployer.POM_TYPE.equals( type ) )
{ {
this.doDeploy( PomRewriter.getRewrittenPom( project ), project, artifactId, DefaultArtifactDeployer.POM_ARTIFACT_TYPE_HANDLER, version, File pomFile = PomRewriter.getRewrittenPom( project );
DefaultArtifactDeployer.POM_TYPE ); if ( !gpgSkip.booleanValue() )
generateSignatureForArtifact( pomFile, gpgPassphrase, gpgUseagent.booleanValue(), gpgKeyname );
this.doDeploy( pomFile, project, artifactId, DefaultArtifactDeployer.POM_ARTIFACT_TYPE_HANDLER, version,
DefaultArtifactDeployer.POM_TYPE, gpgSkip.booleanValue(), gpgPassphrase,
gpgUseagent.booleanValue(), gpgKeyname );
} }
if ( !gpgSkip.booleanValue() )
this.doDeploy( file, project, artifactId, handler, version, type ); generateSignatureForArtifact( file, gpgPassphrase, gpgUseagent.booleanValue(), gpgKeyname );
this.doDeploy( file, project, artifactId, handler, version, type, gpgSkip.booleanValue(), gpgPassphrase,
gpgUseagent.booleanValue(), gpgKeyname );
this.snapshotSignature = null; this.snapshotSignature = null;
@ -129,8 +159,8 @@ public class DefaultArtifactDeployer
/** /**
* @see ArtifactDeployer#install(String, String, Project, ArtifactTypeHandler) * @see ArtifactDeployer#install(String, String, Project, ArtifactTypeHandler)
*/ */
public void install( final String artifact, final String type, final Project project, final ArtifactTypeHandler handler ) public void install( final String artifact, final String type, final Project project,
throws MavenException final ArtifactTypeHandler handler ) throws MavenException
{ {
this.handleInstall( type, project, artifact, handler, project.getCurrentVersion() ); this.handleInstall( type, project, artifact, handler, project.getCurrentVersion() );
} }
@ -138,15 +168,14 @@ public class DefaultArtifactDeployer
/** /**
* @see ArtifactDeployer#installSnapshot(String, String, Project, ArtifactTypeHandler) * @see ArtifactDeployer#installSnapshot(String, String, Project, ArtifactTypeHandler)
*/ */
public void installSnapshot( final String artifact, final String type, final Project project, final ArtifactTypeHandler handler ) public void installSnapshot( final String artifact, final String type, final Project project,
throws MavenException final ArtifactTypeHandler handler ) throws MavenException
{ {
this.handleInstall( type, project, artifact, handler, MavenConstants.SNAPSHOT_SIGNIFIER ); this.handleInstall( type, project, artifact, handler, MavenConstants.SNAPSHOT_SIGNIFIER );
} }
private void handleInstall( final String type, final Project project, final String artifact, final ArtifactTypeHandler handler, private void handleInstall( final String type, final Project project, final String artifact,
final String version ) final ArtifactTypeHandler handler, final String version ) throws MavenException
throws MavenException
{ {
File file; File file;
if ( DefaultArtifactDeployer.POM_TYPE.equals( type ) ) if ( DefaultArtifactDeployer.POM_TYPE.equals( type ) )
@ -163,27 +192,31 @@ public class DefaultArtifactDeployer
// do not install twice // do not install twice
if ( !DefaultArtifactDeployer.POM_TYPE.equals( type ) ) if ( !DefaultArtifactDeployer.POM_TYPE.equals( type ) )
{ {
this.doInstall( PomRewriter.getRewrittenPom( project ), DefaultArtifactDeployer.POM_TYPE, project, version, DefaultArtifactDeployer.POM_ARTIFACT_TYPE_HANDLER ); this.doInstall( PomRewriter.getRewrittenPom( project ), DefaultArtifactDeployer.POM_TYPE, project, version,
DefaultArtifactDeployer.POM_ARTIFACT_TYPE_HANDLER );
} }
} }
/** /**
* Install given file in local repository * Install given file in local repository
* *
* @param file the artifact file to install * @param file
* @param type The type of the artiafct * the artifact file to install
* @param type
* The type of the artiafct
* @param project * @param project
* @param version String denominating the version of the artifact * @param version
* String denominating the version of the artifact
* @throws MavenException * @throws MavenException
*/ */
private void doInstall( final File file, final String type, final Project project, final String version, final ArtifactTypeHandler handler ) private void doInstall( final File file, final String type, final Project project, final String version,
throws MavenException final ArtifactTypeHandler handler ) throws MavenException
{ {
try try
{ {
final Repository repository = new Repository( "local", "file:" + project.getContext().getMavenRepoLocal() ); final Repository repository = new Repository( "local", "file:" + project.getContext().getMavenRepoLocal() );
final String repositoryPath = handler.constructRepositoryFullPath( type, project, version ); final String repositoryPath = handler.constructRepositoryFullPath( type, project, version );
this.deployFile( repository, file, repositoryPath, project ); this.deployFile( repository, file, repositoryPath, project, true, null, false, null );
} }
catch ( final Exception e ) catch ( final Exception e )
{ {
@ -240,9 +273,10 @@ public class DefaultArtifactDeployer
return null; return null;
} }
private void doDeploy( final File file, final Project project, final String artifactId, final ArtifactTypeHandler handler, final String version, private void doDeploy( final File file, final Project project, final String artifactId,
final String type ) final ArtifactTypeHandler handler, final String version, final String type,
throws MavenException final boolean gpgSkip, final String gpgPass, final boolean gpgUseAgent,
final String gpgKeyname ) throws MavenException
{ {
final List srcFiles = new ArrayList( 3 ); final List srcFiles = new ArrayList( 3 );
final List destFiles = new ArrayList( 3 ); final List destFiles = new ArrayList( 3 );
@ -257,13 +291,14 @@ public class DefaultArtifactDeployer
final File snapshotVersionFile = this.createSnapshotVersionFile( file, v, artifactId, type ); final File snapshotVersionFile = this.createSnapshotVersionFile( file, v, artifactId, type );
final String snapshotVersionsFilename = handler.constructRepositoryDirectoryPath( type, project ) + artifactId final String snapshotVersionsFilename =
+ "-snapshot-version"; handler.constructRepositoryDirectoryPath( type, project ) + artifactId + "-snapshot-version";
srcFiles.add( snapshotVersionFile ); srcFiles.add( snapshotVersionFile );
destFiles.add( snapshotVersionsFilename ); destFiles.add( snapshotVersionsFilename );
final String deployTimestamp = (String) project.getContext().getVariable( "maven.artifact.deploy.timestamps" ); final String deployTimestamp =
(String) project.getContext().getVariable( "maven.artifact.deploy.timestamps" );
if ( deployTimestamp.equals( "true" ) ) if ( deployTimestamp.equals( "true" ) )
{ {
srcFiles.add( file ); srcFiles.add( file );
@ -318,7 +353,8 @@ public class DefaultArtifactDeployer
final AuthenticationInfo authenticationInfo = RepositoryBuilder.getAuthenticationInfo( project, repo ); final AuthenticationInfo authenticationInfo = RepositoryBuilder.getAuthenticationInfo( project, repo );
try try
{ {
this.deployFiles( repository, srcFiles, destFiles, authenticationInfo, project ); this.deployFiles( repository, srcFiles, destFiles, authenticationInfo, project, gpgSkip, gpgPass,
gpgUseAgent, gpgKeyname );
success = true; success = true;
} }
catch ( final Exception e ) catch ( final Exception e )
@ -336,15 +372,20 @@ public class DefaultArtifactDeployer
} }
} }
protected void deployFile( final Repository repository, final File src, final String dest, final Project project ) protected void deployFile( final Repository repository, final File src, final String dest, final Project project,
final boolean gpgSkip, final String gpgPass, final boolean gpgUseAgent,
final String gpgKeyname )
throws ResourceDoesNotExistException, MalformedURLException, NoSuchAlgorithmException, TransferFailedException, throws ResourceDoesNotExistException, MalformedURLException, NoSuchAlgorithmException, TransferFailedException,
ConnectionException, AuthenticationException, AuthorizationException, MavenException ConnectionException, AuthenticationException, AuthorizationException, MavenException
{ {
this.deployFiles( repository, Collections.singletonList( src ), Collections.singletonList( dest ), null, project ); this.deployFiles( repository, Collections.singletonList( src ), Collections.singletonList( dest ), null,
project, gpgSkip, gpgPass, gpgUseAgent, gpgKeyname );
} }
protected void deployFiles( final Repository repository, final List srcFiles, final List destFiles, protected void deployFiles( final Repository repository, final List srcFiles, final List destFiles,
final AuthenticationInfo authenticationInfo, final Project project ) final AuthenticationInfo authenticationInfo, final Project project,
final boolean gpgSkip, final String gpgPass, final boolean gpgUseAgent,
final String gpgKeyname )
throws ConnectionException, AuthenticationException, ResourceDoesNotExistException, TransferFailedException, throws ConnectionException, AuthenticationException, ResourceDoesNotExistException, TransferFailedException,
AuthorizationException, MalformedURLException, NoSuchAlgorithmException, MavenException AuthorizationException, MalformedURLException, NoSuchAlgorithmException, MavenException
{ {
@ -379,6 +420,7 @@ public class DefaultArtifactDeployer
final File srcFile = (File) srcIterator.next(); final File srcFile = (File) srcIterator.next();
final String destFile = (String) destIterator.next(); final String destFile = (String) destIterator.next();
wagon.put( srcFile, destFile ); wagon.put( srcFile, destFile );
wagon.removeTransferListener( uploadMonitor ); wagon.removeTransferListener( uploadMonitor );
@ -403,6 +445,13 @@ public class DefaultArtifactDeployer
wagon.put( temp, destFile + "." + extension ); wagon.put( temp, destFile + "." + extension );
} }
if ( !gpgSkip )
{
File gpgSignature = generateSignatureForArtifact( srcFile, gpgPass, gpgUseAgent, gpgKeyname );
wagon.put( gpgSignature, destFile + SIGNATURE_EXTENSION );
}
} }
} }
catch ( final IOException e ) catch ( final IOException e )
@ -475,8 +524,7 @@ public class DefaultArtifactDeployer
return this.snapshotSignature; return this.snapshotSignature;
} }
protected File getFileForArtifact( final String artifact ) protected File getFileForArtifact( final String artifact ) throws MavenException
throws MavenException
{ {
final File file = new File( artifact ); final File file = new File( artifact );
if ( !file.exists() ) if ( !file.exists() )
@ -500,8 +548,8 @@ public class DefaultArtifactDeployer
/** /**
* Create a file which contains timestamp of the latetst snapshot * Create a file which contains timestamp of the latetst snapshot
*/ */
protected File createSnapshotVersionFile( final File artifact, final String snapshotVersion, final String artifactId, final String type ) protected File createSnapshotVersionFile( final File artifact, final String snapshotVersion,
throws MavenException final String artifactId, final String type ) throws MavenException
{ {
File file = null; File file = null;
final String filename = artifactId + "-" + type + "-snapshot-version"; final String filename = artifactId + "-" + type + "-snapshot-version";
@ -518,4 +566,156 @@ public class DefaultArtifactDeployer
return file; return file;
} }
/**
* @param pass
* The passphrase to use when signing. "${maven.artifact.gpg.passphrase}"
* @param keyname
* The "name" of the key to sign with. Passed to gpg as --local-user. "${maven.artifact.gpg.keyname}"
* @param useAgent
* Passes --use-agent or --no-use-agent to gpg. If using an agent, the password is optional as the agent
* will provide it. "${maven.artifact.gpg.useagent}"
*/
protected File generateSignatureForArtifact( File file, String pass, boolean useAgent, String keyname )
throws MavenException
{
File signature = new File( file + SIGNATURE_EXTENSION );
if ( signature.exists() )
{
signature.delete();
}
Commandline cmd = new Commandline();
cmd.setExecutable( "gpg" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" : "" ) );
if ( useAgent )
{
cmd.createArgument().setValue( "--use-agent" );
}
else
{
cmd.createArgument().setValue( "--no-use-agent" );
}
InputStream in = null;
if ( null != pass )
{
cmd.createArgument().setValue( "--passphrase-fd" );
cmd.createArgument().setValue( "0" );
// Prepare the input stream which will be used to pass the passphrase to the executable
in = new ByteArrayInputStream( pass.getBytes() );
}
if ( null != keyname )
{
cmd.createArgument().setValue( "--local-user" );
cmd.createArgument().setValue( keyname );
}
cmd.createArgument().setValue( "--armor" );
cmd.createArgument().setValue( "--detach-sign" );
cmd.createArgument().setFile( file );
try
{
LOG.debug( "GPG cmd : " + cmd );
int exitCode = CommandLineUtils.executeCommandLine( cmd, in, new DefaultConsumer(), new DefaultConsumer() );
if ( exitCode != 0 )
{
throw new MavenException( "Exit code: " + exitCode );
}
}
catch ( CommandLineException e )
{
throw new MavenException( "Unable to execute gpg command", e );
}
return signature;
}
protected String getPassphrase( Project project ) throws IOException
{
String pass = (String) project.getContext().getVariable( "maven.artifact.gpg.passphrase" );
if ( pass == null )
{
// TODO: with JDK 1.6, we could call System.console().readPassword("GPG Passphrase: ", null);
BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
while ( System.in.available() != 0 )
{
// there's some junk already on the input stream, consume it
// so we can get the real passphrase
System.in.read();
}
System.out.print( "GPG Passphrase: " );
MaskingThread thread = new MaskingThread();
thread.start();
pass = in.readLine();
// stop masking
thread.stopMasking();
}
project.getContext().setVariable( "maven.artifact.gpg.passphrase", pass );
return pass;
}
// based on ideas from http://java.sun.com/developer/technicalArticles/Security/pwordmask/
class MaskingThread extends Thread
{
private volatile boolean stop;
/**
* Begin masking until asked to stop.
*/
public void run()
{
// this needs to be high priority to make sure the characters don't
// really get to the screen.
int priority = Thread.currentThread().getPriority();
Thread.currentThread().setPriority( Thread.MAX_PRIORITY );
try
{
stop = false;
while ( !stop )
{
// print a backspace + * to overwrite anything they type
System.out.print( "\010*" );
try
{
// attempt masking at this rate
Thread.sleep( 1 );
}
catch ( InterruptedException iex )
{
Thread.currentThread().interrupt();
return;
}
}
}
finally
{
// restore the original priority
Thread.currentThread().setPriority( priority );
}
}
/**
* Instruct the thread to stop masking.
*/
public void stopMasking()
{
this.stop = true;
}
}
} }

View File

@ -18,14 +18,15 @@ package org.apache.maven.artifact.deployer;
*/ */
import org.apache.maven.MavenException; import org.apache.maven.MavenException;
import org.apache.maven.artifact.deployer.NamedArtifactDeployer;
import org.apache.maven.artifact.deployer.NamedArtifactTypeHandler;
import org.apache.maven.project.Project; import org.apache.maven.project.Project;
import org.apache.maven.repository.ArtifactTypeHandler; import org.apache.maven.repository.ArtifactTypeHandler;
/** /**
* *
* The Bean which provides access to Artifact Deployement API * The Bean which provides access to Artifact Deployement API from jelly scripts.
* from jelly scripts. *
*
* @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka</a> * @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka</a>
* @version $Id$ * @version $Id$
*/ */
@ -109,7 +110,8 @@ public class DeployBean
} }
/** /**
* @param newIdOverride The new id. * @param newIdOverride
* The new id.
*/ */
public void setArtifactIdOverride( final String newIdOverride ) public void setArtifactIdOverride( final String newIdOverride )
{ {
@ -117,10 +119,10 @@ public class DeployBean
} }
/** /**
* @throws MavenException MavenException * @throws MavenException
* MavenException
*/ */
protected void checkAttributes() protected void checkAttributes() throws MavenException
throws MavenException
{ {
if ( this.project == null ) if ( this.project == null )
{ {
@ -146,15 +148,16 @@ public class DeployBean
} }
/** /**
* @throws MavenException MavenException * @throws MavenException
* MavenException
*/ */
public void deploy() public void deploy() throws MavenException
throws MavenException
{ {
this.checkAttributes(); this.checkAttributes();
if ( this.artifactIdOverride != null ) if ( this.artifactIdOverride != null )
{ {
this.artifactDeployer.deploy( this.artifact, this.type, this.project, (NamedArtifactTypeHandler) this.typeHandler ); this.artifactDeployer.deploy( this.artifact, this.type, this.project,
(NamedArtifactTypeHandler) this.typeHandler );
} }
else else
{ {
@ -163,15 +166,16 @@ public class DeployBean
} }
/** /**
* @throws MavenException MavenException * @throws MavenException
* MavenException
*/ */
public void deploySnapshot() public void deploySnapshot() throws MavenException
throws MavenException
{ {
this.checkAttributes(); this.checkAttributes();
if ( this.artifactIdOverride != null ) if ( this.artifactIdOverride != null )
{ {
this.artifactDeployer.deploySnapshot( this.artifact, this.type, this.project, (NamedArtifactTypeHandler) this.typeHandler ); this.artifactDeployer.deploySnapshot( this.artifact, this.type, this.project,
(NamedArtifactTypeHandler) this.typeHandler );
} }
else else
{ {
@ -180,10 +184,10 @@ public class DeployBean
} }
/** /**
* @throws MavenException MavenException * @throws MavenException
* MavenException
*/ */
public void install() public void install() throws MavenException
throws MavenException
{ {
this.checkAttributes(); this.checkAttributes();
if ( this.artifactIdOverride != null ) if ( this.artifactIdOverride != null )
@ -197,10 +201,10 @@ public class DeployBean
} }
/** /**
* @throws MavenException MavenException * @throws MavenException
* MavenException
*/ */
public void installSnapshot() public void installSnapshot() throws MavenException
throws MavenException
{ {
this.checkAttributes(); this.checkAttributes();
if ( this.artifactIdOverride != null ) if ( this.artifactIdOverride != null )

View File

@ -24,10 +24,10 @@ import org.apache.maven.project.Project;
import org.apache.maven.wagon.authentication.AuthenticationInfo; import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.providers.ftp.FtpWagon; import org.apache.maven.wagon.providers.ftp.FtpWagon;
import org.apache.maven.wagon.providers.ssh.AbstractSshWagon; import org.apache.maven.wagon.providers.ssh.AbstractSshWagon;
import org.apache.maven.wagon.providers.ssh.external.ScpExternalWagon;
import org.apache.maven.wagon.providers.ssh.jsch.ScpWagon; import org.apache.maven.wagon.providers.ssh.jsch.ScpWagon;
import org.apache.maven.wagon.providers.ssh.jsch.SftpWagon; import org.apache.maven.wagon.providers.ssh.jsch.SftpWagon;
import org.apache.maven.wagon.providers.ssh.knownhost.NullKnownHostProvider; import org.apache.maven.wagon.providers.ssh.knownhost.NullKnownHostProvider;
import org.apache.maven.wagon.providers.ssh.external.ScpExternalWagon;
import org.apache.maven.wagon.proxy.ProxyInfo; import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository; import org.apache.maven.wagon.repository.Repository;
import org.apache.maven.wagon.repository.RepositoryPermissions; import org.apache.maven.wagon.repository.RepositoryPermissions;

View File

@ -16,15 +16,15 @@ package org.apache.maven.artifact;
* limitations under the License. * limitations under the License.
*/ */
import org.apache.maven.MavenConstants;
import org.apache.maven.project.Dependency;
import org.apache.maven.project.Model;
import java.io.File; import java.io.File;
import junit.framework.Assert; import junit.framework.Assert;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.maven.MavenConstants;
import org.apache.maven.project.Dependency;
import org.apache.maven.project.Model;
/** /**
* Test the POM rewriter. * Test the POM rewriter.
* *

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
/* /*
* Copyright 2001-2004 The Apache Software Foundation. * Copyright 2001-2004 The Apache Software Foundation.
@ -24,19 +23,20 @@
<author email="vmassol@apache.org">Vincent Massol</author> <author email="vmassol@apache.org">Vincent Massol</author>
</properties> </properties>
<body> <body>
<release version="1.8.1-SNAPSHOT" date="In SVN"> <release version="1.9-SNAPSHOT" date="In SVN">
<action dev="aheritier" type="add" issue="MPARTIFACT-75">Allow to sign artifacts to deploy. Refer to properties documentation to know how to activate it.</action>
<action dev="aheritier" type="update" issue="MAVEN-1755">Upgrade maven-model to version 3.0.2 and use stax reader/parser for the pom to allow to use relative entities.</action> <action dev="aheritier" type="update" issue="MAVEN-1755">Upgrade maven-model to version 3.0.2 and use stax reader/parser for the pom to allow to use relative entities.</action>
<action dev="aheritier" type="update" issue="MAVEN-1803">Upgrade plexus-utils to version 1.0.5</action> <action dev="aheritier" type="update" issue="MAVEN-1803">Upgrade plexus-utils to version 1.0.5</action>
<action dev="aheritier" type="update" issue="MAVEN-1796">Upgrade commons-jexl to version 1.1</action> <action dev="aheritier" type="update" issue="MAVEN-1796">Upgrade commons-jexl to version 1.1</action>
<action dev="aheritier" type="update" issue="MAVEN-1789">Change the default repository to http://repo1.maven.org/maven/ for dependencies url in the manifest.</action> <action dev="aheritier" type="update" issue="MAVEN-1789">Change the default repository to http://repo1.maven.org/maven/ for dependencies url in the manifest.</action>
<action dev="ltheussl" type="fix" issue="MPARTIFACT-72">Creating an upload-bundle for a plugin without any java code does not work.</action> <action dev="ltheussl" type="fix" issue="MPARTIFACT-72">Creating an upload-bundle for a plugin without any java code does not work.</action>
<action dev="ltheussl" type="update">Update to velocity 1.5.</action> <action dev="ltheussl" type="update">Update to velocity 1.5.</action>
<action dev="ltheussl" type="update">Update jelly dependency to match the ones in maven 1.1 core.</action> <action dev="ltheussl" type="update">Update jelly dependency to match the ones in maven 1.1 core.</action>
<action dev="ltheussl" type="update" issue="MPARTIFACT-67">Include javadocs in created upload bundle.</action> <action dev="ltheussl" type="update" issue="MPARTIFACT-67">Include javadocs in created upload bundle.</action>
<action dev="aheritier" type="fix" issue="MPARTIFACT-71">"reject HostKey" error : Due to the upgrade of wagon, artifacts can't be deployed with scp and sftp protocols.</action> <action dev="aheritier" type="fix" issue="MPARTIFACT-71">"reject HostKey" error : Due to the upgrade of wagon, artifacts can't be deployed with scp and sftp protocols.</action>
<action dev="ltheussl" type="update" issue="MPARTIFACT-66">Upgrade Wagon dependencies to version 1.0-beta-2.</action> <action dev="ltheussl" type="update" issue="MPARTIFACT-66">Upgrade Wagon dependencies to version 1.0-beta-2.</action>
<action dev="aheritier" type="update" issue="MPARTIFACT-66">Upgrade dependencies required by wagon : upgrade jsch 0.1.27 (instead of 0.1.14) and commons-net 1.4.1 (instead of 1.4.0).</action> <action dev="aheritier" type="update" issue="MPARTIFACT-66">Upgrade dependencies required by wagon : upgrade jsch 0.1.27 (instead of 0.1.14) and commons-net 1.4.1 (instead of 1.4.0).</action>
</release> </release>
<release version="1.8" date="2006-02-24"> <release version="1.8" date="2006-02-24">
<action dev="ltheussl" type="add" issue="MPARTIFACT-65">Document <action dev="ltheussl" type="add" issue="MPARTIFACT-65">Document
<code>artifact:create-upload-bundle</code>. <code>artifact:create-upload-bundle</code>.

View File

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<!-- <!--
/* /*
* Copyright 2001-2004 The Apache Software Foundation. * Copyright 2001-2004 The Apache Software Foundation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
--> -->
<document> <document>
@ -35,118 +35,104 @@
<tr> <tr>
<td>maven.repo.list</td> <td>maven.repo.list</td>
<td> <td>
The list of comma separated names of The list of comma separated names of the repositories to which artifacts produced by the project will be
the repositories to which artifacts produced by deployed. E.g.:
the project will be deployed. E.g.: <br />
<br/>
<i>maven.repo.list=myrepo1,ibiblio</i> <i>maven.repo.list=myrepo1,ibiblio</i>
<br/> <br />
The names of all other properties are constructed using the The names of all other properties are constructed using the entries present in this list. Below the set of
entries present in this list. properties which can be used for configuration of deployment process to each of the repositories provided in
Below the set of properties which can be used for the list.
configuration of deployment process to each of the repositories <i>x</i>
provided in the list. <i>x</i> in the names in the names of those properties should be replaced by actual repository name (like
of those properties should be replaced by actual repository name <i>ibiblio</i>
(like <i>ibiblio</i>). ). In case of doubts see an
In case of doubts see an <a href="examples.html">example</a> <a href="examples.html">example</a>
</td> </td>
<td>No</td> <td>No</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x</td> <td>maven.repo.x</td>
<td> <td>
Specifies the URL of remote repository. The URL Specifies the URL of remote repository. The URL should contain the protocol name.
should contain the protocol name. <br />
<br/> See the
See the <a href="protocols.html">the list</a> of supported protocols. <a href="protocols.html">the list</a>
<br/> of supported protocols.
x corresponds to <br />
repository name defined using <i>maven.repo.list</i> property. x corresponds to repository name defined using
<i>maven.repo.list</i>
property.
</td> </td>
<td>No</td> <td>No</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.directory</td> <td>maven.repo.x.directory</td>
<td> <td>The path on the remote file system where artifacts will be placed</td>
The path on the remote file system where artifacts will be placed
</td>
<td>No</td> <td>No</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.username</td> <td>maven.repo.x.username</td>
<td> <td>
The user name that will be used to authenticated The user name that will be used to authenticated user if access to repository requires authentication.
user if access to repository requires authentication.
</td> </td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.password</td> <td>maven.repo.x.password</td>
<td> <td>
The password which will be used to authenticate The password which will be used to authenticate user.
user. <br />
<br/> If server/protocol supports authentication via both private/public keys and password, it will first try to
If server/protocol supports authentication via use keys for authentication and if that doesn't work then will fall back to using the username and password
both private/public keys and password,
it will first try to use keys for authentication
and if that doesn't work then
will fall back to using the username and password
</td> </td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.group</td> <td>maven.repo.x.group</td>
<td> <td>The remote group (UNIX group) to which the artifact will belong after it is deployed</td>
The remote group (UNIX group) to which
the artifact will belong after it
is deployed
</td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.mode</td> <td>maven.repo.x.mode</td>
<td> <td>
The remote file mode (UNIX permissions) to which The remote file mode (UNIX permissions) to which the artifact will be set to after it is deployed. Default
the artifact will be set to after it is
is deployed. Default is <code>g+w</code>. <code>g+w</code>
.
</td> </td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.directory.mode</td> <td>maven.repo.x.directory.mode</td>
<td> <td>
The remote directory mode (UNIX permissions) The remote directory mode (UNIX permissions) when directories are created while deploying the artifact.
when directories are created while deploying the artifact. Default is
Default is <code>maven.repo.x.mode</code>. <code>maven.repo.x.mode</code>
<b>Warning:</b> if you are using an octal file permission, .
you should not use the default value for this as you should <b>Warning:</b>
add the executable permission for directories. if you are using an octal file permission, you should not use the default value for this as you should add
the executable permission for directories.
</td> </td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.privatekey</td> <td>maven.repo.x.privatekey</td>
<td> <td>
The absolute path to private key file. The absolute path to private key file.
<br/> <br />
Thie is used only for when protocol Thie is used only for when protocol supports authentication via private/public key pair.
supports authentication via private/public
key pair.
</td> </td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.passphrase</td> <td>maven.repo.x.passphrase</td>
<td> <td>The passphrase used to decrypt private key file</td>
The passphrase used to decrypt private key file
</td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.compress</td> <td>maven.repo.x.compress</td>
<td> <td>Used by scp if you want to compress the stream.</td>
Used by scp if you want to compress the stream.
</td>
<td>Yes</td> <td>Yes</td>
</tr> </tr>
</table> </table>
@ -155,98 +141,144 @@
<subsection name="scpexe"> <subsection name="scpexe">
<table> <table>
<tr> <tr>
<td>maven.repo.x.scp.executable</td> <th>Property name</th>
<td>Yes</td> <th>Description</th>
<td> <th>Optional?</th>
Specifies the name (and possibly location) of the remote secure
copy executable to use (SCP).
The default value is <code>maven.scp.executable</code>.
</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.scp.args</td> <td>maven.repo.x.scp.executable</td>
<td>Yes</td>
<td> <td>
Specifies optional parameters that are passed to the scp executable. Specifies the name (and possibly location) of the remote secure copy executable to use (SCP). The default
value is
<code>maven.scp.executable</code>
.
</td> </td>
<td>Yes</td>
</tr>
<tr>
<td>maven.repo.x.scp.args</td>
<td>Specifies optional parameters that are passed to the scp executable.</td>
<td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.ssh.executable</td> <td>maven.repo.x.ssh.executable</td>
<td>Yes</td>
<td> <td>
Specifies the name (and possibly location) of the remote secure Specifies the name (and possibly location) of the remote secure shell executable to use (SSH). The default
shell executable to use (SSH). value is
The default value is <code>maven.ssh.executable</code>. <code>maven.ssh.executable</code>
.
</td> </td>
<td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.ssh.args</td> <td>maven.repo.x.ssh.args</td>
<td>Specifies optional parameters that are passed to the ssh executable.</td>
<td>Yes</td> <td>Yes</td>
<td>
Specifies optional parameters that are passed to the ssh executable.
</td>
</tr> </tr>
<tr> <tr>
<td>maven.repo.x.port</td> <td>maven.repo.x.port</td>
<td></td> <td>This property has no effect with scpexe protocol, use args instead.</td>
<td> <td>Yes</td>
This property has no effect with scpexe protocol, use args instead.
</td>
</tr> </tr>
</table> </table>
</subsection> </subsection>
</section> </section>
<section name="Sign Artifacts - GPG Settings">
<p>
The artifact plugin allows to automatically sign your artifacts with GPG when you deploy a release. You'll find
more informations about signing releases here :
<a href="http://www.apache.org/dev/release-signing.html">http://www.apache.org/dev/release-signing.html</a>
</p>
<table>
<tr>
<th>Property name</th>
<th>Description</th>
<th>Optional?</th>
</tr>
<tr>
<td>maven.artifact.gpg.skip</td>
<td>Do you want to skip the signing step? Default : true. Before to enable it you have to correctly setup GPG. You need to have a key and <code>gpg</code> must be in your PATH.</td>
<td>Yes</td>
</tr>
<tr>
<td>maven.artifact.gpg.passphrase</td>
<td>The passphrase to use when signing. Default : not defined. If not defined and signing activated, the plugin will prompt for the passphrase.</td>
<td>Yes</td>
</tr>
<tr>
<td>maven.artifact.gpg.keyname</td>
<td>The "name" of the key to sign with. Passed to gpg as <code>--local-user</code>. Default : not defined. The default key is used.</td>
<td>Yes</td>
</tr>
<tr>
<td>maven.artifact.gpg.useagent</td>
<td>Passes <code>--use-agent</code> or <code>--no-use-agent</code> to gpg. If using an agent, the password is optional as the agent will provide it. Default : false.</td>
<td>Yes</td>
</tr>
</table>
</section>
<section name="Other properties used"> <section name="Other properties used">
<table> <table>
<tr>
<th>Property name</th>
<th>Description</th>
<th>Optional?</th>
</tr>
<tr> <tr>
<td>maven.artifact.deploy.timestamps</td> <td>maven.artifact.deploy.timestamps</td>
<td> <td>
Specifies whether timestamped versions of artifacts should Specifies whether timestamped versions of artifacts should be deployed as well when deploying SNAPSHOT
be deployed as well when deploying SNAPSHOT versions. versions. Defaults to 'true'.
Defaults to 'true'.
</td> </td>
<td>Yes</td>
</tr> </tr>
</table> </table>
<p> <p>
If you are behind a firewall and need to use a proxy server, check the If you are behind a firewall and need to use a proxy server, check the
<a href="http://maven.apache.org/maven-1.x/reference/properties.html#Proxy_Properties">proxy properties</a>. <a href="http://maven.apache.org/maven-1.x/reference/properties.html#Proxy_Properties">proxy properties</a>
</p> .
</section> </p>
</section>
<section name="Deploy Properties (DEPRECATED)"> <section name="Deploy Properties (DEPRECATED)">
<table> <table>
<tr> <tr>
<td>maven.scp.executable</td> <th>Property name</th>
<td>Yes</td> <th>Description</th>
<td> <th>Optional?</th>
Specifies the name (and possibly location) of the remote secure
copy executable to use (SCP).
The default value is <code>scp</code> (i.e. an executable
named <code>scp</code> must be in your path).
</td>
</tr> </tr>
<tr> <tr>
<td>maven.scp.args</td> <td>maven.scp.executable</td>
<td>Yes</td>
<td> <td>
Specifies optional parameters that are passed to the scp executable. Specifies the name (and possibly location) of the remote secure copy executable to use (SCP). The default
value is
<code>scp</code>
(i.e. an executable named
<code>scp</code>
must be in your path).
</td> </td>
<td>Yes</td>
</tr>
<tr>
<td>maven.scp.args</td>
<td>Specifies optional parameters that are passed to the scp executable.</td>
<td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.ssh.executable</td> <td>maven.ssh.executable</td>
<td>Yes</td>
<td> <td>
Specifies the name (and possibly location) of the remote secure Specifies the name (and possibly location) of the remote secure shell executable to use (SSH). The default
shell executable to use (SSH). value is
The default value is <code>ssh</code> (i.e. an executable <code>ssh</code>
named <code>ssh</code> must be in your path). (i.e. an executable named
<code>ssh</code>
must be in your path).
</td> </td>
<td>Yes</td>
</tr> </tr>
<tr> <tr>
<td>maven.ssh.args</td> <td>maven.ssh.args</td>
<td>Specifies optional parameters that are passed to the ssh executable.</td>
<td>Yes</td> <td>Yes</td>
<td>
Specifies optional parameters that are passed to the ssh executable.
</td>
</tr> </tr>
</table> </table>
</section> </section>