|
17 | 17 | */ |
18 | 18 | package org.jackhuang.hmcl.terracotta.provider; |
19 | 19 |
|
| 20 | +import org.jackhuang.hmcl.Metadata; |
20 | 21 | import org.jackhuang.hmcl.task.Task; |
21 | 22 | import org.jackhuang.hmcl.terracotta.TerracottaNative; |
| 23 | +import org.jackhuang.hmcl.util.io.FileUtils; |
22 | 24 | import org.jackhuang.hmcl.util.platform.ManagedProcess; |
23 | 25 | import org.jackhuang.hmcl.util.platform.SystemUtils; |
24 | 26 | import org.jackhuang.hmcl.util.tree.TarFileTree; |
|
27 | 29 | import java.io.IOException; |
28 | 30 | import java.nio.file.Files; |
29 | 31 | import java.nio.file.Path; |
| 32 | +import java.nio.file.StandardCopyOption; |
30 | 33 | import java.nio.file.attribute.PosixFilePermission; |
31 | 34 | import java.util.List; |
32 | 35 | import java.util.Set; |
33 | 36 |
|
34 | 37 | import static org.jackhuang.hmcl.util.i18n.I18n.i18n; |
| 38 | +import static org.jackhuang.hmcl.util.logging.Logger.LOG; |
35 | 39 |
|
36 | 40 | public final class MacOSProvider implements ITerracottaProvider { |
37 | 41 | public final TerracottaNative installer, binary; |
@@ -62,19 +66,39 @@ public Task<?> install(Context context, @Nullable TarFileTree tree) throws IOExc |
62 | 66 |
|
63 | 67 | return Task.allOf( |
64 | 68 | installerTask.thenComposeAsync(() -> { |
| 69 | + Path osascript = SystemUtils.which("osascript"); |
| 70 | + if (osascript == null) { |
| 71 | + throw new IllegalStateException("Cannot locate 'osascript' system executable on MacOS for installing Terracotta."); |
| 72 | + } |
| 73 | + |
| 74 | + Path pkg = Files.createTempDirectory(Metadata.HMCL_GLOBAL_DIRECTORY, "terracotta-pkg") |
| 75 | + .toRealPath() |
| 76 | + .resolve(FileUtils.getName(installer.getPath())); |
| 77 | + Files.copy(installer.getPath(), pkg, StandardCopyOption.REPLACE_EXISTING); |
| 78 | + |
65 | 79 | ManagedProcess process = new ManagedProcess(new ProcessBuilder( |
66 | | - "osascript", |
67 | | - "-e", |
68 | | - String.format( |
69 | | - "do shell script \"installer -pkg %s -target /\" with prompt \"%s\" with administrator privileges", |
70 | | - installer.getPath(), |
71 | | - i18n("terracotta.sudo_installing") |
72 | | - ) |
73 | | - )); |
| 80 | + osascript.toString(), "-e", String.format( |
| 81 | + "do shell script \"installer -pkg '%s' -target /\" with prompt \"%s\" with administrator privileges", |
| 82 | + pkg, i18n("terracotta.sudo_installing") |
| 83 | + ))); |
74 | 84 | process.pumpInputStream(SystemUtils::onLogLine); |
75 | 85 | process.pumpErrorStream(SystemUtils::onLogLine); |
76 | 86 |
|
77 | | - return Task.fromCompletableFuture(process.getProcess().onExit()); |
| 87 | + return Task.fromCompletableFuture(process.getProcess().onExit()).thenRunAsync(() -> { |
| 88 | + try { |
| 89 | + FileUtils.cleanDirectory(pkg.getParent()); |
| 90 | + } catch (IOException e) { |
| 91 | + LOG.warning("Cannot remove temporary Terracotta package file.", e); |
| 92 | + } |
| 93 | + |
| 94 | + if (process.getExitCode() != 0) { |
| 95 | + throw new IllegalStateException(String.format( |
| 96 | + "Cannot install Terracotta %s: system installer exited with code %d", |
| 97 | + pkg, |
| 98 | + process.getExitCode() |
| 99 | + )); |
| 100 | + } |
| 101 | + }); |
78 | 102 | }), |
79 | 103 | binaryTask.thenRunAsync(() -> Files.setPosixFilePermissions(binary.getPath(), Set.of( |
80 | 104 | PosixFilePermission.OWNER_READ, |
|
0 commit comments