diff --git a/go/conclave.go b/go/conclave.go index 2097fea..641c2bb 100644 --- a/go/conclave.go +++ b/go/conclave.go @@ -5,7 +5,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // conclaveRootFn is swapped in by go-session or a similar session-scoped @@ -58,14 +57,14 @@ func ForConclave(name string, opts ...Option) core.Result { rootResult := resolver(name) if !rootResult.OK { - return core.Fail(coreerr.E(callerForConclave, "failed to resolve conclave root: "+name, resultCause(rootResult).(error))) + return core.Fail(core.E(callerForConclave, "failed to resolve conclave root: "+name, resultCause(rootResult).(error))) } root := rootResult.Value.(string) if root == "" { - return core.Fail(coreerr.E(callerForConclave, "failed to resolve conclave root: "+name, nil)) + return core.Fail(core.E(callerForConclave, "failed to resolve conclave root: "+name, nil)) } if isSymlinkedCoreDir(coreio.Local, core.Path(root, ".core")) { - return core.Fail(coreerr.E(callerForConclave, "symlinked conclave .core directory rejected: "+root, nil)) + return core.Fail(core.E(callerForConclave, "symlinked conclave .core directory rejected: "+root, nil)) } conclaveOpts := append([]Option{}, opts...) @@ -77,13 +76,13 @@ func ForConclave(name string, opts ...Option) core.Result { // the final fallback layer. baseResult := Discover(opts...) if !baseResult.OK { - return core.Fail(coreerr.E(callerForConclave, "failed to discover base config: "+name, resultCause(baseResult).(error))) + return core.Fail(core.E(callerForConclave, "failed to discover base config: "+name, resultCause(baseResult).(error))) } base := baseResult.Value.(*Config) conclaveResult := New(conclaveOpts...) if !conclaveResult.OK { - return core.Fail(coreerr.E(callerForConclave, "failed to load conclave config: "+name, resultCause(conclaveResult).(error))) + return core.Fail(core.E(callerForConclave, "failed to load conclave config: "+name, resultCause(conclaveResult).(error))) } conclaveCfg := conclaveResult.Value.(*Config) @@ -94,7 +93,7 @@ func ForConclave(name string, opts ...Option) core.Result { func defaultConclaveRoot(name string) core.Result { if !isSafePathElement(name) { - return core.Fail(coreerr.E("config.defaultConclaveRoot", "invalid conclave name: "+name, nil)) + return core.Fail(core.E("config.defaultConclaveRoot", "invalid conclave name: "+name, nil)) } return core.Ok(core.Path(XDG().Config(), "conclaves", name)) } diff --git a/go/config.go b/go/config.go index cbf1ebc..4e6d97c 100644 --- a/go/config.go +++ b/go/config.go @@ -17,7 +17,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" "github.com/spf13/viper" "gopkg.in/yaml.v3" ) @@ -206,7 +205,7 @@ func newConfig(loadFromPath bool, opts ...Option) core.Result { if c.path == "" { home := core.Env("DIR_HOME") if home == "" { - return core.Fail(coreerr.E(callerConfigNew, "failed to determine home directory", nil)) + return core.Fail(core.E(callerConfigNew, "failed to determine home directory", nil)) } c.path = core.Path(home, ".core", "config.yaml") } @@ -216,12 +215,12 @@ func newConfig(loadFromPath bool, opts ...Option) core.Result { // Load existing config file if it exists. if loadFromPath && c.medium.Exists(c.path) { if r := c.loadFile(c.medium, c.path, false); !r.OK { - return core.Fail(coreerr.E(callerConfigNew, "failed to load config file", resultCause(r).(error))) + return core.Fail(core.E(callerConfigNew, "failed to load config file", resultCause(r).(error))) } } if loadFromPath { if r := c.loadStoreState(); !r.OK { - return core.Fail(coreerr.E(callerConfigNew, "failed to load config store state", resultCause(r).(error))) + return core.Fail(core.E(callerConfigNew, "failed to load config store state", resultCause(r).(error))) } } @@ -247,7 +246,7 @@ func configTypeForPath(path string) core.Result { case ".env": return core.Ok("env") default: - return core.Fail(coreerr.E("config.configTypeForPath", "unsupported config file type: "+path, nil)) + return core.Fail(core.E("config.configTypeForPath", "unsupported config file type: "+path, nil)) } } @@ -289,19 +288,19 @@ func (c *Config) loadFile(m coreio.Medium, path string, notify bool) core.Result func readConfigSettings(m coreio.Medium, path string) core.Result { configTypeResult := configTypeForPath(path) if !configTypeResult.OK { - return core.Fail(coreerr.E(callerConfigLoadFile, "failed to determine config file type: "+path, resultCause(configTypeResult).(error))) + return core.Fail(core.E(callerConfigLoadFile, "failed to determine config file type: "+path, resultCause(configTypeResult).(error))) } configType := configTypeResult.Value.(string) content, err := m.Read(path) if err != nil { - return core.Fail(coreerr.E(callerConfigLoadFile, "failed to read config file: "+path, err)) + return core.Fail(core.E(callerConfigLoadFile, "failed to read config file: "+path, err)) } parsed := viper.New() parsed.SetConfigType(configType) if err := parsed.MergeConfig(core.NewReader(content)); err != nil { - return core.Fail(coreerr.E(callerConfigLoadFile, core.Sprintf("failed to parse config file: %s", path), err)) + return core.Fail(core.E(callerConfigLoadFile, core.Sprintf("failed to parse config file: %s", path), err)) } settings := parsed.AllSettings() @@ -313,10 +312,10 @@ func readConfigSettings(m coreio.Medium, path string) core.Result { func (c *Config) mergeConfigSettingsLocked(settings map[string]any) core.Result { if err := c.file.MergeConfigMap(settings); err != nil { - return core.Fail(coreerr.E(callerConfigLoadFile, "failed to merge config into file settings", err)) + return core.Fail(core.E(callerConfigLoadFile, "failed to merge config into file settings", err)) } if err := c.full.MergeConfigMap(settings); err != nil { - return core.Fail(coreerr.E(callerConfigLoadFile, "failed to merge config into full settings", err)) + return core.Fail(core.E(callerConfigLoadFile, "failed to merge config into full settings", err)) } return core.Ok(nil) } @@ -358,17 +357,17 @@ func (c *Config) Get(key string, out any) core.Result { if key == "" { if err := c.full.Unmarshal(out); err != nil { - return core.Fail(coreerr.E(callerConfigGet, "failed to unmarshal full config", err)) + return core.Fail(core.E(callerConfigGet, "failed to unmarshal full config", err)) } return core.Ok(nil) } if !c.full.IsSet(key) { - return core.Fail(coreerr.E(callerConfigGet, core.Sprintf("key not found: %s", key), nil)) + return core.Fail(core.E(callerConfigGet, core.Sprintf("key not found: %s", key), nil)) } if err := c.full.UnmarshalKey(key, out); err != nil { - return core.Fail(coreerr.E(callerConfigGet, core.Sprintf("failed to unmarshal key: %s", key), err)) + return core.Fail(core.E(callerConfigGet, core.Sprintf("failed to unmarshal key: %s", key), err)) } return core.Ok(nil) } @@ -426,7 +425,7 @@ func (c *Config) Commit() core.Result { c.mu.Unlock() if r := Save(medium, path, settings); !r.OK { - return core.Fail(coreerr.E("config.Commit", "failed to save config", resultCause(r).(error))) + return core.Fail(core.E("config.Commit", "failed to save config", resultCause(r).(error))) } if attached != nil { _ = attached.ACTION(ConfigChanged{Key: "", Value: nil, Source: configChangeSourceCommit}) @@ -441,7 +440,7 @@ func (c *Config) Commit() core.Result { // (so CORE_CONFIG_DEV_EDITOR shows up as "dev.editor"). // // for key, value := range cfg.All() { -// fmt.Println(key, value) // "dev.editor" "vim" +// core.Println(key, value) // "dev.editor" "vim" // } func (c *Config) All() iter.Seq2[string, any] { c.mu.RLock() @@ -607,7 +606,7 @@ func joinConfigPath(prefix, key string) string { // // cfg.OnChange(func(key string, value any) { // if key == "dev.editor" { -// fmt.Println("editor changed to", value) +// core.Println("editor changed to", value) // } // }) func (c *Config) OnChange(fn func(key string, value any)) { @@ -634,13 +633,13 @@ func Load(m coreio.Medium, path string) core.Result { // dotenv sources are also supported by the RFC contract. default: if core.PathBase(path) != ".env" { - return core.Fail(coreerr.E(callerConfigLoad, unsupportedConfigFileType+": "+path, nil)) + return core.Fail(core.E(callerConfigLoad, unsupportedConfigFileType+": "+path, nil)) } } content, err := m.Read(path) if err != nil { - return core.Fail(coreerr.E(callerConfigLoad, "failed to read config file: "+path, err)) + return core.Fail(core.E(callerConfigLoad, "failed to read config file: "+path, err)) } v := viper.New() @@ -651,7 +650,7 @@ func Load(m coreio.Medium, path string) core.Result { v.SetConfigType("yaml") } if err := v.ReadConfig(core.NewReader(content)); err != nil { - return core.Fail(coreerr.E(callerConfigLoad, "failed to parse config file: "+path, err)) + return core.Fail(core.E(callerConfigLoad, "failed to parse config file: "+path, err)) } return core.Ok(v.AllSettings()) @@ -667,7 +666,7 @@ func Save(m coreio.Medium, path string, data map[string]any) core.Result { case "", ".yaml", ".yml": // These paths are safe to treat as YAML destinations. default: - return core.Fail(coreerr.E(callerConfigSave, unsupportedConfigFileType+": "+path, nil)) + return core.Fail(core.E(callerConfigSave, unsupportedConfigFileType+": "+path, nil)) } payload := make(map[string]any, len(data)+1) @@ -679,16 +678,16 @@ func Save(m coreio.Medium, path string, data map[string]any) core.Result { out, err := yaml.Marshal(payload) if err != nil { - return core.Fail(coreerr.E(callerConfigSave, "failed to marshal config", err)) + return core.Fail(core.E(callerConfigSave, "failed to marshal config", err)) } dir := core.PathDir(path) if err := m.EnsureDir(dir); err != nil { - return core.Fail(coreerr.E(callerConfigSave, "failed to create config directory: "+dir, err)) + return core.Fail(core.E(callerConfigSave, "failed to create config directory: "+dir, err)) } if err := m.WriteMode(path, string(out), 0600); err != nil { - return core.Fail(coreerr.E(callerConfigSave, "failed to write config file: "+path, err)) + return core.Fail(core.E(callerConfigSave, "failed to write config file: "+path, err)) } return core.Ok(nil) @@ -711,7 +710,7 @@ func (c *Config) loadStoreState() core.Result { entries, err := reader.GetAll("config") if err != nil { - return core.Fail(coreerr.E("config.loadStoreState", "failed to read config entries from store", err)) + return core.Fail(core.E("config.loadStoreState", "failed to read config entries from store", err)) } for key, raw := range entries { diff --git a/go/discover.go b/go/discover.go index 87128d0..4151b32 100644 --- a/go/discover.go +++ b/go/discover.go @@ -3,7 +3,6 @@ package config import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const callerDiscoverFrom = "config.DiscoverFrom" @@ -18,7 +17,7 @@ const callerDiscoverFrom = "config.DiscoverFrom" func Discover(opts ...Option) core.Result { r := core.Getwd() if !r.OK { - return core.Fail(coreerr.E("config.Discover", "failed to read working directory", resultCause(r).(error))) + return core.Fail(core.E("config.Discover", "failed to read working directory", resultCause(r).(error))) } return DiscoverFrom(r.Value.(string), opts...) } @@ -30,7 +29,7 @@ func Discover(opts ...Option) core.Result { func DiscoverFrom(start string, opts ...Option) core.Result { baseResult := newConfig(false, opts...) if !baseResult.OK { - return core.Fail(coreerr.E(callerDiscoverFrom, "failed to initialise base config", resultCause(baseResult).(error))) + return core.Fail(core.E(callerDiscoverFrom, "failed to initialise base config", resultCause(baseResult).(error))) } base := baseResult.Value.(*Config) medium := base.medium @@ -49,13 +48,13 @@ func DiscoverFrom(start string, opts ...Option) core.Result { } layerResult := New(layerOpts...) if !layerResult.OK { - return core.Fail(coreerr.E(callerDiscoverFrom, "failed to load discovered config: "+p, resultCause(layerResult).(error))) + return core.Fail(core.E(callerDiscoverFrom, "failed to load discovered config: "+p, resultCause(layerResult).(error))) } layer := layerResult.Value.(*Config) base.MergeFrom(layer) } if r := base.loadStoreState(); !r.OK { - return core.Fail(coreerr.E(callerDiscoverFrom, "failed to load config store state", resultCause(r).(error))) + return core.Fail(core.E(callerDiscoverFrom, "failed to load config store state", resultCause(r).(error))) } return core.Ok(base) diff --git a/go/feature.go b/go/feature.go index 7d737ba..de6eb96 100644 --- a/go/feature.go +++ b/go/feature.go @@ -113,7 +113,7 @@ func SetFeature(name string, enabled bool) { // registry. Environment overrides are not included in the returned slice. // // for _, flag := range config.Features() { -// fmt.Println(flag) +// core.Println(flag) // } func Features() []string { featureMu.RLock() diff --git a/go/images_manifest.go b/go/images_manifest.go index 58429e8..4bec60b 100644 --- a/go/images_manifest.go +++ b/go/images_manifest.go @@ -6,7 +6,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" "github.com/xeipuuv/gojsonschema" ) @@ -70,18 +69,18 @@ func LoadImagesManifest(medium coreio.Medium, path string) core.Result { if core.Is(err, fs.ErrNotExist) { return core.Ok(manifest) } - return core.Fail(coreerr.E(callerLoadImagesManifest, "failed to read images manifest: "+path, err)) + return core.Fail(core.E(callerLoadImagesManifest, "failed to read images manifest: "+path, err)) } var raw map[string]any if r := core.JSONUnmarshalString(content, &raw); !r.OK { - return core.Fail(coreerr.E(callerLoadImagesManifest, "failed to parse images manifest: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadImagesManifest, "failed to parse images manifest: "+path, resultCause(r).(error))) } if r := validateImagesSchema(path, raw); !r.OK { return r } if r := core.JSONUnmarshalString(content, manifest); !r.OK { - return core.Fail(coreerr.E(callerLoadImagesManifest, "failed to decode images manifest: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadImagesManifest, "failed to decode images manifest: "+path, resultCause(r).(error))) } if manifest.Images == nil { manifest.Images = map[string]ImageInfo{} @@ -103,16 +102,16 @@ func SaveImagesManifest(medium coreio.Medium, path string, manifest *ImagesManif payloadResult := core.JSONMarshal(manifest) if !payloadResult.OK { - return core.Fail(coreerr.E(callerSaveImagesManifest, "failed to marshal images manifest", resultCause(payloadResult).(error))) + return core.Fail(core.E(callerSaveImagesManifest, "failed to marshal images manifest", resultCause(payloadResult).(error))) } payload := payloadResult.Value.([]byte) dir := core.PathDir(path) if err := medium.EnsureDir(dir); err != nil { - return core.Fail(coreerr.E(callerSaveImagesManifest, "failed to create images manifest directory: "+dir, err)) + return core.Fail(core.E(callerSaveImagesManifest, "failed to create images manifest directory: "+dir, err)) } if err := medium.WriteMode(path, string(payload), 0o600); err != nil { - return core.Fail(coreerr.E(callerSaveImagesManifest, "failed to write images manifest: "+path, err)) + return core.Fail(core.E(callerSaveImagesManifest, "failed to write images manifest: "+path, err)) } return core.Ok(nil) } @@ -124,12 +123,12 @@ func validateImagesSchema(path string, raw map[string]any) core.Result { schemaBody, err := schemaFS.ReadFile("schema/images.schema.json") if err != nil { - return core.Fail(coreerr.E(callerValidateImagesSchema, "failed to read embedded schema: schema/images.schema.json", err)) + return core.Fail(core.E(callerValidateImagesSchema, "failed to read embedded schema: schema/images.schema.json", err)) } documentResult := core.JSONMarshal(raw) if !documentResult.OK { - return core.Fail(coreerr.E(callerValidateImagesSchema, "failed to encode images manifest for schema validation: "+path, resultCause(documentResult).(error))) + return core.Fail(core.E(callerValidateImagesSchema, "failed to encode images manifest for schema validation: "+path, resultCause(documentResult).(error))) } documentBody := documentResult.Value.([]byte) @@ -138,7 +137,7 @@ func validateImagesSchema(path string, raw map[string]any) core.Result { gojsonschema.NewBytesLoader(documentBody), ) if err != nil { - return core.Fail(coreerr.E(callerValidateImagesSchema, "schema validation failed: "+path, err)) + return core.Fail(core.E(callerValidateImagesSchema, "schema validation failed: "+path, err)) } if result.Valid() { return core.Ok(nil) @@ -148,5 +147,5 @@ func validateImagesSchema(path string, raw map[string]any) core.Result { for _, issue := range result.Errors() { problems = append(problems, issue.String()) } - return core.Fail(coreerr.E(callerValidateImagesSchema, "schema validation failed: "+path+": "+core.Join("; ", problems...), nil)) + return core.Fail(core.E(callerValidateImagesSchema, "schema validation failed: "+path+": "+core.Join("; ", problems...), nil)) } diff --git a/go/manifest.go b/go/manifest.go index 8beaff1..df7a82c 100644 --- a/go/manifest.go +++ b/go/manifest.go @@ -5,14 +5,13 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" "gopkg.in/yaml.v3" ) // Known .core/ file names. Consumers should reference these constants rather // than hard-coding paths so future renames are a single-site change. // -// path := filepath.Join(dir, ".core", config.FileBuild) +// path := core.PathJoin(dir, config.Directory, config.FileBuild) const ( FileConfig = "config.yaml" // go-config — identity, preferences, feature flags FileBuild = "build.yaml" // go-build — targets, ldflags, cgo @@ -142,7 +141,7 @@ func (v *ViewVersion) UnmarshalYAML(node *yaml.Node) core.Result { return core.Ok(nil) } } - return core.Fail(coreerr.E("config.ViewVersion.UnmarshalYAML", "invalid view manifest version", nil)) + return core.Fail(core.E("config.ViewVersion.UnmarshalYAML", "invalid view manifest version", nil)) } // ViewPermissions controls what a webview or application surface is allowed to do. @@ -643,7 +642,7 @@ func (l *buildmanifestldflags) UnmarshalYAML(value *yaml.Node) core.Result { *l = append([]string(nil), values...) return core.Ok(nil) case yaml.MappingNode: - return core.Fail(coreerr.E("config.buildmanifestldflags.UnmarshalYAML", "unsupported ldflags mapping", nil)) + return core.Fail(core.E("config.buildmanifestldflags.UnmarshalYAML", "unsupported ldflags mapping", nil)) default: *l = nil return core.Ok(nil) @@ -718,7 +717,7 @@ func (m *BuildManifest) UnmarshalYAML(value *yaml.Node) core.Result { func buildTargetFromString(raw string) core.Result { parts := core.SplitN(raw, "/", 2) if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return core.Fail(coreerr.E("config.BuildTarget.UnmarshalYAML", "invalid target shorthand: "+raw, nil)) + return core.Fail(core.E("config.BuildTarget.UnmarshalYAML", "invalid target shorthand: "+raw, nil)) } return core.Ok(BuildTarget{OS: parts[0], Arch: parts[1]}) } @@ -755,7 +754,7 @@ func buildTargetFromYAML(value any) core.Result { case nil: return core.Ok(BuildTarget{}) default: - return core.Fail(coreerr.E("config.BuildTarget.UnmarshalYAML", "invalid target entry", nil)) + return core.Fail(core.E("config.BuildTarget.UnmarshalYAML", "invalid target entry", nil)) } } @@ -791,15 +790,15 @@ func buildLDFlagsFromYAML(value any) core.Result { for _, value := range typed { s, ok := value.(string) if !ok { - return core.Fail(coreerr.E("config.buildmanifestldflags.UnmarshalYAML", "invalid ldflags sequence", nil)) + return core.Fail(core.E("config.buildmanifestldflags.UnmarshalYAML", "invalid ldflags sequence", nil)) } out = append(out, s) } return core.Ok(out) case map[string]any, map[any]any: - return core.Fail(coreerr.E("config.buildmanifestldflags.UnmarshalYAML", "unsupported ldflags mapping", nil)) + return core.Fail(core.E("config.buildmanifestldflags.UnmarshalYAML", "unsupported ldflags mapping", nil)) default: - return core.Fail(coreerr.E("config.buildmanifestldflags.UnmarshalYAML", "invalid ldflags value", nil)) + return core.Fail(core.E("config.buildmanifestldflags.UnmarshalYAML", "invalid ldflags value", nil)) } } @@ -825,17 +824,17 @@ type ReposRepo struct { func LoadManifest(m coreio.Medium, path string, out any) core.Result { content, err := m.Read(path) if err != nil { - return core.Fail(coreerr.E(callerLoadManifest, "failed to read manifest: "+path, err)) + return core.Fail(core.E(callerLoadManifest, "failed to read manifest: "+path, err)) } var raw map[string]any if err := yaml.Unmarshal([]byte(content), &raw); err != nil { - return core.Fail(coreerr.E(callerLoadManifest, "failed to parse manifest: "+path, err)) + return core.Fail(core.E(callerLoadManifest, "failed to parse manifest: "+path, err)) } if r := validateSchema(path, raw); !r.OK { return r } if r := decodeManifestYAML(content, out); !r.OK { - return core.Fail(coreerr.E(callerLoadManifest, "failed to decode manifest: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadManifest, "failed to decode manifest: "+path, resultCause(r).(error))) } if r := validateManifest(path, out, raw); !r.OK { return r @@ -929,7 +928,7 @@ func viewVersionFromYAML(value any) core.Result { case float64: return core.Ok(ViewVersion(core.Sprintf("%v", typed))) default: - return core.Fail(coreerr.E("config.ViewVersion.UnmarshalYAML", "invalid view manifest version", nil)) + return core.Fail(core.E("config.ViewVersion.UnmarshalYAML", "invalid view manifest version", nil)) } } @@ -957,17 +956,17 @@ func validateManifest(path string, out any, raw map[string]any) core.Result { func validateLoadedViewManifest(path string, view *ViewManifest, raw map[string]any) core.Result { if missingOrEmptyStringField(raw, "sign", view.Sign) { - return core.Fail(coreerr.E(callerLoadManifest, "unsigned view manifest rejected: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "unsigned view manifest rejected: "+path, nil)) } if r := ValidateViewManifestSignature(view); !r.OK { msg := r.Error() switch { case core.Contains(msg, "not ed25519-sized"): - return core.Fail(coreerr.E(callerLoadManifest, "view manifest signature is not ed25519-sized: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "view manifest signature is not ed25519-sized: "+path, nil)) case core.Contains(msg, "unsigned"): - return core.Fail(coreerr.E(callerLoadManifest, "unsigned view manifest rejected: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "unsigned view manifest rejected: "+path, nil)) default: - return core.Fail(coreerr.E(callerLoadManifest, "invalid view manifest signature: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadManifest, "invalid view manifest signature: "+path, resultCause(r).(error))) } } return core.Ok(nil) @@ -975,30 +974,30 @@ func validateLoadedViewManifest(path string, view *ViewManifest, raw map[string] func verifyLoadedPackageManifest(path string, pkg *PackageManifest, raw map[string]any) core.Result { if missingOrEmptyStringField(raw, "sign", pkg.Sign) { - return core.Fail(coreerr.E(callerLoadManifest, "unsigned package manifest rejected: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "unsigned package manifest rejected: "+path, nil)) } if missingOrEmptyStringField(raw, "sign_key", pkg.SignKey) { - return core.Fail(coreerr.E(callerLoadManifest, "missing package sign_key: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "missing package sign_key: "+path, nil)) } if r := VerifyPackageManifest(pkg); !r.OK { msg := r.Error() switch { case core.Contains(msg, "missing package sign_key"): - return core.Fail(coreerr.E(callerLoadManifest, "missing package sign_key: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "missing package sign_key: "+path, nil)) case core.Contains(msg, "not an ed25519 public key"): - return core.Fail(coreerr.E(callerLoadManifest, "package sign_key is not an ed25519 public key: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "package sign_key is not an ed25519 public key: "+path, nil)) case core.Contains(msg, "not trusted"): - return core.Fail(coreerr.E(callerLoadManifest, "package sign_key is not trusted: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "package sign_key is not trusted: "+path, nil)) case core.Contains(msg, "not ed25519-sized"): - return core.Fail(coreerr.E(callerLoadManifest, "package manifest signature is not ed25519-sized: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "package manifest signature is not ed25519-sized: "+path, nil)) case core.Contains(msg, "signature mismatch"): - return core.Fail(coreerr.E(callerLoadManifest, "package manifest signature mismatch: "+path, nil)) + return core.Fail(core.E(callerLoadManifest, "package manifest signature mismatch: "+path, nil)) case core.Contains(msg, errCanonicalMarshalFailed): - return core.Fail(coreerr.E(callerLoadManifest, errCanonicalMarshalFailed+": "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadManifest, errCanonicalMarshalFailed+": "+path, resultCause(r).(error))) case core.Contains(msg, "decode package sign_key failed"): - return core.Fail(coreerr.E(callerLoadManifest, "decode package sign_key failed: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadManifest, "decode package sign_key failed: "+path, resultCause(r).(error))) default: - return core.Fail(coreerr.E(callerLoadManifest, "invalid package manifest signature: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerLoadManifest, "invalid package manifest signature: "+path, resultCause(r).(error))) } } return core.Ok(nil) @@ -1042,15 +1041,15 @@ func CanonicalViewManifestBytes(view *ViewManifest) core.Result { // if err := config.ValidateViewManifestSignature(&view); err != nil { ... } func ValidateViewManifestSignature(view *ViewManifest) core.Result { if view == nil || core.Trim(view.Sign) == "" { - return core.Fail(coreerr.E(callerValidateViewManifestSignature, "unsigned view manifest rejected", nil)) + return core.Fail(core.E(callerValidateViewManifestSignature, "unsigned view manifest rejected", nil)) } sigResult := decodeManifestSignature(view.Sign) if !sigResult.OK { - return core.Fail(coreerr.E(callerValidateViewManifestSignature, "invalid view manifest signature", resultCause(sigResult).(error))) + return core.Fail(core.E(callerValidateViewManifestSignature, "invalid view manifest signature", resultCause(sigResult).(error))) } sig := sigResult.Value.([]byte) if len(sig) != ed25519.SignatureSize { - return core.Fail(coreerr.E(callerValidateViewManifestSignature, "view manifest signature is not ed25519-sized", nil)) + return core.Fail(core.E(callerValidateViewManifestSignature, "view manifest signature is not ed25519-sized", nil)) } return core.Ok(nil) } @@ -1064,20 +1063,20 @@ func VerifyViewManifestSignature(view *ViewManifest, publicKey ed25519.PublicKey return r } if len(publicKey) != ed25519.PublicKeySize { - return core.Fail(coreerr.E(callerVerifyViewManifestSignature, "view manifest public key is not an ed25519 public key", nil)) + return core.Fail(core.E(callerVerifyViewManifestSignature, "view manifest public key is not an ed25519 public key", nil)) } bodyResult := CanonicalViewManifestBytes(view) if !bodyResult.OK { - return core.Fail(coreerr.E(callerVerifyViewManifestSignature, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) + return core.Fail(core.E(callerVerifyViewManifestSignature, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) } body := bodyResult.Value.([]byte) sigResult := decodeManifestSignature(view.Sign) if !sigResult.OK { - return core.Fail(coreerr.E(callerVerifyViewManifestSignature, "invalid view manifest signature", resultCause(sigResult).(error))) + return core.Fail(core.E(callerVerifyViewManifestSignature, "invalid view manifest signature", resultCause(sigResult).(error))) } sig := sigResult.Value.([]byte) if !ed25519.Verify(publicKey, body, sig) { - return core.Fail(coreerr.E(callerVerifyViewManifestSignature, "view manifest signature mismatch", nil)) + return core.Fail(core.E(callerVerifyViewManifestSignature, "view manifest signature mismatch", nil)) } return core.Ok(nil) } @@ -1088,14 +1087,14 @@ func VerifyViewManifestSignature(view *ViewManifest, publicKey ed25519.PublicKey // _ = config.SignViewManifest(&view, priv) func SignViewManifest(view *ViewManifest, privateKey ed25519.PrivateKey) core.Result { if view == nil { - return core.Fail(coreerr.E(callerSignViewManifest, "nil view manifest", nil)) + return core.Fail(core.E(callerSignViewManifest, "nil view manifest", nil)) } if len(privateKey) != ed25519.PrivateKeySize { - return core.Fail(coreerr.E(callerSignViewManifest, "view manifest private key is not an ed25519 private key", nil)) + return core.Fail(core.E(callerSignViewManifest, "view manifest private key is not an ed25519 private key", nil)) } bodyResult := CanonicalViewManifestBytes(view) if !bodyResult.OK { - return core.Fail(coreerr.E(callerSignViewManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) + return core.Fail(core.E(callerSignViewManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) } body := bodyResult.Value.([]byte) view.Sign = core.Base64Encode(ed25519.Sign(privateKey, body)) @@ -1125,19 +1124,19 @@ func CanonicalPackageManifestBytes(pkg *PackageManifest) core.Result { // _ = config.SignPackageManifest(&pkg, priv) func SignPackageManifest(pkg *PackageManifest, privateKey ed25519.PrivateKey) core.Result { if pkg == nil { - return core.Fail(coreerr.E(callerSignPackageManifest, "nil package manifest", nil)) + return core.Fail(core.E(callerSignPackageManifest, "nil package manifest", nil)) } if len(privateKey) != ed25519.PrivateKeySize { - return core.Fail(coreerr.E(callerSignPackageManifest, "package manifest private key is not an ed25519 private key", nil)) + return core.Fail(core.E(callerSignPackageManifest, "package manifest private key is not an ed25519 private key", nil)) } publicKey, ok := privateKey.Public().(ed25519.PublicKey) if !ok || len(publicKey) != ed25519.PublicKeySize { - return core.Fail(coreerr.E(callerSignPackageManifest, "derive package manifest public key failed", nil)) + return core.Fail(core.E(callerSignPackageManifest, "derive package manifest public key failed", nil)) } pkg.SignKey = core.HexEncode(publicKey) bodyResult := CanonicalPackageManifestBytes(pkg) if !bodyResult.OK { - return core.Fail(coreerr.E(callerSignPackageManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) + return core.Fail(core.E(callerSignPackageManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) } body := bodyResult.Value.([]byte) pkg.Sign = core.Base64Encode(ed25519.Sign(privateKey, body)) @@ -1159,46 +1158,46 @@ func packageManifestBytes(pkg *PackageManifest) core.Result { // if err := config.VerifyPackageManifest(&pkg); err != nil { ... } func VerifyPackageManifest(pkg *PackageManifest) core.Result { if pkg == nil || core.Trim(pkg.Sign) == "" { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "unsigned package manifest rejected", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "unsigned package manifest rejected", nil)) } if core.Trim(pkg.SignKey) == "" { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "missing package sign_key", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "missing package sign_key", nil)) } pubResult := core.HexDecode(core.Trim(pkg.SignKey)) if !pubResult.OK { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "decode package sign_key failed", resultCause(pubResult).(error))) + return core.Fail(core.E(callerVerifyPackageManifest, "decode package sign_key failed", resultCause(pubResult).(error))) } pub := pubResult.Value.([]byte) if len(pub) != ed25519.PublicKeySize { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "package sign_key is not an ed25519 public key", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "package sign_key is not an ed25519 public key", nil)) } trustedKeysResult := trustedManifestVerificationKeys() if !trustedKeysResult.OK { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "load trusted manifest public keys failed", resultCause(trustedKeysResult).(error))) + return core.Fail(core.E(callerVerifyPackageManifest, "load trusted manifest public keys failed", resultCause(trustedKeysResult).(error))) } trustedKeys := trustedKeysResult.Value.([]ed25519.PublicKey) if len(trustedKeys) > 0 && !manifestKeyTrusted(ed25519.PublicKey(pub), trustedKeys) { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "package sign_key is not trusted", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "package sign_key is not trusted", nil)) } sigResult := decodeManifestSignature(pkg.Sign) if !sigResult.OK { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "invalid package manifest signature", resultCause(sigResult).(error))) + return core.Fail(core.E(callerVerifyPackageManifest, "invalid package manifest signature", resultCause(sigResult).(error))) } sig := sigResult.Value.([]byte) if len(sig) != ed25519.SignatureSize { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "package manifest signature is not ed25519-sized", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "package manifest signature is not ed25519-sized", nil)) } bodyResult := CanonicalPackageManifestBytes(pkg) if !bodyResult.OK { - return core.Fail(coreerr.E(callerVerifyPackageManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) + return core.Fail(core.E(callerVerifyPackageManifest, errCanonicalMarshalFailed, resultCause(bodyResult).(error))) } body := bodyResult.Value.([]byte) if !ed25519.Verify(ed25519.PublicKey(pub), body, sig) { - return core.Fail(coreerr.E(callerVerifyPackageManifest, "package manifest signature mismatch", nil)) + return core.Fail(core.E(callerVerifyPackageManifest, "package manifest signature mismatch", nil)) } return core.Ok(nil) } @@ -1224,7 +1223,7 @@ func parseTrustedManifestKeyList(raw string) core.Result { for _, item := range splitManifestTrustedKeys(raw) { pubResult := parseManifestPublicKey(item) if !pubResult.OK { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, errDecodeTrustedKeyFailed, resultCause(pubResult).(error))) + return core.Fail(core.E(callerTrustedManifestPublicKeys, errDecodeTrustedKeyFailed, resultCause(pubResult).(error))) } keys = append(keys, pubResult.Value.(ed25519.PublicKey)) } @@ -1239,10 +1238,10 @@ func trustedManifestPublicKeysFromDisk(home string) core.Result { coreDir := core.PathJoin(home, ".core") keyDir := core.PathJoin(coreDir, "keys") if isSymlinkedCoreDir(coreio.Local, coreDir) { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, "symlinked .core directory rejected: "+coreDir, nil)) + return core.Fail(core.E(callerTrustedManifestPublicKeys, "symlinked .core directory rejected: "+coreDir, nil)) } if isSymlinkedLocalPath(keyDir) { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, "symlinked trusted keys directory rejected: "+keyDir, nil)) + return core.Fail(core.E(callerTrustedManifestPublicKeys, "symlinked trusted keys directory rejected: "+keyDir, nil)) } entriesResult := core.ReadDir(core.DirFS(keyDir), ".") @@ -1250,7 +1249,7 @@ func trustedManifestPublicKeysFromDisk(home string) core.Result { return core.Ok([]ed25519.PublicKey(nil)) } if !entriesResult.OK { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, "read trusted keys directory failed", resultCause(entriesResult).(error))) + return core.Fail(core.E(callerTrustedManifestPublicKeys, "read trusted keys directory failed", resultCause(entriesResult).(error))) } return trustedManifestKeysFromEntries(keyDir, entriesResult.Value.([]core.FsDirEntry)) } @@ -1282,15 +1281,15 @@ func trustedManifestPublicKeyFromEntry(keyDir string, entry core.FsDirEntry) cor entryPath := core.PathJoin(keyDir, entry.Name()) if isSymlinkedLocalPath(entryPath) { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, "symlinked trusted key rejected: "+entry.Name(), nil)) + return core.Fail(core.E(callerTrustedManifestPublicKeys, "symlinked trusted key rejected: "+entry.Name(), nil)) } bodyResult := core.ReadFSFile(core.DirFS(keyDir), entry.Name()) if !bodyResult.OK { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, "read trusted key file failed: "+entry.Name(), resultCause(bodyResult).(error))) + return core.Fail(core.E(callerTrustedManifestPublicKeys, "read trusted key file failed: "+entry.Name(), resultCause(bodyResult).(error))) } pubResult := parseManifestPublicKey(core.Trim(string(bodyResult.Value.([]byte)))) if !pubResult.OK { - return core.Fail(coreerr.E(callerTrustedManifestPublicKeys, errDecodeTrustedKeyFailed+": "+entry.Name(), resultCause(pubResult).(error))) + return core.Fail(core.E(callerTrustedManifestPublicKeys, errDecodeTrustedKeyFailed+": "+entry.Name(), resultCause(pubResult).(error))) } return core.Ok(trustedManifestPublicKeyEntry{Key: pubResult.Value.(ed25519.PublicKey), Found: true}) } @@ -1331,15 +1330,15 @@ func isManifestTrustKeySeparator(r rune) bool { func parseManifestPublicKey(raw string) core.Result { trimmed := core.Trim(raw) if trimmed == "" { - return core.Fail(coreerr.E(callerParseManifestPublicKey, "empty manifest public key", nil)) + return core.Fail(core.E(callerParseManifestPublicKey, "empty manifest public key", nil)) } pubResult := core.HexDecode(trimmed) if !pubResult.OK { - return core.Fail(coreerr.E(callerParseManifestPublicKey, "decode manifest public key failed", resultCause(pubResult).(error))) + return core.Fail(core.E(callerParseManifestPublicKey, "decode manifest public key failed", resultCause(pubResult).(error))) } pub := pubResult.Value.([]byte) if len(pub) != ed25519.PublicKeySize { - return core.Fail(coreerr.E(callerParseManifestPublicKey, "manifest public key has invalid size", nil)) + return core.Fail(core.E(callerParseManifestPublicKey, "manifest public key has invalid size", nil)) } return core.Ok(ed25519.PublicKey(pub)) } diff --git a/go/resolve.go b/go/resolve.go index f948d73..c7b43cd 100644 --- a/go/resolve.go +++ b/go/resolve.go @@ -3,7 +3,6 @@ package config import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // FindProjectManifest searches upward from start for the nearest project-local @@ -161,7 +160,7 @@ func userCorePath(parts ...string) string { func ResolveConfigManifest(medium coreio.Medium, start string) core.Result { path := FindManifest(medium, start, FileConfig) if path == "" { - return core.Fail(coreerr.E("config.ResolveConfigManifest", "no config manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveConfigManifest", "no config manifest could be detected", nil)) } return New(WithMedium(medium), WithPath(path)) } @@ -181,7 +180,7 @@ func FindBuildManifest(medium coreio.Medium, start string) string { func ResolveBuildManifest(medium coreio.Medium, start string) core.Result { path := FindBuildManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveBuildManifest", "no build manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveBuildManifest", "no build manifest could be detected", nil)) } var build BuildManifest @@ -221,7 +220,7 @@ func ResolveTestManifest(medium coreio.Medium, start string) core.Result { }) } - return core.Fail(coreerr.E(callerResolveTestManifest, "no test command could be detected", nil)) + return core.Fail(core.E(callerResolveTestManifest, "no test command could be detected", nil)) } // FindReleaseManifest returns the nearest project-local .core/release.yaml. @@ -233,7 +232,7 @@ func FindReleaseManifest(medium coreio.Medium, start string) string { func ResolveReleaseManifest(medium coreio.Medium, start string) core.Result { path := FindReleaseManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveReleaseManifest", "no release manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveReleaseManifest", "no release manifest could be detected", nil)) } var release ReleaseManifest @@ -252,7 +251,7 @@ func FindRunManifest(medium coreio.Medium, start string) string { func ResolveRunManifest(medium coreio.Medium, start string) core.Result { path := FindRunManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveRunManifest", "no run manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveRunManifest", "no run manifest could be detected", nil)) } var run RunManifest @@ -271,7 +270,7 @@ func FindViewManifest(medium coreio.Medium, start string) string { func ResolveViewManifest(medium coreio.Medium, start string) core.Result { path := FindViewManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveViewManifest", "no view manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveViewManifest", "no view manifest could be detected", nil)) } var view ViewManifest @@ -290,7 +289,7 @@ func FindPackageManifest(medium coreio.Medium, start string) string { func ResolvePackageManifest(medium coreio.Medium, start string) core.Result { path := FindPackageManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolvePackageManifest", "no package manifest could be detected", nil)) + return core.Fail(core.E("config.ResolvePackageManifest", "no package manifest could be detected", nil)) } var pkg PackageManifest @@ -313,7 +312,7 @@ func FindAgentManifest(medium coreio.Medium) string { func ResolveAgentManifest(medium coreio.Medium) core.Result { path := FindAgentManifest(medium) if path == "" { - return core.Fail(coreerr.E("config.ResolveAgentManifest", "no agent manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveAgentManifest", "no agent manifest could be detected", nil)) } var agent AgentManifest @@ -336,7 +335,7 @@ func FindZoneManifest(medium coreio.Medium) string { func ResolveZoneManifest(medium coreio.Medium) core.Result { path := FindZoneManifest(medium) if path == "" { - return core.Fail(coreerr.E("config.ResolveZoneManifest", "no zone manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveZoneManifest", "no zone manifest could be detected", nil)) } var zone ZoneManifest @@ -355,7 +354,7 @@ func FindWorkspaceManifest(medium coreio.Medium, start string) string { func ResolveWorkspaceManifest(medium coreio.Medium, start string) core.Result { path := FindWorkspaceManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveWorkspaceManifest", "no workspace manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveWorkspaceManifest", "no workspace manifest could be detected", nil)) } var ws WorkspaceManifest @@ -374,7 +373,7 @@ func FindIDEManifest(medium coreio.Medium, start string) string { func ResolveIDEManifest(medium coreio.Medium, start string) core.Result { path := FindIDEManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveIDEManifest", "no ide manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveIDEManifest", "no ide manifest could be detected", nil)) } var ide IDEManifest @@ -417,7 +416,7 @@ func FindLinuxKitManifest(medium coreio.Medium, start string) string { func ResolveLinuxKitManifest(medium coreio.Medium, start string) core.Result { path := FindLinuxKitManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveLinuxKitManifest", "no linuxkit manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveLinuxKitManifest", "no linuxkit manifest could be detected", nil)) } manifestResult := Load(medium, path) @@ -551,7 +550,7 @@ func FindWorkspaceRegistryManifest(medium coreio.Medium, start string) string { func ResolveReposManifest(medium coreio.Medium, start string) core.Result { path := FindReposManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolveReposManifest", "no repos manifest could be detected", nil)) + return core.Fail(core.E("config.ResolveReposManifest", "no repos manifest could be detected", nil)) } var repos ReposManifest @@ -577,7 +576,7 @@ func FindPHPManifest(medium coreio.Medium, start string) string { func ResolvePHPManifest(medium coreio.Medium, start string) core.Result { path := FindPHPManifest(medium, start) if path == "" { - return core.Fail(coreerr.E("config.ResolvePHPManifest", "no php manifest could be detected", nil)) + return core.Fail(core.E("config.ResolvePHPManifest", "no php manifest could be detected", nil)) } var php PHPManifest diff --git a/go/schema.go b/go/schema.go index feca404..95eec5b 100644 --- a/go/schema.go +++ b/go/schema.go @@ -4,7 +4,6 @@ import ( "embed" core "dappco.re/go" - coreerr "dappco.re/go/log" "github.com/xeipuuv/gojsonschema" ) @@ -44,12 +43,12 @@ func validateSchema(path string, raw map[string]any) core.Result { schemaBody, err := schemaFS.ReadFile(schemaPath) if err != nil { - return core.Fail(coreerr.E(callerValidateSchema, "failed to read embedded schema: "+schemaPath, err)) + return core.Fail(core.E(callerValidateSchema, "failed to read embedded schema: "+schemaPath, err)) } documentResult := core.JSONMarshal(raw) if !documentResult.OK { - return core.Fail(coreerr.E(callerValidateSchema, "failed to encode config for schema validation: "+path, resultCause(documentResult).(error))) + return core.Fail(core.E(callerValidateSchema, "failed to encode config for schema validation: "+path, resultCause(documentResult).(error))) } documentBody := documentResult.Value.([]byte) @@ -58,7 +57,7 @@ func validateSchema(path string, raw map[string]any) core.Result { gojsonschema.NewBytesLoader(documentBody), ) if err != nil { - return core.Fail(coreerr.E(callerValidateSchema, "schema validation failed: "+path, err)) + return core.Fail(core.E(callerValidateSchema, "schema validation failed: "+path, err)) } if result.Valid() { return core.Ok(nil) @@ -68,7 +67,7 @@ func validateSchema(path string, raw map[string]any) core.Result { for _, issue := range result.Errors() { problems = append(problems, issue.String()) } - return core.Fail(coreerr.E( + return core.Fail(core.E( callerValidateSchema, "schema validation failed: "+path+": "+core.Join("; ", problems...), nil, diff --git a/go/service.go b/go/service.go index 1365fd9..3d425eb 100644 --- a/go/service.go +++ b/go/service.go @@ -6,11 +6,11 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const ( callerValidateServiceLoadPath = "config.validateServiceLoadPath" + callerServiceRegisterCommands = "config.Service.registerCommands" actionConfigGet = "config.get" actionConfigSet = "config.set" @@ -120,7 +120,7 @@ func (s *Service) OnStartup(_ context.Context) core.Result { cfgResult := newServiceConfig(opts, configOpts) if !cfgResult.OK { - return core.Fail(coreerr.E("config.Service.OnStartup", "failed to create config", resultCause(cfgResult).(error))) + return core.Fail(core.E("config.Service.OnStartup", "failed to create config", resultCause(cfgResult).(error))) } s.config = cfgResult.Value.(*Config) @@ -132,7 +132,9 @@ func (s *Service) OnStartup(_ context.Context) core.Result { if c := s.Core(); c != nil { s.config.AttachCore(c) s.registerActions(c) - s.registerCommands(c) + if r := s.registerCommands(c); !r.OK { + return r + } } return core.Ok(nil) @@ -176,18 +178,18 @@ func resolveValidatedServiceLoadPath(basePath, path string) core.Result { func validateServiceLoadPathInput(path string) core.Result { if path == "" { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "empty config path", nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "empty config path", nil)) } if core.PathIsAbs(path) { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "absolute config paths are not allowed: "+path, nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "absolute config paths are not allowed: "+path, nil)) } clean := core.CleanPath(path, string(core.PathSeparator)) if clean == "." || clean == ".." || core.HasPrefix(clean, ".."+string(core.PathSeparator)) { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "path traversal rejected: "+path, nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "path traversal rejected: "+path, nil)) } if !isProjectCoreRelativePath(clean) { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "config paths must remain under .core/: "+path, nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "config paths must remain under .core/: "+path, nil)) } return core.Ok(clean) } @@ -197,14 +199,14 @@ func resolveServiceLoadPathWithinCore(basePath, clean, original string) core.Res corePath := core.CleanPath(core.PathJoin(projectRoot, Directory), string(core.PathSeparator)) absCoreResult := core.PathAbs(corePath) if !absCoreResult.OK { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "resolve config base failed: "+original, resultCause(absCoreResult).(error))) + return core.Fail(core.E(callerValidateServiceLoadPath, "resolve config base failed: "+original, resultCause(absCoreResult).(error))) } absCorePath := absCoreResult.Value.(string) candidatePath := core.CleanPath(core.PathJoin(projectRoot, clean), string(core.PathSeparator)) absCandidateResult := core.PathAbs(candidatePath) if !absCandidateResult.OK { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "resolve config path failed: "+original, resultCause(absCandidateResult).(error))) + return core.Fail(core.E(callerValidateServiceLoadPath, "resolve config path failed: "+original, resultCause(absCandidateResult).(error))) } absCandidate := absCandidateResult.Value.(string) @@ -222,11 +224,11 @@ func resolveServiceLoadPathWithinCore(basePath, clean, original string) core.Res func ensureServicePathInsideCore(coreAbs, candidateAbs, original string) core.Result { relResult := core.PathRel(coreAbs, candidateAbs) if !relResult.OK { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "failed relative path check: "+original, resultCause(relResult).(error))) + return core.Fail(core.E(callerValidateServiceLoadPath, "failed relative path check: "+original, resultCause(relResult).(error))) } rel := relResult.Value.(string) if rel != "." && (rel == ".." || core.HasPrefix(rel, ".."+string(core.PathSeparator))) { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "config path escapes .core/: "+original, nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "config path escapes .core/: "+original, nil)) } return core.Ok(nil) } @@ -253,13 +255,13 @@ func isProjectCoreRelativePath(path string) bool { func resolveServiceLoadPath(candidatePath, coreAbs, absCandidate string) core.Result { resolvedCore := coreAbs if r := core.Lstat(coreAbs); r.OK && r.Value.(core.FsFileInfo).Mode()&core.ModeSymlink != 0 { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "symlinked .core directories are not allowed: "+coreAbs, nil)) + return core.Fail(core.E(callerValidateServiceLoadPath, "symlinked .core directories are not allowed: "+coreAbs, nil)) } if statResult := core.Stat(coreAbs); statResult.OK && statResult.Value.(core.FsFileInfo).IsDir() { if realCoreResult := core.PathEvalSymlinks(coreAbs); realCoreResult.OK { resolvedCore = realCoreResult.Value.(string) } else { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "resolve .core symlink failed: "+coreAbs, resultCause(realCoreResult).(error))) + return core.Fail(core.E(callerValidateServiceLoadPath, "resolve .core symlink failed: "+coreAbs, resultCause(realCoreResult).(error))) } } @@ -267,7 +269,7 @@ func resolveServiceLoadPath(candidatePath, coreAbs, absCandidate string) core.Re if core.Stat(absCandidate).OK { realCandidateResult := core.PathEvalSymlinks(absCandidate) if !realCandidateResult.OK { - return core.Fail(coreerr.E(callerValidateServiceLoadPath, "resolve config symlink failed: "+candidatePath, resultCause(realCandidateResult).(error))) + return core.Fail(core.E(callerValidateServiceLoadPath, "resolve config symlink failed: "+candidatePath, resultCause(realCandidateResult).(error))) } resolvedCandidate = realCandidateResult.Value.(string) } @@ -297,14 +299,27 @@ func (s *Service) registerActions(c *core.Core) { // registerCommands exposes config commands for CLI discovery. // // core config/get --key dev.editor -func (s *Service) registerCommands(c *core.Core) { - _ = c.Command(commandConfigGet, s.configCommand("Read a config value", c, commandConfigGet, configGetOperation)) - _ = c.Command(commandConfigSet, s.configCommand("Set a config value", c, commandConfigSet, configSetOperation)) - _ = c.Command(commandConfigList, s.configCommand("List all config values", c, commandConfigList, configAllOperation)) - _ = c.Command(commandConfigCommit, s.configCommand("Persist config changes", c, commandConfigCommit, configCommitOperation)) - _ = c.Command(commandConfigLoad, s.configCommand("Load a config file", c, commandConfigLoad, configLoadOperation)) - _ = c.Command(commandConfigAll, s.configCommand("List all config values", c, commandConfigAll, configAllOperation)) - _ = c.Command(commandConfigPath, s.configCommand("Show the config file path", c, commandConfigPath, configPathOperation)) +func (s *Service) registerCommands(c *core.Core) core.Result { + commands := []struct { + path string + description string + operation configOperation + }{ + {path: commandConfigGet, description: "Read a config value", operation: configGetOperation}, + {path: commandConfigSet, description: "Set a config value", operation: configSetOperation}, + {path: commandConfigList, description: "List all config values", operation: configAllOperation}, + {path: commandConfigCommit, description: "Persist config changes", operation: configCommitOperation}, + {path: commandConfigLoad, description: "Load a config file", operation: configLoadOperation}, + {path: commandConfigAll, description: "List all config values", operation: configAllOperation}, + {path: commandConfigPath, description: "Show the config file path", operation: configPathOperation}, + } + for _, command := range commands { + r := c.Command(command.path, s.configCommand(command.description, c, command.path, command.operation)) + if !r.OK { + return core.Fail(core.E(callerServiceRegisterCommands, "failed to register command: "+command.path, resultCause(r).(error))) + } + } + return core.Ok(nil) } func (s *Service) actionHandler(c *core.Core, name string, op configOperation) core.ActionHandler { @@ -327,7 +342,7 @@ func (s *Service) runConfigOperation(c *core.Core, name string, opts core.Option return result } if s.config == nil { - return core.Fail(coreerr.E(name, errConfigNotLoaded, nil)) + return core.Fail(core.E(name, errConfigNotLoaded, nil)) } return op(s, s.config, opts) } @@ -386,7 +401,7 @@ func configValues(cfg *Config) map[string]any { // svc.Get("dev.editor", &editor) func (s *Service) Get(key string, out any) core.Result { if s.config == nil { - return core.Fail(coreerr.E("config.Service.Get", errConfigNotLoaded, nil)) + return core.Fail(core.E("config.Service.Get", errConfigNotLoaded, nil)) } return s.config.Get(key, out) } @@ -396,7 +411,7 @@ func (s *Service) Get(key string, out any) core.Result { // svc.Set("dev.editor", "vim") func (s *Service) Set(key string, v any) core.Result { if s.config == nil { - return core.Fail(coreerr.E("config.Service.Set", errConfigNotLoaded, nil)) + return core.Fail(core.E("config.Service.Set", errConfigNotLoaded, nil)) } return s.config.Set(key, v) } @@ -406,7 +421,7 @@ func (s *Service) Set(key string, v any) core.Result { // svc.Commit() func (s *Service) Commit() core.Result { if s.config == nil { - return core.Fail(coreerr.E("config.Service.Commit", errConfigNotLoaded, nil)) + return core.Fail(core.E("config.Service.Commit", errConfigNotLoaded, nil)) } return s.config.Commit() } @@ -416,7 +431,7 @@ func (s *Service) Commit() core.Result { // svc.LoadFile(io.Local, ".core/build.yaml") func (s *Service) LoadFile(m coreio.Medium, path string) core.Result { if s.config == nil { - return core.Fail(coreerr.E("config.Service.LoadFile", errConfigNotLoaded, nil)) + return core.Fail(core.E("config.Service.LoadFile", errConfigNotLoaded, nil)) } resolvedPathResult := resolveValidatedServiceLoadPath(s.config.Path(), path) if !resolvedPathResult.OK { @@ -427,10 +442,10 @@ func (s *Service) LoadFile(m coreio.Medium, path string) core.Result { func ensureConfigEntitlement(c *core.Core, action string) core.Result { if c == nil { - return core.Fail(coreerr.E(action, "core not available", nil)) + return core.Fail(core.E(action, "core not available", nil)) } if e := c.Entitled(action); !e.Allowed { - return core.Fail(coreerr.E(action, "not entitled: "+action+": "+e.Reason, nil)) + return core.Fail(core.E(action, "not entitled: "+action+": "+e.Reason, nil)) } return core.Ok(nil) } diff --git a/go/test_detect.go b/go/test_detect.go index 47dcf1b..a2d01bc 100644 --- a/go/test_detect.go +++ b/go/test_detect.go @@ -3,7 +3,6 @@ package config import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const callerResolveTestManifest = "config.ResolveTestManifest" @@ -59,14 +58,14 @@ func detectTestCommandAtDir(medium coreio.Medium, dir string) core.Result { func detectJSONTestCommand(medium coreio.Medium, path, label, fallback string) core.Result { content, err := medium.Read(path) if err != nil { - return core.Fail(coreerr.E(callerResolveTestManifest, "failed to read "+label+" manifest: "+path, err)) + return core.Fail(core.E(callerResolveTestManifest, "failed to read "+label+" manifest: "+path, err)) } var data struct { Scripts map[string]any `json:"scripts"` } if r := core.JSONUnmarshalString(content, &data); !r.OK { - return core.Fail(coreerr.E(callerResolveTestManifest, "failed to parse "+label+" manifest: "+path, resultCause(r).(error))) + return core.Fail(core.E(callerResolveTestManifest, "failed to parse "+label+" manifest: "+path, resultCause(r).(error))) } raw, ok := data.Scripts["test"] @@ -76,7 +75,7 @@ func detectJSONTestCommand(medium coreio.Medium, path, label, fallback string) c script, ok := raw.(string) if !ok { - return core.Fail(coreerr.E(callerResolveTestManifest, "invalid "+label+" test script: "+path, nil)) + return core.Fail(core.E(callerResolveTestManifest, "invalid "+label+" test script: "+path, nil)) } if script == "" { return core.Ok(detectedTestCommand{Command: fallback, Found: true}) diff --git a/go/watch.go b/go/watch.go index f960c81..cf1754d 100644 --- a/go/watch.go +++ b/go/watch.go @@ -7,7 +7,6 @@ import ( "time" core "dappco.re/go" - coreerr "dappco.re/go/log" "github.com/fsnotify/fsnotify" ) @@ -80,7 +79,7 @@ func (c *Config) Watch() core.Result { wResult := newWatchBackend() if !wResult.OK { c.mu.Unlock() - return core.Fail(coreerr.E("config.Watch", "failed to create watcher", resultCause(wResult).(error))) + return core.Fail(core.E("config.Watch", "failed to create watcher", resultCause(wResult).(error))) } w := wResult.Value.(watchBackend) path := c.path @@ -96,7 +95,7 @@ func (c *Config) Watch() core.Result { c.mu.Lock() c.watcher = nil c.mu.Unlock() - return core.Fail(coreerr.E("config.Watch", "failed to watch path: "+path, watchErr)) + return core.Fail(core.E("config.Watch", "failed to watch path: "+path, watchErr)) } go c.watchLoop(fw)