This is an automated email from the ASF dual-hosted git repository. sjaranowski pushed a commit to branch MRESOLVER-310 in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
commit 814930770272085dbeca05840149604fd523eb3e Author: Slawomir Jaranowski <[email protected]> AuthorDate: Wed Feb 15 22:45:21 2023 +0100 [MRESOLVER-310] Preserve configuration of Enhanced LRM in local repo --- .../DefaultLocalPathPrefixComposerFactory.java | 5 +- .../impl/EnhancedLocalRepositoryConfig.java | 170 +++++++++++++++++++++ .../EnhancedLocalRepositoryManagerFactory.java | 8 +- .../impl/LocalPathPrefixComposerFactory.java | 6 +- .../LocalPathPrefixComposerFactorySupport.java | 10 -- .../DefaultLocalPathPrefixComposerFactoryTest.java | 18 ++- .../impl/EnhancedLocalRepositoryManagerTest.java | 5 +- .../EnhancedSplitLocalRepositoryManagerTest.java | 9 +- 8 files changed, 204 insertions(+), 27 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactory.java index 7fce1a04..f1ba820d 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactory.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactory.java @@ -35,9 +35,10 @@ import org.eclipse.aether.RepositorySystemSession; public final class DefaultLocalPathPrefixComposerFactory extends LocalPathPrefixComposerFactorySupport { @Override - public LocalPathPrefixComposer createComposer( RepositorySystemSession session ) + public LocalPathPrefixComposer createComposer( RepositorySystemSession session, + EnhancedLocalRepositoryConfig repositoryConfig ) { - return new DefaultLocalPathPrefixComposer( isSplit( session ), getLocalPrefix( session ), + return new DefaultLocalPathPrefixComposer( repositoryConfig.isSplit(), getLocalPrefix( session ), isSplitLocal( session ), getRemotePrefix( session ), isSplitRemote( session ), isSplitRemoteRepository( session ), isSplitRemoteRepositoryLast( session ), getReleasesPrefix( session ), getSnapshotsPrefix( session ) ); diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryConfig.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryConfig.java new file mode 100644 index 00000000..a9114fff --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryConfig.java @@ -0,0 +1,170 @@ +package org.eclipse.aether.internal.impl; + +/* + * 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.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.util.ConfigUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; +import static java.nio.file.StandardOpenOption.WRITE; + +/** + * Enhanced Local Repository configuration holder. + */ +class EnhancedLocalRepositoryConfig +{ + private static final Logger LOGGER = LoggerFactory.getLogger( EnhancedLocalRepositoryConfig.class ); + + private static final String CONFIG_PROP_TRACKING_FILENAME = "aether.enhancedLocalRepository.trackingFilename"; + + private static final String DEFAULT_TRACKING_FILENAME = "_remote.repositories"; + + protected static final String CONF_PROP_SPLIT = "aether.enhancedLocalRepository.split"; + + protected static final String DEFAULT_SPLIT = "false"; + + private Properties config; + + EnhancedLocalRepositoryConfig( RepositorySystemSession session, File basedir ) + { + try + { + config = loadConfiguration( basedir ); + int configHash0 = configurationHash( config ); + populateConfiguration( config, session ); + int configHash1 = configurationHash( config ); + + if ( configHash0 != configHash1 ) + { + storeConfig( config, basedir ); + } + else + { + LOGGER.debug( "Use saved ELRM configuration" ); + } + } + catch ( IOException e ) + { + throw new UncheckedIOException( e ); + } + } + + private static void populateConfiguration( Properties configurations, RepositorySystemSession session ) + { + populateConfiguration( configurations, session, CONFIG_PROP_TRACKING_FILENAME, DEFAULT_TRACKING_FILENAME ); + populateConfiguration( configurations, session, CONF_PROP_SPLIT, DEFAULT_SPLIT ); + } + + private static void populateConfiguration( Properties configurations, RepositorySystemSession session, String key, + String defaultValue ) + { + String valueConf = configurations.getProperty( key ); + String valueSession = ConfigUtils.getString( session, null, key ); + + if ( StringUtils.isNotBlank( valueConf ) && StringUtils.isNotBlank( valueSession ) + && !valueConf.equals( valueSession ) ) + { + LOGGER.debug( "New config {}={} for ELRM will not be used", key, valueSession ); + } + + if ( StringUtils.isBlank( valueConf ) && StringUtils.isNotBlank( valueSession ) ) + { + configurations.setProperty( key, valueSession ); + } + else if ( StringUtils.isBlank( valueConf ) && StringUtils.isBlank( valueSession ) ) + { + configurations.setProperty( key, defaultValue ); + } + } + + private static int configurationHash( Properties configurations ) + { + return configurations.entrySet().stream() + .mapToInt( e -> Objects.hash( e.getKey(), e.getValue() ) ) + .reduce( 1, ( i1, i2 ) -> 31 * i1 * i2 ); + } + + private static Properties loadConfiguration( File basedir ) throws IOException + { + Properties props = new Properties(); + Path configPath = Optional.ofNullable( basedir ) + .map( File::toPath ) + .map( p -> p.resolve( "elrm.properties" ) ) + .filter( Files::isReadable ) + .orElse( null ); + + if ( configPath != null ) + { + try ( InputStream inputStream = Files.newInputStream( configPath ) ) + { + props.load( inputStream ); + } + } + return props; + } + + private void storeConfig( Properties configurations, File basedir ) throws IOException + { + Path configPath = Optional.ofNullable( basedir ) + .map( File::toPath ) + .map( p -> p.resolve( "elrm.properties" ) ) + .orElse( null ); + + if ( configPath != null ) + { + Path parent = configPath.getParent(); + if ( parent != null ) + { + Files.createDirectories( parent ); + } + + LOGGER.debug( "Create local repository configuration: {}", configPath ); + try ( OutputStream outputStream = Files.newOutputStream( configPath, WRITE, TRUNCATE_EXISTING, CREATE ) ) + { + configurations.store( outputStream, "Enhanced Local Repository Configuration" ); + } + } + } + + public String getTrackingFilename() + { + return config.getProperty( CONFIG_PROP_TRACKING_FILENAME ); + } + + public boolean isSplit() + { + return Boolean.parseBoolean( config.getProperty( CONF_PROP_SPLIT ) ); + } +} diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java index 98fcddb5..db93fdf9 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java @@ -30,7 +30,6 @@ import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; import org.eclipse.aether.spi.locator.Service; import org.eclipse.aether.spi.locator.ServiceLocator; -import org.eclipse.aether.util.ConfigUtils; import static java.util.Objects.requireNonNull; @@ -88,7 +87,10 @@ public class EnhancedLocalRepositoryManagerFactory requireNonNull( session, "session cannot be null" ); requireNonNull( repository, "repository cannot be null" ); - String trackingFilename = ConfigUtils.getString( session, "", CONFIG_PROP_TRACKING_FILENAME ); + EnhancedLocalRepositoryConfig repositoryConfig = + new EnhancedLocalRepositoryConfig( session, repository.getBasedir() ); + + String trackingFilename = repositoryConfig.getTrackingFilename(); if ( trackingFilename.isEmpty() || trackingFilename.contains( "/" ) || trackingFilename.contains( "\\" ) || trackingFilename.contains( ".." ) ) { @@ -102,7 +104,7 @@ public class EnhancedLocalRepositoryManagerFactory localPathComposer, trackingFilename, trackingFileManager, - localPathPrefixComposerFactory.createComposer( session ) + localPathPrefixComposerFactory.createComposer( session, repositoryConfig ) ); } else diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactory.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactory.java index 2ef76937..41efb6c2 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactory.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactory.java @@ -31,8 +31,10 @@ public interface LocalPathPrefixComposerFactory /** * Creates {@link LocalPathPrefixComposer} instance out of whatever configuration it finds in passed in session. * - * @param session The repository session, never {@code null}. + * @param session The repository session, never {@code null}. + * @param repositoryConfig The locla repository configuration * @return The created instance, never {@code null}. */ - LocalPathPrefixComposer createComposer( RepositorySystemSession session ); + LocalPathPrefixComposer createComposer( RepositorySystemSession session, + EnhancedLocalRepositoryConfig repositoryConfig ); } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactorySupport.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactorySupport.java index eff360eb..f1301500 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactorySupport.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/LocalPathPrefixComposerFactorySupport.java @@ -38,10 +38,6 @@ import org.eclipse.aether.util.ConfigUtils; */ public abstract class LocalPathPrefixComposerFactorySupport implements LocalPathPrefixComposerFactory { - protected static final String CONF_PROP_SPLIT = "aether.enhancedLocalRepository.split"; - - protected static final boolean DEFAULT_SPLIT = false; - protected static final String CONF_PROP_LOCAL_PREFIX = "aether.enhancedLocalRepository.localPrefix"; protected static final String DEFAULT_LOCAL_PREFIX = "installed"; @@ -76,12 +72,6 @@ public abstract class LocalPathPrefixComposerFactorySupport implements LocalPath protected static final String DEFAULT_SNAPSHOTS_PREFIX = "snapshots"; - protected boolean isSplit( RepositorySystemSession session ) - { - return ConfigUtils.getBoolean( - session, DEFAULT_SPLIT, CONF_PROP_SPLIT ); - } - protected String getLocalPrefix( RepositorySystemSession session ) { return ConfigUtils.getString( diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactoryTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactoryTest.java index 2728c5bb..3ce4e1df 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactoryTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultLocalPathPrefixComposerFactoryTest.java @@ -31,6 +31,8 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * UT for {@link DefaultLocalPathPrefixComposerFactory}. @@ -51,13 +53,15 @@ public class DefaultLocalPathPrefixComposerFactoryTest private final RemoteRepository repository = new RemoteRepository.Builder( "my-repo", "default", "https://repo.maven.apache.org/maven2/" ).build(); + private final EnhancedLocalRepositoryConfig repositoryConfig = mock( EnhancedLocalRepositoryConfig.class ); + @Test public void defaultConfigNoSplitAllNulls() { DefaultRepositorySystemSession session = TestUtils.newSession(); LocalPathPrefixComposerFactory factory = new DefaultLocalPathPrefixComposerFactory(); - LocalPathPrefixComposer composer = factory.createComposer( session ); + LocalPathPrefixComposer composer = factory.createComposer( session, repositoryConfig ); assertNotNull( composer ); String prefix; @@ -78,10 +82,10 @@ public class DefaultLocalPathPrefixComposerFactoryTest public void splitEnabled() { DefaultRepositorySystemSession session = TestUtils.newSession(); - session.setConfigProperty( "aether.enhancedLocalRepository.split", Boolean.TRUE.toString() ); + when( repositoryConfig.isSplit() ).thenReturn( true ); LocalPathPrefixComposerFactory factory = new DefaultLocalPathPrefixComposerFactory(); - LocalPathPrefixComposer composer = factory.createComposer( session ); + LocalPathPrefixComposer composer = factory.createComposer( session, repositoryConfig ); assertNotNull( composer ); String prefix; @@ -106,12 +110,12 @@ public class DefaultLocalPathPrefixComposerFactoryTest public void saneConfig() { DefaultRepositorySystemSession session = TestUtils.newSession(); - session.setConfigProperty( "aether.enhancedLocalRepository.split", Boolean.TRUE.toString() ); + when( repositoryConfig.isSplit() ).thenReturn( true ); session.setConfigProperty( "aether.enhancedLocalRepository.splitLocal", Boolean.TRUE.toString() ); session.setConfigProperty( "aether.enhancedLocalRepository.splitRemoteRepository", Boolean.TRUE.toString() ); LocalPathPrefixComposerFactory factory = new DefaultLocalPathPrefixComposerFactory(); - LocalPathPrefixComposer composer = factory.createComposer( session ); + LocalPathPrefixComposer composer = factory.createComposer( session, repositoryConfig ); assertNotNull( composer ); String prefix; @@ -168,13 +172,13 @@ public class DefaultLocalPathPrefixComposerFactoryTest public void fullConfig() { DefaultRepositorySystemSession session = TestUtils.newSession(); - session.setConfigProperty( "aether.enhancedLocalRepository.split", Boolean.TRUE.toString() ); + when( repositoryConfig.isSplit() ).thenReturn( true ); session.setConfigProperty( "aether.enhancedLocalRepository.splitLocal", Boolean.TRUE.toString() ); session.setConfigProperty( "aether.enhancedLocalRepository.splitRemote", Boolean.TRUE.toString() ); session.setConfigProperty( "aether.enhancedLocalRepository.splitRemoteRepository", Boolean.TRUE.toString() ); LocalPathPrefixComposerFactory factory = new DefaultLocalPathPrefixComposerFactory(); - LocalPathPrefixComposer composer = factory.createComposer( session ); + LocalPathPrefixComposer composer = factory.createComposer( session, repositoryConfig ); assertNotNull( composer ); String prefix; diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java index f69d8bd7..78426048 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerTest.java @@ -20,6 +20,7 @@ package org.eclipse.aether.internal.impl; */ import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; import java.io.File; import java.io.IOException; @@ -71,6 +72,8 @@ public class EnhancedLocalRepositoryManagerTest private Metadata noVerMetadata; + private final EnhancedLocalRepositoryConfig repositoryConfig = mock( EnhancedLocalRepositoryConfig.class ); + @Before public void setup() throws Exception @@ -110,7 +113,7 @@ public class EnhancedLocalRepositoryManagerTest new DefaultLocalPathComposer(), "_remote.repositories", trackingFileManager, - new DefaultLocalPathPrefixComposerFactory().createComposer( session ) + new DefaultLocalPathPrefixComposerFactory().createComposer( session, repositoryConfig ) ); } diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedSplitLocalRepositoryManagerTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedSplitLocalRepositoryManagerTest.java index 54036460..b2017fed 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedSplitLocalRepositoryManagerTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/EnhancedSplitLocalRepositoryManagerTest.java @@ -25,20 +25,25 @@ import org.eclipse.aether.repository.RemoteRepository; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class EnhancedSplitLocalRepositoryManagerTest extends EnhancedLocalRepositoryManagerTest { + private final EnhancedLocalRepositoryConfig repositoryConfig = mock( EnhancedLocalRepositoryConfig.class ); + @Override protected EnhancedLocalRepositoryManager getManager() { - session.setConfigProperty( "aether.enhancedLocalRepository.split", Boolean.TRUE.toString() ); + when( repositoryConfig.isSplit() ).thenReturn( true ); + return new EnhancedLocalRepositoryManager( basedir, new DefaultLocalPathComposer(), "_remote.repositories", trackingFileManager, - new DefaultLocalPathPrefixComposerFactory().createComposer( session ) + new DefaultLocalPathPrefixComposerFactory().createComposer( session, repositoryConfig ) ); }
