41
41
import java .io .StringWriter ;
42
42
import java .nio .charset .StandardCharsets ;
43
43
import java .nio .file .Files ;
44
+ import java .nio .file .LinkOption ;
44
45
import java .nio .file .Path ;
45
46
import java .util .ArrayList ;
46
47
import java .util .HashMap ;
72
73
import jdk .jpackage .internal .model .Package ;
73
74
import jdk .jpackage .internal .model .PackageType ;
74
75
import jdk .jpackage .internal .model .PackagerException ;
76
+ import jdk .jpackage .internal .util .FileUtils ;
75
77
import jdk .jpackage .internal .util .PathUtils ;
76
78
import jdk .jpackage .internal .util .function .ThrowingConsumer ;
77
79
@@ -91,6 +93,7 @@ enum MacBuildApplicationTaskID implements TaskID {
91
93
enum MacCopyAppImageTaskID implements TaskID {
92
94
COPY_PACKAGE_FILE ,
93
95
COPY_RUNTIME_INFO_PLIST ,
96
+ COPY_RUNTIME_JLILIB ,
94
97
REPLACE_APP_IMAGE_FILE ,
95
98
COPY_SIGN
96
99
}
@@ -115,10 +118,10 @@ static PackagingPipeline.Builder build(Optional<Package> pkg) {
115
118
.task (CopyAppImageTaskID .COPY )
116
119
.copyAction (MacPackagingPipeline ::copyAppImage ).add ()
117
120
.task (MacBuildApplicationTaskID .RUNTIME_INFO_PLIST )
118
- .applicationAction (MacPackagingPipeline ::writeApplicationRuntimeInfoPlist )
121
+ .appImageAction (MacPackagingPipeline ::writeRuntimeInfoPlist )
119
122
.addDependent (BuildApplicationTaskID .CONTENT ).add ()
120
123
.task (MacBuildApplicationTaskID .COPY_JLILIB )
121
- .applicationAction (MacPackagingPipeline ::copyJliLib )
124
+ .appImageAction (MacPackagingPipeline ::copyJliLib )
122
125
.addDependency (BuildApplicationTaskID .RUNTIME )
123
126
.addDependent (BuildApplicationTaskID .CONTENT ).add ()
124
127
.task (MacBuildApplicationTaskID .APP_ICON )
@@ -138,13 +141,18 @@ static PackagingPipeline.Builder build(Optional<Package> pkg) {
138
141
.addDependencies (CopyAppImageTaskID .COPY )
139
142
.addDependents (PrimaryTaskID .COPY_APP_IMAGE ).add ()
140
143
.task (MacCopyAppImageTaskID .COPY_RUNTIME_INFO_PLIST )
144
+ .appImageAction (MacPackagingPipeline ::writeRuntimeInfoPlist )
145
+ .addDependencies (CopyAppImageTaskID .COPY )
146
+ .addDependents (PrimaryTaskID .COPY_APP_IMAGE ).add ()
147
+ .task (MacCopyAppImageTaskID .COPY_RUNTIME_JLILIB )
148
+ .noaction ()
141
149
.addDependencies (CopyAppImageTaskID .COPY )
142
150
.addDependents (PrimaryTaskID .COPY_APP_IMAGE ).add ()
143
151
.task (MacBuildApplicationTaskID .FA_ICONS )
144
152
.applicationAction (MacPackagingPipeline ::writeFileAssociationIcons )
145
153
.addDependent (BuildApplicationTaskID .CONTENT ).add ()
146
154
.task (MacBuildApplicationTaskID .APP_INFO_PLIST )
147
- .applicationAction (MacPackagingPipeline ::writeAppInfoPlist )
155
+ .applicationAction (MacPackagingPipeline ::writeApplicationInfoPlist )
148
156
.addDependent (BuildApplicationTaskID .CONTENT ).add ();
149
157
150
158
builder .task (MacBuildApplicationTaskID .SIGN )
@@ -172,16 +180,38 @@ static PackagingPipeline.Builder build(Optional<Package> pkg) {
172
180
disabledTasks .add (MacCopyAppImageTaskID .COPY_PACKAGE_FILE );
173
181
disabledTasks .add (CopyAppImageTaskID .COPY );
174
182
disabledTasks .add (PackageTaskID .RUN_POST_IMAGE_USER_SCRIPT );
175
- builder .task (MacCopyAppImageTaskID .REPLACE_APP_IMAGE_FILE ).applicationAction (createWriteAppImageFileAction ()).add ();
183
+ builder .task (MacCopyAppImageTaskID .REPLACE_APP_IMAGE_FILE )
184
+ .applicationAction (createWriteAppImageFileAction ()).add ();
176
185
builder .appImageLayoutForPackaging (Package ::appImageLayout );
177
- } else if (p .isRuntimeInstaller () || ((MacPackage )p ).predefinedAppImageSigned ().orElse (false )) {
178
- // If this is a runtime package or a signed predefined app image,
179
- // don't create ".package" file and don't sign it.
186
+ } else if (p .isRuntimeInstaller ()) {
187
+
188
+ builder .task (MacCopyAppImageTaskID .COPY_RUNTIME_JLILIB )
189
+ .appImageAction (MacPackagingPipeline ::copyJliLib ).add ();
190
+
191
+ final var predefinedRuntimeBundle = Optional .of (
192
+ new MacBundle (p .predefinedAppImage ().orElseThrow ())).filter (MacBundle ::isValid );
193
+
194
+ // Don't create ".package" file.
195
+ disabledTasks .add (MacCopyAppImageTaskID .COPY_PACKAGE_FILE );
196
+
197
+ if (predefinedRuntimeBundle .isPresent ()) {
198
+ // The predefined app image is a macOS bundle.
199
+ // Disable all alterations of the input bundle, but keep the signing enabled.
200
+ disabledTasks .addAll (List .of (MacCopyAppImageTaskID .values ()));
201
+ disabledTasks .remove (MacCopyAppImageTaskID .COPY_SIGN );
202
+ }
203
+
204
+ if (predefinedRuntimeBundle .map (MacBundle ::isSigned ).orElse (false ) && !((MacPackage )p ).app ().sign ()) {
205
+ // The predefined app image is a signed bundle; explicit signing is not requested for the package.
206
+ // Disable the signing, i.e. don't re-sign the input bundle.
207
+ disabledTasks .add (MacCopyAppImageTaskID .COPY_SIGN );
208
+ }
209
+ } else if (((MacPackage )p ).predefinedAppImageSigned ().orElse (false )) {
210
+ // This is a signed predefined app image.
211
+ // Don't create ".package" file.
180
212
disabledTasks .add (MacCopyAppImageTaskID .COPY_PACKAGE_FILE );
213
+ // Don't sign the image.
181
214
disabledTasks .add (MacCopyAppImageTaskID .COPY_SIGN );
182
- // if (p.isRuntimeInstaller()) {
183
- // builder.task(MacCopyAppImageTaskID.COPY_RUNTIME_INFO_PLIST).packageAction(MacPackagingPipeline::writeRuntimeRuntimeInfoPlist).add();
184
- // }
185
215
}
186
216
187
217
for (final var taskId : disabledTasks ) {
@@ -208,13 +238,27 @@ static Package createSignAppImagePackage(MacApplication app, BuildEnv env) {
208
238
209
239
private static void copyAppImage (MacPackage pkg , AppImageDesc srcAppImage ,
210
240
AppImageDesc dstAppImage ) throws IOException {
211
- PackagingPipeline .copyAppImage (srcAppImage , dstAppImage , !pkg .predefinedAppImageSigned ().orElse (false ));
241
+
242
+ boolean predefinedAppImageSigned = pkg .predefinedAppImageSigned ().orElse (false );
243
+
244
+ var inputRootDirectory = srcAppImage .resolvedAppImagelayout ().rootDirectory ();
245
+
246
+ if (pkg .isRuntimeInstaller () && MacBundle .isDirectoryMacBundle (inputRootDirectory )) {
247
+ // Building runtime package from the input runtime bundle.
248
+ // Copy the input bundle verbatim.
249
+ FileUtils .copyRecursive (
250
+ inputRootDirectory ,
251
+ dstAppImage .resolvedAppImagelayout ().rootDirectory (),
252
+ LinkOption .NOFOLLOW_LINKS );
253
+ } else {
254
+ PackagingPipeline .copyAppImage (srcAppImage , dstAppImage , !predefinedAppImageSigned );
255
+ }
212
256
}
213
257
214
258
private static void copyJliLib (
215
- AppImageBuildEnv <MacApplication , MacApplicationLayout > env ) throws IOException {
259
+ AppImageBuildEnv <MacApplication , AppImageLayout > env ) throws IOException {
216
260
217
- final var runtimeMacOSDir = env . resolvedLayout (). runtimeRootDirectory (). resolve ( "Contents/MacOS" );
261
+ final var runtimeBundle = runtimeBundle ( env );
218
262
219
263
final var jliName = Path .of ("libjli.dylib" );
220
264
@@ -223,8 +267,8 @@ private static void copyJliLib(
223
267
.filter (file -> file .getFileName ().equals (jliName ))
224
268
.findFirst ()
225
269
.orElseThrow ();
226
- Files .createDirectories (runtimeMacOSDir );
227
- Files .copy (jli , runtimeMacOSDir .resolve (jliName ));
270
+ Files .createDirectories (runtimeBundle . macOsDir () );
271
+ Files .copy (jli , runtimeBundle . macOsDir () .resolve (jliName ));
228
272
}
229
273
}
230
274
@@ -247,36 +291,47 @@ private static void writePkgInfoFile(
247
291
"APPL????" .getBytes (StandardCharsets .ISO_8859_1 ));
248
292
}
249
293
250
- private static void writeRuntimeRuntimeInfoPlist (PackageBuildEnv <MacPackage , AppImageLayout > env ) throws IOException {
251
- writeRuntimeInfoPlist (env .pkg ().app (), env .env (), env .resolvedLayout ().rootDirectory ());
252
- }
253
-
254
- private static void writeApplicationRuntimeInfoPlist (
255
- AppImageBuildEnv <MacApplication , MacApplicationLayout > env ) throws IOException {
256
- writeRuntimeInfoPlist (env .app (), env .env (), env .resolvedLayout ().runtimeRootDirectory ());
257
- }
294
+ private static void writeRuntimeInfoPlist (
295
+ AppImageBuildEnv <MacApplication , AppImageLayout > env ) throws IOException {
258
296
259
- private static void writeRuntimeInfoPlist ( MacApplication app , BuildEnv env , Path runtimeRootDirectory ) throws IOException {
297
+ final var app = env . app ();
260
298
261
299
Map <String , String > data = new HashMap <>();
262
300
data .put ("CF_BUNDLE_IDENTIFIER" , app .bundleIdentifier ());
263
301
data .put ("CF_BUNDLE_NAME" , app .bundleName ());
264
302
data .put ("CF_BUNDLE_VERSION" , app .version ());
265
303
data .put ("CF_BUNDLE_SHORT_VERSION_STRING" , app .shortVersion ().toString ());
304
+ if (app .isRuntime ()) {
305
+ data .put ("CF_BUNDLE_VENDOR" , app .vendor ());
306
+ }
307
+
308
+ final String template ;
309
+ final String publicName ;
310
+ final String category ;
311
+
312
+ if (app .isRuntime ()) {
313
+ template = "Runtime-Info.plist.template" ;
314
+ publicName = "Info.plist" ;
315
+ category = "resource.runtime-info-plist" ;
316
+ } else {
317
+ template = "ApplicationRuntime-Info.plist.template" ;
318
+ publicName = "Runtime-Info.plist" ;
319
+ category = "resource.app-runtime-info-plist" ;
320
+ }
266
321
267
- env .createResource ( "Runtime-Info.plist. template" )
268
- .setPublicName ("Runtime-Info.plist" )
269
- .setCategory (I18N .getString ("resource.runtime-info-plist" ))
322
+ env .env (). createResource ( template )
323
+ .setPublicName (publicName )
324
+ .setCategory (I18N .getString (category ))
270
325
.setSubstitutionData (data )
271
- .saveToFile (runtimeRootDirectory . resolve ( "Contents/Info.plist" ));
326
+ .saveToFile (runtimeBundle ( env ). infoPlistFile ( ));
272
327
}
273
328
274
- private static void writeAppInfoPlist (
329
+ private static void writeApplicationInfoPlist (
275
330
AppImageBuildEnv <MacApplication , MacApplicationLayout > env ) throws IOException {
276
331
277
332
final var app = env .app ();
278
333
279
- final var infoPlistFile = env .resolvedLayout (). contentDirectory (). resolve ( "Info.plist" );
334
+ final var infoPlistFile = MacBundle . fromAppImageLayout ( env .resolvedLayout ()). infoPlistFile ( );
280
335
281
336
Log .verbose (I18N .format ("message.preparing-info-plist" , PathUtils .normalizedAbsolutePathString (infoPlistFile )));
282
337
@@ -308,7 +363,7 @@ private static void writeAppInfoPlist(
308
363
.saveToFile (infoPlistFile );
309
364
}
310
365
311
- private static void sign (AppImageBuildEnv <MacApplication , MacApplicationLayout > env ) throws IOException {
366
+ private static void sign (AppImageBuildEnv <MacApplication , AppImageLayout > env ) throws IOException {
312
367
313
368
final var app = env .app ();
314
369
@@ -410,6 +465,14 @@ private static void addFaToUTExportedTypeDeclarations(XMLStreamWriter xml,
410
465
}));
411
466
}
412
467
468
+ private static MacBundle runtimeBundle (AppImageBuildEnv <MacApplication , AppImageLayout > env ) {
469
+ if (env .app ().isRuntime ()) {
470
+ return new MacBundle (env .resolvedLayout ().rootDirectory ());
471
+ } else {
472
+ return new MacBundle (((MacApplicationLayout )env .resolvedLayout ()).runtimeRootDirectory ());
473
+ }
474
+ }
475
+
413
476
private static class ApplicationIcon implements ApplicationImageTaskAction <MacApplication , MacApplicationLayout > {
414
477
static Path getPath (Application app , ApplicationLayout appLayout ) {
415
478
return appLayout .desktopIntegrationDirectory ().resolve (app .name () + ".icns" );
0 commit comments