Skip to content

Commit

Permalink
Add support for override flag (#296)
Browse files Browse the repository at this point in the history
* Fix FileUtilsTest

* Remove unused imports in FileUtils

* Add support for override flag

This commit adds support for overriding reachability
metadata when the override flag is set to true, designed
to be used with oracle/graalvm-reachability-metadata#51.
It is implemented by adding the required --exclude-config
build arguments.

Closes #268

* Fix NativeImagePlugin.addExcludeConfigArg and related documentation

* Remove unused import

* Fix functional tests
  • Loading branch information
sdeleuze committed Sep 18, 2022
1 parent e10ec8a commit cb61940
Show file tree
Hide file tree
Showing 21 changed files with 236 additions and 102 deletions.
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.graalvm.reachability;

import java.nio.file.Path;

public class DirectoryConfiguration {

private final Path directory;

private final boolean override;

public DirectoryConfiguration(Path directory, boolean override) {
this.directory = directory;
this.override = override;
}

public Path getDirectory() {
return directory;
}

public boolean isOverride() {
return override;
}
}
Expand Up @@ -40,7 +40,6 @@
*/
package org.graalvm.reachability;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
import java.util.function.Consumer;
Expand All @@ -63,29 +62,29 @@ public interface GraalVMReachabilityMetadataRepository {
* example if a configuration directory isn't available for a
* particular artifact version.
* @param queryBuilder the query builder
* @return the set of configuration directories matching the query
* @return the set of configuration matching the query
*/
Set<Path> findConfigurationDirectoriesFor(Consumer<? super Query> queryBuilder);
Set<DirectoryConfiguration> findConfigurationsFor(Consumer<? super Query> queryBuilder);

/**
* Returns a list of configuration directories for the specified artifact.
* There may be more than one configuration directory for a given artifact,
* but the list may also be empty if the repository doesn't contain any.
* Never null.
* @param gavCoordinates the artifact GAV coordinates (group:artifact:version)
* @return a list of configuration directories
* @return a list of configuration
*/
default Set<Path> findConfigurationDirectoriesFor(String gavCoordinates) {
return findConfigurationDirectoriesFor(q -> q.forArtifacts(gavCoordinates));
default Set<DirectoryConfiguration> findConfigurationsFor(String gavCoordinates) {
return findConfigurationsFor(q -> q.forArtifacts(gavCoordinates));
}

/**
* Returns the set of configuration directories for all the modules supplied
* as an argument.
* @param modules the list of modules
* @return the set of configuration directories
* @return the set of configuration
*/
default Set<Path> findConfigurationDirectoriesFor(Collection<String> modules) {
return findConfigurationDirectoriesFor(q -> q.forArtifacts(modules));
default Set<DirectoryConfiguration> findConfigurationsFor(Collection<String> modules) {
return findConfigurationsFor(q -> q.forArtifacts(modules));
}
}
Expand Up @@ -40,6 +40,7 @@
*/
package org.graalvm.reachability.internal;

import org.graalvm.reachability.DirectoryConfiguration;
import org.graalvm.reachability.GraalVMReachabilityMetadataRepository;
import org.graalvm.reachability.Query;
import org.graalvm.reachability.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex;
Expand Down Expand Up @@ -90,7 +91,7 @@ public static boolean isSupportedArchiveFormat(String path) {
}

@Override
public Set<Path> findConfigurationDirectoriesFor(Consumer<? super Query> queryBuilder) {
public Set<DirectoryConfiguration> findConfigurationsFor(Consumer<? super Query> queryBuilder) {
DefaultQuery query = new DefaultQuery();
queryBuilder.accept(query);
return query.getArtifacts()
Expand All @@ -106,25 +107,25 @@ public Set<Path> findConfigurationDirectoriesFor(Consumer<? super Query> queryBu
if (artifactQuery.getForcedConfig().isPresent()) {
String configVersion = artifactQuery.getForcedConfig().get();
logger.log(groupId, artifactId, version, "Configuration is forced to version " + configVersion);
return index.findForcedConfiguration(configVersion);
return index.findConfiguration(groupId, artifactId, configVersion);
}
Optional<Path> configurationDirectory = index.findConfigurationDirectory(groupId, artifactId, version);
if (!configurationDirectory.isPresent() && artifactQuery.isUseLatestVersion()) {
Optional<DirectoryConfiguration> configuration = index.findConfiguration(groupId, artifactId, version);
if (!configuration.isPresent() && artifactQuery.isUseLatestVersion()) {
logger.log(groupId, artifactId, version, "Configuration directory not found. Trying latest version.");
configurationDirectory = index.findLatestConfigurationFor(groupId, artifactId);
if (!configurationDirectory.isPresent()) {
configuration = index.findLatestConfigurationFor(groupId, artifactId);
if (!configuration.isPresent()) {
logger.log(groupId, artifactId, version, "Latest version not found!");
}
}
Optional<Path> finalConfigurationDirectory = configurationDirectory;
Optional<DirectoryConfiguration> finalConfigurationDirectory = configuration;
logger.log(groupId, artifactId, version, () -> {
if (finalConfigurationDirectory.isPresent()) {
Path path = finalConfigurationDirectory.get();
Path path = finalConfigurationDirectory.get().getDirectory();
return "Configuration directory is " + rootDirectory.relativize(path);
}
return "missing.";
});
return configurationDirectory;
return configuration;
})
.filter(Optional::isPresent)
.map(Optional::get);
Expand Down
Expand Up @@ -52,16 +52,19 @@ public class Artifact {
private final Set<String> versions;
private final String directory;
private final boolean latest;
private final boolean override;

@JsonCreator
public Artifact(@JsonProperty("module") String module,
@JsonProperty("tested-versions") Set<String> versions,
@JsonProperty("metadata-version") String directory,
@JsonProperty(value = "latest", defaultValue = "false") boolean latest) {
@JsonProperty(value = "latest", defaultValue = "false") boolean latest,
@JsonProperty(value = "override", defaultValue = "false") boolean override) {
this.module = module;
this.versions = versions;
this.directory = directory;
this.latest = latest;
this.override = override;
}

public String getModule() {
Expand All @@ -79,4 +82,8 @@ public String getDirectory() {
public boolean isLatest() {
return latest;
}

public boolean isOverride() {
return override;
}
}
Expand Up @@ -42,6 +42,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.graalvm.reachability.DirectoryConfiguration;
import org.graalvm.reachability.internal.UncheckedIOException;

import java.io.BufferedReader;
Expand Down Expand Up @@ -80,12 +81,6 @@ private Map<String, List<Artifact>> parseIndexFile(Path rootPath) {

}

@Override
public Optional<Path> findForcedConfiguration(String version) {
Path configDir = moduleRoot.resolve(version);
return Files.isDirectory(configDir) ? Optional.of(configDir) : Optional.empty();
}

/**
* Returns the configuration directory for the requested artifact.
*
Expand All @@ -95,7 +90,7 @@ public Optional<Path> findForcedConfiguration(String version) {
* @return a configuration directory, or empty if no configuration directory is available
*/
@Override
public Optional<Path> findConfigurationDirectory(String groupId, String artifactId, String version) {
public Optional<DirectoryConfiguration> findConfiguration(String groupId, String artifactId, String version) {
return findConfigurationFor(groupId, artifactId, artifact -> artifact.getVersions().contains(version));
}

Expand All @@ -107,11 +102,11 @@ public Optional<Path> findConfigurationDirectory(String groupId, String artifact
* @return a configuration directory, or empty if no configuration directory is available
*/
@Override
public Optional<Path> findLatestConfigurationFor(String groupId, String artifactId) {
public Optional<DirectoryConfiguration> findLatestConfigurationFor(String groupId, String artifactId) {
return findConfigurationFor(groupId, artifactId, Artifact::isLatest);
}

private Optional<Path> findConfigurationFor(String groupId, String artifactId, Predicate<? super Artifact> predicate) {
private Optional<DirectoryConfiguration> findConfigurationFor(String groupId, String artifactId, Predicate<? super Artifact> predicate) {
String module = groupId + ":" + artifactId;
List<Artifact> artifacts = index.get(module);
if (artifacts == null) {
Expand All @@ -121,6 +116,7 @@ private Optional<Path> findConfigurationFor(String groupId, String artifactId, P
.filter(artifact -> artifact.getModule().equals(module))
.filter(predicate)
.findFirst()
.map(artifact -> moduleRoot.resolve(artifact.getDirectory()));
.map(artifact -> new DirectoryConfiguration(moduleRoot.resolve(artifact.getDirectory()), artifact.isOverride()));
}

}
Expand Up @@ -40,33 +40,26 @@
*/
package org.graalvm.reachability.internal.index.artifacts;

import java.nio.file.Path;
import java.util.Optional;

public interface VersionToConfigDirectoryIndex {
import org.graalvm.reachability.DirectoryConfiguration;

/**
* Returns the specified configuration directory version, ignoring
* any existing configuration.
* @param version the requested version
* @return the configuration directory
*/
Optional<Path> findForcedConfiguration(String version);
public interface VersionToConfigDirectoryIndex {

/**
* Returns the configuration directory for the requested artifact.
* Returns the configuration for the requested artifact.
* @param groupId the group ID of the artifact
* @param artifactId the artifact ID of the artifact
* @param version the version of the artifact
* @return a configuration directory, or empty if no configuration directory is available
* @return a configuration, or empty if no configuration directory is available
*/
Optional<Path> findConfigurationDirectory(String groupId, String artifactId, String version);
Optional<DirectoryConfiguration> findConfiguration(String groupId, String artifactId, String version);

/**
* Returns the latest configuration directory for the requested artifact.
* Returns the latest configuration for the requested artifact.
* @param groupId the group ID of the artifact
* @param artifactId the artifact ID of the artifact
* @return a configuration directory, or empty if no configuration directory is available
* @return a configuration, or empty if no configuration directory is available
*/
Optional<Path> findLatestConfigurationFor(String groupId, String artifactId);
Optional<DirectoryConfiguration> findLatestConfigurationFor(String groupId, String artifactId);
}
Expand Up @@ -41,6 +41,7 @@

package org.graalvm.reachability.internal;

import org.graalvm.reachability.DirectoryConfiguration;
import org.graalvm.reachability.Query;
import org.junit.jupiter.api.Test;

Expand All @@ -51,6 +52,8 @@
import java.util.function.Consumer;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class FileSystemRepositoryTest {
private FileSystemRepository repository;
Expand All @@ -65,9 +68,11 @@ void testRepo1() {

// then:
result.hasSinglePath("org/foo/1.0");
result.hasNoOverride();

// when:
lookup("org:foo:1.1");
result.hasOverride();

// then:
result.hasSinglePath("org/foo/1.1");
Expand All @@ -87,6 +92,7 @@ void testRepo2() {

// then:
result.hasSinglePath("org/foo/1.1");
result.hasNoOverride();
}

@Test
Expand Down Expand Up @@ -166,11 +172,11 @@ void canUseLatestConfigDir() {
}

private void lookup(Consumer<? super Query> builder) {
result = new Result(repository.findConfigurationDirectoriesFor(builder), repoPath);
result = new Result(repository.findConfigurationsFor(builder), repoPath);
}

private void lookup(String gav) {
result = new Result(repository.findConfigurationDirectoriesFor(gav), repoPath);
result = new Result(repository.findConfigurationsFor(gav), repoPath);
}

private void withRepo(String id) {
Expand All @@ -184,20 +190,32 @@ private void withRepo(String id) {

private static final class Result {
private final Path repoPath;
private final Set<Path> configDirs;
private final Set<DirectoryConfiguration> configs;

private Result(Set<Path> configDirs, Path repoPath) {
this.configDirs = configDirs;
private Result(Set<DirectoryConfiguration> configs, Path repoPath) {
this.configs = configs;
this.repoPath = repoPath;
}

public void isEmpty() {
assertEquals(0, configDirs.size());
assertEquals(0, configs.size());
}

public void hasSinglePath(String path) {
assertEquals(1, configDirs.size());
assertEquals(repoPath.resolve(path), configDirs.iterator().next());
assertEquals(1, configs.size());
assertEquals(repoPath.resolve(path), configs.iterator().next().getDirectory());
}

public void hasOverride() {
for (DirectoryConfiguration config : configs) {
assertTrue(config.isOverride());
}
}

public void hasNoOverride() {
for (DirectoryConfiguration config : configs) {
assertFalse(config.isOverride());
}
}
}
}

0 comments on commit cb61940

Please sign in to comment.