JetBrains Mono Nerd Font for monospace, Inter for the interface, the Nerd Fonts symbols and Noto Color Emoji as fallbacks, Noto for serif. One owned fontconfig file in the account's conf.d maps monospace, sans-serif, system-ui, serif and emoji, bound `same`: measured with fontconfig 2.18, a weakly bound preference loses to Noto Sans Mono. Families today's configs name but the laptop lacks (Iosevka, the old JetBrains name) stop falling back to sans-serif. Six Go tools: families, match, glyph, sources (which hand-copied files can go and why), config, cache-rebuild. The README lists the hand-copied files to remove and the modules that must name the new family.
108 lines
3.0 KiB
Go
108 lines
3.0 KiB
Go
package main
|
|
|
|
// manifest_kit_test.go is the same file in each workstation module: it reads the module's
|
|
// definition so the module's own tests can hold it to what it says.
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type manifest struct {
|
|
Module string `json:"module"`
|
|
Capabilities []string `json:"capabilities"`
|
|
Claims []any `json:"claims"`
|
|
Seats []any `json:"seats"`
|
|
Tools []string `json:"tools"`
|
|
Resources []map[string]any `json:"resources"`
|
|
Build struct {
|
|
Artifacts []map[string]any `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
|
|
func readManifest(t *testing.T) manifest {
|
|
t.Helper()
|
|
raw, err := os.ReadFile(filepath.Join("..", "..", "module.json"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var m manifest
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
t.Fatalf("module.json: %v", err)
|
|
}
|
|
return m
|
|
}
|
|
|
|
func (m manifest) resource(id string) map[string]any {
|
|
for _, r := range m.Resources {
|
|
if r["id"] == id {
|
|
return r
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// packages are the packages the module installs, sorted.
|
|
func (m manifest) packages() []string {
|
|
out := []string{}
|
|
for _, r := range m.Resources {
|
|
if r["type"] == "package" && r["absent"] != true {
|
|
out = append(out, r["package"].(string))
|
|
}
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|
|
|
|
// services are the units the module declares, by unit name.
|
|
func (m manifest) services() map[string]map[string]any {
|
|
out := map[string]map[string]any{}
|
|
for _, r := range m.Resources {
|
|
if r["type"] == "service" {
|
|
out[r["unit"].(string)] = r
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// holdsTheBundle holds the manifest to the Go bundle this directory builds: every tool registered
|
|
// is listed and nothing else, each named <prefix>_…, and the artifact builds this command.
|
|
func holdsTheBundle(t *testing.T, m manifest, prefix string) {
|
|
t.Helper()
|
|
registered := []string{}
|
|
for _, tool := range tools() {
|
|
registered = append(registered, tool.Name)
|
|
if !strings.HasPrefix(tool.Name, prefix+"_") {
|
|
t.Errorf("tool %s is not named %s_…", tool.Name, prefix)
|
|
}
|
|
if tool.Description == "" || tool.Run == nil || tool.Input == nil {
|
|
t.Errorf("tool %s is not described, runnable and given an input schema", tool.Name)
|
|
}
|
|
}
|
|
if strings.Join(registered, ",") != strings.Join(m.Tools, ",") {
|
|
t.Errorf("registered %v, listed %v", registered, m.Tools)
|
|
}
|
|
if len(m.Build.Artifacts) != 1 {
|
|
t.Fatalf("one artifact, got %d", len(m.Build.Artifacts))
|
|
}
|
|
cwd, _ := os.Getwd()
|
|
binary := filepath.Base(cwd)
|
|
a := m.Build.Artifacts[0]
|
|
want := map[string]any{"kind": "bundle", "language": "go", "system": "arch", "from": "cmd/" + binary, "binary": binary}
|
|
for k, v := range want {
|
|
if a[k] != v {
|
|
t.Errorf("artifact %s = %v, want %v", k, a[k], v)
|
|
}
|
|
}
|
|
if loads, _ := a["loads"].([]any); len(loads) != 1 || loads[0] != binary {
|
|
t.Errorf("artifact loads %v, want [%s]", a["loads"], binary)
|
|
}
|
|
if m.Claims != nil || m.Seats != nil {
|
|
t.Errorf("claims %v, seats %v: this module holds no seat", m.Claims, m.Seats)
|
|
}
|
|
}
|