v0.35.2 lwconf, doc and deploy update
Package / arch (push) Canceled after 0s
Package / user (push) Canceled after 0s
Package / deb (push) Canceled after 0s
Package / freebsd (push) Canceled after 0s
Package / image (push) Canceled after 0s
Test / test (push) Canceled after 0s
Test / e2e (push) Canceled after 0s
Package / arch (push) Canceled after 0s
Package / user (push) Canceled after 0s
Package / deb (push) Canceled after 0s
Package / freebsd (push) Canceled after 0s
Package / image (push) Canceled after 0s
Test / test (push) Canceled after 0s
Test / e2e (push) Canceled after 0s
This commit is contained in:
1 parent
0b8701ec13
commit
de87b9a008
21 files changed
+255
-185
No files matched your search
@@ -31,8 +31,9 @@ function script(src, integrity) {
|
||||
}
|
||||
|
||||
// Engine's calls take objects or JSON text and return the engine's answer,
|
||||
// {value} or {error, path?, pipeline?, node?, key?}; dirs answers whether a
|
||||
// preset path is a directory, {"/var/log/app.log": false}
|
||||
// {value} or {error, path?, pipeline?, node?, key?, ask?}; ask is the path a
|
||||
// preset names whose kind dirs must answer: pass dirs {[ask]: true for a
|
||||
// directory, false for a file} and call again
|
||||
export class Engine {
|
||||
#api;
|
||||
constructor(api) { this.#api = api; }
|
||||
|
||||
@@ -72,10 +72,22 @@ test("load takes an engine a server sends as plain bytes", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
// A path neither ending in '/' nor holding a glob is a question, in a preset
|
||||
// or a pasted one, whose ask dirs answers
|
||||
test("a preset path of unknown kind is asked, and dirs answers it", () => {
|
||||
const path = { path: "/var/log/app.log" }, dirs = { "/var/log/app.log": false };
|
||||
const asked = engine.preset("tail", path);
|
||||
assert.deepEqual([asked.path, asked.ask, asked.value], ["path", "/var/log/app.log", undefined]);
|
||||
assert.match(asked.error, /^path: "\/var\/log\/app\.log": a directory or a file\? end a directory with \//);
|
||||
const pasted = engine.parse("lw -p tail:path=/var/log/app.log", "command");
|
||||
assert.deepEqual([pasted.path, pasted.ask], ["path", "/var/log/app.log"]);
|
||||
const { value: pipelines } = engine.preset("tail", path, dirs);
|
||||
assert.deepEqual(value(pipelines, 0, { role: "source", id: "file" }), { directory: "/var/log", pattern: "app.log", from: "end" });
|
||||
});
|
||||
|
||||
// The environment holds one pipeline, which a preset makes
|
||||
test("a preset's pipeline, a single file answered by dirs, reads back from every form", () => {
|
||||
const path = { path: "/var/log/app.log" }, dirs = { "/var/log/app.log": false };
|
||||
assert.deepEqual(engine.preset("tail", path), { error: "path: a directory or a file pattern?", path: "path" });
|
||||
const { value: pipelines } = engine.preset("serve", { ...path, allow: ["192.0.2.0/24", "198.51.100.7"] }, dirs);
|
||||
assert.deepEqual(value(pipelines, 0, { role: "source", id: "file" }), { directory: "/var/log", pattern: "app.log", from: "end" });
|
||||
assert.deepEqual(value(pipelines, 0, { role: "sink", id: "http" }, "acl.allow"), ["192.0.2.0/24", "198.51.100.7"]);
|
||||
@@ -166,7 +178,7 @@ test("a refused call answers why and where, and the engine keeps answering", ()
|
||||
[["edit", JSON.stringify([{ name: "p", plugin_sinks: [{ type: "tcp" }] }]),
|
||||
JSON.stringify({ op: "set", pipeline: 0, node: { role: "sink", id: "tcp" }, key: "port", values: ["x"] })],
|
||||
{ error: /port: not an integer$/, path: "pipelines[0].plugin_sinks[tcp].config.port", pipeline: 0, key: "port" }],
|
||||
[["emit", JSON.stringify([{ name: "p" }]), "command"], { error: /no sources defined/, path: "pipelines[0].plugin_sources" }],
|
||||
[["emit", JSON.stringify([{ name: "p" }]), "command"], { error: /plugin_sources: add a source; a pipeline needs at least one\n/, path: "pipelines[0].plugin_sources" }],
|
||||
[["emit", "[]", "yaml"], { error: /no form "yaml"/ }],
|
||||
[["edit", "[]", JSON.stringify({ op: "add_pipeline", nmae: "p" })], { error: /unknown field "nmae"/ }],
|
||||
[["edit", "[]", JSON.stringify({ op: "rename" })], { error: /^no op "rename" \(valid: add, add_pipeline/ }],
|
||||
|
||||
+7
-2
@@ -4,7 +4,7 @@
|
||||
// globalThis.lwconf for lwconf.js, calls taking strings and returning JSON,
|
||||
// {"value"} or {"error"} with its path, one in a pipeline placed on its node
|
||||
// and key, any other a preset's or flag's key. Pipelines are compose's JSON
|
||||
// form; dirs answers config.IsDir by path, {} leaving '/' and globs to tell.
|
||||
// form; dirs answers config.IsDir by path; an error's ask is a path to answer.
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -146,7 +146,8 @@ var edits = map[string]func(*compose.Composition, op) (compose.Node, error){
|
||||
}
|
||||
|
||||
// problem is where a problem, or a call's refusal, lies as far as the engine
|
||||
// knows: its path, and the pipeline, node and key Locate reads from it
|
||||
// knows: its path, and the pipeline, node and key Locate reads from it; ask
|
||||
// is a preset's path whose kind dirs must answer
|
||||
type problem struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
@@ -154,6 +155,7 @@ type problem struct {
|
||||
Node *compose.Node `json:"node,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Ask string `json:"ask,omitempty"`
|
||||
}
|
||||
|
||||
func place(err error) problem {
|
||||
@@ -161,6 +163,9 @@ func place(err error) problem {
|
||||
if ke, ok := errors.AsType[*config.KeyError](err); ok {
|
||||
p.Path = ke.Key
|
||||
}
|
||||
if pk, ok := errors.AsType[*config.PathKindError](err); ok {
|
||||
p.Ask = pk.Path
|
||||
}
|
||||
if pi, n, key, text, ok := compose.Locate(err); ok {
|
||||
p.Pipeline, p.Key, p.Text = &pi, key, text
|
||||
if n.Role != "" {
|
||||
|
||||
Reference in new issue
Block a user