kclprojects

package
v1.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package kclprojects lets one forge project's KCL import another forge project's KCL package, at the version the importing project's Go module already pins.

The declaration

The importing project names the other project in its KCL module's kcl.mod, in a table forge owns:

# deploy/kcl/kcl.mod
[forge_projects]
reliant = { module = "github.com/reliant-labs/reliant" }

and its KCL then says `import reliant.workloads as rwl`. `subdir` names the KCL package root inside the module and defaults to `deploy/kcl`, where every forge project keeps it. There is no version field, on purpose: see below.

Where the version comes from: go.mod, and nowhere else

A project that imports another project's KCL almost always runs that project's code too — control-plane deploys reliant's binaries, and pins them with `require github.com/reliant-labs/reliant <version>` in go.mod. A second pin for the KCL (a kpm git dependency with its own ref, a vendored copy with its own provenance) is a second fact that can disagree with the first, and the failure it permits is the one this package exists to remove: the deployment describes one version of the workloads while the image runs another. So the KCL comes from exactly where the Go build's copy of that module comes from, following the go command's own rules:

  • a go.work `use` of the module wins — the workspace builds that directory;
  • then a go.work `replace`, then a go.mod `replace`: a directory target is read in place (a sibling checkout, in dev), a module target is read from the module cache at the replacement version;
  • otherwise the module cache, at the version go.mod requires — downloaded with `go mod download` when it is not there yet, and verified against the go.sum hash, so the bytes rendered are the bytes the pin names.

A module the go.mod does not require is refused: there is no pin to resolve. (A project whose Go code does not depend on the other project has no Go pin to share, and declares a kpm git dependency in [dependencies] instead — that IS its one pin.)

Why a table of its own, and not an entry in [dependencies]

kpm owns [dependencies]. It parses every entry there as a git, OCI, local or registry source, and an entry in a shape it does not know becomes a dependency with no source at all, which it then tries to fetch — so every render, and the `kcl` CLI and the KCL language server reading the same file, would fail on it. kpm ignores a top-level table it does not know, so [forge_projects] is invisible to it, and forge supplies each package to the evaluation as an external package (`-E <name>=<dir>`), exactly as it supplies `import forge` itself (internal/kclvendor). A [dependencies] entry spelled with `forge_project =` or `module =` is refused with the move to make.

Version skew is refused

An imported project's `import forge` resolves to the IMPORTING render's forge module — there is one `forge` package per evaluation, and it is the rendering binary's. So the imported KCL is only evaluated against the schema it was written for when both projects pin the same forge. When their forge.yaml `forge_version` pins differ, Resolve refuses and names both pins: otherwise a field one side's schema added or removed surfaces as a KCL error at the imported project's line numbers, which reads as a bug in that project rather than as a version problem. FORGE_ALLOW_VERSION_SKEW (internal/forgecompat) overrides, as it does for the binary-vs-pin skew.

Names

An external package's name is global to the evaluation, so a name that would shadow something is refused: `forge`, `kcl_plugin`, a KCL system module, a file or directory at the importing package's root, or a kpm dependency of the same name. Inside the imported package, its own absolute imports (`import config_gen`) resolve against ITS root, not the importer's, so two projects that both keep a `config_gen.k` do not collide.

The imported project's own [forge_projects] are resolved too, against the ROOT project's go.mod — one build, one version of each module. An imported package's kpm [dependencies] are not resolved (forge evaluates the package in place), so a non-empty one is refused rather than left to fail as an unresolvable import.

Index

Constants

View Source
const DefaultSubdir = "deploy/kcl"

DefaultSubdir is where a forge project keeps its KCL package root.

View Source
const TableName = "forge_projects"

TableName is the kcl.mod table that declares forge-project imports.

Variables

This section is empty.

Functions

func ExternalPkgArgs

func ExternalPkgArgs(rs []Resolved) []string

ExternalPkgArgs is the `name=dir` external-package binding for each resolved import, sorted by name.

func FindKCLRoot

func FindKCLRoot(p string) string

FindKCLRoot returns the directory of the kcl.mod that owns path (a .k file or a package directory), walking up. "" when there is none.

Types

type Import

type Import struct {
	// Name is the KCL package name: `import <Name>.workloads`.
	Name string `json:"name"`
	// Module is the Go module path the project is published as.
	Module string `json:"module"`
	// Subdir is the KCL package root inside the module (slash-separated).
	Subdir string `json:"subdir"`
	// DeclaredIn is the kcl.mod that declares it.
	DeclaredIn string `json:"declared_in"`
}

Import is one [forge_projects] entry, as declared.

type Resolved

type Resolved struct {
	Import
	// Version is the module version the KCL is read at. Empty when the
	// module resolves to a directory (a go.work `use`, a directory
	// `replace`): the go command builds whatever that directory holds, and
	// so does the render.
	Version string `json:"version,omitempty"`
	// Via names the declaration that decided the location, e.g.
	// "go.mod require github.com/x/y v1.2.3" or "go.mod replace => ../y".
	Via string `json:"via"`
	// ModuleDir is the module's root directory.
	ModuleDir string `json:"module_dir"`
	// Dir is the KCL package root: ModuleDir/Subdir.
	Dir string `json:"dir"`
	// ForgePin is the imported project's forge.yaml forge_version.
	ForgePin string `json:"forge_pin,omitempty"`
}

Resolved is an Import located on disk.

func Resolve

func Resolve(kclRoot string) ([]Resolved, error)

Resolve locates every forge project the KCL module rooted at kclRoot imports, directly or through another imported project. A kclRoot with no kcl.mod, or a kcl.mod with no [forge_projects], resolves to nothing and costs one file read — the common case for every project that imports none.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL