Format Markdown with prettier in make fmt (closes #43)
check / check (push) Failing after 3s
check / check (push) Failing after 3s
script/fmt and script/fmt-check now run prettier on every Markdown file after their Go steps, as the standard scripts from sneak/prompts at dd4027b do. script/bootstrap gains the standard node, nvm and yarn install next to its goimports install, and the last Dockerfile stage copies package.json and yarn.lock before running it. .prettierrc, .prettierignore and yarn.lock are the standard copies. package.json is the standard one without its licence field and marked private, because this repo's licence is the WTFPL. .dockerignore keeps the log of a failed yarn install out of the build context. README.md and TODO.md are reformatted once with it; REPO_POLICIES.md already matched. Model: opus-5-5
This commit was merged in pull request #44.
This commit is contained in:
+3
-1
@@ -72,10 +72,12 @@
|
|||||||
**/*.sublime-*
|
**/*.sublime-*
|
||||||
|
|
||||||
# This repository's host-built artifacts: the example program's binary,
|
# This repository's host-built artifacts: the example program's binary,
|
||||||
# test binaries and coverage output.
|
# test binaries, coverage output, and the log yarn writes when an install
|
||||||
|
# fails.
|
||||||
/cmd/example/example
|
/cmd/example/example
|
||||||
/*.test
|
/*.test
|
||||||
/*.out
|
/*.out
|
||||||
|
/yarn-error.log
|
||||||
|
|
||||||
# aider's files, among them a config file that can hold an API key.
|
# aider's files, among them a config file that can hold an API key.
|
||||||
**/.aider*
|
**/.aider*
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
yarn.lock
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"proseWrap": "always"
|
||||||
|
}
|
||||||
+1
-1
@@ -31,6 +31,6 @@ COPY --from=lint /src/go.sum /dev/null
|
|||||||
COPY --from=test /src/go.sum /dev/null
|
COPY --from=test /src/go.sum /dev/null
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY script/ script/
|
COPY script/ script/
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum package.json yarn.lock ./
|
||||||
RUN script/bootstrap
|
RUN script/bootstrap
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
simplelog is an opinionated logging package designed to facilitate easy and
|
simplelog is an opinionated logging package designed to facilitate easy and
|
||||||
structured logging in Go applications with an absolute minimum of
|
structured logging in Go applications with an absolute minimum of boilerplate.
|
||||||
boilerplate.
|
|
||||||
|
|
||||||
The idea is that you can add a single import line which replaces the
|
The idea is that you can add a single import line which replaces the stdlib
|
||||||
stdlib `log/slog` default handler, and solve the 90% case for logging.
|
`log/slog` default handler, and solve the 90% case for logging.
|
||||||
|
|
||||||
## Current Status
|
## Current Status
|
||||||
|
|
||||||
@@ -18,16 +17,15 @@ Released v1.0.0 2024-06-14. Works as intended. No known bugs.
|
|||||||
- if output is a tty, outputs pretty color logs
|
- if output is a tty, outputs pretty color logs
|
||||||
- if output is not a tty, outputs json
|
- if output is not a tty, outputs json
|
||||||
- supports delivering each log message via a webhook
|
- supports delivering each log message via a webhook
|
||||||
- emits every `slog` attribute: those passed to a log call, those
|
- emits every `slog` attribute: those passed to a log call, those accumulated
|
||||||
accumulated with `WithAttrs`, and those qualified by `WithGroup`.
|
with `WithAttrs`, and those qualified by `WithGroup`. `slog.Group` values
|
||||||
`slog.Group` values nest, and `slog.LogValuer` values are resolved. In
|
nest, and `slog.LogValuer` values are resolved. In json output attributes are
|
||||||
json output attributes are object fields (groups become nested objects);
|
object fields (groups become nested objects); in console output they are
|
||||||
in console output they are appended as `key=value` pairs, with grouped
|
appended as `key=value` pairs, with grouped keys written as `group.key=value`.
|
||||||
keys written as `group.key=value`. See
|
See [Attribute output](#attribute-output) for the details worth knowing
|
||||||
[Attribute output](#attribute-output) for the details worth knowing
|
- reports a record that could not be delivered as an error from the handler's
|
||||||
- reports a record that could not be delivered as an error from the
|
`Handle` method. See [When delivery fails](#when-delivery-fails) for how to
|
||||||
handler's `Handle` method. See
|
receive it
|
||||||
[When delivery fails](#when-delivery-fails) for how to receive it
|
|
||||||
|
|
||||||
## Planned Features
|
## Planned Features
|
||||||
|
|
||||||
@@ -49,9 +47,9 @@ go get sneak.berlin/go/simplelog
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Below is an example of how to use SimpleLog in a Go application. This
|
Below is an example of how to use SimpleLog in a Go application. This example is
|
||||||
example is provided in the form of a `main.go` file, which demonstrates
|
provided in the form of a `main.go` file, which demonstrates logging at various
|
||||||
logging at various levels using structured logging syntax.
|
levels using structured logging syntax.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -73,63 +71,58 @@ func main() {
|
|||||||
## Attribute output
|
## Attribute output
|
||||||
|
|
||||||
Attributes reach every handler: the ones passed to the log call, the ones
|
Attributes reach every handler: the ones passed to the log call, the ones
|
||||||
accumulated with `WithAttrs`, and the ones qualified by the groups open at
|
accumulated with `WithAttrs`, and the ones qualified by the groups open at the
|
||||||
the time they were attached. `slog.Group` values nest, and
|
time they were attached. `slog.Group` values nest, and `slog.LogValuer` values
|
||||||
`slog.LogValuer` values are resolved to the value they stand for. A few
|
are resolved to the value they stand for. A few behaviours are worth knowing
|
||||||
behaviours are worth knowing before you rely on them.
|
before you rely on them.
|
||||||
|
|
||||||
**Your values are never modified.** Whatever you log is read and rendered,
|
**Your values are never modified.** Whatever you log is read and rendered, never
|
||||||
never written to. A map or a slice you pass to `slog.Any` comes back from
|
written to. A map or a slice you pass to `slog.Any` comes back from the logger
|
||||||
the logger exactly as you handed it over, even when a group later uses the
|
exactly as you handed it over, even when a group later uses the same key.
|
||||||
same key.
|
|
||||||
|
|
||||||
**Durations are nanoseconds in json, and readable on the console.** The
|
**Durations are nanoseconds in json, and readable on the console.** The json and
|
||||||
json and webhook payloads emit a `slog.Duration` as a number of
|
webhook payloads emit a `slog.Duration` as a number of nanoseconds, matching
|
||||||
nanoseconds, matching `slog.NewJSONHandler`, so a consumer can compare and
|
`slog.NewJSONHandler`, so a consumer can compare and aggregate the field without
|
||||||
aggregate the field without parsing it. The console line emits the same
|
parsing it. The console line emits the same duration as `3s`, matching
|
||||||
duration as `3s`, matching `slog.NewTextHandler`, because a person reads
|
`slog.NewTextHandler`, because a person reads it.
|
||||||
it.
|
|
||||||
|
|
||||||
**The json payload is an object, with the consequences an object has.**
|
**The json payload is an object, with the consequences an object has.** The
|
||||||
The record's own fields are named `Time`, `Level`, `Message` and `PC`, and
|
record's own fields are named `Time`, `Level`, `Message` and `PC`, and they own
|
||||||
they own those names: an attribute keyed after one of them is dropped from
|
those names: an attribute keyed after one of them is dropped from the json and
|
||||||
the json and webhook output. A key logged more than once keeps its last
|
webhook output. A key logged more than once keeps its last value there for the
|
||||||
value there for the same reason, with one exception: when both are
|
same reason, with one exception: when both are `slog.Group` values sharing a
|
||||||
`slog.Group` values sharing a key, the two groups are merged into one
|
key, the two groups are merged into one object holding the members of both,
|
||||||
object holding the members of both, rather than the second replacing the
|
rather than the second replacing the first. Neither the collision nor the merge
|
||||||
first. Neither the collision nor the merge applies to the console output,
|
applies to the console output, which is a line of text: every pair appears, in
|
||||||
which is a line of text: every pair appears, in order. If you need a field
|
order. If you need a field called `message`, pick a key that does not collide -
|
||||||
called `message`, pick a key that does not collide - the collision is
|
the collision is silent.
|
||||||
silent.
|
|
||||||
|
|
||||||
**Empty things follow the `slog.Handler` contract.** An empty `Attr` is
|
**Empty things follow the `slog.Handler` contract.** An empty `Attr` is ignored,
|
||||||
ignored, an empty group is elided along with its key, a group with an
|
an empty group is elided along with its key, a group with an empty key is
|
||||||
empty key is inlined into its parent, and `WithGroup("")` returns the
|
inlined into its parent, and `WithGroup("")` returns the handler unchanged.
|
||||||
handler unchanged.
|
|
||||||
|
|
||||||
## When delivery fails
|
## When delivery fails
|
||||||
|
|
||||||
Every handler returns an error from `Handle` when it could not deliver
|
Every handler returns an error from `Handle` when it could not deliver the
|
||||||
the record:
|
record:
|
||||||
|
|
||||||
- `ConsoleHandler` and `JSONHandler` return the error from their write to
|
- `ConsoleHandler` and `JSONHandler` return the error from their write to
|
||||||
stdout, wrapped, so `errors.Is` still matches the original
|
stdout, wrapped, so `errors.Is` still matches the original
|
||||||
- `WebhookHandler` returns an error when the request fails, and also when
|
- `WebhookHandler` returns an error when the request fails, and also when the
|
||||||
the server answers with a status outside 2xx, a redirect included,
|
server answers with a status outside 2xx, a redirect included, since it does
|
||||||
since it does not follow redirects. A request that has not finished
|
not follow redirects. A request that has not finished after 5 seconds fails
|
||||||
after 5 seconds fails with a timeout error, so a webhook server that
|
with a timeout error, so a webhook server that never answers holds up a log
|
||||||
never answers holds up a log call for 5 seconds at most
|
call for 5 seconds at most
|
||||||
- `MultiplexHandler`, which simplelog installs as the default, passes the
|
- `MultiplexHandler`, which simplelog installs as the default, passes the record
|
||||||
record to every handler it holds even after one of them fails, then
|
to every handler it holds even after one of them fails, then returns all their
|
||||||
returns all their errors joined with `errors.Join` (nil if none failed)
|
errors joined with `errors.Join` (nil if none failed)
|
||||||
|
|
||||||
`slog.Info`, `slog.Error` and the other `slog.Logger` methods throw that
|
`slog.Info`, `slog.Error` and the other `slog.Logger` methods throw that error
|
||||||
error away. That is how `log/slog` works, and simplelog cannot change it.
|
away. That is how `log/slog` works, and simplelog cannot change it. To find out
|
||||||
To find out whether a record was delivered, build a `slog.Record` and pass
|
whether a record was delivered, build a `slog.Record` and pass it to the handler
|
||||||
it to the handler yourself, for example
|
yourself, for example `slog.Default().Handler().Handle(ctx, record)`, then check
|
||||||
`slog.Default().Handler().Handle(ctx, record)`, then check the error it
|
the error it returns. Console output takes the file and line from the record's
|
||||||
returns. Console output takes the file and line from the record's `PC`,
|
`PC`, which you set with `runtime.Callers` as the `log/slog` documentation
|
||||||
which you set with `runtime.Callers` as the `log/slog` documentation
|
|
||||||
shows. A record whose `PC` is zero prints `???:0` instead.
|
shows. A record whose `PC` is zero prints `???:0` instead.
|
||||||
|
|
||||||
## Entrypoints
|
## Entrypoints
|
||||||
@@ -143,8 +136,10 @@ alpine. We provide:
|
|||||||
|
|
||||||
- `script/bootstrap` — install all dependencies (go if missing, goimports with
|
- `script/bootstrap` — install all dependencies (go if missing, goimports with
|
||||||
`go install` at a pinned commit unless the installed one already reports the
|
`go install` at a pinned commit unless the installed one already reports the
|
||||||
pinned version, then `go mod download`); golangci-lint is not installed,
|
pinned version, then `go mod download`; node through nvm at a pinned version
|
||||||
since it runs only in Docker
|
if node is missing, yarn at a pinned version if it is missing, then the
|
||||||
|
`prettier` that `package.json` and `yarn.lock` pin); golangci-lint is not
|
||||||
|
installed, since it runs only in Docker
|
||||||
- `script/setup` — set up the repo for development after a fresh clone: runs
|
- `script/setup` — set up the repo for development after a fresh clone: runs
|
||||||
`script/bootstrap`, then `script/install-precommit`
|
`script/bootstrap`, then `script/install-precommit`
|
||||||
- `script/projectname` — output the project name (our own extension); used by
|
- `script/projectname` — output the project name (our own extension); used by
|
||||||
@@ -152,23 +147,23 @@ alpine. We provide:
|
|||||||
- `script/test` — run the test suite under the race detector in Docker by
|
- `script/test` — run the test suite under the race detector in Docker by
|
||||||
building only the `test` stage of the `Dockerfile`, without the build cache,
|
building only the `test` stage of the `Dockerfile`, without the build cache,
|
||||||
so every run tests; the image is tagged `simplelog-test`
|
so every run tests; the image is tagged `simplelog-test`
|
||||||
- `script/lint` — run golangci-lint in Docker by building only the `lint`
|
- `script/lint` — run golangci-lint in Docker by building only the `lint` stage
|
||||||
stage of the `Dockerfile`, without the build cache, so every run lints; the
|
of the `Dockerfile`, without the build cache, so every run lints; the image is
|
||||||
image is tagged `simplelog-lint`
|
tagged `simplelog-lint`
|
||||||
- `script/fmt` — format all files (writes) with the goimports that
|
- `script/fmt` — format all files (writes): Go with the goimports that
|
||||||
`script/bootstrap` installs
|
`script/bootstrap` installs, then every `*.md` file with `prettier`
|
||||||
- `script/fmt-check` — check formatting (read-only); fails if `gofmt -l`
|
- `script/fmt-check` — check formatting (read-only); fails if `gofmt -l` reports
|
||||||
reports files
|
files, or if `prettier` would change any `*.md` file
|
||||||
- `script/check` — run all checks: `test`, `lint`, `fmt-check` (our own
|
- `script/check` — run all checks: `test`, `lint`, `fmt-check` (our own
|
||||||
extension)
|
extension)
|
||||||
- `script/docker` — build the Docker image without the build cache, tagged
|
- `script/docker` — build the Docker image without the build cache, tagged via
|
||||||
via `script/projectname` (byte-identical across repos); it also passes the
|
`script/projectname` (byte-identical across repos); it also passes the output
|
||||||
output of `git describe` as the `VERSION` build argument, which is ignored
|
of `git describe` as the `VERSION` build argument, which is ignored because
|
||||||
because this `Dockerfile` does not declare it
|
this `Dockerfile` does not declare it
|
||||||
- `script/cibuild` — what CI runs: `script/bootstrap`, then `script/check`,
|
- `script/cibuild` — what CI runs: `script/bootstrap`, then `script/check`, then
|
||||||
then the same image build as `script/docker` (byte-identical across repos)
|
the same image build as `script/docker` (byte-identical across repos)
|
||||||
- `script/precommit` — run by the git pre-commit hook (our own extension);
|
- `script/precommit` — run by the git pre-commit hook (our own extension); runs
|
||||||
runs a `go mod tidy` guard, then `script/check`
|
a `go mod tidy` guard, then `script/check`
|
||||||
- `script/install-precommit` — installs the git pre-commit hook (our own
|
- `script/install-precommit` — installs the git pre-commit hook (our own
|
||||||
extension); `make hooks` shims to it
|
extension); `make hooks` shims to it
|
||||||
|
|
||||||
|
|||||||
@@ -1,86 +1,89 @@
|
|||||||
# Workflow
|
# Workflow
|
||||||
|
|
||||||
* branch (from `main`)
|
- branch (from `main`)
|
||||||
* do the work in Next Step
|
- do the work in Next Step
|
||||||
* move Next Step to the top of Completed Steps
|
- move Next Step to the top of Completed Steps
|
||||||
* move the top item of Future Steps into Next Step
|
- move the top item of Future Steps into Next Step
|
||||||
* commit (`TODO.md` changes in the same commit as the work)
|
- commit (`TODO.md` changes in the same commit as the work)
|
||||||
* merge to `main` if the branch is not protected, otherwise open a PR
|
- merge to `main` if the branch is not protected, otherwise open a PR
|
||||||
* push
|
- push
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
|
|
||||||
1.0+
|
1.0+
|
||||||
|
|
||||||
Tagged v1.0.0 (2024-06-14) and 1.0.1 (2026-02-08). In post-1.0
|
Tagged v1.0.0 (2024-06-14) and 1.0.1 (2026-02-08). In post-1.0 maintenance; the
|
||||||
maintenance; the library is referenced by the Go styleguide.
|
library is referenced by the Go styleguide.
|
||||||
|
|
||||||
# Next Step
|
# Next Step
|
||||||
|
|
||||||
Restructure README.md into the standard sections: Description, Getting
|
Restructure README.md into the standard sections: Description, Getting Started,
|
||||||
Started, Rationale, Design, TODO, License, Author
|
Rationale, Design, TODO, License, Author
|
||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
* 2026-10-06: re-vendored the standard files from `sneak/prompts` at
|
- 2026-10-06: `make fmt` and `make fmt-check` also format Markdown, with
|
||||||
commit `dd4027b`: `REPO_POLICIES.md`, the CI workflow, `.gitignore`,
|
`prettier` at the standard settings, pinned through `package.json` and
|
||||||
and `.golangci.yml` together with the lint stage's new image, plus
|
`yarn.lock`; `script/bootstrap` installs node and yarn for it, and the
|
||||||
the `.editorconfig` and `.dockerignore` this repo lacked, which
|
existing Markdown was formatted once
|
||||||
finishes the Makefile and policy-files step. `script/cibuild` now
|
- 2026-10-06: re-vendored the standard files from `sneak/prompts` at commit
|
||||||
bootstraps and runs `script/check` before building the image, the
|
`dd4027b`: `REPO_POLICIES.md`, the CI workflow, `.gitignore`, and
|
||||||
format check runs only on the host, the last `Dockerfile` stage runs
|
`.golangci.yml` together with the lint stage's new image, plus the
|
||||||
`script/bootstrap`, which installs goimports at a pinned commit
|
`.editorconfig` and `.dockerignore` this repo lacked, which finishes the
|
||||||
* 2026-10-06: a webhook request now times out after 5 seconds, so a
|
Makefile and policy-files step. `script/cibuild` now bootstraps and runs
|
||||||
server that never answers no longer stops every log call; the webhook
|
`script/check` before building the image, the format check runs only on the
|
||||||
handler also reads each answer to the end so its connection is reused
|
host, the last `Dockerfile` stage runs `script/bootstrap`, which installs
|
||||||
* 2026-10-06: the console handler takes the file and line it prints from
|
goimports at a pinned commit
|
||||||
the record's `PC` instead of counting stack frames, so they name the
|
- 2026-10-06: a webhook request now times out after 5 seconds, so a server that
|
||||||
call site whether the record came through a `slog.Logger` or straight
|
never answers no longer stops every log call; the webhook handler also reads
|
||||||
to `Handle`
|
each answer to the end so its connection is reused
|
||||||
* 2026-10-06: the tests run under the race detector, in Docker:
|
- 2026-10-06: the console handler takes the file and line it prints from the
|
||||||
`script/test` builds the `test` stage of the `Dockerfile`, which runs
|
record's `PC` instead of counting stack frames, so they name the call site
|
||||||
`go test -race`, and a new final stage makes a plain `docker build`
|
whether the record came through a `slog.Logger` or straight to `Handle`
|
||||||
run both the `lint` and `test` stages
|
- 2026-10-06: the tests run under the race detector, in Docker: `script/test`
|
||||||
* 2026-10-06: the linter runs only in Docker: `script/lint` builds the
|
builds the `test` stage of the `Dockerfile`, which runs `go test -race`, and a
|
||||||
`lint` stage of the `Dockerfile`, every `docker build` in `script/`
|
new final stage makes a plain `docker build` run both the `lint` and `test`
|
||||||
runs without the build cache, and `script/bootstrap` no longer
|
stages
|
||||||
installs golangci-lint
|
- 2026-10-06: the linter runs only in Docker: `script/lint` builds the `lint`
|
||||||
* 2026-10-06: every handler now returns a failed delivery from `Handle`
|
stage of the `Dockerfile`, every `docker build` in `script/` runs without the
|
||||||
instead of discarding it: console and JSON return the stdout write
|
build cache, and `script/bootstrap` no longer installs golangci-lint
|
||||||
error, the webhook also fails on a non-2xx answer, and the multiplex
|
- 2026-10-06: every handler now returns a failed delivery from `Handle` instead
|
||||||
delivers to every handler and returns their errors joined
|
of discarding it: console and JSON return the stdout write error, the webhook
|
||||||
* 2026-08-10: fixed every handler discarding slog attributes: console,
|
also fails on a non-2xx answer, and the multiplex delivers to every handler
|
||||||
JSON and webhook handlers now emit record attributes, accumulate
|
and returns their errors joined
|
||||||
WithAttrs without mutating the receiver, and honour WithGroup;
|
- 2026-08-10: fixed every handler discarding slog attributes: console, JSON and
|
||||||
slog.Group values nest and LogValuer values are resolved; console
|
webhook handlers now emit record attributes, accumulate WithAttrs without
|
||||||
keys and values holding invalid UTF-8 are quoted
|
mutating the receiver, and honour WithGroup; slog.Group values nest and
|
||||||
* 2026-08-07: added canonical `.golangci.yml` (v2 schema), pinned the
|
LogValuer values are resolved; console keys and values holding invalid UTF-8
|
||||||
`Dockerfile` lint stage to golangci-lint v2.12.2 (tag+digest), and
|
are quoted
|
||||||
fixed all findings the v1→v2 jump surfaced without changing any
|
- 2026-08-07: added canonical `.golangci.yml` (v2 schema), pinned the
|
||||||
exported signatures or behavior
|
`Dockerfile` lint stage to golangci-lint v2.12.2 (tag+digest), and fixed all
|
||||||
- 2026-07-07 Adopted scripts-to-rule-them-all: `script/` entrypoints,
|
findings the v1→v2 jump surfaced without changing any exported signatures or
|
||||||
Makefile shims, README Entrypoints section
|
behavior
|
||||||
* 2026-02-08: fixed JSONHandler deadlock from recursive log.Println,
|
|
||||||
with regression test; tagged 1.0.1
|
* 2026-07-07 Adopted scripts-to-rule-them-all: `script/` entrypoints, Makefile
|
||||||
* 2024-06-14: 1.0 prep: lint and fmt enforced in Docker build, call
|
shims, README Entrypoints section
|
||||||
stack depth fix so log locations report correctly, example script,
|
|
||||||
removed non-building RELP code; tagged v1.0.0
|
- 2026-02-08: fixed JSONHandler deadlock from recursive log.Println, with
|
||||||
* 2024-05-22: module path moved to sneak.berlin/go/simplelog
|
regression test; tagged 1.0.1
|
||||||
* 2024-05-14: initial library: slog-based console, JSON, webhook, and
|
- 2024-06-14: 1.0 prep: lint and fmt enforced in Docker build, call stack depth
|
||||||
RELP handlers, MultiplexHandler, caller file/line info, UTC ISO
|
fix so log locations report correctly, example script, removed non-building
|
||||||
timestamps, level-colored output
|
RELP code; tagged v1.0.0
|
||||||
|
- 2024-05-22: module path moved to sneak.berlin/go/simplelog
|
||||||
|
- 2024-05-14: initial library: slog-based console, JSON, webhook, and RELP
|
||||||
|
handlers, MultiplexHandler, caller file/line info, UTC ISO timestamps,
|
||||||
|
level-colored output
|
||||||
|
|
||||||
# Future Steps
|
# Future Steps
|
||||||
|
|
||||||
* Delete the old plain TODO file once this TODO.md lands
|
- Delete the old plain TODO file once this TODO.md lands
|
||||||
* Add .aider.* to .gitignore and remove the stray aider artifacts from
|
- Add .aider.\* to .gitignore and remove the stray aider artifacts from the
|
||||||
the working tree
|
working tree
|
||||||
* Pick one tag scheme before the next release (v1.0.0 vs 1.0.1 are
|
- Pick one tag scheme before the next release (v1.0.0 vs 1.0.1 are inconsistent)
|
||||||
inconsistent)
|
- Tag v1.0.2, with the leading v, once the attribute fix lands, so consuming
|
||||||
* Tag v1.0.2, with the leading v, once the attribute fix lands, so
|
repos can move off pseudo-version pins in one step
|
||||||
consuming repos can move off pseudo-version pins in one step
|
- Fix RELP output to cache (from old TODO)
|
||||||
* Fix RELP output to cache (from old TODO)
|
- Re-add RELP delivery over TCP to remote rsyslog imrelp; removed 2024-06-14
|
||||||
* Re-add RELP delivery over TCP to remote rsyslog imrelp; removed
|
because it did not build (README planned feature)
|
||||||
2024-06-14 because it did not build (README planned feature)
|
- Add regex filtering for webhook logs (from old TODO)
|
||||||
* Add regex filtering for webhook logs (from old TODO)
|
- Better console output format (from old TODO)
|
||||||
* Better console output format (from old TODO)
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "3.8.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
+78
-1
@@ -2,11 +2,21 @@
|
|||||||
# script/bootstrap: install all dependencies needed to build and develop
|
# script/bootstrap: install all dependencies needed to build and develop
|
||||||
# this repo. Idempotent: every install is guarded by a check so already
|
# this repo. Idempotent: every install is guarded by a check so already
|
||||||
# installed tools are skipped. Base tooling comes from nix, apt, brew,
|
# installed tools are skipped. Base tooling comes from nix, apt, brew,
|
||||||
# or apk (detected in that order); assumes nothing is present.
|
# or apk (detected in that order); assumes nothing is present. Node is
|
||||||
|
# used directly if installed; otherwise it is installed at a pinned
|
||||||
|
# version via nvm (installing nvm itself first, from a hash-verified
|
||||||
|
# release archive, never curl | sh).
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|
||||||
|
# Pinned versions, 2026-07-06
|
||||||
|
NODE_VERSION="22.17.0"
|
||||||
|
NVM_VERSION="0.40.3"
|
||||||
|
# sha256 of https://github.com/nvm-sh/nvm/archive/refs/tags/v0.40.3.tar.gz
|
||||||
|
NVM_SHA256="5f4d6aaa04a177dc93c985e31dbc411ab6b8c6e1e21d8015dbc1372625fcd1d0"
|
||||||
|
YARN_VERSION="1.22.22"
|
||||||
|
|
||||||
# goimports from golang.org/x/tools v0.30.0, 2025-02-10: the last release
|
# goimports from golang.org/x/tools v0.30.0, 2025-02-10: the last release
|
||||||
# that Go 1.22, the Go of go.mod and the Dockerfile, can build.
|
# that Go 1.22, the Go of go.mod and the Dockerfile, can build.
|
||||||
GOIMPORTS_COMMIT="09747cdf594a7924dcecb506312be3bd6e437962"
|
GOIMPORTS_COMMIT="09747cdf594a7924dcecb506312be3bd6e437962"
|
||||||
@@ -81,6 +91,69 @@ ensure_goimports() {
|
|||||||
echo "goimports $GOIMPORTS_VERSION at $(command -v goimports)"
|
echo "goimports $GOIMPORTS_VERSION at $(command -v goimports)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# verify_sha256 <file> <expected-hash>
|
||||||
|
verify_sha256() {
|
||||||
|
if command -v sha256sum >/dev/null 2>&1; then
|
||||||
|
actual="$(sha256sum "$1" | cut -d' ' -f1)"
|
||||||
|
else
|
||||||
|
actual="$(shasum -a 256 "$1" | cut -d' ' -f1)"
|
||||||
|
fi
|
||||||
|
if [ "$actual" != "$2" ]; then
|
||||||
|
echo "bootstrap: sha256 mismatch for $1" >&2
|
||||||
|
echo " expected: $2" >&2
|
||||||
|
echo " actual: $actual" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# nvm is a bash script; run a command in a bash with nvm loaded
|
||||||
|
nvm_sh() {
|
||||||
|
bash -c ". \"\$HOME/.nvm/nvm.sh\" && $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_nvm() {
|
||||||
|
[ -s "$HOME/.nvm/nvm.sh" ] && return 0
|
||||||
|
# nvm prerequisites; nvm itself requires bash
|
||||||
|
if missing bash; then pkg_install bash bash bash bash; fi
|
||||||
|
if missing curl; then pkg_install curl curl curl curl; fi
|
||||||
|
if missing git; then pkg_install git git git git; fi
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
curl -fsSL -o "$tmp/nvm.tar.gz" \
|
||||||
|
"https://github.com/nvm-sh/nvm/archive/refs/tags/v${NVM_VERSION}.tar.gz"
|
||||||
|
verify_sha256 "$tmp/nvm.tar.gz" "$NVM_SHA256"
|
||||||
|
mkdir -p "$HOME/.nvm"
|
||||||
|
tar -xzf "$tmp/nvm.tar.gz" -C "$HOME/.nvm" --strip-components=1
|
||||||
|
rm -rf "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_node() {
|
||||||
|
if ! missing node; then return 0; fi
|
||||||
|
ensure_nvm
|
||||||
|
nvm_sh "nvm install $NODE_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_yarn() {
|
||||||
|
if ! missing yarn; then return 0; fi
|
||||||
|
if ! missing corepack; then
|
||||||
|
corepack enable
|
||||||
|
corepack prepare "yarn@$YARN_VERSION" --activate
|
||||||
|
elif [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||||
|
nvm_sh "nvm use $NODE_VERSION >/dev/null && corepack enable && \
|
||||||
|
corepack prepare yarn@$YARN_VERSION --activate"
|
||||||
|
else
|
||||||
|
npm install -g "yarn@$YARN_VERSION"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_js_deps() {
|
||||||
|
if missing yarn && [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||||
|
nvm_sh "nvm use $NODE_VERSION >/dev/null && cd \"$ROOT\" && \
|
||||||
|
yarn install --frozen-lockfile"
|
||||||
|
else
|
||||||
|
yarn install --frozen-lockfile
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
|
|
||||||
@@ -93,6 +166,10 @@ main() {
|
|||||||
|
|
||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
|
ensure_node
|
||||||
|
ensure_yarn
|
||||||
|
install_js_deps
|
||||||
|
|
||||||
echo "bootstrap complete"
|
echo "bootstrap complete"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-4
@@ -1,17 +1,37 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# script/fmt: format all files (writes) with the goimports that
|
# script/fmt: format all files (writes): Go with the goimports that
|
||||||
# script/bootstrap installs. It puts Go's bin directory first on PATH, as
|
# script/bootstrap installs, then Markdown with prettier. It puts Go's bin
|
||||||
# script/bootstrap does, so it runs that goimports even when the directory
|
# directory first on PATH, as script/bootstrap does, so it runs that
|
||||||
# is not on the caller's PATH.
|
# goimports even when the directory is not on the caller's PATH.
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|
||||||
|
# Must match the pin in script/bootstrap.
|
||||||
|
NODE_VERSION="22.17.0"
|
||||||
|
|
||||||
|
# script/bootstrap installs node and yarn under nvm and leaves neither
|
||||||
|
# on the PATH of the shell that called it, so resolve the pinned
|
||||||
|
# toolchain here the way bootstrap's own install step does. nvm is a
|
||||||
|
# bash script, hence the subshell.
|
||||||
|
run_yarn() {
|
||||||
|
if command -v yarn >/dev/null 2>&1; then
|
||||||
|
exec yarn "$@"
|
||||||
|
fi
|
||||||
|
if [ ! -s "$HOME/.nvm/nvm.sh" ]; then
|
||||||
|
echo "fmt: no yarn; run script/bootstrap first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exec bash -c '. "$HOME/.nvm/nvm.sh" && nvm use "$1" >/dev/null &&
|
||||||
|
shift && exec yarn "$@"' bash "$NODE_VERSION" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
gobin="$(go env GOBIN)"
|
gobin="$(go env GOBIN)"
|
||||||
PATH="${gobin:-$(go env GOPATH)/bin}:$PATH"
|
PATH="${gobin:-$(go env GOPATH)/bin}:$PATH"
|
||||||
goimports -l -w .
|
goimports -l -w .
|
||||||
|
run_yarn run prettier --write '**/*.md' --tab-width 4 --prose-wrap always
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
+22
-1
@@ -1,10 +1,30 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# script/fmt-check: check formatting (read-only). Fails and lists the
|
# script/fmt-check: check formatting (read-only). Fails and lists the
|
||||||
# offending files if gofmt would reformat anything.
|
# offending files if gofmt would reformat any Go file; otherwise fails if
|
||||||
|
# prettier would reformat any Markdown file.
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|
||||||
|
# Must match the pin in script/bootstrap.
|
||||||
|
NODE_VERSION="22.17.0"
|
||||||
|
|
||||||
|
# script/bootstrap installs node and yarn under nvm and leaves neither
|
||||||
|
# on the PATH of the shell that called it, so resolve the pinned
|
||||||
|
# toolchain here the way bootstrap's own install step does. nvm is a
|
||||||
|
# bash script, hence the subshell.
|
||||||
|
run_yarn() {
|
||||||
|
if command -v yarn >/dev/null 2>&1; then
|
||||||
|
exec yarn "$@"
|
||||||
|
fi
|
||||||
|
if [ ! -s "$HOME/.nvm/nvm.sh" ]; then
|
||||||
|
echo "fmt-check: no yarn; run script/bootstrap first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exec bash -c '. "$HOME/.nvm/nvm.sh" && nvm use "$1" >/dev/null &&
|
||||||
|
shift && exec yarn "$@"' bash "$NODE_VERSION" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
unformatted="$(gofmt -l .)"
|
unformatted="$(gofmt -l .)"
|
||||||
@@ -13,6 +33,7 @@ main() {
|
|||||||
echo "$unformatted"
|
echo "$unformatted"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
run_yarn run prettier --check '**/*.md' --tab-width 4 --prose-wrap always
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
prettier@3.8.1:
|
||||||
|
version "3.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.8.1.tgz#edf48977cf991558f4fcbd8a3ba6015ba2a3a173"
|
||||||
|
integrity sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==
|
||||||
Reference in New Issue
Block a user