diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReport.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReport.java index 2d8eeedd..a327d632 100644 --- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReport.java +++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReport.java @@ -18,6 +18,9 @@ */ package org.apache.maven.plugins.artifact.buildinfo; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -167,12 +170,8 @@ private void renderReproducibleCentralArtifact(Sink sink, Artifact a) { private void renderReproducibleCentralArtifact( Sink sink, String groupId, String artifactId, String version, String scope) { - String url = "https://jvm-repo-rebuild.github.io/reproducible-central/badge/artifact/" - + groupId.replace('.', '/') + '/' + artifactId + ".html"; - String badge = "https://img.shields.io/reproducible-central/artifact/" + groupId + '/' + artifactId + '/' - + version + "?labelColor=1e5b96"; - sink.link(url); - sink.figureGraphics(badge); + sink.link(reproducibleCentralArtifactUrl(groupId, artifactId)); + sink.figureGraphics(reproducibleCentralArtifactBadgeUrl(groupId, artifactId, version)); sink.link_(); sink.text(' ' + groupId + ':' + artifactId + ':' + version); if (scope != null) { @@ -180,6 +179,24 @@ private void renderReproducibleCentralArtifact( } } + static String reproducibleCentralArtifactUrl(String groupId, String artifactId) { + return "https://jvm-repo-rebuild.github.io/reproducible-central/badge/artifact/" + + encode(groupId).replace('.', '/') + '/' + encode(artifactId) + ".html"; + } + + static String reproducibleCentralArtifactBadgeUrl(String groupId, String artifactId, String version) { + return "https://img.shields.io/reproducible-central/artifact/" + encode(groupId) + '/' + encode(artifactId) + + '/' + encode(version) + "?labelColor=1e5b96"; + } + + private static String encode(String s) { + try { + return URLEncoder.encode(s, StandardCharsets.UTF_8.name()).replace("+", "%20"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("UTF-8 encoding is not supported", e); + } + } + /** * @deprecated use {@link #getOutputPath()} instead */ diff --git a/src/test/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReportTest.java b/src/test/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReportTest.java new file mode 100644 index 00000000..c60f103d --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/artifact/buildinfo/ReproducibleCentralReportTest.java @@ -0,0 +1,42 @@ +/* + * 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.plugins.artifact.buildinfo; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ReproducibleCentralReportTest { + @Test + void artifactUrlEncodesCoordinates() { + assertEquals( + "https://jvm-repo-rebuild.github.io/reproducible-central/badge/artifact/" + + "com%26pany/example/my%24artifact.html", + ReproducibleCentralReport.reproducibleCentralArtifactUrl("com&pany.example", "my$artifact")); + } + + @Test + void artifactBadgeUrlEncodesCoordinates() { + assertEquals( + "https://img.shields.io/reproducible-central/artifact/com%26pany/my%24artifact/" + + "1.0%2FRC%3F1%23x%22%26?labelColor=1e5b96", + ReproducibleCentralReport.reproducibleCentralArtifactBadgeUrl( + "com&pany", "my$artifact", "1.0/RC?1#x\"&")); + } +}