You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ne...@apache.org on 2022/04/13 12:49:24 UTC

[netbeans-tools] branch master updated: Initial image creation for macOS pkg installer.

This is an automated email from the ASF dual-hosted git repository.

neilcsmith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-tools.git


The following commit(s) were added to refs/heads/master by this push:
     new d6db73c  Initial image creation for macOS pkg installer.
     new 042c765  Merge pull request #49 from neilcsmith-net/nbpackage-macos
d6db73c is described below

commit d6db73c55bc9ba40efa54d093cb701a5e1a63306
Author: Neil C Smith <ne...@apache.org>
AuthorDate: Fri Mar 4 18:27:17 2022 +0000

    Initial image creation for macOS pkg installer.
---
 .../netbeans/nbpackage/AbstractPackagerTask.java   |   8 +-
 .../org/apache/netbeans/nbpackage/NBPackage.java   |   3 +-
 .../netbeans/nbpackage/macos/AppBundleTask.java    | 197 +++++++++++++++++++++
 .../netbeans/nbpackage/macos/PkgPackager.java      |  76 ++++++++
 .../apache/netbeans/nbpackage/macos/PkgTask.java   |  48 +++++
 .../apache/netbeans/nbpackage/apache-netbeans.icns | Bin 0 -> 168443 bytes
 .../netbeans/nbpackage/macos/Info.plist.template   |  37 ++++
 .../netbeans/nbpackage/macos/Messages.properties   |  20 +++
 .../nbpackage/macos/Package.swift.template         |  35 ++++
 .../netbeans/nbpackage/macos/main.swift.template   |  53 ++++++
 10 files changed, 472 insertions(+), 5 deletions(-)

diff --git a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/AbstractPackagerTask.java b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/AbstractPackagerTask.java
index d77b04c..6bea23c 100644
--- a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/AbstractPackagerTask.java
+++ b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/AbstractPackagerTask.java
@@ -156,7 +156,7 @@ public abstract class AbstractPackagerTask implements Packager.Task {
     private void extractAppFromArchive(Path input, Path destDir) throws IOException {
         var tmp = Files.createTempDirectory("nbpackageImageExtract");
         FileUtils.extractArchive(input, tmp);
-        var images = FileUtils.findDirs(tmp, 2, "bin/*", "etc/*.conf");
+        var images = FileUtils.findDirs(tmp, 5, "bin/*", "etc/*.conf");
         if (images.size() != 1) {
             throw new IOException(input.toString());
         }
@@ -165,7 +165,7 @@ public abstract class AbstractPackagerTask implements Packager.Task {
     }
 
     private void copyAppFromDirectory(Path input, Path destDir) throws IOException {
-        var images = FileUtils.findDirs(input, 2, "bin/*", "etc/*.conf");
+        var images = FileUtils.findDirs(input, 5, "bin/*", "etc/*.conf");
         if (images.size() != 1) {
             throw new IOException(input.toString());
         }
@@ -180,7 +180,7 @@ public abstract class AbstractPackagerTask implements Packager.Task {
     private void extractRuntimeFromArchive(Path runtime, Path destDir) throws IOException {
         var tmp = Files.createTempDirectory("nbpackageRuntimeExtract");
         FileUtils.extractArchive(runtime, tmp);
-        var runtimes = FileUtils.findDirs(tmp, 2, "bin/java*");
+        var runtimes = FileUtils.findDirs(tmp, 5, "bin/java*");
         if (runtimes.size() != 1) {
             throw new IOException(runtime.toString());
         }
@@ -189,7 +189,7 @@ public abstract class AbstractPackagerTask implements Packager.Task {
     }
 
     private void copyRuntimeFromDirectory(Path runtime, Path destDir) throws IOException {
-        var runtimes = FileUtils.findDirs(runtime, 2, "bin/java*");
+        var runtimes = FileUtils.findDirs(runtime, 5, "bin/java*");
         if (runtimes.size() != 1) {
             throw new IOException(runtime.toString());
         }
diff --git a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/NBPackage.java b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/NBPackage.java
index 1ae29fa..06ea784 100644
--- a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/NBPackage.java
+++ b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/NBPackage.java
@@ -25,11 +25,11 @@ import java.nio.file.StandardOpenOption;
 import java.text.MessageFormat;
 import java.util.List;
 import java.util.ResourceBundle;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.netbeans.nbpackage.appimage.AppImagePackager;
 import org.apache.netbeans.nbpackage.deb.DebPackager;
 import org.apache.netbeans.nbpackage.innosetup.InnoSetupPackager;
+import org.apache.netbeans.nbpackage.macos.PkgPackager;
 import org.apache.netbeans.nbpackage.zip.ZipPackager;
 
 /**
@@ -70,6 +70,7 @@ public final class NBPackage {
             new AppImagePackager(),
             new DebPackager(),
             new InnoSetupPackager(),
+            new PkgPackager(),
             new ZipPackager()
     );
 
diff --git a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java
new file mode 100644
index 0000000..77d0924
--- /dev/null
+++ b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java
@@ -0,0 +1,197 @@
+/*
+ * 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.netbeans.nbpackage.macos;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.netbeans.nbpackage.AbstractPackagerTask;
+import org.apache.netbeans.nbpackage.ExecutionContext;
+import org.apache.netbeans.nbpackage.NBPackage;
+import org.apache.netbeans.nbpackage.StringUtils;
+
+import static org.apache.netbeans.nbpackage.macos.PkgPackager.*;
+
+/**
+ *
+ */
+class AppBundleTask extends AbstractPackagerTask {
+
+    private String bundleName;
+
+    AppBundleTask(ExecutionContext context) {
+        super(context);
+    }
+
+    @Override
+    public void validateCreatePackage() throws Exception {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Path createImage(Path input) throws Exception {
+        Path image = super.createImage(input);
+        Path bundle = image.resolve(getBundleName() + ".app");
+        Path contents = bundle.resolve("Contents");
+        Path resources = contents.resolve("Resources");
+
+        String execName = findLauncher(
+                resources
+                        .resolve("APPDIR")
+                        .resolve("bin"))
+                .getFileName().toString();
+        Files.move(resources.resolve("APPDIR"), resources.resolve(execName));
+
+        Files.createDirectory(contents.resolve("MacOS"));
+        setupIcons(resources, execName);
+        setupInfo(contents, execName);
+        setupLauncherSource(image);
+
+        return image;
+
+    }
+
+    @Override
+    public Path createPackage(Path image) throws Exception {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    protected String imageName(Path input) throws Exception {
+        return super.imageName(input) + "-macOS-app";
+    }
+
+    @Override
+    protected Path applicationDirectory(Path image) throws Exception {
+        return image.resolve(getBundleName() + ".app")
+                .resolve("Contents")
+                .resolve("Resources")
+                .resolve("APPDIR");
+    }
+
+    @Override
+    protected Path runtimeDirectory(Path image, Path application) throws Exception {
+        return image.resolve(getBundleName() + ".app")
+                .resolve("Contents")
+                .resolve("Home");
+    }
+
+    String getBundleName() {
+        if (bundleName == null) {
+            var name = sanitize(context().getValue(NBPackage.PACKAGE_NAME).orElseThrow());
+            if (name.length() > 15) {
+                name = name.substring(0, 16);
+            }
+            bundleName = name;
+        }
+        return bundleName;
+    }
+
+    private String sanitize(String name) {
+        return name.replaceAll("[\\\\/:*?\"<>|]", "_");
+    }
+
+    private String sanitizeBundleID(String name) {
+        return name.replaceAll("[^a-zA-Z0-9-\\.]", "-");
+    }
+
+    private Path findLauncher(Path binDir) throws IOException {
+        try ( var files = Files.list(binDir)) {
+            return files.filter(f -> !f.getFileName().toString().endsWith(".exe"))
+                    .findFirst().orElseThrow(IOException::new);
+        }
+    }
+
+    private void setupIcons(Path resources, String execName) throws IOException {
+        Path icnsFile = context().getValue(MACOS_ICON).orElse(null);
+        Path dstFile = resources.resolve(execName + ".icns");
+        if (icnsFile != null) {
+            Files.copy(icnsFile, dstFile);
+        } else {
+            Files.copy(getClass().getResourceAsStream(
+                    "/org/apache/netbeans/nbpackage/apache-netbeans.icns"), dstFile);
+        }
+    }
+
+    private void setupInfo(Path contents, String execName) throws IOException {
+        Path templateFile = context().getValue(MACOS_INFO_TEMPLATE).orElse(null);
+        String template;
+        try ( var reader = templateFile != null
+                ? Files.newBufferedReader(templateFile)
+                : new BufferedReader(
+                        new InputStreamReader(
+                                getClass().getResourceAsStream("Info.plist.template"),
+                                StandardCharsets.UTF_8))) {
+            template = reader.lines().collect(Collectors.joining("\n", "", "\n"));
+        }
+
+        var tokenMap = Map.of(
+                "BUNDLE_NAME", getBundleName(),
+                "BUNDLE_DISPLAY", context().getValue(NBPackage.PACKAGE_NAME).orElseThrow(),
+                "BUNDLE_VERSION", context().getValue(NBPackage.PACKAGE_VERSION).orElseThrow(),
+                "BUNDLE_EXEC", execName,
+                "BUNDLE_ID", context().getValue(MACOS_BUNDLE_ID)
+                        .orElse(sanitizeBundleID(getBundleName())),
+                "BUNDLE_ICON", execName + ".icns"
+        );
+
+        String info = StringUtils.replaceTokens(template, tokenMap);
+
+        Files.writeString(contents.resolve("Info.plist"), info,
+                StandardOpenOption.CREATE_NEW);
+
+    }
+
+    private void setupLauncherSource(Path image) throws IOException {
+        Path launcherProject = image.resolve("macos-launcher-src");
+        Files.createDirectories(launcherProject);
+        Path sourceDir = launcherProject.resolve("Sources").resolve("AppLauncher");
+        Files.createDirectories(sourceDir);
+
+        String packageSwift;
+        try ( var reader = new BufferedReader(
+                new InputStreamReader(
+                        getClass().getResourceAsStream("Package.swift.template"),
+                        StandardCharsets.UTF_8
+                ))) {
+            packageSwift = reader.lines().collect(Collectors.joining("\n", "", "\n"));
+        }
+
+        String mainSwift;
+        try ( var reader = new BufferedReader(
+                new InputStreamReader(
+                        getClass().getResourceAsStream("main.swift.template"),
+                        StandardCharsets.UTF_8
+                ))) {
+            mainSwift = reader.lines().collect(Collectors.joining("\n", "", "\n"));
+        }
+
+        Files.writeString(launcherProject.resolve("Package.swift"),
+                packageSwift, StandardOpenOption.CREATE_NEW);
+        Files.writeString(sourceDir.resolve("main.swift"),
+                mainSwift, StandardOpenOption.CREATE_NEW);
+    }
+
+}
diff --git a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java
new file mode 100644
index 0000000..f8de2a8
--- /dev/null
+++ b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java
@@ -0,0 +1,76 @@
+/*
+ * 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.netbeans.nbpackage.macos;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.stream.Stream;
+import org.apache.netbeans.nbpackage.ExecutionContext;
+import org.apache.netbeans.nbpackage.Option;
+import org.apache.netbeans.nbpackage.Packager;
+
+/**
+ * Packager for macOS PKG installer.
+ */
+public class PkgPackager implements Packager {
+    
+    static final ResourceBundle MESSAGES
+            = ResourceBundle.getBundle(PkgPackager.class.getPackageName() + ".Messages");
+
+    /**
+     * Value for CFBundleIdentifier.
+     */
+    public static final Option<String> MACOS_BUNDLE_ID
+            = Option.ofString("package.macos.bundleid", "",
+                    MESSAGES.getString("option.bundle_id.description"));
+    
+    /**
+     * Path to icon (*.icns) file.
+     */
+    public static final Option<Path> MACOS_ICON
+            = Option.ofPath("package.macos.icon", "",
+                    MESSAGES.getString("option.icon.description"));
+    
+    /**
+     * Optional Info.plist template.
+     */
+    public static final Option<Path> MACOS_INFO_TEMPLATE
+            = Option.ofPath("package.macos.info-template", "",
+                    MESSAGES.getString("option.info_template.description"));
+    
+    private static final List<Option<?>> PKG_OPTIONS = List.of(
+            MACOS_BUNDLE_ID, MACOS_ICON);
+    
+    @Override
+    public Task createTask(ExecutionContext context) {
+        return new PkgTask(context);
+    }
+
+    @Override
+    public String name() {
+        return "macos-pkg";
+    }
+
+    @Override
+    public Stream<Option<?>> options() {
+        return PKG_OPTIONS.stream();
+    }
+
+}
diff --git a/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgTask.java b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgTask.java
new file mode 100644
index 0000000..755fe37
--- /dev/null
+++ b/nbpackage/src/main/java/org/apache/netbeans/nbpackage/macos/PkgTask.java
@@ -0,0 +1,48 @@
+/*
+ * 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.netbeans.nbpackage.macos;
+
+import java.nio.file.Path;
+import org.apache.netbeans.nbpackage.ExecutionContext;
+
+/**
+ *
+ */
+class PkgTask extends AppBundleTask {
+
+    PkgTask(ExecutionContext context) {
+        super(context);
+    }
+
+    @Override
+    public Path createPackage(Path image) throws Exception {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void validateCreatePackage() throws Exception {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    protected String imageName(Path input) throws Exception {
+        return super.imageName(input) + "-pkg";
+    }
+
+}
diff --git a/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/apache-netbeans.icns b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/apache-netbeans.icns
new file mode 100644
index 0000000..9f55491
Binary files /dev/null and b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/apache-netbeans.icns differ
diff --git a/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Info.plist.template b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Info.plist.template
new file mode 100644
index 0000000..5d69228
--- /dev/null
+++ b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Info.plist.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+
+    <key>CFBundleName</key>
+    <string>${BUNDLE_NAME}</string>
+    
+    <key>CFBundleDisplayName</key>
+    <string>${BUNDLE_DISPLAY}</string>
+
+    <key>CFBundleVersion</key>
+    <string>${BUNDLE_VERSION}</string>
+
+    <key>CFBundleShortVersionString</key>
+    <string>${BUNDLE_VERSION}</string>
+    
+    <key>CFBundleExecutable</key>
+    <string>${BUNDLE_EXEC}</string>
+
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+
+    <key>CFBundleIdentifier</key>
+    <string>${BUNDLE_ID}</string>
+
+    <key>CFBundleSignature</key>
+    <string>????</string>
+
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+
+    <key>CFBundleIconFile</key>
+    <string>${BUNDLE_ICON}</string>
+       
+  </dict>
+</plist>
diff --git a/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties
new file mode 100644
index 0000000..b120e58
--- /dev/null
+++ b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties
@@ -0,0 +1,20 @@
+# 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.
+
+option.bundle_id.description=Value for CFBundleIdentifier.
+option.icon.description=Path to icon file (*.icns). Defaults to Apache NetBeans logo.
+option.info_template.description=Optional Info.plist template.
diff --git a/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Package.swift.template b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Package.swift.template
new file mode 100644
index 0000000..0e9b7f1
--- /dev/null
+++ b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/Package.swift.template
@@ -0,0 +1,35 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+/*
+* 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.
+*/
+
+import PackageDescription
+
+let package = Package(
+    name: "AppLauncher",
+    platforms: [
+        .macOS(.v10_13)
+    ],
+    dependencies: [],
+    targets: [
+        .target(
+            name: "AppLauncher",
+            dependencies: []),
+    ]
+)
diff --git a/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/main.swift.template b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/main.swift.template
new file mode 100644
index 0000000..d080677
--- /dev/null
+++ b/nbpackage/src/main/resources/org/apache/netbeans/nbpackage/macos/main.swift.template
@@ -0,0 +1,53 @@
+/*
+* 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.
+*/
+
+import Foundation
+
+let brandingToken = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable") as? String
+let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
+let launcherURL = Bundle.main.url(forResource: brandingToken, withExtension: "", subdirectory: brandingToken! + "/bin")
+
+var args = [String]()
+
+// check for JDK
+let fileManager = FileManager.default
+let jdkPath = Bundle.main.bundlePath + "/Contents/Home"
+
+if (fileManager.fileExists(atPath: jdkPath)) {
+    args.append("--jdkhome")
+    args.append(jdkPath)
+}
+
+// add user's command line arguments
+for argument in Array(CommandLine.arguments.dropFirst()) {
+    args.append(argument)
+}
+
+
+let launchNbexec = Process()
+var env = ProcessInfo.processInfo.environment
+env["APP_DOCK_NAME"] = appName
+launchNbexec.environment = env
+launchNbexec.arguments = args
+launchNbexec.executableURL = launcherURL
+try launchNbexec.run()
+
+// needed to keep Dock name based on CFBundleName from Info.plist
+// does not work if called from command line.
+launchNbexec.waitUntilExit()


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists