This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/working-directory-detection in repository https://gitbox.apache.org/repos/asf/maven-scm.git
commit fcf04e6701420e700a94db910c0c256e2fc0fd7d Author: Konrad Windszus <k...@apache.org> AuthorDate: Thu Sep 18 11:38:43 2025 +0200 Add method to ScmManager to get an ScmRepository from an existing directory It tries to find a suitable provider by using ScmProvider.makeProviderScmRepository(directory) on all providers Extend checkoutTck to make sure that the working copy is recognized afterwards by the provider. --- .../maven/scm/manager/AbstractScmManager.java | 23 ++++++++++++++++++++++ .../org/apache/maven/scm/manager/ScmManager.java | 20 ++++++++++++++++++- .../org/apache/maven/scm/provider/ScmProvider.java | 8 ++++++++ .../scm/provider/git/jgit/JGitScmProvider.java | 4 +++- .../apache/maven/scm/manager/ScmManagerStub.java | 6 ++++++ .../command/checkout/CheckOutCommandTckTest.java | 5 +++++ 6 files changed, 64 insertions(+), 2 deletions(-) diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/AbstractScmManager.java b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/AbstractScmManager.java index f58e4053c..240c0ccb4 100644 --- a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/AbstractScmManager.java +++ b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/AbstractScmManager.java @@ -23,6 +23,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.scm.CommandParameters; @@ -245,6 +246,28 @@ public ScmRepository makeProviderScmRepository(String providerType, File path) return new ScmRepository(providerType, providerRepository); } + @Override + public Optional<ScmRepository> makeProviderScmRepository(File workingDirectory) { + // + for (ScmProvider provider : scmProviders.values()) { + logger.debug( + "Checking if SCM provider {} is suitable for processing: {}", + provider.getScmType(), + workingDirectory); + try { + ScmProviderRepository providerRepository = provider.makeProviderScmRepository(workingDirectory); + return Optional.of(new ScmRepository(provider.getScmType(), providerRepository)); + } catch (ScmRepositoryException | UnknownRepositoryStructure e) { + logger.debug( + "SCM provider {} is not suitable for processing: {}", + provider.getScmType(), + workingDirectory, + e); + } + } + return Optional.empty(); + } + /** * {@inheritDoc} */ diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java index eef11c157..6d868c012 100644 --- a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java +++ b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java @@ -21,6 +21,7 @@ import java.io.File; import java.util.Date; import java.util.List; +import java.util.Optional; import org.apache.maven.scm.CommandParameters; import org.apache.maven.scm.ScmBranch; @@ -62,7 +63,7 @@ public interface ScmManager { // ---------------------------------------------------------------------- /** - * Generate a SCMRepository from an SCM URL. + * Generate a {@link ScmRepository} from an SCM URL. * * @param scmUrl the scm url * @return the scm repository @@ -71,9 +72,26 @@ public interface ScmManager { */ ScmRepository makeScmRepository(String scmUrl) throws ScmRepositoryException, NoSuchScmProviderException; + /** + * Generate a {@link ScmRepository} for a specific provider and an a given checkout (working) directory + * @param providerType + * @param path the checkout (working) directory + * @return the SCM repository + * @throws ScmRepositoryException if the provider does not recognize the directory + * @throws UnknownRepositoryStructure if the provider does not support this way of generating a {@link ScmRepository} + * @throws NoSuchScmProviderException if the given provider type does not have a provider implementation bound + */ ScmRepository makeProviderScmRepository(String providerType, File path) throws ScmRepositoryException, UnknownRepositoryStructure, NoSuchScmProviderException; + /** + * Determines a suitable SCM provider for a checkout (working) directory by looking for SCM specific metadata files. + * @param path the checkout (working) directory + * @return the {@link ScmRepository} or empty if no suitable provider found + * @since 2.2.1 + */ + Optional<ScmRepository> makeProviderScmRepository(File path); + /** * Validate a SCM URL. * diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java index 97b6540b8..071282309 100644 --- a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java +++ b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java @@ -65,6 +65,14 @@ public interface ScmProvider { ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter) throws ScmRepositoryException; + /** + * Try to create a ScmProviderRepository for this provider from the given working directory (created through a previous checkout). + * This is only successful if the working directory is recognized as a working copy of this SCM. + * @param path the checkout(working) directory + * @return the repository bound to this provider + * @throws ScmRepositoryException in case the given directory does not contain a valid working directory recognized by this provider + * @throws UnknownRepositoryStructure in case the provider does not support this way of initializing an ScmProviderRepository + */ ScmProviderRepository makeProviderScmRepository(File path) throws ScmRepositoryException, UnknownRepositoryStructure; diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java index 2bc872cf5..14011fe15 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java @@ -44,6 +44,7 @@ import org.apache.maven.scm.provider.git.jgit.command.status.JGitStatusCommand; import org.apache.maven.scm.provider.git.jgit.command.tag.JGitTagCommand; import org.apache.maven.scm.provider.git.jgit.command.untag.JGitUntagCommand; +import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; import org.apache.maven.scm.repository.ScmRepositoryException; import org.codehaus.plexus.components.interactivity.Prompter; import org.eclipse.jgit.transport.CredentialsProvider; @@ -188,7 +189,8 @@ protected String getRepositoryURL(File path) throws ScmException { // Note: I need to supply just 1 absolute path, but ScmFileSet won't let // me without // a basedir (which isn't used here anyway), so use a dummy file. - InfoScmResult result = info(null, new ScmFileSet(new File(""), path), null); + InfoScmResult result = + info(new GitScmProviderRepository(path.toPath().toUri().toASCIIString()), new ScmFileSet(path), null); if (result.getInfoItems().size() != 1) { throw new ScmRepositoryException("Cannot find URL: " diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/manager/ScmManagerStub.java b/maven-scm-test/src/main/java/org/apache/maven/scm/manager/ScmManagerStub.java index c732cfbcb..716153f80 100644 --- a/maven-scm-test/src/main/java/org/apache/maven/scm/manager/ScmManagerStub.java +++ b/maven-scm-test/src/main/java/org/apache/maven/scm/manager/ScmManagerStub.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Optional; import org.apache.maven.scm.CommandParameters; import org.apache.maven.scm.ScmBranch; @@ -141,6 +142,11 @@ public ScmRepository makeProviderScmRepository(String providerType, File path) return getScmRepository(); } + @Override + public Optional<ScmRepository> makeProviderScmRepository(File path) { + return Optional.ofNullable(getScmRepository()); + } + /** * Returns the same list as getMessages() * diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/checkout/CheckOutCommandTckTest.java b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/checkout/CheckOutCommandTckTest.java index 3f76ecd0f..001f6883a 100644 --- a/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/checkout/CheckOutCommandTckTest.java +++ b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/checkout/CheckOutCommandTckTest.java @@ -20,14 +20,17 @@ import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.SortedSet; import java.util.TreeSet; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmTckTestCase; import org.apache.maven.scm.command.checkout.CheckOutScmResult; +import org.apache.maven.scm.repository.ScmRepository; import org.junit.Test; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** @@ -59,5 +62,7 @@ public void testCheckOutCommandTest() throws Exception { fail("Expected 4 files in the updated files list, was " + checkedOutFiles.size()); } + Optional<ScmRepository> repository = getScmManager().makeProviderScmRepository(getWorkingCopy()); + assertTrue("Could not detect SCM repository for working copy at " + getWorkingCopy(), repository.isPresent()); } }