Documentation
¶
Overview ¶
Package pkgmanager implements luascript's git/URL-based package manager: the `luascript pkg add/install/remove` subcommands. It is deliberately server-less — a package is just a git repository (or any URL git can clone). Dependencies are recorded in a JSON manifest and pinned to exact commits in a JSON lockfile so installs are reproducible.
The runtime side needs no cooperation: packages are cloned into `./lua_modules/<name>`, which `vm/loader.go` already searches via package.path. Installing a package and `require`-ing it are fully decoupled.
JSON (not a `.lsc` table) is used for both files because the tool must round-trip them — read, mutate one dependency, write back — and hand- emitting Lua table literals from Go would not preserve formatting or comments anyway. Humans edit the manifest; the tool owns the lockfile.
Index ¶
Constants ¶
const LockName = "luascript-lock.json"
LockName pins each resolved dependency to an exact commit.
const ManifestName = "luascript.json"
ManifestName is the per-project dependency manifest, human-editable.
const ModulesDir = "lua_modules"
ModulesDir is the install root. It matches the `./lua_modules/...` entries added to baseSearchPath in vm/loader.go.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Env ¶
Env carries everything the commands operate on: the project root (where the manifest, lockfile, and lua_modules/ live), the Fetcher to clone with, and an optional progress logger. A zero Logf means silent.
func (*Env) Add ¶
Add fetches a single package, installs it under lua_modules/<name>, and records it in both the manifest and the lockfile. name may be "" to derive it from the spec's last path segment.
func (*Env) Install ¶
Install fetches every dependency listed in the manifest that is not already present under lua_modules/. When the lockfile pins a commit for a package, that exact commit is checked out (reproducible install); otherwise the manifest's ref is resolved and written back to the lock.
type Fetcher ¶
Fetcher clones a package's source into destDir and reports the exact commit it landed on. destDir must not already exist; the fetcher creates it. The interface exists so command orchestration can be tested without a network or a git binary (see fakeFetcher in the tests).
type GitFetcher ¶
type GitFetcher struct{}
GitFetcher fetches by shelling out to the system `git`. It clones over https, checks out the requested ref, records HEAD, then deletes the `.git` directory so installed packages are plain source trees (smaller, and no nested-repo surprises for the consuming project's own VCS).
type Lock ¶
Lock is the parsed `luascript-lock.json`. It records, per installed package name, exactly what was fetched so a later `install` reproduces the same bytes regardless of where the upstream ref now points.
type LockEntry ¶
type LockEntry struct {
Source string `json:"source"`
Ref string `json:"ref,omitempty"`
URL string `json:"url"`
Commit string `json:"commit"`
}
LockEntry is one resolved dependency. Source is the `host/path` (no ref), Ref is the tag/branch/commit the user asked for ("" = default branch), URL is the clone URL git was given, and Commit is the exact resolved hash.
type Manifest ¶
type Manifest struct {
Name string `json:"name"`
Version string `json:"version"`
Dependencies map[string]string `json:"dependencies"`
}
Manifest is the parsed `luascript.json`. Dependencies maps a local package name (the name used in `require`) to a source spec of the form `host/path[@ref]` — e.g. "github.com/alice/router@v1.2.0".
func LoadManifest ¶
LoadManifest reads and parses the manifest at path. A missing file is not an error: it returns an empty manifest so `pkg add` can bootstrap a project that has none yet. The caller distinguishes "absent" via the second return.
type Spec ¶
type Spec struct {
Source string // host/path, no scheme, no ref
Ref string // tag/branch/commit, or "" for the default branch
}
Spec is a parsed dependency source: a `host/path` with an optional ref (tag, branch, or commit) after `@`. Example inputs:
github.com/alice/router -> Source=github.com/alice/router, Ref="" github.com/alice/router@v1.2.0 -> Ref="v1.2.0" gitlab.com/team/lib@main -> Ref="main"
A bare `@` or empty source is rejected. Schemes (`https://`, `git@...`) are intentionally not accepted here: the source is a stable identity, and the clone URL is derived from it via CloneURL so the same package always resolves to the same lockfile key.
func (Spec) CloneURL ¶
CloneURL is the https git URL derived from the source. We always clone over https so no SSH keys are required for public packages.
func (Spec) DefaultName ¶
DefaultName derives the package's local name (the `require` name) from the last path segment, with a trailing `.git` stripped if present.