JAL-3631 Installers with separate actions for user/administrator installation
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 27 Jun 2024 21:15:41 +0000 (22:15 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 27 Jun 2024 21:15:41 +0000 (22:15 +0100)
utils/install4j/install4j10_template.install4j

index 59d5079..8600f75 100644 (file)
                   <property name="obtainIfNormalWin" type="boolean" value="true" />
                 </serializedBean>
               </action>
-              <action name="USERSPACE: Set unixUserBinDir (Linux or Unix)" id="2738" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+              <action name="USERSPACE: Set unixBinDir (Linux or Unix)" id="2738" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
                 <serializedBean>
                   <property name="script">
                     <object class="com.install4j.api.beans.ScriptProperty">
@@ -339,14 +339,40 @@ tryPaths.add(userHome + File.separator + "local" + File.separator + "bin");
 tryPaths.add(userHome + File.separator + ".local" + File.separator + "bin");
 tryPaths.add(userHome + File.separator + "opt" + File.separator + "bin");
 
-if (Util.isMacOS()) { // &amp;&amp; root permission?
-    tryPaths.add(File.separator + "usr" + File.separator + "local" + File.separator + "bin"); 
+for (int i = 0; i &lt; tryPaths.size(); i++) {
+    String tryPath = tryPaths.get(i);
+    File unixBinDir = new File(tryPath);
+    if (unixBinDir.exists()) {
+        return tryPath;
+    }
 }
 
+return null;
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">unixBinDir</property>
+                </serializedBean>
+                <condition>!Util.hasFullAdminRights()
+&amp;&amp;
+(
+  Util.isLinux()
+  || Util.isUnixInstaller()
+  || Util.isMacOS()
+)</condition>
+              </action>
+              <action name="SYSTEMSPACE: Set unixBinDir (Linux or Unix)" id="2845" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">ArrayList&lt;String&gt; tryPaths = new ArrayList&lt;&gt; ();
+tryPaths.add(File.separator + "opt" + File.separator + "bin");
+tryPaths.add(File.separator + "usr" + File.separator + "local" + File.separator + "bin");
+
 for (int i = 0; i &lt; tryPaths.size(); i++) {
     String tryPath = tryPaths.get(i);
-    File unixUserBinDir = new File(tryPath);
-    if (unixUserBinDir.exists()) {
+    File unixBinDir = new File(tryPath);
+    if (unixBinDir.exists()) {
         return tryPath;
     }
 }
@@ -355,9 +381,9 @@ return null;
 </property>
                     </object>
                   </property>
-                  <property name="variableName" type="string">unixUserBinDir</property>
+                  <property name="variableName" type="string">unixBinDir</property>
                 </serializedBean>
-                <condition>!Util.hasFullAdminRights()
+                <condition>Util.hasFullAdminRights()
 &amp;&amp;
 (
   Util.isLinux()
@@ -704,7 +730,7 @@ return console.askOkCancel(message, true);
           </screen>
           <screen id="20" beanClass="com.install4j.runtime.beans.screens.FinishedScreen" rollbackBarrierExitCode="0" finishScreen="true">
             <actions>
-              <action name="macOS/Linux Jalview Appname-&gt;java symlink" id="2813" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+              <action name="macOS/Linux Jalview-&gt;java symlink" id="2814" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
@@ -713,14 +739,14 @@ return console.askOkCancel(message, true);
                   </property>
                   <property name="linkFile">
                     <object class="java.io.File">
-                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_APPLICATION_NAME}</string>
+                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_NAME}</string>
                     </object>
                   </property>
                   <property name="removeOnUninstall" type="boolean" value="false" />
                 </serializedBean>
-                <condition>Util.isLinux()</condition>
+                <condition>Util.isLinux() || Util.isMacOS()</condition>
               </action>
-              <action name="macOS/Linux Jalview-&gt;java symlink" id="2814" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+              <action name="macOS/Linux Jalview Appname-&gt;java symlink" id="2813" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
@@ -729,12 +755,13 @@ return console.askOkCancel(message, true);
                   </property>
                   <property name="linkFile">
                     <object class="java.io.File">
-                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_NAME}</string>
+                      <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_APPLICATION_NAME}</string>
                     </object>
                   </property>
                   <property name="removeOnUninstall" type="boolean" value="false" />
                 </serializedBean>
-                <condition>Util.isLinux()</condition>
+                <condition>(Util.isLinux() || Util.isMacOS())
+&amp;&amp; !((String)context.getCompilerVariable("JALVIEW_APPLICATION_NAME")).equals((String)context.getCompilerVariable("JALVIEW_NAME"))</condition>
               </action>
               <action name="USERSPACE: Create start menu item" id="2012" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
                 <serializedBean>
@@ -809,69 +836,45 @@ context.getBooleanVariable("addToDockAction")</condition>
 &amp;&amp;
 context.getBooleanVariable("appendToPathAction")</condition>
               </action>
-              <action name="Linux/Unix symlink" id="2733" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+              <action name="USERSPACE: Create macOS symbolic link to jalview in user's local bin" id="2743" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixBinDir}">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
-                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
-                    </object>
-                  </property>
-                  <property name="linkFile">
-                    <object class="java.io.File">
-                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}</string>
-                    </object>
-                  </property>
-                </serializedBean>
-                <condition>( 
-  Util.isLinux()
-  || Util.isUnixInstaller()
-  || Util.isMacOS()
-)</condition>
-              </action>
-              <action name="USERSPACE: Create Linux/Unix user symbolic link to jalview.sh in user's local bin" id="2739" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
-                <serializedBean>
-                  <property name="file">
-                    <object class="java.io.File">
-                      <string>${installer:sys.contentDir}/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
+                      <string>${installer:macWrapperLinkLocation}</string>
                     </object>
                   </property>
                   <property name="linkFile">
                     <object class="java.io.File">
-                      <string>${installer:unixUserBinDir}/${compiler:WRAPPER_LINK}</string>
+                      <string>${installer:unixBinDir}/${compiler:WRAPPER_LINK}</string>
                     </object>
                   </property>
                 </serializedBean>
                 <condition>!Util.hasFullAdminRights()
 &amp;&amp;
 (
-  context.getBooleanVariable("makeUserSymbolicLinkAction")
-  &amp;&amp; (
-       Util.isLinux()
-       || Util.isUnixInstaller()
-     )
-  &amp;&amp; context.getVariable("unixUserBinDir") != null
+  Util.isMacOS()
+  &amp;&amp; context.getBooleanVariable("makeUserSymbolicLinkAction")
+  &amp;&amp; context.getVariable("unixBinDir") != null
+  &amp;&amp; context.getVariable("macWrapperLinkLocation") != null
 )</condition>
               </action>
-              <action name="USERSPACE: Create macOS symbolic link to jalview in user's local bin" id="2743" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixUserBinDir}">
+              <action name="Linux/Unix symlink" id="2733" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
                 <serializedBean>
                   <property name="file">
                     <object class="java.io.File">
-                      <string>${installer:macWrapperLinkLocation}</string>
+                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
                     </object>
                   </property>
                   <property name="linkFile">
                     <object class="java.io.File">
-                      <string>${installer:unixUserBinDir}/${compiler:WRAPPER_LINK}</string>
+                      <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}</string>
                     </object>
                   </property>
                 </serializedBean>
-                <condition>!Util.hasFullAdminRights()
-&amp;&amp;
-(
-  Util.isMacOS()
-  &amp;&amp; context.getBooleanVariable("makeUserSymbolicLinkAction")
-  &amp;&amp; context.getVariable("unixUserBinDir") != null
-  &amp;&amp; context.getVariable("macWrapperLinkLocation") != null
+                <condition>( 
+  Util.isLinux()
+  || Util.isUnixInstaller()
+  || Util.isMacOS()
 )</condition>
               </action>
               <action name="Windows copy BAT file" id="2817" beanClass="com.install4j.runtime.beans.actions.files.CopyFileAction" rollbackBarrierExitCode="0">
@@ -908,6 +911,102 @@ context.getBooleanVariable("appendToPathAction")</condition>
                 </serializedBean>
                 <condition>Util.isWindows() &amp;&amp; !(((String)context.getCompilerVariable("WRAPPER_LINK")+".ps1").equals((String)context.getCompilerVariable("POWERSHELL_WRAPPER_SCRIPT")))</condition>
               </action>
+              <action name="SYSTEMSPACE: Create start menu item" id="2846" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="categories" type="string">${compiler:APPLICATION_CATEGORIES}</property>
+                  <property name="entryName" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                    </object>
+                  </property>
+                  <property name="icon">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                    </object>
+                  </property>
+                  <property name="programGroupName" type="string">${compiler:JALVIEW_NAME}</property>
+                  <property name="runAsAdministrator" type="boolean" value="true" />
+                  <property name="unixIconFile">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                    </object>
+                  </property>
+                </serializedBean>
+                <condition>Util.hasFullAdminRights()
+&amp;&amp;
+!context.getBooleanVariable("sys.programGroupDisabled")</condition>
+              </action>
+              <action name="SYSTEMSPACE: Add a desktop link" id="2847" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDesktopLinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make desktop link">
+                <serializedBean>
+                  <property name="description" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                    </object>
+                  </property>
+                  <property name="name" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                  <property name="runAsAdministrator" type="boolean" value="true" />
+                  <property name="unixIconFile">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                    </object>
+                  </property>
+                  <property name="winIconFile">
+                    <object class="com.install4j.api.beans.ExternalFile">
+                      <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                    </object>
+                  </property>
+                </serializedBean>
+                <condition>Util.hasFullAdminRights()
+&amp;&amp;
+context.getBooleanVariable("createDesktopLinkAction")</condition>
+              </action>
+              <action name="SYSTEMSPACE: Add Jalview bin to the user's path (Windows)" id="2849" beanClass="com.install4j.runtime.beans.actions.misc.ModifyEnvironmentVariableAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not add &quot;${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}&quot; to the Path environment variable">
+                <serializedBean>
+                  <property name="type" type="enum" class="com.install4j.runtime.beans.actions.misc.ModifyStringType" value="APPEND" />
+                  <property name="userSpecific" type="boolean" value="false" />
+                  <property name="value" type="string">${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}</property>
+                  <property name="variableName" type="string">Path</property>
+                </serializedBean>
+                <condition>Util.hasFullAdminRights()
+&amp;&amp;
+context.getBooleanVariable("appendToPathAction")</condition>
+              </action>
+              <action name="SYSTEMSPACE: macOS /etc/paths.d entry" id="2852" beanClass="com.install4j.runtime.beans.actions.text.WriteTextFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>/etc/paths.d/${compiler:APPLICATION_FOLDER}</string>
+                    </object>
+                  </property>
+                  <property name="text" type="string">/Applications/${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS</property>
+                </serializedBean>
+                <condition>Util.hasFullAdminRights()
+&amp;&amp; Util.isMacOS()</condition>
+              </action>
+              <action name="BOTHSPACE: Create Linux/Unix user symbolic link to jalview.sh in system bin" id="2850" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixBinDir}">
+                <serializedBean>
+                  <property name="file">
+                    <object class="java.io.File">
+                      <string>${installer:sys.contentDir}/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
+                    </object>
+                  </property>
+                  <property name="linkFile">
+                    <object class="java.io.File">
+                      <string>${installer:unixBinDir}/${compiler:WRAPPER_LINK}</string>
+                    </object>
+                  </property>
+                </serializedBean>
+                <condition>(
+  context.getBooleanVariable("makeUserSymbolicLinkAction")
+  &amp;&amp; (
+       Util.isLinux()
+       || Util.isUnixInstaller()
+     )
+  &amp;&amp; context.getVariable("unixBinDir") != null
+)</condition>
+              </action>
             </actions>
             <formComponents>
               <formComponent id="21" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
@@ -915,12 +1014,14 @@ context.getBooleanVariable("appendToPathAction")</condition>
                   <property name="labelText" type="string">${form:finishedMessage}</property>
                 </serializedBean>
               </formComponent>
-              <formComponent name="Add a desktop link" id="574" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+              <formComponent name="Add a desktop link" id="574" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" resetInitOnPrevious="true">
                 <serializedBean>
                   <property name="checkboxText" type="string">${i18n:CreateDesktopIcon}</property>
                   <property name="variableName" type="string">createDesktopLinkAction</property>
                 </serializedBean>
-                <visibilityScript>!Util.isMacOS()</visibilityScript>
+                <visibilityScript>!Util.isMacOS()
+&amp;&amp; !Util.hasFullAdminRights()
+</visibilityScript>
               </formComponent>
               <formComponent name="Add an executable to the dock" id="577" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                 <serializedBean>
@@ -928,7 +1029,9 @@ context.getBooleanVariable("appendToPathAction")</condition>
                   <property name="initiallySelected" type="boolean" value="true" />
                   <property name="variableName" type="string">addToDockAction</property>
                 </serializedBean>
-                <visibilityScript>Util.isMacOS()</visibilityScript>
+                <visibilityScript>Util.isMacOS()
+&amp;&amp; !Util.hasFullAdminRights()
+</visibilityScript>
               </formComponent>
               <formComponent name="Add jalview bin to the user's Path environment variable (Windows)" id="2734" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                 <serializedBean>
@@ -938,15 +1041,13 @@ context.getBooleanVariable("appendToPathAction")</condition>
                 </serializedBean>
                 <visibilityScript>Util.isWindows()</visibilityScript>
               </formComponent>
-              <formComponent name="USERSPACE: Make a symbolic link to jalview.sh bash script in the user's local bin (Linux or Unix)" id="2736" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+              <formComponent name="BOTHSPACE: Make a symbolic link to jalview.sh bash script in the user's/system local bin (Linux or Unix)" id="2736" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                 <serializedBean>
-                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixUserBinDir}</property>
+                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixBinDir}</property>
                   <property name="initiallySelected" type="boolean" value="true" />
                   <property name="variableName" type="string">makeUserSymbolicLinkAction</property>
                 </serializedBean>
-                <visibilityScript>!Util.hasFullAdminRights()
-&amp;&amp;
-(
+                <visibilityScript>(
   Util.isLinux()
   || Util.isUnixInstaller()
   || (
@@ -954,7 +1055,7 @@ context.getBooleanVariable("appendToPathAction")</condition>
        &amp;&amp; context.getVariable("macWrapperLinkLocation") != null
      )
  )
- &amp;&amp; context.getVariable("unixUserBinDir") != null</visibilityScript>
+ &amp;&amp; context.getVariable("unixBinDir") != null</visibilityScript>
               </formComponent>
             </formComponents>
           </screen>
@@ -1341,7 +1442,7 @@ return console.askYesNo(message, true);
               </formComponent>
               <formComponent name="Make a symbolic link to jalview.sh bash script in the user's local bin (Linux or Unix)" id="2777" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                 <serializedBean>
-                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixUserBinDir}</property>
+                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixBinDir}</property>
                   <property name="initiallySelected" type="boolean" value="true" />
                   <property name="variableName" type="string">makeUserSymbolicLinkAction</property>
                 </serializedBean>
@@ -1353,7 +1454,7 @@ return console.askYesNo(message, true);
        &amp;&amp; context.getVariable("macWrapperLinkLocation") != null
      )
  )
- &amp;&amp; context.getVariable("unixUserBinDir") != null</visibilityScript>
+ &amp;&amp; context.getVariable("unixBinDir") != null</visibilityScript>
               </formComponent>
               <formComponent id="2780" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                 <serializedBean>