Require global settings file to use pkl:settings (#477)

This is technically a breaking change, but follows the intended use-case
and documentation of settings.

* Require that the global settings file at `~/.pkl/settings.pkl`
amends stdlib module `pkl:settings`, or otherwise sets `output.value`
to an instance of `pkl.Settings`.
* Simplify the object mapping of `PklSettings.java`
This commit is contained in:
Daniel Chao
2024-05-07 07:49:00 -07:00
committed by GitHub
parent aeb17588b3
commit 21aa44cfc4
5 changed files with 19 additions and 19 deletions

View File

@@ -37,6 +37,7 @@ public final class PClassInfo<T> implements Serializable {
public static final URI pklBaseUri = URI.create("pkl:base");
public static final URI pklSemverUri = URI.create("pkl:semver");
public static final URI pklSettingsUri = URI.create("pkl:settings");
public static final URI pklProjectUri = URI.create("pkl:Project");
public static final PClassInfo<Void> Any = pklBaseClassInfo("Any", Void.class);
@@ -79,6 +80,8 @@ public final class PClassInfo<T> implements Serializable {
new PClassInfo<>("pkl.semver", "Version", PObject.class, pklSemverUri);
public static final PClassInfo<PObject> Project =
new PClassInfo<>("pkl.Project", "ModuleClass", PObject.class, pklProjectUri);
public static final PClassInfo<PObject> Settings =
new PClassInfo<>("pkl.settings", "ModuleClass", PObject.class, pklSettingsUri);
public static final PClassInfo<Object> Unavailable =
new PClassInfo<>("unavailable", "unavailable", Object.class, URI.create("pkl:unavailable"));

View File

@@ -15,13 +15,13 @@
*/
package org.pkl.core.runtime;
import java.net.URI;
import static org.pkl.core.PClassInfo.pklSettingsUri;
public final class SettingsModule extends StdLibModule {
private static final VmTyped instance = VmUtils.createEmptyModule();
static {
loadModule(URI.create("pkl:settings"), instance);
loadModule(pklSettingsUri, instance);
}
private SettingsModule() {}

View File

@@ -23,7 +23,6 @@ import org.pkl.core.*;
import org.pkl.core.module.ModuleKeyFactories;
import org.pkl.core.resource.ResourceReaders;
import org.pkl.core.runtime.VmEvalException;
import org.pkl.core.runtime.VmExceptionBuilder;
import org.pkl.core.util.IoUtils;
import org.pkl.core.util.Nullable;
@@ -73,23 +72,16 @@ public final class PklSettings {
.addResourceReader(ResourceReaders.environmentVariable())
.addEnvironmentVariables(System.getenv())
.build()) {
var module = evaluator.evaluate(moduleSource);
return parseSettings(module, moduleSource);
var module = evaluator.evaluateOutputValueAs(moduleSource, PClassInfo.Settings);
return parseSettings(module);
}
}
private static PklSettings parseSettings(PModule module, ModuleSource location)
throws VmEvalException {
private static PklSettings parseSettings(PObject module) throws VmEvalException {
// can't use object mapping in pkl-core, so map manually
var editor = module.getPropertyOrNull("editor");
if (!(editor instanceof PObject pObject)) {
throw new VmExceptionBuilder().evalError("invalidSettingsFile", location.getUri()).build();
}
var urlScheme = pObject.getPropertyOrNull("urlScheme");
if (!(urlScheme instanceof String string)) {
throw new VmExceptionBuilder().evalError("invalidSettingsFile", location.getUri()).build();
}
return new PklSettings(new Editor(string));
var editor = (PObject) module.getProperty("editor");
var urlScheme = (String) editor.getProperty("urlScheme");
return new PklSettings(new Editor(urlScheme));
}
/** Returns the editor for viewing and editing Pkl files. */

View File

@@ -700,9 +700,6 @@ Refusing to load module `{0}` because it does not match any entry in the module
insufficientModuleTrustLevel=\
Refusing to import module `{0}` because importing module `{1}` has an insufficient trust level.
invalidSettingsFile=\
Pkl settings file `{0}` must start with `amends "pkl:settings"`.
invalidRegexSyntax=\
Syntax error in regex `{0}`: {1}

View File

@@ -2,6 +2,7 @@ package org.pkl.core.settings
import java.nio.file.Path
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatCode
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import org.pkl.commons.createParentDirectories
@@ -67,6 +68,13 @@ class PklSettingsTest {
checkEquals(Editor.VS_CODE, module.getProperty("vsCode") as PObject)
}
@Test
fun `invalid settings file`(@TempDir tempDir: Path) {
val settingsFile = tempDir.resolve("settings.pkl").apply { writeString("foo = 1") }
assertThatCode { PklSettings.loadFromPklHomeDir(tempDir) }
.hasMessageContaining("Expected `output.value` of module `${settingsFile.toUri()}` to be of type `pkl.settings`, but got type `settings`.")
}
private fun checkEquals(expected: Editor, actual: PObject) {
assertThat(actual.getProperty("urlScheme") as String).isEqualTo(expected.urlScheme)
}