mirror of
https://github.com/apple/pkl.git
synced 2026-05-25 08:09:17 +02:00
pkl-executor: Migrate nullness to jSpecify (#1527)
Annotating SPI classes is binary compatible (forward and backward).
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.pkl.executor.spi.v1.ExecutorSpi;
|
||||
import org.pkl.executor.spi.v1.ExecutorSpiException;
|
||||
import org.slf4j.Logger;
|
||||
@@ -60,8 +61,7 @@ final class EmbeddedExecutor implements Executor {
|
||||
|
||||
Version requestedVersion = null;
|
||||
PklDistribution distribution = null;
|
||||
String output = null;
|
||||
RuntimeException exception = null;
|
||||
String output;
|
||||
|
||||
try {
|
||||
if (!Files.isRegularFile(modulePath)) {
|
||||
@@ -76,29 +76,33 @@ final class EmbeddedExecutor implements Executor {
|
||||
// (but not any modules imported by it) and only requires parsing (but not evaluating) the
|
||||
// module.
|
||||
requestedVersion = detectRequestedPklVersion(modulePath, options);
|
||||
//noinspection resource
|
||||
distribution = findCompatibleDistribution(modulePath, requestedVersion, options);
|
||||
output = distribution.evaluatePath(modulePath, options);
|
||||
} catch (RuntimeException e) {
|
||||
exception = e;
|
||||
// Could log exception, but this would violate "don't log and throw",
|
||||
// and Pkl stack trace might contain semi-sensitive information.
|
||||
logFinished(modulePath, false, requestedVersion, distribution, startTime, System.nanoTime());
|
||||
throw e;
|
||||
}
|
||||
|
||||
var endTime = System.nanoTime();
|
||||
logFinished(modulePath, true, requestedVersion, distribution, startTime, System.nanoTime());
|
||||
return output;
|
||||
}
|
||||
|
||||
// Could log exception, but this would violate "don't log and throw",
|
||||
// and Pkl stack trace might contain semi-sensitive information.
|
||||
private static void logFinished(
|
||||
Path modulePath,
|
||||
boolean success,
|
||||
@Nullable Version requestedVersion,
|
||||
@Nullable PklDistribution distribution,
|
||||
long startTime,
|
||||
long endTime) {
|
||||
logger.info(
|
||||
"Finished evaluating Pkl module. modulePath={} outcome={} requestedVersion={} selectedVersion={} elapsedMillis={}",
|
||||
modulePath,
|
||||
exception == null ? "success" : "failure",
|
||||
success,
|
||||
requestedVersion == null ? "n/a" : requestedVersion.toString(),
|
||||
distribution == null ? "n/a" : distribution.getVersion().toString(),
|
||||
(endTime - startTime) / 1_000_000);
|
||||
|
||||
if (exception != null) throw exception;
|
||||
|
||||
assert output != null;
|
||||
return output;
|
||||
}
|
||||
|
||||
private Version detectRequestedPklVersion(Path modulePath, ExecutorOptions options) {
|
||||
@@ -126,7 +130,7 @@ final class EmbeddedExecutor implements Executor {
|
||||
toDisplayPath(modulePath, options), availableVersions));
|
||||
}
|
||||
|
||||
/* @Nullable */ static Version extractMinPklVersion(String sourceText) {
|
||||
static @Nullable Version extractMinPklVersion(String sourceText) {
|
||||
var matcher = MODULE_INFO_PATTERN.matcher(sourceText);
|
||||
return matcher.find() ? Version.parse(matcher.group(1)) : null;
|
||||
}
|
||||
@@ -177,7 +181,7 @@ final class EmbeddedExecutor implements Executor {
|
||||
|
||||
private static final class PklDistribution implements AutoCloseable {
|
||||
final URLClassLoader pklDistributionClassLoader;
|
||||
final /* @Nullable */ ExecutorSpi executorSpi;
|
||||
final ExecutorSpi executorSpi;
|
||||
final Version version;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,24 +16,26 @@
|
||||
package org.pkl.executor;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Indicates an {@link Executor} error. {@link #getMessage()} returns a user-facing error message.
|
||||
*/
|
||||
public final class ExecutorException extends RuntimeException {
|
||||
private final String pklVersion;
|
||||
private final @Nullable String pklVersion;
|
||||
|
||||
public ExecutorException(String message) {
|
||||
super(message);
|
||||
pklVersion = null;
|
||||
}
|
||||
|
||||
public ExecutorException(String message, Throwable cause) {
|
||||
public ExecutorException(@Nullable String message, @Nullable Throwable cause) {
|
||||
super(message, cause);
|
||||
pklVersion = null;
|
||||
}
|
||||
|
||||
public ExecutorException(String message, Throwable cause, String version) {
|
||||
public ExecutorException(
|
||||
@Nullable String message, @Nullable Throwable cause, @Nullable String version) {
|
||||
super(message, cause);
|
||||
pklVersion = Objects.requireNonNull(version);
|
||||
}
|
||||
@@ -43,12 +45,12 @@ public final class ExecutorException extends RuntimeException {
|
||||
*
|
||||
* <p>Returns {@code null} if this exception does not originate from an underlying Pkl evaluator.
|
||||
*/
|
||||
public String getPklVersion() {
|
||||
public @Nullable String getPklVersion() {
|
||||
return pklVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
public @Nullable String getMessage() {
|
||||
var message = super.getMessage();
|
||||
if (pklVersion == null) {
|
||||
return message;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.pkl.executor.spi.v1.ExecutorSpiOptions;
|
||||
import org.pkl.executor.spi.v1.ExecutorSpiOptions2;
|
||||
import org.pkl.executor.spi.v1.ExecutorSpiOptions3;
|
||||
@@ -41,15 +42,15 @@ public final class ExecutorOptions {
|
||||
|
||||
private final List<Path> modulePath;
|
||||
|
||||
private final /* @Nullable */ Path rootDir;
|
||||
private final @Nullable Path rootDir;
|
||||
|
||||
private final /* @Nullable */ Duration timeout;
|
||||
private final @Nullable Duration timeout;
|
||||
|
||||
private final /* @Nullable */ String outputFormat;
|
||||
private final @Nullable String outputFormat;
|
||||
|
||||
private final /* @Nullable */ Path moduleCacheDir;
|
||||
private final @Nullable Path moduleCacheDir;
|
||||
|
||||
private final /* @Nullable */ Path projectDir;
|
||||
private final @Nullable Path projectDir;
|
||||
|
||||
private final List<Path> certificateFiles;
|
||||
|
||||
@@ -81,11 +82,11 @@ public final class ExecutorOptions {
|
||||
private Map<String, String> environmentVariables = Map.of();
|
||||
private Map<String, String> externalProperties = Map.of();
|
||||
private List<Path> modulePath = List.of();
|
||||
private /* @Nullable */ Path rootDir;
|
||||
private /* @Nullable */ Duration timeout;
|
||||
private /* @Nullable */ String outputFormat;
|
||||
private /* @Nullable */ Path moduleCacheDir;
|
||||
private /* @Nullable */ Path projectDir;
|
||||
private @Nullable Path rootDir;
|
||||
private @Nullable Duration timeout;
|
||||
private @Nullable String outputFormat;
|
||||
private @Nullable Path moduleCacheDir;
|
||||
private @Nullable Path projectDir;
|
||||
private List<Path> certificateFiles = List.of();
|
||||
private List<byte[]> certificateBytes = List.of();
|
||||
private Map<URI, URI> httpRewrites = Map.of();
|
||||
@@ -270,11 +271,11 @@ public final class ExecutorOptions {
|
||||
Map<String, String> environmentVariables,
|
||||
Map<String, String> externalProperties,
|
||||
List<Path> modulePath,
|
||||
/* @Nullable */ Path rootDir,
|
||||
/* @Nullable */ Duration timeout,
|
||||
/* @Nullable */ String outputFormat,
|
||||
/* @Nullable */ Path moduleCacheDir,
|
||||
/* @Nullable */ Path projectDir) {
|
||||
@Nullable Path rootDir,
|
||||
@Nullable Duration timeout,
|
||||
@Nullable String outputFormat,
|
||||
@Nullable Path moduleCacheDir,
|
||||
@Nullable Path projectDir) {
|
||||
|
||||
this(
|
||||
allowedModules,
|
||||
@@ -300,11 +301,11 @@ public final class ExecutorOptions {
|
||||
Map<String, String> environmentVariables,
|
||||
Map<String, String> externalProperties,
|
||||
List<Path> modulePath,
|
||||
/* @Nullable */ Path rootDir,
|
||||
/* @Nullable */ Duration timeout,
|
||||
/* @Nullable */ String outputFormat,
|
||||
/* @Nullable */ Path moduleCacheDir,
|
||||
/* @Nullable */ Path projectDir,
|
||||
@Nullable Path rootDir,
|
||||
@Nullable Duration timeout,
|
||||
@Nullable String outputFormat,
|
||||
@Nullable Path moduleCacheDir,
|
||||
@Nullable Path projectDir,
|
||||
List<Path> certificateFiles,
|
||||
List<byte[]> certificateBytes,
|
||||
Map<URI, URI> httpRewrites,
|
||||
@@ -354,17 +355,17 @@ public final class ExecutorOptions {
|
||||
}
|
||||
|
||||
/** API equivalent of the {@code --root-dir} CLI option. */
|
||||
public /* @Nullable */ Path getRootDir() {
|
||||
public @Nullable Path getRootDir() {
|
||||
return rootDir;
|
||||
}
|
||||
|
||||
/** API equivalent of the {@code --timeout} CLI option. */
|
||||
public Duration getTimeout() {
|
||||
public @Nullable Duration getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/** API equivalent of the {@code --format} CLI option. */
|
||||
public /* @Nullable */ String getOutputFormat() {
|
||||
public @Nullable String getOutputFormat() {
|
||||
return outputFormat;
|
||||
}
|
||||
|
||||
@@ -372,7 +373,7 @@ public final class ExecutorOptions {
|
||||
* API equivalent of the {@code --cache-dir} CLI option. {@code null} is equivalent to {@code
|
||||
* --no-cache}.
|
||||
*/
|
||||
public /* @Nullable */ Path getModuleCacheDir() {
|
||||
public @Nullable Path getModuleCacheDir() {
|
||||
return moduleCacheDir;
|
||||
}
|
||||
|
||||
@@ -382,7 +383,7 @@ public final class ExecutorOptions {
|
||||
* <p>Unlike the CLI, this option only sets project dependencies. It does not set evaluator
|
||||
* settings.
|
||||
*/
|
||||
public /* @Nullable */ Path getProjectDir() {
|
||||
public @Nullable Path getProjectDir() {
|
||||
return projectDir;
|
||||
}
|
||||
|
||||
@@ -407,11 +408,10 @@ public final class ExecutorOptions {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(/* @Nullable */ Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj.getClass() != ExecutorOptions.class) return false;
|
||||
if (!(obj instanceof ExecutorOptions other)) return false;
|
||||
|
||||
var other = (ExecutorOptions) obj;
|
||||
return allowedModules.equals(other.allowedModules)
|
||||
&& allowedResources.equals(other.allowedResources)
|
||||
&& environmentVariables.equals(other.environmentVariables)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.pkl.executor;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A <a href="https://semver.org/spec/v2.0.0.html">semantic version</a>.
|
||||
@@ -54,19 +55,15 @@ final class Version implements Comparable<Version> {
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
private final /*@Nullable*/ String preRelease;
|
||||
private final /*@Nullable*/ String build;
|
||||
private final @Nullable String preRelease;
|
||||
private final @Nullable String build;
|
||||
|
||||
// always access through getter
|
||||
private volatile Identifier[] __preReleaseIdentifiers;
|
||||
private volatile Identifier @Nullable [] __preReleaseIdentifiers;
|
||||
|
||||
/** Constructs a semantic version. */
|
||||
public Version(
|
||||
int major,
|
||||
int minor,
|
||||
int patch,
|
||||
/*@Nullable*/ String preRelease,
|
||||
/*@Nullable*/ String build) {
|
||||
int major, int minor, int patch, @Nullable String preRelease, @Nullable String build) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
@@ -99,7 +96,7 @@ final class Version implements Comparable<Version> {
|
||||
* <p>Returns {@code null} if the given string could not be parsed as a semantic version number or
|
||||
* is too large to fit into a {@link Version}.
|
||||
*/
|
||||
public static /*@Nullable*/ Version parseOrNull(String version) {
|
||||
public static @Nullable Version parseOrNull(String version) {
|
||||
var matcher = VERSION.matcher(version);
|
||||
if (!matcher.matches()) return null;
|
||||
|
||||
@@ -151,22 +148,22 @@ final class Version implements Comparable<Version> {
|
||||
}
|
||||
|
||||
/** Returns the pre-release version (if any). */
|
||||
public /*@Nullable*/ String getPreRelease() {
|
||||
public @Nullable String getPreRelease() {
|
||||
return preRelease;
|
||||
}
|
||||
|
||||
/** Returns a copy of this version with the given pre-release version. */
|
||||
public Version withPreRelease(/*@Nullable*/ String preRelease) {
|
||||
public Version withPreRelease(@Nullable String preRelease) {
|
||||
return new Version(major, minor, patch, preRelease, build);
|
||||
}
|
||||
|
||||
/** Returns the build metadata (if any). */
|
||||
public /*@Nullable*/ String getBuild() {
|
||||
public @Nullable String getBuild() {
|
||||
return build;
|
||||
}
|
||||
|
||||
/** Returns a copy of this version with the given build metadata. */
|
||||
public Version withBuild(/*@Nullable*/ String build) {
|
||||
public Version withBuild(@Nullable String build) {
|
||||
return new Version(major, minor, patch, preRelease, build);
|
||||
}
|
||||
|
||||
@@ -196,7 +193,7 @@ final class Version implements Comparable<Version> {
|
||||
|
||||
/** Tells if this version is equal to {@code obj} according to semantic versioning rules. */
|
||||
@Override
|
||||
public boolean equals(/* @Nullable */ Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Version other)) return false;
|
||||
return major == other.major
|
||||
@@ -222,8 +219,9 @@ final class Version implements Comparable<Version> {
|
||||
}
|
||||
|
||||
private Identifier[] getPreReleaseIdentifiers() {
|
||||
if (__preReleaseIdentifiers == null) {
|
||||
__preReleaseIdentifiers =
|
||||
var result = __preReleaseIdentifiers;
|
||||
if (result == null) {
|
||||
result =
|
||||
preRelease == null
|
||||
? new Identifier[0]
|
||||
: Arrays.stream(preRelease.split("\\."))
|
||||
@@ -233,11 +231,12 @@ final class Version implements Comparable<Version> {
|
||||
? new Identifier(Long.parseLong(str), null)
|
||||
: new Identifier(-1, str))
|
||||
.toArray(Identifier[]::new);
|
||||
__preReleaseIdentifiers = result;
|
||||
}
|
||||
return __preReleaseIdentifiers;
|
||||
return result;
|
||||
}
|
||||
|
||||
private record Identifier(long numericId, /*@Nullable*/ String alphanumericId)
|
||||
private record Identifier(long numericId, @Nullable String alphanumericId)
|
||||
implements Comparable<Identifier> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package org.pkl.executor;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -9,4 +9,7 @@
|
||||
* <li>X MUST only use classes from its own package and Java platform packages.
|
||||
* </ol>
|
||||
*/
|
||||
@NullMarked
|
||||
package org.pkl.executor.spi;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class ExecutorSpiOptions {
|
||||
private final List<String> allowedModules;
|
||||
@@ -31,13 +32,13 @@ public class ExecutorSpiOptions {
|
||||
|
||||
private final List<Path> modulePath;
|
||||
|
||||
private final Path rootDir;
|
||||
private final @Nullable Path rootDir;
|
||||
|
||||
private final Duration timeout;
|
||||
private final @Nullable Duration timeout;
|
||||
|
||||
private final String outputFormat;
|
||||
private final Path moduleCacheDir;
|
||||
private final Path projectDir;
|
||||
private final @Nullable String outputFormat;
|
||||
private final @Nullable Path moduleCacheDir;
|
||||
private final @Nullable Path projectDir;
|
||||
|
||||
public ExecutorSpiOptions(
|
||||
List<String> allowedModules,
|
||||
@@ -45,11 +46,11 @@ public class ExecutorSpiOptions {
|
||||
Map<String, String> environmentVariables,
|
||||
Map<String, String> externalProperties,
|
||||
List<Path> modulePath,
|
||||
/* @Nullable */ Path rootDir,
|
||||
/* @Nullable */ Duration timeout,
|
||||
/* @Nullable */ String outputFormat,
|
||||
/* @Nullable */ Path moduleCacheDir,
|
||||
/* @Nullable */ Path projectDir) {
|
||||
@Nullable Path rootDir,
|
||||
@Nullable Duration timeout,
|
||||
@Nullable String outputFormat,
|
||||
@Nullable Path moduleCacheDir,
|
||||
@Nullable Path projectDir) {
|
||||
|
||||
this.allowedModules = allowedModules;
|
||||
this.allowedResources = allowedResources;
|
||||
@@ -83,23 +84,23 @@ public class ExecutorSpiOptions {
|
||||
return modulePath;
|
||||
}
|
||||
|
||||
public /* @Nullable */ Path getRootDir() {
|
||||
public @Nullable Path getRootDir() {
|
||||
return rootDir;
|
||||
}
|
||||
|
||||
public /* @Nullable */ Duration getTimeout() {
|
||||
public @Nullable Duration getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public /* @Nullable */ String getOutputFormat() {
|
||||
public @Nullable String getOutputFormat() {
|
||||
return outputFormat;
|
||||
}
|
||||
|
||||
public /* @Nullable */ Path getModuleCacheDir() {
|
||||
public @Nullable Path getModuleCacheDir() {
|
||||
return moduleCacheDir;
|
||||
}
|
||||
|
||||
public Path getProjectDir() {
|
||||
public @Nullable Path getProjectDir() {
|
||||
return projectDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class ExecutorSpiOptions2 extends ExecutorSpiOptions {
|
||||
private final List<Path> certificateFiles;
|
||||
@@ -33,11 +34,11 @@ public class ExecutorSpiOptions2 extends ExecutorSpiOptions {
|
||||
Map<String, String> environmentVariables,
|
||||
Map<String, String> externalProperties,
|
||||
List<Path> modulePath,
|
||||
Path rootDir,
|
||||
Duration timeout,
|
||||
String outputFormat,
|
||||
Path moduleCacheDir,
|
||||
Path projectDir,
|
||||
@Nullable Path rootDir,
|
||||
@Nullable Duration timeout,
|
||||
@Nullable String outputFormat,
|
||||
@Nullable Path moduleCacheDir,
|
||||
@Nullable Path projectDir,
|
||||
List<Path> certificateFiles,
|
||||
List<byte[]> certificateBytes,
|
||||
int testPort) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class ExecutorSpiOptions3 extends ExecutorSpiOptions2 {
|
||||
|
||||
@@ -31,11 +32,11 @@ public class ExecutorSpiOptions3 extends ExecutorSpiOptions2 {
|
||||
Map<String, String> environmentVariables,
|
||||
Map<String, String> externalProperties,
|
||||
List<Path> modulePath,
|
||||
Path rootDir,
|
||||
Duration timeout,
|
||||
String outputFormat,
|
||||
Path moduleCacheDir,
|
||||
Path projectDir,
|
||||
@Nullable Path rootDir,
|
||||
@Nullable Duration timeout,
|
||||
@Nullable String outputFormat,
|
||||
@Nullable Path moduleCacheDir,
|
||||
@Nullable Path projectDir,
|
||||
List<Path> certificateFiles,
|
||||
List<byte[]> certificateBytes,
|
||||
int testPort,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package org.pkl.executor.spi.v1;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
Reference in New Issue
Block a user