Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider other locations when resolving IUs from updatesites #792

Merged

Conversation

laeubi
Copy link
Contributor

@laeubi laeubi commented Oct 8, 2023

Currently the IULocation can only consider units from other locations if these are also of type IU location but other target types might be able to supply items in a way not know to the IULocation.

This adds the necessary infrastructure to support this usecase by using the adapter pattern.

Fix #207
Requires eclipse-equinox/p2#348

@github-actions
Copy link

github-actions bot commented Oct 8, 2023

Test Results

     273 files  +       6       273 suites  +6   1h 4m 43s ⏱️ + 19m 8s
  3 340 tests  -        1    3 310 ✔️ ±       0  30 💤 ±  0  0  - 1 
10 317 runs  +2 721  10 227 ✔️ +2 698  90 💤 +24  0  - 1 

Results for commit 3e98782. ± Comparison against base commit fccc098.

This pull request removes 1 test.
AllPDETests org.eclipse.pde.ui.tests.launcher.AllLauncherTests org.eclipse.pde.ui.tests.launcher.FeatureBasedLaunchTest ‑ Unknown test

♻️ This comment has been updated with latest results.

@laeubi laeubi force-pushed the allow_other_locations_to_supply_units branch from bcedeb8 to 66a5c24 Compare October 9, 2023 08:16
@laeubi laeubi marked this pull request as ready for review October 9, 2023 08:18
@laeubi
Copy link
Contributor Author

laeubi commented Oct 9, 2023

This is now ready as the first minimal increment. It is likely that there are some changes one like to adjust sometime but at least this allows to resolve an IU location when using a Directory location that supply a missing bundle as in this example:

<target name="target_require_other">
   <locations>
      <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
         <repository location="https://download.eclipse.org/linuxtools/updates-docker-nightly/"/>
         <unit id="com.google.guava" version="0.0.0"/>
      </location>
      <location path="${project_loc:/test.pde}/lib" type="Directory"/>
      </locations>
</target>

@laeubi
Copy link
Contributor Author

laeubi commented Oct 10, 2023

Testfailure seems unrelated, build is otherwhise green...

@HannesWell HannesWell force-pushed the allow_other_locations_to_supply_units branch from 66a5c24 to 04fc433 Compare October 10, 2023 22:04
@laeubi
Copy link
Contributor Author

laeubi commented Oct 11, 2023

Using a Generic Type is simply bad and fixing this later on up by adding filter only complicates the whole story for absolutely no gain and will limit our ability to later, also this discussion about "API" or "not API" does not bring any value this is not API this is a decoupled way of using optional features and if we remove it and later replace it by some other means things have to be adjusted or one can use another Adapter that bridges old -> new behavior as done already in the past when migrating to the more feature rich target locations..

With that squashed into your commit I would be more than happy to have this great new feature. :)

Because of mentioned flaws I discard that change. Let me know if we should close this instead as I don't want to invest more time in a crippled solution that sooner or later will break or only works by some inherit assumptions about Types we never can reliable enforce..

@laeubi laeubi force-pushed the allow_other_locations_to_supply_units branch from f31c542 to 66a5c24 Compare October 11, 2023 06:44
@laeubi laeubi force-pushed the allow_other_locations_to_supply_units branch 2 times, most recently from 968dac7 to e825d30 Compare October 22, 2023 09:17
Currently the IULocation can only consider units from other locations if
these are also of type IU location but other target types might be able
to supply items in a way not know to the IULocation.

This adds the necessary infrastructure to support this usecase by using
the adapter pattern.

Fix eclipse-pde#207
@laeubi laeubi force-pushed the allow_other_locations_to_supply_units branch from e825d30 to 3e98782 Compare October 22, 2023 17:23
@laeubi
Copy link
Contributor Author

laeubi commented Oct 22, 2023

@HannesWell I now reworked the whole part so it automatically queries the locations and converts them I hope this now addresses your concerns.

Copy link
Member

@HannesWell HannesWell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HannesWell I now reworked the whole part so it automatically queries the locations and converts them I hope this now addresses your concerns.

Yes, this looks perfectly fine, thanks. 👍🏽
I'm glad we came to a better solution that has less requirements and also works without adjustments in other target-locations. :)

Just two small style-remarks below, but nothing critical.

Comment on lines +60 to +95
public static Stream<IInstallableUnit> generateInstallableUnits(TargetBundle[] bundles) {
if (bundles == null || bundles.length == 0) {
return Stream.empty();
}
return Arrays.stream(bundles).flatMap(InstallableUnitGenerator::generateInstallableUnits);
}

public static Stream<IInstallableUnit> generateInstallableUnits(TargetBundle targetBundle) {
BundleInfo bundleInfo = targetBundle.getBundleInfo();
if (bundleInfo != null) {
String manifest = bundleInfo.getManifest();
if (manifest != null) {
try {
Manifest parsed = new Manifest(new ByteArrayInputStream(manifest.getBytes(StandardCharsets.UTF_8)));
Attributes mainAttributes = parsed.getMainAttributes();
CaseInsensitiveDictionaryMap<String, String> headers = new CaseInsensitiveDictionaryMap<>(
mainAttributes.size());
Set<Entry<Object, Object>> entrySet = mainAttributes.entrySet();
for (Entry<Object, Object> entry : entrySet) {
headers.put(entry.getKey().toString(), entry.getValue().toString());
}
PublisherInfo publisherInfo = new PublisherInfo();
publisherInfo.setArtifactOptions(IPublisherInfo.A_INDEX);
BundleDescription bundleDescription = BundlesAction.createBundleDescription(headers, null);
IInstallableUnit iu = BundlesAction.createBundleIU(bundleDescription,
BundlesAction.createBundleArtifactKey(bundleDescription.getSymbolicName(),
bundleDescription.getVersion().toString()),
publisherInfo);
return Stream.of(iu);
} catch (IOException e) {
// can't use it then...
}
}
}
return Stream.empty();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Stream.mapMulti() would save the creation of Streams with one element.

Suggested change
public static Stream<IInstallableUnit> generateInstallableUnits(TargetBundle[] bundles) {
if (bundles == null || bundles.length == 0) {
return Stream.empty();
}
return Arrays.stream(bundles).flatMap(InstallableUnitGenerator::generateInstallableUnits);
}
public static Stream<IInstallableUnit> generateInstallableUnits(TargetBundle targetBundle) {
BundleInfo bundleInfo = targetBundle.getBundleInfo();
if (bundleInfo != null) {
String manifest = bundleInfo.getManifest();
if (manifest != null) {
try {
Manifest parsed = new Manifest(new ByteArrayInputStream(manifest.getBytes(StandardCharsets.UTF_8)));
Attributes mainAttributes = parsed.getMainAttributes();
CaseInsensitiveDictionaryMap<String, String> headers = new CaseInsensitiveDictionaryMap<>(
mainAttributes.size());
Set<Entry<Object, Object>> entrySet = mainAttributes.entrySet();
for (Entry<Object, Object> entry : entrySet) {
headers.put(entry.getKey().toString(), entry.getValue().toString());
}
PublisherInfo publisherInfo = new PublisherInfo();
publisherInfo.setArtifactOptions(IPublisherInfo.A_INDEX);
BundleDescription bundleDescription = BundlesAction.createBundleDescription(headers, null);
IInstallableUnit iu = BundlesAction.createBundleIU(bundleDescription,
BundlesAction.createBundleArtifactKey(bundleDescription.getSymbolicName(),
bundleDescription.getVersion().toString()),
publisherInfo);
return Stream.of(iu);
} catch (IOException e) {
// can't use it then...
}
}
}
return Stream.empty();
}
private static Stream<IInstallableUnit> generateInstallableUnits(TargetBundle[] bundles) {
if (bundles == null || bundles.length == 0) {
return Stream.empty();
}
return Arrays.stream(bundles).mapMulti(InstallableUnitGenerator::generateInstallableUnits);
}
private static void generateInstallableUnits(TargetBundle targetBundle, Consumer<IInstallableUnit> downStream) {
BundleInfo bundleInfo = targetBundle.getBundleInfo();
if (bundleInfo != null) {
String manifest = bundleInfo.getManifest();
if (manifest != null) {
try {
Manifest parsed = new Manifest(new ByteArrayInputStream(manifest.getBytes(StandardCharsets.UTF_8)));
Attributes mainAttributes = parsed.getMainAttributes();
CaseInsensitiveDictionaryMap<String, String> headers = new CaseInsensitiveDictionaryMap<>(
mainAttributes.size());
Set<Entry<Object, Object>> entrySet = mainAttributes.entrySet();
for (Entry<Object, Object> entry : entrySet) {
headers.put(entry.getKey().toString(), entry.getValue().toString());
}
PublisherInfo publisherInfo = new PublisherInfo();
publisherInfo.setArtifactOptions(IPublisherInfo.A_INDEX);
BundleDescription bundleDescription = BundlesAction.createBundleDescription(headers, null);
IInstallableUnit iu = BundlesAction.createBundleIU(bundleDescription,
BundlesAction.createBundleArtifactKey(bundleDescription.getSymbolicName(),
bundleDescription.getVersion().toString()),
publisherInfo);
downStream.accept(iu);
} catch (IOException e) {
// can't use it then...
}
}
}
}

return Stream.empty();
}

public static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature[] features) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature[] features) {
private static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature[] features) {

return Arrays.stream(features).flatMap(InstallableUnitGenerator::generateInstallableUnits);
}

public static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature targetFeature) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature targetFeature) {
private static Stream<IInstallableUnit> generateInstallableUnits(TargetFeature targetFeature) {

@laeubi laeubi merged commit dd321b5 into eclipse-pde:master Oct 23, 2023
16 checks passed
ptziegler added a commit to ptziegler/eclipse.pde that referenced this pull request Dec 1, 2023
…e#792

Given that units from non-IU locations are considered when resolving
IUs, it may happen that units are contained in the resolution path,
which are not contained by any repository. This may break previously
functional target definitions.

To resolve this problem, an in-memory artifact and metadata repository
is created, based on the metadata of the non-IU locations. Those
repositories are then added to the provisioning context for further
processing.

Amends dd321b5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[target] consider other locations in planner mode
2 participants