Skip to content

Commit

Permalink
tycho-p2-director:director: Fix handling of destination on macOS
Browse files Browse the repository at this point in the history
* In DirectorMojo, the adjustment of 'destination' must consider the
  actual target environment (p2os/p2ws/p2arch parameters) that is to be
  installed and only fall back to the running environment if no explicit
  target environment is given.

* Document in the tycho-p2-director:director JavaDoc / mojo parameter
  description that this intentionally deviates from the behavior of the
  stand-alone director application invocation:
      eclipse -application org.eclipse.equinox.p2.director
              -destination <destination> ...

* In DirectorMojo, add a consistency check that p2os/p2ws/p2arch must
  all be specified mutually.

* The helper methods in DirectorRuntime are extended, to properly handle
  all three possible scenarios:

  1)     /path/without/app/bundle/layout
     --> /path/without/app/bundle/layout/Eclipse.app/Contents/Eclipse

  2)     /path/to/real.app/Contents/Eclipse
     --> /path/to/real.app/Contents/Eclipse

  3)     /path/to/real.app
     --> /path/to/real.app/Contents/Eclipse

  This allows us to remove redundant code in
  ProvisionedInstallationBuilder.

Fixes #3548.
  • Loading branch information
sratz committed Mar 25, 2024
1 parent d23230d commit 5f363fa
Show file tree
Hide file tree
Showing 8 changed files with 581 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,35 @@ public interface Command {

/**
* Computes the destination of a director install based on a target environment
*
* <p>
* Currently, this implements special handling for macOS and behaves as follows:
* <ul>
* <li>If <code>baseLocation</code> already conforms to the full app bundle layout
* (<code>/path/to/Foo.app/Contents/Eclipse</code>), <code>baseLocation</code> is returned
* as-is.
* <li>If <code>baseLocation</code> points to the root of an app bundle
* (<code>/path/to/Foo.app</code>), <code>Contents/Eclipse</code> is appended and the path
* <code>/path/to/Foo.app/Contents/Eclipse</code> is returned.
* <li>Otherwise, i.e. if no app bundle path is given (<code>/path/to/work</code>), a valid app
* bundle path is appended, and the path <code>/path/to/work/Eclipse.app/Contents/Eclipse</code>
* is returned.
* </ul>
*
* @param baseLocation
* the base location
* @param env
* @return
* the target environment
* @return the adjusted location to conform to layouts required by the target environment
*/
public static File getDestination(File baseLocation, TargetEnvironment env) {
if (PlatformPropertiesUtils.OS_MACOSX.equals(env.getOs()) && !hasRequiredMacLayout(baseLocation)) {
return new File(baseLocation, "Eclipse.app/Contents/Eclipse/");
if (PlatformPropertiesUtils.OS_MACOSX.equals(env.getOs())) {
if (hasRequiredMacLayout(baseLocation)) {
return baseLocation;
} else if (isMacOsAppBundleRoot(baseLocation)) {
return new File(baseLocation, "Contents/Eclipse/");
} else {
return new File(baseLocation, "Eclipse.app/Contents/Eclipse/");
}
}
return baseLocation;
}
Expand All @@ -100,9 +121,14 @@ private static boolean hasRequiredMacLayout(File folder) {
File folder2 = folder.getParentFile();
if (folder2 != null && "Contents".equals(folder2.getName())) {
File parent = folder2.getParentFile();
return parent != null && parent.getName().endsWith(".app");
return parent != null && isMacOsAppBundleRoot(parent);
}
}
return false;
}

private static boolean isMacOsAppBundleRoot(File folder) {
return folder.getName().endsWith(".app");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,206 @@
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/dummy</destination>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>director-windows</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-windows</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/productwindows</destination>
<p2os>win32</p2os>
<p2ws>win32</p2ws>
<p2arch>x86_64</p2arch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-linux</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-linux</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/productlinux</destination>
<p2os>linux</p2os>
<p2ws>gtk</p2ws>
<p2arch>x86_64</p2arch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-macos-destination-with-app-suffix</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-macos-destination-with-app-suffix</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/productmacos.app</destination>
<p2os>macosx</p2os>
<p2ws>cocoa</p2ws>
<p2arch>x86_64</p2arch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-macos-destination-without-app-suffix</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-macos-destinationout-with-app-suffix</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/productmacos</destination>
<p2os>macosx</p2os>
<p2ws>cocoa</p2ws>
<p2arch>x86_64</p2arch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-macos-destination-with-full-bundle-path</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-macos-destination-with-full-bundle-path</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/productmacos.app/Contents/Eclipse</destination>
<p2os>macosx</p2os>
<p2ws>cocoa</p2ws>
<p2arch>x86_64</p2arch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-running-environment</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-running-environment</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/product</destination>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>director-iconsistent-p2-arguments</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>run-director-iconsistent-p2-arguments</id>
<goals>
<goal>director</goal>
</goals>
<phase>package</phase>
<configuration>
<repositories>${target-platform}</repositories>
<installIUs>org.eclipse.osgi</installIUs>
<destination>target/product</destination>
<p2os>win32</p2os>
<!-- other ones missing -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,99 @@
package org.eclipse.tycho.test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.maven.it.VerificationException;
import org.apache.maven.it.Verifier;
import org.eclipse.tycho.TargetEnvironment;
import org.junit.Test;

public class P2DirectorPluginTest extends AbstractTychoIntegrationTest {

@Test
public void testDirectorStandalone() throws Exception {
public void testDirectorStandaloneWindows() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-windows");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

assertTrue(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "productwindows", "plugins")));
}

@Test
public void testDirectorStandaloneLinux() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-linux");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

assertTrue(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "productlinux", "plugins")));
}

@Test
public void testDirectorStandaloneMacOsDestinationWithAppSuffix() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-macos-destination-with-app-suffix");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

assertTrue(Files.isDirectory(
Path.of(verifier.getBasedir(), "target", "productmacos.app", "Contents", "Eclipse", "plugins")));
}

@Test
public void testDirectorStandaloneMacOsDestinationWithoutAppSuffix() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-macos-destination-without-app-suffix");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

assertTrue(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "productmacos", "Eclipse.app", "Contents",
"Eclipse", "plugins")));
}

@Test
public void testDirectorStandaloneMacOsDestinationWithFullBundlePath() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-macos-destination-with-full-bundle-path");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

assertTrue(Files.isDirectory(
Path.of(verifier.getBasedir(), "target", "productmacos.app", "Contents", "Eclipse", "plugins")));
}

@Test
public void testDirectorStandaloneUsingRunningEnvironment() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-running-environment");
verifier.executeGoal("package");
verifier.verifyErrorFreeLog();

if ("macosx".equals(TargetEnvironment.getRunningEnvironment().getOs())) {
assertTrue(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "product", "Eclipse.app", "Contents",
"Eclipse", "plugins")));
} else {
assertTrue(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "product", "plugins")));
}
}

@Test
public void testDirectorStandaloneInconsistentP2Options() throws Exception {
Verifier verifier = getVerifier("tycho-p2-director-plugin/director-goal-standalone", true, true);
verifier.addCliOption("-Pdirector-iconsistent-p2-arguments");
try {
verifier.executeGoal("package");
fail(VerificationException.class.getName() + " expected");
} catch (VerificationException e) {
}
verifier.verifyTextInLog(
"p2os / p2ws / p2arch must be mutually specified, p2os=win32 given, p2ws missing, p2arch missing");
assertFalse(Files.isDirectory(Path.of(verifier.getBasedir(), "target", "product")));
}

}
Loading

0 comments on commit 5f363fa

Please sign in to comment.