Skip to content

Commit d6a9a01

Browse files
committed
Merge branch 'macos-platform-logic'
This branch adds true support for the macos-arm64 and macos64 platforms as their own entities, and retools the macosx platform into a "platform group" encompassing any Mac, including both macos-arm64 and macos64. It also rebrands the "updateable platforms" logic as "active platforms" to avoid naming confusion with "updateable" files and related API. And it broadens the platform activation logic to also activate a platform when its special jars and/or lib subdirectory is present in the installation. This makes it easier and hopefully less mysterious to start receiving updates for a particular platform of interest, even if your actual platform does not match the one you want the files for. This is especially important for macos-arm64 systems, because people are likely to want the macos64 platform active as well so that they can run in x86 mode with Rosetta and make use of x86-specific native libraries, until all macos-arm64 native libraries become fully accessible (not only are builds for that architecture needed, but they also need to be code-signed to appease the hardened runtime!). Relatedly: this branch now treats *all* files beneath a toplevel folder ending in .app as launchers for the macosx platform group. In this way, the entire Fiji.app for Fiji (or whatever the launcher is named) will always be shipped together by the Updater, to avoid ruining the immutable app bundle's code signature by splitting it up. As such, the fact that macos-arm64 and macos64 activate when one of their native library subfolders is present is actually now needed, since there are not native launchers that would activate them otherwise. Instead of the macosx platform group, I considered going through the db.xml.gz files to update macosx platform files to `macosx,macos-arm64`, since each file is allowed to belong to multiple platforms, and this branch does add support for comma-splitting the platform field of the db.xml (which wasn't being done before). But I think we never use the multiple platforms feature of FileObject right now, and furthermore, changing the db.xml.gz files would still leave third-party update sites in a suboptimal place, with any macOS-specific files they ship still labeled with previous architecture-agnostic macosx platform tag. I figured it's better to keep support for the macosx tag, and leave it meaning essentially what it has always meant: any Mac machine. That way, existing update sites continue to "just work" on both Mac architectures, at least from the perspective of those installations not ignoring any potentially relevant Mac-specific files.
2 parents 2123fba + 5d09913 commit d6a9a01

19 files changed

+392
-509
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>net.imagej</groupId>
1313
<artifactId>imagej-updater</artifactId>
14-
<version>1.1.3-SNAPSHOT</version>
14+
<version>2.0.0-SNAPSHOT</version>
1515

1616
<name>ImageJ Updater</name>
1717
<description>Keeps components of ImageJ up-to-date.</description>

src/main/java/net/imagej/updater/Checksummer.java

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.io.Writer;
4040
import java.security.NoSuchAlgorithmException;
4141
import java.util.ArrayList;
42+
import java.util.Arrays;
4243
import java.util.Collections;
4344
import java.util.Comparator;
4445
import java.util.HashMap;
@@ -57,6 +58,7 @@
5758
import net.imagej.updater.Conflicts.Conflict.Severity;
5859
import net.imagej.updater.FileObject.Status;
5960
import net.imagej.updater.util.AbstractProgressable;
61+
import net.imagej.updater.util.Platforms;
6062
import net.imagej.updater.util.Progress;
6163
import net.imagej.updater.util.UpdaterUtil;
6264

@@ -75,23 +77,23 @@
7577
*/
7678
public class Checksummer extends AbstractProgressable {
7779

78-
private FilesCollection files;
80+
private final FilesCollection files;
7981
private int counter, total;
8082
private Map<String, FileObject.Version> cachedChecksums;
81-
private boolean isWindows; // time tax for Redmond
83+
private final boolean isWindows; // time tax for Redmond
8284
private Map<String, List<StringAndFile>> queue;
8385

8486
public Checksummer(final FilesCollection files, final Progress progress) {
8587
this.files = files;
8688
if (progress != null) addProgress(progress);
8789
setTitle("Checksummer");
88-
isWindows = UpdaterUtil.getPlatform().startsWith("win");
90+
isWindows = Platforms.isWindows(files.platform());
8991
}
9092

9193
protected static class StringAndFile {
9294

93-
private String path;
94-
private File file;
95+
private final String path;
96+
private final File file;
9597
public long timestamp;
9698
public String checksum;
9799

@@ -135,8 +137,7 @@ protected boolean exists(final File file) {
135137

136138
public void queueDir(final String[] dirs, final String[] extensions) {
137139
final Set<String> set = new HashSet<>();
138-
for (final String extension : extensions)
139-
set.add(extension);
140+
Collections.addAll(set, extensions);
140141
for (final String dir : dirs)
141142
queueDir(dir, set);
142143
}
@@ -176,7 +177,7 @@ protected void queue(final String path, final File file) {
176177
// from the consideration.
177178
if (unversioned.contains(".old")) return;
178179
if (!queue.containsKey(unversioned))
179-
queue.put(unversioned, new ArrayList<StringAndFile>());
180+
queue.put(unversioned, new ArrayList<>());
180181
List<StringAndFile> list = queue.get(unversioned);
181182
StringAndFile entry = new StringAndFile(path, file);
182183
if (!list.contains(entry)) list.add(entry);
@@ -242,27 +243,24 @@ else if (object.hasPreviousVersion(p.checksum))
242243
else
243244
locallyModifieds.add(p);
244245
}
245-
Comparator<StringAndFile> comparator = new Comparator<StringAndFile>() {
246-
@Override
247-
public int compare(StringAndFile a, StringAndFile b) {
248-
long diff = a.file.lastModified() - b.file.lastModified();
249-
return diff < 0 ? +1 : diff > 0 ? -1 : 0;
250-
}
246+
Comparator<StringAndFile> comparator = (a, b) -> {
247+
long diff = a.file.lastModified() - b.file.lastModified();
248+
return diff < 0 ? +1 : diff > 0 ? -1 : 0;
251249
};
252-
Collections.sort(upToDates, comparator);
253-
Collections.sort(obsoletes, comparator);
254-
Collections.sort(locallyModifieds, comparator);
255-
if (upToDates.size() > 0)
250+
upToDates.sort(comparator);
251+
obsoletes.sort(comparator);
252+
locallyModifieds.sort(comparator);
253+
if (!upToDates.isEmpty())
256254
pair = pickNewest(upToDates);
257-
else if (obsoletes.size() > 0)
255+
else if (!obsoletes.isEmpty())
258256
pair = pickNewest(obsoletes);
259257
else
260258
pair = pickNewest(locallyModifieds);
261-
if (locallyModifieds.size() > 0)
259+
if (!locallyModifieds.isEmpty())
262260
addConflict(pair.path, "locally-modified", true, convert(locallyModifieds));
263-
if (obsoletes.size() > 0)
261+
if (!obsoletes.isEmpty())
264262
addConflict(pair.path, "obsolete", false, convert(obsoletes));
265-
if (upToDates.size() > 0)
263+
if (!upToDates.isEmpty())
266264
addConflict(pair.path, "up-to-date", false, convert(upToDates));
267265
}
268266
handle(pair);
@@ -289,7 +287,7 @@ protected static List<File> convert(final List<StringAndFile> pairs) {
289287
}
290288

291289
protected void addConflict(final String filename, String adjective, boolean isCritical, final List<File> toDelete) {
292-
if (!adjective.equals("") && !adjective.endsWith(" "))
290+
if (!adjective.isEmpty() && !adjective.endsWith(" "))
293291
adjective += " ";
294292
String conflictMessage = "Multiple " + adjective + "versions of " + filename + " exist: " + UpdaterUtil.join(", ", toDelete);
295293
Resolution ignore = new Resolution("Ignore for now") {
@@ -349,9 +347,9 @@ protected void handle(final StringAndFile pair) {
349347
object.localFilename = pair.path;
350348
object.localChecksum = pair.checksum;
351349
object.localTimestamp = pair.timestamp;
352-
if ((!isWindows && UpdaterUtil.canExecute(pair.file)) || pair.path.endsWith(".exe")) object.executable =
353-
true;
354-
tryToGuessPlatform(object);
350+
if ((!isWindows && UpdaterUtil.canExecute(pair.file)) || pair.path.endsWith(".exe"))
351+
object.executable = true;
352+
guessPlatform(object);
355353
files.add(object);
356354
}
357355
else {
@@ -367,7 +365,7 @@ protected void handle(final StringAndFile pair) {
367365
}
368366
}
369367
} else if (object.current != null && obsoletes != null
370-
&& (":" + obsoletes.checksum + ":").indexOf(":" + object.current.checksum + ":") >= 0) {
368+
&& (":" + obsoletes.checksum + ":").contains(":" + object.current.checksum + ":")) {
371369
// if the recorded checksum is an obsolete equivalent of the current one, use the obsolete one
372370
pair.checksum = object.current.checksum;
373371
}
@@ -428,11 +426,11 @@ public void updateFromLocal(final List<String> files) {
428426
handleQueue();
429427
}
430428

431-
protected boolean tryToGuessPlatform(final FileObject file) {
429+
protected boolean guessPlatform(final FileObject file) {
432430
// Look for platform names as subdirectories of lib/ and mm/
433431
String platform;
434432
if (file.executable) {
435-
platform = UpdaterUtil.platformForLauncher(file.filename);
433+
platform = Platforms.platformForLauncher(file.filename);
436434
if (platform == null) return false;
437435
}
438436
else {
@@ -454,7 +452,7 @@ else if (file.filename.startsWith("mm/")) {
454452

455453
if (platform.equals("linux")) platform = "linux32";
456454

457-
for (final String valid : files.util.platforms)
455+
for (final String valid : Platforms.known())
458456
if (platform.equals(valid)) {
459457
file.addPlatform(platform);
460458
return true;
@@ -485,9 +483,7 @@ else if (file.filename.startsWith("mm/")) {
485483
static {
486484
extensions = new HashMap<>();
487485
for (int i = 0; i < directories.length; i += 2) {
488-
final Set<String> set = new HashSet<>();
489-
for (final String extension : directories[i + 1])
490-
set.add(extension);
486+
final Set<String> set = new HashSet<>(Arrays.asList(directories[i + 1]));
491487
for (final String dir : directories[i + 1])
492488
extensions.put(dir, set);
493489
}
@@ -496,7 +492,7 @@ else if (file.filename.startsWith("mm/")) {
496492
public boolean isCandidate(String path) {
497493
path = path.replace('\\', '/'); // Microsoft time toll
498494
final int slash = path.indexOf('/');
499-
if (slash < 0) return files.util.isLauncher(path);
495+
if (slash < 0) return Platforms.isLauncher(path);
500496
final Set<String> exts = extensions.get(path.substring(0, slash));
501497
final int dot = path.lastIndexOf('.');
502498
return exts != null && dot >= 0 && exts.contains(path.substring(dot));
@@ -507,8 +503,10 @@ protected void initializeQueue() {
507503

508504
queueIfExists("README.md");
509505
queueIfExists("WELCOME.md");
510-
queueIfExists("ImageJ.sh");
511-
for (final String launcher : files.util.launchers)
506+
queueIfExists("fiji");
507+
queueIfExists("fiji.bat");
508+
queueIfExists("ImageJ.sh"); // deprecated
509+
for (final String launcher : Platforms.launchers())
512510
queueIfExists(launcher);
513511

514512
// Queue any macOS .app folders.
@@ -585,8 +583,7 @@ protected void writeCachedChecksums() {
585583
}
586584

587585
protected String getDigest(final String path, final File file,
588-
final long timestamp) throws IOException, NoSuchAlgorithmException,
589-
ZipException
586+
final long timestamp) throws IOException, NoSuchAlgorithmException
590587
{
591588
if (cachedChecksums == null) readCachedChecksums();
592589
FileObject.Version version = cachedChecksums.get(path);

src/main/java/net/imagej/updater/CommandLine.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,7 @@ public FileFilter(final List<String> files) {
151151

152152
@Override
153153
public boolean matches(final FileObject file) {
154-
if (!file.isUpdateablePlatform(files)) {
155-
return false;
156-
}
154+
if (!file.isActivePlatform(files)) return false;
157155
if (fileNames != null
158156
&& !fileNames.contains(file.getFilename(true))) {
159157
return false;
@@ -164,7 +162,7 @@ public boolean matches(final FileObject file) {
164162

165163
public void diff(final List<String> list) {
166164
ensureChecksummed();
167-
final Diff diff = new Diff(System.out, files.util);
165+
final Diff diff = new Diff(System.out);
168166

169167
Mode mode = Mode.CLASS_FILE_DIFF;
170168
while (list.size() > 0 && list.get(0).startsWith("--")) {
@@ -488,8 +486,8 @@ public String toString() {
488486
public void download(final FileObject file) {
489487
ensureChecksummed();
490488
try {
491-
new Downloader(progress, files.util).start(new OneFile(file));
492-
if (file.executable && !files.util.platform.startsWith("win")) {
489+
new Downloader(progress).start(new OneFile(file));
490+
if (file.executable && !Platforms.isWindows(files.platform())) {
493491
try {
494492
Runtime.getRuntime().exec(
495493
new String[] { "chmod", "0755",
@@ -930,7 +928,7 @@ public void uploadCompleteSite(final List<String> list) {
930928
throw die("Which files do you mean to upload?");
931929
}
932930
boolean ignoreWarnings = false, forceShadow = false, simulate = false;
933-
while (list.size() > 0 && list.get(0).startsWith("-")) {
931+
while (!list.isEmpty() && list.get(0).startsWith("-")) {
934932
final String option = list.remove(0);
935933
if ("--force".equals(option)) {
936934
ignoreWarnings = true;
@@ -939,10 +937,10 @@ public void uploadCompleteSite(final List<String> list) {
939937
} else if ("--simulate".equals(option)) {
940938
simulate = true;
941939
} else if ("--platforms".equals(option)) {
942-
if (list.size() == 0) {
940+
if (list.isEmpty()) {
943941
throw die("Need a comma-separated list of platforms with --platform");
944942
}
945-
files.util.setUpdateablePlatforms(list.remove(0).split(","));
943+
files.setActivePlatforms(list.remove(0).split(","));
946944
} else {
947945
throw die("Unknown option: " + option);
948946
}
@@ -959,7 +957,7 @@ public void uploadCompleteSite(final List<String> list) {
959957

960958
int removeCount = 0, uploadCount = 0, warningCount = 0;
961959
for (final FileObject file : files) {
962-
if (!file.isUpdateablePlatform(files)) {
960+
if (!file.isActivePlatform(files)) {
963961
continue;
964962
}
965963
final String name = file.filename;
@@ -1013,7 +1011,7 @@ public void uploadCompleteSite(final List<String> list) {
10131011
&& file.getFilename(true).equals("jars/tools.jar")) {
10141012
break;
10151013
}
1016-
if (!file.isUpdateablePlatform(files)) break;
1014+
if (!file.isActivePlatform(files)) break;
10171015
file.setAction(files, Action.REMOVE);
10181016
if (simulate) {
10191017
log.info("Would mark " + file.filename + " obsolete");
@@ -1087,9 +1085,9 @@ public void uploadCompleteSite(final List<String> list) {
10871085

10881086
private void handleLauncherForUpload(final FileObject file) {
10891087
if (file.getStatus() == Status.LOCAL_ONLY
1090-
&& files.util.isLauncher(file.filename)) {
1088+
&& Platforms.isLauncher(file.filename)) {
10911089
file.executable = true;
1092-
file.addPlatform(UpdaterUtil.platformForLauncher(file.filename));
1090+
file.addPlatform(Platforms.platformForLauncher(file.filename));
10931091
for (final String fileName : new String[] { "jars/imagej-launcher.jar" }) {
10941092
final FileObject dependency = files.get(fileName);
10951093
if (dependency != null) {

src/main/java/net/imagej/updater/Diff.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ public String toString() {
9595
}
9696

9797
private final PrintStream out;
98-
private final UpdaterUtil util;
9998

10099
/**
101100
* Construct a Diff object.
@@ -104,18 +103,7 @@ public String toString() {
104103
*/
105104
@Deprecated
106105
public Diff(final PrintStream out) {
107-
this(out, null);
108-
}
109-
110-
/**
111-
* Construct a Diff object.
112-
*
113-
* @param out this is where the output goes
114-
* @param util an instance of {@link UpdaterUtil} to access URLs
115-
*/
116-
public Diff(final PrintStream out, final UpdaterUtil util) {
117106
this.out = out;
118-
this.util = util != null ? util : new UpdaterUtil(null);
119107
}
120108

121109
/**
@@ -447,7 +435,7 @@ protected File cacheFile(final URL url, boolean evenLocal) throws IOException {
447435
if (extension.startsWith("jar-")) extension = "jar";
448436
final File result = File.createTempFile("diff-", "".equals(extension) ? "" : "." + extension);
449437
result.deleteOnExit();
450-
copy(util.openStream(url), new FileOutputStream(result), true, true);
438+
copy(UpdaterUtil.openStream(url), new FileOutputStream(result), true, true);
451439
return result;
452440
}
453441

0 commit comments

Comments
 (0)