Gloat Ecosystem Tutorial¶
Gloat compiles YAMLScript, Clojure, or Glojure to Go source, native binaries, WebAssembly, and shared libraries.
Compilation Pipeline¶
The normal YAMLScript pipeline is:
The YAMLScript compiler produces portable Clojure that requires ys.v0 and
calls ys.v0/init. Gloat uses the source tree shipped by ys-v0-glj while
Glojure analyzes the application, then links the precompiled runtime loaders
from that module into the generated Go program.
Repositories¶
The main repositories in the build are:
gloathub/gloat— the compiler orchestration and output templates.gloathub/ys-v0-glj— patched portableys.v0sources, Glojure-native backends, and generated Go loaders.glojurelang/glojure— the Clojure-to-Go compiler and runtime.yaml/yamlscript— the YAMLScript compiler and publishedys.v0sources.makeplus/makes— repository-local tool and dependency management.
The runtime has its own release lifecycle. Gloat pins it with
YS-V0-GLJ-VERSION in common/common.mk; a Gloat release does not publish or
tag the runtime module.
Repository Layout¶
Important Gloat paths are:
gloat/
|-- bin/gloat Bash CLI entry point
|-- src/gloat.clj Compiler orchestration
|-- src/prune.clj Dependency graph and pruning
|-- template/ Generated Go module templates
|-- common/common.mk Pinned dependency versions
|-- util/make-do Build and release helpers
|-- ys/lg/ let-go runtime sources
`-- repos/ys-v0-glj/ Optional development checkout
Gloat no longer keeps copies of the YAMLScript Clojure, Glojure, or generated
Go runtime trees. Installed copies clone the pinned ys-v0-glj tag into
.cache/ys-v0-glj; a checkout at repos/ys-v0-glj takes precedence for local
development.
The standalone runtime repository contains:
ys-v0-glj/
|-- source/ Exact patched analysis sources
|-- ys/ Generated ys namespace loaders
|-- yamlscript/ Generated compatibility loaders
|-- babashka/ Go-native process and HTTP backends
|-- clojure/ Go-native JSON and walk loaders
|-- runtime/ Ordered Load function and manifests
|-- bb/runtime.clj Self-contained Babashka runtime
|-- src/ Hand-maintained Go backend sources
|-- patches/ Temporary upstream AOT patches
`-- script/generate Reproducible source and loader generation
Generated Go Modules¶
For a directory, binary, library, or WebAssembly output, Gloat:
- Compiles YAMLScript to portable Clojure.
- Copies
ys-v0-glj/sourceinto a temporary compiler workspace. - Rewrites and compiles the application namespace with Glojure.
- Copies only application loaders into the generated module.
- Renders
go.modand the appropriate Go entry point. - Links and requires the runtime namespaces the application loaders reach before requiring the application namespace.
The generated go.mod has this dependency shape:
require (
github.com/glojurelang/glojure GLOJURE-VERSION
github.com/gloathub/ys-v0-glj YS-V0-GLJ-VERSION
)
Setting GLOAT_EXTRA_GO_DIR to a directory copies that Go package tree into
the generated module as internal/<directory name>, so a build can ship hand
written Go packages next to the compiled loaders.
When repos/ys-v0-glj exists, Gloat adds a local replace pointing at that
development checkout. Cached runtime clones never produce a replace, so
generated modules otherwise resolve the pinned tag through the Go proxy.
Runtime Loading and Pruning¶
The normal templates blank-import the generated application package plus the
ys-v0-glj and Glojure stdlib namespaces the application loaders reach.
Gloat finds that set by following the namespace symbols in each loader
transitively, so a program that never touches the YS runtime links none of it,
while a YAMLScript program pulls in the ys.v0.* namespaces its compiled
form refers to, and what those require.
The requires run in the order recorded by runtime/namespaces.edn, and the
ENV, CWD, RUN and NS globals are set only when ys.v0.global and
ys.v0 are loaded.
Set GLOAT_YS_RUNTIME=all to link and require the whole runtime for programs
that reach namespaces only through strings built at run time.
With pruning enabled, Gloat analyzes references from the user loaders and the
runtime loaders in ys-v0-glj. It copies the retained runtime packages into
the generated module's internal tree and emits ordered imports and requires.
This keeps pruned programs independent of internal Gloat runtime copies while
allowing unused loader blocks to be removed.
Source Formats¶
Gloat can also stop before building Go:
-t cljemits the portable Clojure produced by YAMLScript.-t bbprependsys-v0-glj/bb/runtime.clj, producing a self-contained Babashka program with no run-time Java or Maven requirement.-t gljemits rewritten Glojure source.-t goemits the generated application loader.-t lguses theys/lgsource tree for the let-go engine.
Makes Bootstrap¶
Gloat and downstream projects use Makes to install pinned tools under
.cache/local/. The usual bootstrap is:
M := .cache/makes
$(shell [ -d $M ] || git clone -q https://github.com/makeplus/makes $M)
include $M/init.mk
Gloat includes modules for Babashka, Glojure, Go, and YAMLScript. Run
make path to install the declared tools and print an environment with their
paths.
Development¶
Run the normal suite with:
To work on the runtime module beside Gloat:
git clone https://github.com/gloathub/ys-v0-glj repos/ys-v0-glj
make -C repos/ys-v0-glj generate
make -C repos/ys-v0-glj test
make test
The runtime generator normally downloads the pinned
org.yamlscript/ys.v0 Clojars artifact. To test unpublished YAMLScript
sources, point it at the portable source tree:
Temporary AOT compatibility changes live in ys-v0-glj/patches and are
applied with zero fuzz before the Go-native backend sources are overlaid.
After changing the runtime, run make check-generated in that repository and
commit the source changes and generated loaders together.
Version Management¶
The dependency pins used in generated modules come from
common/common.mk:
common/gloat-vars.mk exposes the resolved versions and local checkout paths
to src/gloat.clj. Gloat renders those values into generated go.mod files.
Release the runtime module first when its code or generated loaders change.
After its tag is visible on the Go proxy, update YS-V0-GLJ-VERSION, validate
Gloat, and release Gloat separately.
Downstream Projects¶
Downstream Makes projects typically include gloat.mk, generate a committed
Go submodule, and tag that submodule independently. A generated directory can
also be built directly:
For local integration, keep the replace generated by Gloat. Before
publishing a downstream Go module, remove local replacements and verify that
both Glojure and ys-v0-glj resolve from the Go proxy.