Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bench/src/jmh/java/org/pkl/core/ListSort.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
Expand Down Expand Up @@ -51,7 +51,8 @@ public class ListSort {
null,
IoUtils.getCurrentWorkingDir(),
StackFrameTransformers.defaultTransformer,
false);
false,
null);
private static final List<Object> list = new ArrayList<>(100000);

static {
Expand Down
1 change: 1 addition & 0 deletions docs/src/test/kotlin/DocSnippetTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class DocSnippetTestsEngine : HierarchicalTestEngine<DocSnippetTestsEngine.Execu
IoUtils.getCurrentWorkingDir(),
StackFrameTransformers.defaultTransformer,
false,
null
)
return ExecutionContext(replServer)
}
Expand Down
1 change: 1 addition & 0 deletions pkl-cli/src/main/kotlin/org/pkl/cli/CliRepl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ internal class CliRepl(private val options: CliEvaluatorOptions) : CliCommand(op
options.base.normalizedWorkingDir,
stackFrameTransformer,
options.base.color?.hasColor() ?: false,
options.base.traceMode,
)
Repl(options.base.normalizedWorkingDir, server).run()
}
Expand Down
3 changes: 2 additions & 1 deletion pkl-cli/src/test/kotlin/org/pkl/cli/repl/ReplMessagesTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
Expand Down Expand Up @@ -43,6 +43,7 @@ class ReplMessagesTest {
"/".toPath(),
StackFrameTransformers.defaultTransformer,
false,
null,
)

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
Expand All @@ -22,6 +22,7 @@ import java.time.Duration
import java.util.regex.Pattern
import org.pkl.core.evaluatorSettings.Color
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader
import org.pkl.core.evaluatorSettings.TraceMode
import org.pkl.core.module.ProjectDependenciesManager
import org.pkl.core.util.IoUtils

Expand Down Expand Up @@ -145,6 +146,9 @@ data class CliBaseOptions(

/** External resource reader process specs */
val externalResourceReaders: Map<String, ExternalReader> = mapOf(),

/** Defines options for the formatting of calls to the trace() method. */
val traceMode: TraceMode? = null,
) {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import org.pkl.commons.cli.CliException
import org.pkl.commons.shlex
import org.pkl.core.evaluatorSettings.Color
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader
import org.pkl.core.evaluatorSettings.TraceMode
import org.pkl.core.runtime.VmUtils
import org.pkl.core.util.IoUtils

Expand Down Expand Up @@ -255,6 +256,17 @@ class BaseOptions : OptionGroup() {
.multiple()
.toMap()

val traceMode: TraceMode by
option(
names = arrayOf("--trace-mode"),
metavar = "when",
help =
"Specifies how calls to trace() are formatted. Possible values of <when> are 'default', 'pretty' and 'hidden'.",
)
.enum<TraceMode> { it.name.lowercase() }
.single()
.default(TraceMode.DEFAULT)

// hidden option used by native tests
private val testPort: Int by
option(names = arrayOf("--test-port"), help = "Internal test option", hidden = true)
Expand Down Expand Up @@ -291,6 +303,7 @@ class BaseOptions : OptionGroup() {
httpNoProxy = noProxy ?: emptyList(),
externalModuleReaders = externalModuleReaders,
externalResourceReaders = externalResourceReaders,
traceMode = traceMode,
)
}
}
9 changes: 7 additions & 2 deletions pkl-core/src/main/java/org/pkl/core/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
import org.graalvm.polyglot.Context;
import org.pkl.core.evaluatorSettings.TraceMode;
import org.pkl.core.http.HttpClient;
import org.pkl.core.http.HttpClientInitException;
import org.pkl.core.module.ModuleKeyFactory;
Expand All @@ -46,6 +47,7 @@ public class Analyzer {
private final @Nullable DeclaredDependencies projectDependencies;
private final ModuleResolver moduleResolver;
private final HttpClient httpClient;
private final TraceMode traceMode;

public Analyzer(
StackFrameTransformer transformer,
Expand All @@ -54,14 +56,16 @@ public Analyzer(
Collection<ModuleKeyFactory> moduleKeyFactories,
@Nullable Path moduleCacheDir,
@Nullable DeclaredDependencies projectDependencies,
HttpClient httpClient) {
HttpClient httpClient,
@Nullable TraceMode traceMode) {
this.transformer = transformer;
this.color = color;
this.securityManager = securityManager;
this.moduleCacheDir = moduleCacheDir;
this.projectDependencies = projectDependencies;
this.moduleResolver = new ModuleResolver(moduleKeyFactories);
this.httpClient = httpClient;
this.traceMode = traceMode;
}

/**
Expand Down Expand Up @@ -115,7 +119,8 @@ private Context createContext() {
projectDependencies == null
? null
: new ProjectDependenciesManager(
projectDependencies, moduleResolver, securityManager)));
projectDependencies, moduleResolver, securityManager),
traceMode));
});
}
}
20 changes: 19 additions & 1 deletion pkl-core/src/main/java/org/pkl/core/EvaluatorBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.regex.Pattern;
import org.pkl.core.SecurityManagers.StandardBuilder;
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader;
import org.pkl.core.evaluatorSettings.TraceMode;
import org.pkl.core.externalreader.ExternalReaderProcess;
import org.pkl.core.http.HttpClient;
import org.pkl.core.module.ModuleKeyFactories;
Expand Down Expand Up @@ -67,6 +68,8 @@ public final class EvaluatorBuilder {

private @Nullable DeclaredDependencies dependencies;

private @Nullable TraceMode traceMode;

private EvaluatorBuilder() {}

/**
Expand Down Expand Up @@ -454,6 +457,17 @@ public EvaluatorBuilder setProjectDependencies(DeclaredDependencies dependencies
return this.dependencies;
}

/** Sets whether calls to trace() produce indented, multi-line output. */
public EvaluatorBuilder setTraceMode(TraceMode traceMode) {
this.traceMode = traceMode;
return this;
}

/** Returns whether calls to trace() produce indented, multi-line output. */
public TraceMode getTraceMode() {
return this.traceMode;
}

/**
* Given a project, sets its dependencies, and also applies any evaluator settings if set.
*
Expand Down Expand Up @@ -517,6 +531,9 @@ public EvaluatorBuilder applyFromProject(Project project) {
procs.computeIfAbsent(entry.getValue(), ExternalReaderProcess::of)));
}
}
if (settings.traceMode() != null) {
setTraceMode(settings.traceMode());
}
return this;
}

Expand All @@ -543,6 +560,7 @@ public Evaluator build() {
timeout,
moduleCacheDir,
dependencies,
outputFormat);
outputFormat,
traceMode);
}
}
7 changes: 5 additions & 2 deletions pkl-core/src/main/java/org/pkl/core/EvaluatorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.graalvm.polyglot.Context;
import org.pkl.core.ast.ConstantValueNode;
import org.pkl.core.ast.internal.ToStringNodeGen;
import org.pkl.core.evaluatorSettings.TraceMode;
import org.pkl.core.http.HttpClient;
import org.pkl.core.module.ModuleKeyFactory;
import org.pkl.core.module.ProjectDependenciesManager;
Expand Down Expand Up @@ -80,7 +81,8 @@ public EvaluatorImpl(
@Nullable Duration timeout,
@Nullable Path moduleCacheDir,
@Nullable DeclaredDependencies projectDependencies,
@Nullable String outputFormat) {
@Nullable String outputFormat,
@Nullable TraceMode traceMode) {

securityManager = manager;
frameTransformer = transformer;
Expand Down Expand Up @@ -108,7 +110,8 @@ public EvaluatorImpl(
projectDependencies == null
? null
: new ProjectDependenciesManager(
projectDependencies, moduleResolver, securityManager)));
projectDependencies, moduleResolver, securityManager),
traceMode));
});
this.timeout = timeout;
// NOTE: would probably make sense to share executor between evaluators
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
Expand All @@ -19,12 +19,17 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.pkl.core.ast.ExpressionNode;
import org.pkl.core.evaluatorSettings.TraceMode;
import org.pkl.core.runtime.*;

public final class TraceNode extends ExpressionNode {
@Child private ExpressionNode valueNode;

private final VmValueRenderer renderer = VmValueRenderer.singleLine(1000000);
private static final int MAX_RENDERER_LENGTH = 1000000;

private final VmValueRenderer singleLineRenderer =
VmValueRenderer.singleLine(MAX_RENDERER_LENGTH);
private final VmValueRenderer multiLineRenderer = VmValueRenderer.multiLine(MAX_RENDERER_LENGTH);

public TraceNode(SourceSection sourceSection, ExpressionNode valueNode) {
super(sourceSection);
Expand All @@ -40,6 +45,10 @@ public Object executeGeneric(VirtualFrame frame) {

@TruffleBoundary
private void doTrace(Object value, VmContext context) {
// If traces are disabled, returns early.
if (context.getTraceMode() == TraceMode.HIDDEN) {
return;
}
if (value instanceof VmObjectLike objectLike) {
try {
objectLike.force(true, true);
Expand All @@ -48,7 +57,12 @@ private void doTrace(Object value, VmContext context) {
}

var sourceSection = valueNode.getSourceSection();
var renderedValue = renderer.render(value);
String renderedValue;
if (context.getTraceMode() == TraceMode.PRETTY) {
renderedValue = multiLineRenderer.render(value);
} else {
renderedValue = singleLineRenderer.render(value);
}
var message =
(sourceSection.isAvailable() ? sourceSection.getCharacters() : "<value")
+ " = "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public record PklEvaluatorSettings(
@Nullable Path rootDir,
@Nullable Http http,
@Nullable Map<String, ExternalReader> externalModuleReaders,
@Nullable Map<String, ExternalReader> externalResourceReaders) {
@Nullable Map<String, ExternalReader> externalResourceReaders,
@Nullable TraceMode traceMode) {

/** Initializes a {@link PklEvaluatorSettings} from a raw object representation. */
@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -104,6 +105,7 @@ public static PklEvaluatorSettings parse(
Entry::getKey, entry -> ExternalReader.parse(entry.getValue())));

var color = (String) pSettings.get("color");
var traceMode = (String) pSettings.get("traceMode");

return new PklEvaluatorSettings(
(Map<String, String>) pSettings.get("externalProperties"),
Expand All @@ -118,7 +120,8 @@ public static PklEvaluatorSettings parse(
rootDir,
Http.parse((Value) pSettings.get("http")),
externalModuleReaders,
externalResourceReaders);
externalResourceReaders,
traceMode == null ? null : TraceMode.valueOf(traceMode.toUpperCase()));
}

public record Http(@Nullable Proxy proxy) {
Expand Down Expand Up @@ -213,7 +216,8 @@ && arePatternsEqual(allowedResources, that.allowedResources)
&& Objects.equals(moduleCacheDir, that.moduleCacheDir)
&& Objects.equals(timeout, that.timeout)
&& Objects.equals(rootDir, that.rootDir)
&& Objects.equals(http, that.http);
&& Objects.equals(http, that.http)
&& Objects.equals(traceMode, that.traceMode);
}

private int hashPatterns(@Nullable List<Pattern> patterns) {
Expand All @@ -231,7 +235,15 @@ private int hashPatterns(@Nullable List<Pattern> patterns) {
public int hashCode() {
var result =
Objects.hash(
externalProperties, env, color, noCache, moduleCacheDir, timeout, rootDir, http);
externalProperties,
env,
color,
noCache,
moduleCacheDir,
timeout,
rootDir,
http,
traceMode);
result = 31 * result + hashPatterns(allowedModules);
result = 31 * result + hashPatterns(allowedResources);
return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright © 2025 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pkl.core.evaluatorSettings;

/** Dictates the rendering of calls to the trace() method within Pkl. */
public enum TraceMode {
/** All trace() calls will not be emitted to stderr. */
HIDDEN,
/** All structures passed to trace() will be emitted on a single line. */
DEFAULT,
/** All structures passed to trace() will be indented and emitted across multiple lines. */
PRETTY
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
Expand Down Expand Up @@ -72,7 +72,8 @@ protected void packMapHeader(
@Nullable Object valueC,
@Nullable Object valueD,
@Nullable Object valueE,
@Nullable Object valueF)
@Nullable Object valueF,
@Nullable Object valueG)
throws IOException {
packer.packMapHeader(
size
Expand All @@ -90,7 +91,8 @@ protected void packMapHeader(
+ (valueC != null ? 1 : 0)
+ (valueD != null ? 1 : 0)
+ (valueE != null ? 1 : 0)
+ (valueF != null ? 1 : 0));
+ (valueF != null ? 1 : 0)
+ (valueG != null ? 1 : 0));
}

protected void packKeyValue(String name, @Nullable Integer value) throws IOException {
Expand Down
Loading