[MNG-4343] maven always checks missing release artifacts

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@816563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Benjamin Bentmann 2009-09-18 09:48:49 +00:00
parent ddf8257866
commit 5097fd5116
9 changed files with 101 additions and 188 deletions

View File

@ -146,11 +146,6 @@ public class DefaultRepositoryMetadataManager
updateCheckManager.touch( metadata, repository, file );
}
}
else
{
getLogger().debug( "Skipping metadata update of " + metadata.getKey() + " from "
+ repository.getId() );
}
// TODO: should this be inside the above check?
// touch file so that this is not checked again until interval has passed

View File

@ -169,11 +169,13 @@ public class DefaultArtifactResolver
if ( artifact.getRepository() != null )
{
// the transformations discovered the artifact - so use it exclusively
wagonManager.getArtifact( artifact, artifact.getRepository(), downloadMonitor );
wagonManager.getArtifact( artifact, artifact.getRepository(), downloadMonitor,
request.isForceUpdate() );
}
else
{
wagonManager.getArtifact( artifact, remoteRepositories, downloadMonitor );
wagonManager.getArtifact( artifact, remoteRepositories, downloadMonitor,
request.isForceUpdate() );
}
}
catch ( ResourceDoesNotExistException e )

View File

@ -215,8 +215,10 @@ public class LegacyRepositorySystem
public ArtifactRepository createDefaultRemoteRepository()
throws InvalidRepositoryException
{
return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID, true, ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER, false,
ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID,
true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false,
ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
}
public ArtifactRepository createLocalRepository( String url, String repositoryId )

View File

@ -34,6 +34,7 @@ import java.util.Properties;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.Authentication;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.logging.AbstractLogEnabled;
@ -60,37 +61,27 @@ public class DefaultUpdateCheckManager
public boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository )
{
// Update intervals are never used for release artifacts. These intervals
// only exist on the release section of the repository definition in the POM for one reason:
// to specify how often artifact METADATA is checked. Here, we simply shortcut for non-snapshot
// artifacts.
if ( !artifact.isSnapshot() )
File file = artifact.getFile();
ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
if ( !policy.isEnabled() )
{
getLogger().debug( "Skipping update check for non-snapshot artifact " + artifact );
if ( getLogger().isDebugEnabled() )
{
getLogger().debug(
"Skipping update check for " + artifact + " (" + file + ") from "
+ repository.getId() + " (" + repository.getUrl() + ")" );
}
return false;
}
// we can safely assume that we're calculating based on the snapshot policy here if we've made it past the
// release-artifact short circuit above.
ArtifactRepositoryPolicy policy = repository.getSnapshots();
return isUpdateRequired( artifact, repository, policy );
}
private boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository, ArtifactRepositoryPolicy policy )
{
File file = artifact.getFile();
if ( getLogger().isDebugEnabled() )
{
getLogger().debug(
"Determining update check for " + artifact + " (" + file + ") from " + repository
+ " (enabled = " + policy.isEnabled() + ")" );
}
if ( !policy.isEnabled() )
{
return false;
"Determining update check for " + artifact + " (" + file + ") from "
+ repository.getId() + " (" + repository.getUrl() + ")" );
}
if ( file == null )
@ -108,7 +99,7 @@ public class DefaultUpdateCheckManager
else
{
File touchfile = getTouchfile( artifact );
lastCheckDate = readLastUpdated( touchfile, repository.getId() );
lastCheckDate = readLastUpdated( touchfile, getRepositoryKey( repository ) );
}
return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
@ -124,17 +115,23 @@ public class DefaultUpdateCheckManager
// artifacts available.
ArtifactRepositoryPolicy policy = metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
if ( !policy.isEnabled() )
{
if ( getLogger().isDebugEnabled() )
{
getLogger().debug(
"Skipping update check for " + metadata.getKey() + " (" + file + ") from "
+ repository.getId() + " (" + repository.getUrl() + ")" );
}
return false;
}
if ( getLogger().isDebugEnabled() )
{
getLogger().debug(
"Determining update check for " + metadata + " (" + file + ") from " + repository
+ " (snapshot = " + metadata.isSnapshot() + ", enabled = " + policy.isEnabled()
+ ")" );
}
if ( !policy.isEnabled() )
{
return false;
"Determining update check for " + metadata.getKey() + " (" + file + ") from "
+ repository.getId() + " (" + repository.getUrl() + ")" );
}
if ( file == null )
@ -148,7 +145,7 @@ public class DefaultUpdateCheckManager
return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
}
public Date readLastUpdated( RepositoryMetadata metadata, ArtifactRepository repository, File file )
private Date readLastUpdated( RepositoryMetadata metadata, ArtifactRepository repository, File file )
{
File touchfile = getTouchfile( metadata, file );
@ -169,9 +166,8 @@ public class DefaultUpdateCheckManager
}
else
{
writeLastUpdated( touchfile, repository.getId() );
writeLastUpdated( touchfile, getRepositoryKey( repository ) );
}
}
public void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file )
@ -183,9 +179,27 @@ public class DefaultUpdateCheckManager
writeLastUpdated( touchfile, key );
}
public String getMetadataKey( ArtifactRepository repository, File file )
String getMetadataKey( ArtifactRepository repository, File file )
{
return repository.getId() + "." + file.getName() + LAST_UPDATE_TAG;
return repository.getId() + '.' + file.getName() + LAST_UPDATE_TAG;
}
String getRepositoryKey( ArtifactRepository repository )
{
StringBuilder buffer = new StringBuilder( 256 );
// consider the username&password because a repo manager might block artifacts depending on authorization
Authentication auth = repository.getAuthentication();
if ( auth != null )
{
int hash = ( auth.getUsername() + auth.getPassword() ).hashCode();
buffer.append( hash ).append( '@' );
}
// consider the URL (instead of the id) as this most closely relates to the contents in the repo
buffer.append( repository.getUrl() );
return buffer.toString();
}
private void writeLastUpdated( File touchfile, String key )
@ -350,9 +364,9 @@ public class DefaultUpdateCheckManager
}
}
public File getTouchfile( Artifact artifact )
File getTouchfile( Artifact artifact )
{
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder( 128 );
sb.append( artifact.getArtifactId() );
sb.append( '-' ).append( artifact.getBaseVersion() );
if ( artifact.getClassifier() != null )
@ -363,14 +377,9 @@ public class DefaultUpdateCheckManager
return new File( artifact.getFile().getParentFile(), sb.toString() );
}
public File getTouchfile( RepositoryMetadata metadata, File file )
File getTouchfile( RepositoryMetadata metadata, File file )
{
return new File( file.getParent(), TOUCHFILE_NAME );
}
public boolean isPomUpdateRequired( Artifact artifact, ArtifactRepository repository )
{
return isUpdateRequired( artifact, repository, repository.getReleases() );
}
}

View File

@ -76,106 +76,57 @@ public class DefaultWagonManager
//
// Retriever
//
public void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener downloadMonitor )
public void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener downloadMonitor, boolean force )
throws TransferFailedException, ResourceDoesNotExistException
{
String remotePath = repository.pathOf( artifact );
ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
boolean updateCheckIsRequired = updateCheckManager.isUpdateRequired( artifact, repository );
if ( !policy.isEnabled() )
{
logger.debug( "Skipping disabled repository " + repository.getId() + " for resolution of "
+ artifact.getId() );
}
// If the artifact is a snapshot, we need to determine whether it's time to check this repository for an update:
// 1. If it's forced, then check
// 2. If the updateInterval has been exceeded since the last check for this artifact on this repository, then check.
else if ( artifact.isSnapshot() && updateCheckIsRequired )
else if ( artifact.isSnapshot() || !artifact.getFile().exists() )
{
logger.debug( "Trying repository " + repository.getId() + " for resolution of " + artifact.getId()
+ " from " + remotePath );
try
{
getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor, policy.getChecksumPolicy(), false );
}
finally
{
updateCheckManager.touch( artifact, repository );
}
logger.debug( " Artifact " + artifact.getId() + " resolved to " + artifact.getFile() );
artifact.setResolved( true );
}
// XXX: This is not really intended for the long term - unspecified POMs should be converted to failures
// meaning caching would be unnecessary. The code for this is here instead of the MavenMetadataSource
// to keep the logic related to update checks enclosed, and so to keep the rules reasonably consistent
// with release metadata
else if ( "pom".equals( artifact.getType() ) && !artifact.getFile().exists() )
{
// if POM is not present locally, try and get it if it's forced, out of date, or has not been attempted yet
if ( updateCheckManager.isPomUpdateRequired( artifact, repository ) )
if ( force || updateCheckManager.isUpdateRequired( artifact, repository ) )
{
logger.debug( "Trying repository " + repository.getId() + " for resolution of " + artifact.getId()
+ " from " + remotePath );
try
{
getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor, policy.getChecksumPolicy(), false );
getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor,
policy.getChecksumPolicy(), false );
}
catch ( ResourceDoesNotExistException e )
finally
{
// cache the POM failure
updateCheckManager.touch( artifact, repository );
throw e;
}
logger.debug( " Artifact " + artifact.getId() + " resolved to " + artifact.getFile() );
artifact.setResolved( true );
}
else
else if ( !artifact.getFile().exists() )
{
// cached failure - pass on the failure
throw new ResourceDoesNotExistException( "Failure was cached in the local repository" );
throw new ResourceDoesNotExistException( "Failure to resolve " + remotePath + " from "
+ repository.getUrl() + " was cached in the local repository. "
+ "Resolution will not be reattempted until the update interval of " + repository.getId()
+ " has elapsed or updates are forced." );
}
}
// If it's not a snapshot artifact, then we don't care what the force flag says. If it's on the local
// system, it's resolved. Releases are presumed to be immutable, so release artifacts are not ever updated.
// NOTE: This is NOT the case for metadata files on relese-only repositories. This metadata may contain information
// about successive releases, so it should be checked using the same updateInterval/force characteristics as snapshot
// artifacts, above.
// don't write touch-file for release artifacts.
else if ( !artifact.isSnapshot() )
{
logger.debug( "Trying repository " + repository.getId() + " for resolution of " + artifact.getId()
+ " from " + remotePath );
getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor, policy.getChecksumPolicy(), false );
logger.debug( " Artifact " + artifact.getId() + " resolved to " + artifact.getFile() );
artifact.setResolved( true );
}
}
public void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories, TransferListener downloadMonitor )
public void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories, TransferListener downloadMonitor, boolean force )
throws TransferFailedException, ResourceDoesNotExistException
{
for ( ArtifactRepository repository : remoteRepositories )
{
try
{
getArtifact( artifact, repository, downloadMonitor );
getArtifact( artifact, repository, downloadMonitor, force );
if ( artifact.isResolved() )
{

View File

@ -28,8 +28,6 @@ import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
public interface UpdateCheckManager
{
String ROLE = UpdateCheckManager.class.getName();
boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository );
void touch( Artifact artifact, ArtifactRepository repository );
@ -38,6 +36,4 @@ public interface UpdateCheckManager
void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file );
boolean isPomUpdateRequired( Artifact artifact, ArtifactRepository repository );
}

View File

@ -41,10 +41,10 @@ public interface WagonManager
//
// Retriever
//
void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener transferListener )
void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener transferListener, boolean force )
throws TransferFailedException, ResourceDoesNotExistException;
void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories, TransferListener transferListener )
void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories, TransferListener transferListener, boolean force )
throws TransferFailedException, ResourceDoesNotExistException;
void getRemoteFile( ArtifactRepository repository, File destination, String remotePath, TransferListener downloadMonitor, String checksumPolicy, boolean force )

View File

@ -75,7 +75,8 @@ public class DefaultUpdateCheckManagerTest
assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
assertNull( updateCheckManager.readLastUpdated( touchFile, remoteRepository.getId() ) );
assertNull( updateCheckManager.readLastUpdated( touchFile,
updateCheckManager.getRepositoryKey( remoteRepository ) ) );
assertFalse( updateCheckManager.getTouchfile( a ).exists() );
}
@ -103,7 +104,8 @@ public class DefaultUpdateCheckManagerTest
assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
assertFalse( file.exists() );
assertNotNull( updateCheckManager.readLastUpdated( touchFile, remoteRepository.getId() ) );
assertNotNull( updateCheckManager.readLastUpdated( touchFile,
updateCheckManager.getRepositoryKey( remoteRepository ) ) );
}
public void testPom() throws Exception
@ -121,15 +123,16 @@ public class DefaultUpdateCheckManagerTest
File touchFile = updateCheckManager.getTouchfile( a );
touchFile.delete();
assertTrue( updateCheckManager.isPomUpdateRequired( a, remoteRepository ) );
assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
file.getParentFile().mkdirs();
file.createNewFile();
updateCheckManager.touch( a, remoteRepository );
assertFalse( updateCheckManager.isPomUpdateRequired( a, remoteRepository ) );
assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
assertNull( updateCheckManager.readLastUpdated( touchFile, remoteRepository.getId() ) );
assertNull( updateCheckManager.readLastUpdated( touchFile,
updateCheckManager.getRepositoryKey( remoteRepository ) ) );
assertFalse( updateCheckManager.getTouchfile( a ).exists() );
}
@ -150,14 +153,15 @@ public class DefaultUpdateCheckManagerTest
File touchFile = updateCheckManager.getTouchfile( a );
touchFile.delete();
assertTrue( updateCheckManager.isPomUpdateRequired( a, remoteRepository ) );
assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
updateCheckManager.touch( a, remoteRepository );
assertFalse( updateCheckManager.isPomUpdateRequired( a, remoteRepository ) );
assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
assertFalse( file.exists() );
assertNotNull( updateCheckManager.readLastUpdated( touchFile, remoteRepository.getId() ) );
assertNotNull( updateCheckManager.readLastUpdated( touchFile,
updateCheckManager.getRepositoryKey( remoteRepository ) ) );
}
public void testMetadata() throws Exception

View File

@ -108,33 +108,10 @@ public class DefaultWagonManagerTest
}
TransferListener listener = new TransferListener();
wagonManager.getArtifact( artifact, repos, listener );
wagonManager.getArtifact( artifact, repos, listener, false );
assertEquals( 1, listener.events.size() );
}
public void testGetPomExistsLocallyForced()
throws IOException, TransferFailedException, ResourceDoesNotExistException, UnsupportedProtocolException
{
Artifact artifact = createTestPomArtifact( "target/test-data/get-remote-pom" );
artifact.getFile().createNewFile();
artifact.getFile().setLastModified( System.currentTimeMillis() - 60 * 1000 );
ArtifactRepository repo = createStringRepo();
StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
MockControl control = MockControl.createControl( UpdateCheckManager.class );
control.replay();
wagonManager.getArtifact( artifact, repo, null );
assertTrue( artifact.getFile().exists() );
assertEquals( "expected", FileUtils.fileRead( artifact.getFile(), "UTF-8" ) );
control.verify();
}
public void testGetMissingJar() throws TransferFailedException, UnsupportedProtocolException, IOException
{
Artifact artifact = createTestArtifact( "target/test-data/get-missing-jar", "jar" );
@ -143,7 +120,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
fail();
}
@ -163,7 +140,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
fail();
}
@ -189,30 +166,7 @@ public class DefaultWagonManagerTest
MockControl control = MockControl.createControl( UpdateCheckManager.class );
control.replay();
wagonManager.getArtifact( artifact, repo, null );
assertTrue( artifact.getFile().exists() );
assertEquals( "expected", FileUtils.fileRead( artifact.getFile(), "UTF-8" ) );
control.verify();
}
public void testGetJarExistsLocallyForced()
throws IOException, TransferFailedException, ResourceDoesNotExistException, UnsupportedProtocolException
{
Artifact artifact = createTestArtifact( "target/test-data/get-remote-jar", "jar" );
artifact.getFile().createNewFile();
artifact.getFile().setLastModified( System.currentTimeMillis() - 60 * 1000 );
ArtifactRepository repo = createStringRepo();
StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
MockControl control = MockControl.createControl( UpdateCheckManager.class );
control.replay();
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
assertTrue( artifact.getFile().exists() );
assertEquals( "expected", FileUtils.fileRead( artifact.getFile(), "UTF-8" ) );
@ -318,7 +272,7 @@ public class DefaultWagonManagerTest
/* getArtifact */
assertFalse( "Transfer listener is registered before test",
wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
wagonManager.getArtifact( artifact, repo, transferListener );
wagonManager.getArtifact( artifact, repo, transferListener, false );
assertFalse( "Transfer listener still registered after getArtifact",
wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
@ -354,7 +308,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
}
catch ( ChecksumFailedException e )
{
@ -367,7 +321,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
}
catch ( ChecksumFailedException e )
{
@ -380,7 +334,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
fail( "Checksum verification did not fail" );
}
catch ( ChecksumFailedException e )
@ -394,7 +348,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
}
catch ( ChecksumFailedException e )
{
@ -407,7 +361,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
}
catch ( ChecksumFailedException e )
{
@ -420,7 +374,7 @@ public class DefaultWagonManagerTest
try
{
wagonManager.getArtifact( artifact, repo, null );
wagonManager.getArtifact( artifact, repo, null, false );
fail( "Checksum verification did not fail" );
}
catch ( ChecksumFailedException e )