[
https://issues.apache.org/jira/browse/MNG-6869?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17686711#comment-17686711
]
ASF GitHub Bot commented on MNG-6869:
-------------------------------------
rfscholte commented on code in PR #995:
URL: https://github.com/apache/maven/pull/995#discussion_r1101903050
##########
maven-embedder/src/main/java/org/apache/maven/cli/MavenStatusCommand.java:
##########
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+package org.apache.maven.cli;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.maven.api.ArtifactCoordinate;
+import org.apache.maven.api.Session;
+import org.apache.maven.api.services.ArtifactResolver;
+import org.apache.maven.api.services.ArtifactResolverException;
+import org.apache.maven.api.services.ArtifactResolverResult;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequestPopulationException;
+import org.apache.maven.execution.MavenExecutionRequestPopulator;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
+import org.apache.maven.internal.impl.DefaultArtifactCoordinate;
+import org.apache.maven.internal.impl.DefaultSession;
+import org.apache.maven.internal.impl.DefaultSessionFactory;
+import org.apache.maven.session.scope.internal.SessionScope;
+import org.codehaus.plexus.PlexusContainer;
+import
org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MavenStatusCommand {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(MavenStatusCommand.class);
+
+ /**
+ * In order to verify artifacts can be downloaded from the remote
repositories we want to resolve an actual
+ * artifact. The Apache Maven artifact was chosen as it eventually, be it
by proxy, mirror or directly, will be
+ * gathered from the central repository. The version is chosen arbitrarily
since any listed should work.
+ */
+ public static final Artifact APACHE_MAVEN_ARTIFACT =
+ new DefaultArtifact("org.apache.maven", "apache-maven", null,
"pom", "3.8.6");
+
+ private final MavenExecutionRequestPopulator
mavenExecutionRequestPopulator;
+ private final ArtifactResolver artifactResolver;
+ private final RemoteRepositoryConnectionVerifier
remoteRepositoryConnectionVerifier;
+ private final DefaultSessionFactory defaultSessionFactory;
+ private final DefaultRepositorySystemSessionFactory repoSession;
+ private final MavenRepositorySystem repositorySystem;
+ private final PlexusContainer container;
+ private final SessionScope sessionScope;
+ private Path tempLocalRepository;
+
+ public MavenStatusCommand(final PlexusContainer container) throws
ComponentLookupException {
+ this.container = container;
+ this.remoteRepositoryConnectionVerifier = new
RemoteRepositoryConnectionVerifier(container);
+ this.mavenExecutionRequestPopulator =
container.lookup(MavenExecutionRequestPopulator.class);
+ this.artifactResolver = container.lookup(ArtifactResolver.class);
+ this.defaultSessionFactory =
container.lookup(DefaultSessionFactory.class);
+ this.repoSession =
container.lookup(DefaultRepositorySystemSessionFactory.class);
+ this.sessionScope = container.lookup(SessionScope.class);
+ this.repositorySystem = container.lookup(MavenRepositorySystem.class);
+ }
+
+ public List<String> verify(final MavenExecutionRequest cliRequest) throws
MavenExecutionRequestPopulationException {
+ final MavenExecutionRequest mavenExecutionRequest =
mavenExecutionRequestPopulator.populateDefaults(cliRequest);
+
+ final ArtifactRepository localRepository =
cliRequest.getLocalRepository();
+
+ final List<String> localRepositoryIssues =
+
verifyLocalRepository(Paths.get(URI.create(localRepository.getUrl())));
+
+ // We overwrite the local repository with a temporary folder to avoid
using a cached version of the artifact.
+ setTemporaryLocalRepositoryPathOnRequest(cliRequest);
+
+ final List<String> remoteRepositoryIssues =
+
verifyRemoteRepositoryConnections(cliRequest.getRemoteRepositories(),
mavenExecutionRequest);
+ final List<String> artifactResolutionIssues =
verifyArtifactResolution(mavenExecutionRequest);
+
+ cleanupTempFiles();
+
+ // Collect all issues into a single list
+ return Stream.of(localRepositoryIssues, remoteRepositoryIssues,
artifactResolutionIssues)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ private void cleanupTempFiles() {
+ if (tempLocalRepository != null) {
+ try (Stream<Path> files = Files.walk(tempLocalRepository)) {
+ files.sorted(Comparator.reverseOrder()) // Sort in reverse
order so that directories are deleted last
+ .map(Path::toFile)
+ .forEach(File::delete);
+ } catch (IOException ioe) {
+ LOGGER.debug("Failed to delete temporary local repository",
ioe);
+ }
+ }
+ }
+
+ private void setTemporaryLocalRepositoryPathOnRequest(final
MavenExecutionRequest request) {
+ try {
+ tempLocalRepository =
Files.createTempDirectory("mvn-status").toAbsolutePath();
+ request.setLocalRepositoryPath(tempLocalRepository.toString());
+
request.setLocalRepository(repositorySystem.createLocalRepository(request,
tempLocalRepository.toFile()));
+ } catch (Exception ex) {
+ LOGGER.debug("Could not create temporary local repository", ex);
+ LOGGER.warn("Artifact resolution test is less accurate as it may
use earlier resolution results.");
+ }
+ }
+
+ private List<String> verifyRemoteRepositoryConnections(
+ final List<ArtifactRepository> remoteRepositories, final
MavenExecutionRequest mavenExecutionRequest) {
+ final List<String> issues = new ArrayList<>();
+
+ for (ArtifactRepository remoteRepository : remoteRepositories) {
+ final RepositorySystemSession repositorySession =
repoSession.newRepositorySession(mavenExecutionRequest);
+ remoteRepositoryConnectionVerifier
+ .verifyConnectionToRemoteRepository(repositorySession,
remoteRepository)
+ .ifPresent(issues::add);
+ }
+
+ return issues;
+ }
+
+ private List<String> verifyArtifactResolution(final MavenExecutionRequest
mavenExecutionRequest) {
Review Comment:
I think this is 1 step too much. Is this the only way to verify if a remote
repository is accessible? If you need to use an explicit file instead of a
directory, is it possible to use http HEAD ?
> New flag to verify the status
> -----------------------------
>
> Key: MNG-6869
> URL: https://issues.apache.org/jira/browse/MNG-6869
> Project: Maven
> Issue Type: New Feature
> Reporter: Robert Scholte
> Assignee: Maarten Mulders
> Priority: Major
>
> While working on INFRA-19861 we had issues with invalid changes in the
> settings.xml.
> This was detected too late. After installation {{mvn --version}} is called,
> but it will only show the version of Maven.
> It would be better to have a flag that verifies it a bit more:
> - can Maven read/write to the local repository
> - can Maven access all predefined repositories? (does the proxy work?)
> This gives a much better feedback if Maven can do its job.
> Current workaround: call something like {{mvn help:evaluate
> -Dexpression=settings.localRepository -q -DforceStdout}}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)