Skip to content

Commit 2992176

Browse files
committed
Enumerate native classifiers more exhaustively
Now we generate all combinations of OS family + architectures matching all observed naming conventions. It's still a hack, but these suffixes are highly unlikely to be part of any version number. And we use these generated platform strings in two places: the version pattern regex, and the default list of subdirectory classifiers.
1 parent 35e7737 commit 2992176

File tree

3 files changed

+156
-83
lines changed

3 files changed

+156
-83
lines changed

src/main/java/org/scijava/maven/plugin/install/AbstractInstallMojo.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.nio.file.Path;
3636
import java.nio.file.Paths;
3737
import java.util.ArrayList;
38+
import java.util.Arrays;
3839
import java.util.Collection;
3940
import java.util.Collections;
4041
import java.util.List;
@@ -50,7 +51,6 @@
5051
import org.apache.maven.plugin.AbstractMojo;
5152
import org.apache.maven.plugin.MojoExecution;
5253
import org.apache.maven.plugin.MojoExecutionException;
53-
import org.apache.maven.plugin.logging.Log;
5454
import org.apache.maven.plugins.annotations.Parameter;
5555
import org.apache.maven.project.MavenProject;
5656
import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
@@ -228,7 +228,7 @@ else if (isBioFormatsArtifact(artifact)) {
228228
break;
229229
case older:
230230
final String toInstall = artifact.getVersion();
231-
final Matcher matcher = versionPattern.matcher(otherName.toString());
231+
final Matcher matcher = VERSION_PATTERN.matcher(otherName.toString());
232232
if (!matcher.matches()) break;
233233
final String group = matcher.group(VERSION_INDEX);
234234
if (group == null) {
@@ -319,9 +319,30 @@ private String subdirectory(final Artifact artifact) {
319319
return null;
320320
}
321321

322-
private final static Pattern versionPattern = Pattern.compile("(.+?)"
323-
+ "(-\\d+(\\.\\d+|\\d{7})+[a-z]?\\d?(-[A-Za-z0-9.]+?|\\.GA)*?)?"
324-
+ "((-(swing|swt|sources|javadoc|native|linux-x86|linux-x86_64|linux-armhf|linux-ppc64le|macosx-x86_64|windows-x86|windows-x86_64|android-x86|android-x86_64|android-arm|android-arm64|ios-x86_64|ios-arm64|natives-windows|natives-macos|natives-linux))?(\\.jar(-[a-z]*)?))");
322+
private final static Pattern VERSION_PATTERN = Pattern.compile(versionPattern());
323+
324+
private static String versionPattern() {
325+
final String[] other = {
326+
"javadoc", "native", "sources", "swing", "swt"
327+
};
328+
final List<String> classifiers = new ArrayList<>();
329+
for (final String family : KnownPlatforms.FAMILIES) {
330+
classifiers.add(family);
331+
classifiers.add("native-" + family);
332+
classifiers.add("natives-" + family);
333+
for (final String arch : KnownPlatforms.ARCHES) {
334+
final String slug = family + "-" + arch;
335+
classifiers.add(slug);
336+
classifiers.add("native-" + slug);
337+
classifiers.add("natives-" + slug);
338+
}
339+
}
340+
classifiers.addAll(Arrays.asList(other));
341+
return "(.+?)"
342+
+ "(-\\d+(\\.\\d+|\\d{7})+[a-z]?\\d?(-[A-Za-z0-9.]+?|\\.GA)*?)?"
343+
+ "((-(" + String.join("|", classifiers) + "))?(\\.jar(-[a-z]*)?))";
344+
}
345+
325346
private final static int PREFIX_INDEX = 1;
326347
private final static int VERSION_INDEX = 2;
327348
private final static int SUFFIX_INDEX = 5;
@@ -350,7 +371,7 @@ private static String majorVersion( String v )
350371
* @return A collection of {@link Path}s to files of the same base name.
351372
*/
352373
private Collection<Path> getEncroachingVersions(final Path directory, final Path file) {
353-
final Matcher matcher = versionPattern.matcher(file.getFileName().toString());
374+
final Matcher matcher = VERSION_PATTERN.matcher(file.getFileName().toString());
354375
if (!matcher.matches()) return null;
355376

356377
final String prefix = matcher.group(PREFIX_INDEX);
@@ -361,7 +382,7 @@ private Collection<Path> getEncroachingVersions(final Path directory, final Path
361382
result = Files.walk(directory)
362383
.filter(path -> path.getFileName().toString().startsWith(prefix))
363384
.filter(path -> {
364-
final Matcher matcherIterator = versionPattern.matcher(path.getFileName().toString());
385+
final Matcher matcherIterator = VERSION_PATTERN.matcher(path.getFileName().toString());
365386
return matcherIterator.matches() &&
366387
prefix.equals(matcherIterator.group(PREFIX_INDEX)) &&
367388
suffix.equals(matcherIterator.group(SUFFIX_INDEX));
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* #%L
3+
* A plugin for managing SciJava-based projects.
4+
* %%
5+
* Copyright (C) 2014 - 2020 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package org.scijava.maven.plugin.install;
31+
32+
import java.util.Arrays;
33+
import java.util.List;
34+
35+
/**
36+
* Data structure enumerating known platform strings.
37+
*
38+
* @author Curtis Rueden
39+
*/
40+
public final class KnownPlatforms {
41+
42+
public static final List<String> FAMILIES = Arrays.asList(
43+
"android",
44+
"ios",
45+
"linux",
46+
"macos",
47+
"macosx",
48+
"osx",
49+
"windows"
50+
);
51+
52+
public static final List<String> ARCHES = Arrays.asList(
53+
"aarch64",
54+
"all",
55+
"amd64",
56+
"arm",
57+
"arm64",
58+
"armhf",
59+
"i586",
60+
"ppc64le",
61+
"universal",
62+
"x86",
63+
"x86_64"
64+
);
65+
66+
public static String shortName(final String family, final String arch) {
67+
if (isMacOS(family)) return "macosx";
68+
if (isWindows(family) && isArch32(arch)) return "win32";
69+
if (isWindows(family) && isArch64(arch)) return "win64";
70+
if (isLinux(family) && isArch32(arch)) return "linux32";
71+
if (isLinux(family) && isArch64(arch)) return "linux64";
72+
return null;
73+
}
74+
75+
private static boolean isWindows(final String family) {
76+
return "windows".equals(family);
77+
}
78+
private static boolean isLinux(final String family) {
79+
return "linux".equals(family);
80+
}
81+
private static boolean isMacOS(final String family) {
82+
final String[] macFamily = {"macos", "macosx", "osx"};
83+
return Arrays.asList(macFamily).contains(family);
84+
}
85+
private static boolean isArch32(final String arch) {
86+
return "i586".equals(arch) || "x86".equals(arch);
87+
}
88+
private static boolean isArch64(final String arch) {
89+
return arch == null || "amd64".equals(arch) || "x86_64".equals(arch);
90+
}
91+
}

src/main/java/org/scijava/maven/plugin/install/SubdirectoryPattern.java

Lines changed: 37 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929

3030
package org.scijava.maven.plugin.install;
3131

32-
import java.util.Arrays;
32+
import java.util.ArrayList;
33+
import java.util.HashMap;
3334
import java.util.List;
35+
import java.util.Map;
36+
import java.util.stream.Collectors;
3437

3538
/**
3639
* Data structure for mapping classifiers to subdirectories.
@@ -48,87 +51,45 @@ public class SubdirectoryPattern {
4851
public List<String> classifiers;
4952

5053
public static List<SubdirectoryPattern> defaultPatterns() {
51-
return Arrays.asList(
52-
pattern("jars/win64",
53-
"windows",
54-
"windows-amd64",
55-
"windows-x86_64",
56-
"native-windows",
57-
"native-windows-amd64",
58-
"native-windows-x86_64",
59-
"natives-windows",
60-
"natives-windows-amd64",
61-
"natives-windows-x64_64"),
62-
pattern("jars/win32",
63-
"windows-x86",
64-
"windows-x86_32",
65-
"native-windows-x86",
66-
"native-windows-x86_32",
67-
"natives-windows-x86",
68-
"natives-windows-x86_32"),
69-
pattern("jars/macosx",
70-
"macos",
71-
"macos-amd64",
72-
"macos-universal",
73-
"macos-x86_64",
74-
"macosx",
75-
"macosx-amd64",
76-
"macosx-universal",
77-
"macosx-x86_64",
78-
"osx",
79-
"osx-amd64",
80-
"osx-universal",
81-
"osx-x86_64",
82-
"native-macos",
83-
"native-macos-amd64",
84-
"native-macos-universal",
85-
"native-macos-x86_64",
86-
"native-macosx",
87-
"native-macosx-amd64",
88-
"native-macosx-universal",
89-
"native-macosx-x86_64",
90-
"native-osx",
91-
"native-osx-amd64",
92-
"native-osx-universal",
93-
"native-osx-x86_64",
94-
"natives-macos",
95-
"natives-macos-amd64",
96-
"natives-macos-universal",
97-
"natives-macos-x86_64",
98-
"natives-macosx",
99-
"natives-macosx-amd64",
100-
"natives-macosx-universal",
101-
"natives-macosx-x86_64",
102-
"natives-osx",
103-
"natives-osx-amd64",
104-
"natives-osx-universal",
105-
"natives-osx-x86_64"),
106-
pattern("jars/linux64",
107-
"linux",
108-
"linux-amd64",
109-
"linux-x86_64",
110-
"native-linux",
111-
"native-linux-amd64",
112-
"native-linux-x86_64",
113-
"natives-linux",
114-
"natives-linux-amd64",
115-
"natives-linux-x64_64"),
116-
pattern("jars/linux32",
117-
"linux-x86",
118-
"linux-x86_32",
119-
"native-linux-x86",
120-
"native-linux-x86_32",
121-
"natives-linux-x86",
122-
"natives-linux-x86_32")
123-
);
54+
final Map<String, List<String>> patterns = new HashMap<>();
55+
56+
for (final String family : KnownPlatforms.FAMILIES) {
57+
for (final String arch : KnownPlatforms.ARCHES) {
58+
// NB: Convert family+arch to short name --
59+
// e.g. win32, win64, macosx, linux32, linux64.
60+
final String shortName = KnownPlatforms.shortName(family, arch);
61+
if (shortName == null) continue;
62+
addClassifier(patterns, "jars/" + shortName, family + "-" + arch);
63+
}
64+
// NB: Convert family alone (no arch) to short name --
65+
// e.g. windows -> win64, osx -> macosx, linux -> linux64.
66+
final String shortName = KnownPlatforms.shortName(family, null);
67+
if (shortName == null) continue;
68+
addClassifier(patterns, "jars/" + shortName, family);
69+
}
70+
71+
return patterns.entrySet().stream() //
72+
.map(entry -> pattern(entry.getKey(), entry.getValue())) //
73+
.collect(Collectors.toList());
74+
}
75+
76+
private static void addClassifier(final Map<String, List<String>> patterns,
77+
final String name, final String classifier)
78+
{
79+
final String[] prefixes = { "", "native-", "natives-" };
80+
final List<String> classifiers = //
81+
patterns.computeIfAbsent(name, l -> new ArrayList<>());
82+
for (final String prefix : prefixes) {
83+
classifiers.add(prefix + classifier);
84+
}
12485
}
12586

12687
private static SubdirectoryPattern pattern(final String name,
127-
final String... classifiers)
88+
final List<String> classifiers)
12889
{
12990
final SubdirectoryPattern pattern = new SubdirectoryPattern();
13091
pattern.name = name;
131-
pattern.classifiers = Arrays.asList(classifiers);
92+
pattern.classifiers = classifiers;
13293
return pattern;
13394
}
13495
}

0 commit comments

Comments
 (0)