Skip to content

Commit a254952

Browse files
committed
[MSITE-1033] Improve heuristics to detect inheritance for SCM site URLs
1 parent 5a0e56d commit a254952

File tree

3 files changed

+121
-6
lines changed

3 files changed

+121
-6
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,12 @@ under the License.
415415
</exclusions>
416416
</dependency>
417417

418+
<dependency>
419+
<groupId>org.apache.maven.scm</groupId>
420+
<artifactId>maven-scm-api</artifactId>
421+
<version>2.1.0</version>
422+
</dependency>
423+
418424
<dependency>
419425
<groupId>org.apache.commons</groupId>
420426
<artifactId>commons-lang3</artifactId>

src/main/java/org/apache/maven/plugins/site/deploy/AbstractDeployMojo.java

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020

2121
import java.io.File;
2222
import java.net.MalformedURLException;
23+
import java.net.URI;
2324
import java.net.URL;
2425
import java.util.List;
2526
import java.util.Locale;
27+
import java.util.Objects;
2628

2729
import org.apache.maven.doxia.site.inheritance.URIPathDescriptor;
2830
import org.apache.maven.doxia.tools.SiteTool;
@@ -35,6 +37,7 @@
3537
import org.apache.maven.plugins.annotations.Parameter;
3638
import org.apache.maven.plugins.site.AbstractSiteMojo;
3739
import org.apache.maven.project.MavenProject;
40+
import org.apache.maven.scm.provider.ScmUrlUtils;
3841
import org.apache.maven.settings.Proxy;
3942
import org.apache.maven.settings.Server;
4043
import org.apache.maven.settings.Settings;
@@ -523,18 +526,69 @@ protected MavenProject getTopLevelProject(MavenProject project) throws MojoExecu
523526
return oldProject;
524527
}
525528

526-
// MSITE-600
527-
URIPathDescriptor siteURI = new URIPathDescriptor(URIEncoder.encodeURI(site.getUrl()), "");
528-
URIPathDescriptor oldSiteURI = new URIPathDescriptor(URIEncoder.encodeURI(oldSite.getUrl()), "");
529-
530-
if (!siteURI.sameSite(oldSiteURI.getBaseURI())) {
529+
try {
530+
if (!isSameSite(site.getUrl(), oldSite.getUrl())) {
531+
return oldProject;
532+
}
533+
} catch (IllegalArgumentException e) {
534+
getLog().warn("Failed to parse distributionManagement.site.url of project \"" + getFullName(oldProject)
535+
+ "\" or project \"" + getFullName(parent) + "\": " + e.getMessage());
531536
return oldProject;
532537
}
533538
}
534-
535539
return parent;
536540
}
537541

542+
/**
543+
* Returns {@code true} if the URIs are probably pointing to the same site which means
544+
* <ul>
545+
* <li>both arguments are hierarchical URIs,</li>
546+
* <li>both arguments share the same host and</li>
547+
* <li>the path of the latter URI is a subpath of the first URI</li>
548+
* </ul>.
549+
* @param parentUri
550+
* @param uri
551+
* @return {@code true} if the URIs are probably pointing to the same site
552+
* @throws IllegalArgumentException if the given URIs cannot be parsed
553+
*/
554+
static boolean isSameSite(String parentUri, String uri) {
555+
// this just normalizes the paths in it
556+
URIPathDescriptor siteURI =
557+
new URIPathDescriptor(URIEncoder.encodeURI(extractProviderSpecificPartFromScmUri(parentUri)), "");
558+
URIPathDescriptor oldSiteURI =
559+
new URIPathDescriptor(URIEncoder.encodeURI(extractProviderSpecificPartFromScmUri(uri)), "");
560+
// compare host and path (port and scheme should not matter)
561+
return isSameSite(siteURI.getBaseURI(), oldSiteURI.getBaseURI());
562+
}
563+
564+
private static boolean isSameSite(URI parentUri, URI uri) {
565+
// host must be equal
566+
if (!Objects.equals(uri.getHost(), parentUri.getHost())) {
567+
return false;
568+
}
569+
// path must be a subpath
570+
if (uri.getPath() == null
571+
|| parentUri.getPath() == null
572+
|| !uri.getPath().startsWith(parentUri.getPath())) {
573+
return false;
574+
}
575+
return true;
576+
}
577+
578+
/**
579+
* Unwraps <a href="https://maven.apache.org/scm/scm-url-format.html">SCM URLs</a> to get the provider specific part.
580+
* @param uri
581+
* @return the provider specific part if the given URI is a SCM URI, otherwise just the uri
582+
*
583+
*/
584+
static String extractProviderSpecificPartFromScmUri(String uri) {
585+
if (ScmUrlUtils.isValid(uri)) {
586+
return ScmUrlUtils.getProviderSpecificPart(uri);
587+
} else {
588+
return uri;
589+
}
590+
}
591+
538592
private static class URIEncoder {
539593
private static final String MARK = "-_.!~*'()";
540594
private static final String RESERVED = ";/?:@&=+$,";
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.plugins.site.deploy;
20+
21+
import org.junit.Test;
22+
23+
import static org.junit.Assert.assertFalse;
24+
import static org.junit.Assert.assertThrows;
25+
import static org.junit.Assert.assertTrue;
26+
27+
public class AbstractDeployMojoTest {
28+
29+
@Test
30+
public void testIsSameSite() {
31+
assertTrue(AbstractDeployMojo.isSameSite(
32+
"scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}",
33+
"scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}"));
34+
assertTrue(AbstractDeployMojo.isSameSite(
35+
"https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}",
36+
"https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}"));
37+
assertTrue(AbstractDeployMojo.isSameSite(
38+
"scm:svn:http://svn.apache.org/repos/asf/maven/website",
39+
"scm:svn:https://svn.apache.org/repos/asf/maven/website/components"));
40+
assertTrue(AbstractDeployMojo.isSameSite(
41+
"scm:git:ssh://github.com/codehaus-plexus/plexus-pom.git/",
42+
"scm:git:ssh://github.com/codehaus-plexus/plexus-pom.git"));
43+
assertFalse(AbstractDeployMojo.isSameSite(
44+
"scm:svn:https://svn.apache.org/repos/asf/maven/website/a/${maven.site.path}",
45+
"scm:svn:https://svn.apache.org/repos/asf/maven/website/b/${maven.site.path}"));
46+
assertFalse(AbstractDeployMojo.isSameSite(
47+
"scm:git:ssh://github.com/codehaus-plexus/plexus-pom.git/",
48+
"scm:git:ssh://[email protected]/codehaus-plexus/plexus-sec-dispatcher.git/"));
49+
// SCM URLs which are opaque (i.e. non hierarchical URIs)
50+
assertThrows(
51+
IllegalArgumentException.class,
52+
() -> AbstractDeployMojo.isSameSite(
53+
"scm:local:/usr/modules:my_module", "scm:local:/usr/modules:my_module"));
54+
}
55+
}

0 commit comments

Comments
 (0)