106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
// Command locks refuses a TypeScript module that names packages beyond the SDK in its package.json and commits no
|
|
// package-lock.json (novox/hq ADR 0469 §5, issue 1868): the Node build module installs a module's own packages only
|
|
// from its committed lock, so such a module is refused by the builder and could not be delivered.
|
|
//
|
|
// go run . <catalogue root>
|
|
//
|
|
// Exits 1 on a finding. The packages that count are those the build module counts (mesh-build-node fetch.go
|
|
// ownDependencies): the `dependencies` beyond the SDK, typescript and the @types packages.
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// Finding is one module refused: it names Packages beyond the SDK and has no lock file.
|
|
type Finding struct {
|
|
Module string
|
|
Packages []string
|
|
}
|
|
|
|
// Check reads every module under root/modules that builds a TypeScript artifact.
|
|
func Check(root string) ([]Finding, error) {
|
|
manifests, err := filepath.Glob(filepath.Join(root, "modules", "*", "module.json"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sort.Strings(manifests)
|
|
var out []Finding
|
|
for _, path := range manifests {
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var m struct {
|
|
Module string `json:"module"`
|
|
Build struct {
|
|
Artifacts []struct {
|
|
Language string `json:"language"`
|
|
} `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
return nil, fmt.Errorf("%s: %w", path, err)
|
|
}
|
|
typescript := false
|
|
for _, a := range m.Build.Artifacts {
|
|
typescript = typescript || a.Language == "typescript"
|
|
}
|
|
if !typescript {
|
|
continue
|
|
}
|
|
dir := filepath.Dir(path)
|
|
pkgRaw, err := os.ReadFile(filepath.Join(dir, "package.json"))
|
|
if os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var pkg struct {
|
|
Dependencies map[string]json.RawMessage `json:"dependencies"`
|
|
}
|
|
if err := json.Unmarshal(pkgRaw, &pkg); err != nil {
|
|
return nil, fmt.Errorf("%s: package.json: %w", m.Module, err)
|
|
}
|
|
var names []string
|
|
for n := range pkg.Dependencies {
|
|
if n != "@novox/mesh-sdk" && n != "typescript" && !strings.HasPrefix(n, "@types/") {
|
|
names = append(names, n)
|
|
}
|
|
}
|
|
if len(names) == 0 {
|
|
continue
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "package-lock.json")); err != nil {
|
|
sort.Strings(names)
|
|
out = append(out, Finding{Module: m.Module, Packages: names})
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func main() {
|
|
root := "."
|
|
if len(os.Args) > 1 {
|
|
root = os.Args[1]
|
|
}
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
for _, f := range found {
|
|
fmt.Printf("%s names packages beyond the SDK (%s) and has no package-lock.json: commit one made by the build module's toolchain (novox/hq ADR 0469 §5)\n", f.Module, strings.Join(f.Packages, ", "))
|
|
}
|
|
if len(found) > 0 {
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println("locks: every TypeScript module that names packages beyond the SDK commits its lock")
|
|
}
|