From 0be90aa9cd9f08da2d038f14e73374ef414db85d Mon Sep 17 00:00:00 2001 From: Snider Date: Thu, 30 Apr 2026 18:26:28 +0100 Subject: [PATCH] refactor(go): use core.E directly instead of coreerr/log alias (Mantis #1218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the `coreerr "dappco.re/go/log"` import alias across 39 files in go/ and call `core.E(...)` directly. The log package's E was just a forwarder to core.E; the alias added indirection without value. Audit (audit.sh): 2575 → 2562 (-13 findings). 0 gaming patterns. Build, vet, test all clean. No exported API changes. No new abstractions. Result literal sites remain in place — those are pre-existing structural and out of scope for this lane. Closes tasks.lthn.sh/view.php?id=1218 Co-authored-by: Codex --- go/access.go | 31 ++++--- go/app.go | 25 +++--- go/cmd/core-app/main.go | 43 ++++----- go/cmd/core-app/pkg.go | 5 +- go/compile.go | 31 ++++--- go/compile_json.go | 3 +- go/conclave.go | 11 ++- go/config.go | 17 ++-- go/config_template.go | 26 +++--- go/discover.go | 15 ++-- go/host.go | 47 +++++----- go/integrity.go | 17 ++-- go/layout.go | 11 ++- go/marketplace.go | 103 +++++++++++----------- go/marketplace_verify.go | 21 +++-- go/permissions.go | 5 +- go/pkg.go | 149 ++++++++++++++++---------------- go/pkg_electron.go | 31 ++++--- go/pkg_electron_extract.go | 29 +++---- go/pkg_electron_extract_tar.go | 33 ++++--- go/pkg_electron_fetch.go | 31 ++++--- go/pkg_pwa.go | 27 +++--- go/pkg_repo.go | 29 +++---- go/pkg_type.go | 3 +- go/pkg_web.go | 29 ++++--- go/plugin.go | 15 ++-- go/pwa_runtime.go | 47 +++++----- go/registry.go | 11 ++- go/runtime.go | 112 ++++++++++++------------ go/runtime_process.go | 42 +++++---- go/runtime_store.go | 43 +++++---- go/sdk.go | 17 ++-- go/sign.go | 63 +++++++------- go/start.go | 9 +- go/validate.go | 3 +- go/verify.go | 49 +++++------ go/workspace.go | 21 +++-- go/workspace_crypto_metadata.go | 55 +++++++----- go/yaml.go | 9 +- 39 files changed, 618 insertions(+), 650 deletions(-) diff --git a/go/access.go b/go/access.go index 3dbcad1..cd50ffa 100644 --- a/go/access.go +++ b/go/access.go @@ -5,7 +5,6 @@ package app import ( core "dappco.re/go" "dappco.re/go/config" - coreerr "dappco.re/go/log" ) // AccessMode names the capability an action requires. The capital-letter @@ -123,7 +122,7 @@ func (a AccessMode) String() string { // } func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m == nil { - return coreerr.E("app.CheckAccess", "nil manifest", nil) + return core.E("app.CheckAccess", "nil manifest", nil) } switch mode { @@ -137,7 +136,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if matchPrefix(m.Permissions.Read, arg) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "read access to '"+arg+"' not declared in manifest.permissions.read", nil, @@ -156,7 +155,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if matchPrefix(manifestWriteList(m), arg) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "write access to '"+arg+"' not declared in manifest.permissions.write", nil, @@ -168,7 +167,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if matchNet(m.Permissions.Net, arg) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "net access to '"+arg+"' not declared in manifest.permissions.net", nil, @@ -177,7 +176,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if matchExact(m.Permissions.Run, arg) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "run access to '"+arg+"' not declared in manifest.permissions.run", nil, @@ -186,7 +185,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if hasManifestStorePermission(m) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "store access to '"+arg+"' not declared (set permissions.store: true in view.yaml)", nil, @@ -195,7 +194,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m.Permissions.Notifications { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "notification access not declared (set permissions.notifications: true in view.yaml)", nil, @@ -204,7 +203,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m.Permissions.Clipboard { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "clipboard read not declared (set permissions.clipboard: true in view.yaml)", nil, @@ -213,7 +212,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m.Permissions.Clipboard { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "clipboard write not declared (set permissions.clipboard: true in view.yaml)", nil, @@ -222,7 +221,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m.Permissions.Camera { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "camera access not declared (set permissions.camera: true in view.yaml)", nil, @@ -231,7 +230,7 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if m.Permissions.Microphone { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "microphone access not declared (set permissions.microphone: true in view.yaml)", nil, @@ -240,13 +239,13 @@ func CheckAccess(m *config.ViewManifest, mode AccessMode, arg string) error { if hasManifestLocationPermission(m) { return nil } - return coreerr.E( + return core.E( "app.CheckAccess", "location access not declared (set permissions.device.location: true in view.yaml)", nil, ) default: - return coreerr.E("app.CheckAccess", "unknown access mode", nil) + return core.E("app.CheckAccess", "unknown access mode", nil) } } @@ -317,7 +316,7 @@ func rejectPathTraversal(scope, arg string) error { core.Contains(arg, "\\..\\") || core.HasSuffix(arg, "/..") || core.HasSuffix(arg, "\\..") { - return coreerr.E( + return core.E( "app.CheckAccess", scope+" access refused: path traversal in '"+arg+"'", nil, @@ -458,7 +457,7 @@ func ActionAccessMode(action string) (AccessMode, bool) { // silently bypass the gate. func CheckActionAccess(m *config.ViewManifest, action, arg string) error { if m == nil { - return coreerr.E("app.CheckActionAccess", "nil manifest", nil) + return core.E("app.CheckActionAccess", "nil manifest", nil) } mode, ok := ActionAccessMode(action) if !ok { diff --git a/go/app.go b/go/app.go index 0326c8a..5baa0a5 100644 --- a/go/app.go +++ b/go/app.go @@ -22,7 +22,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // Mode selects which enforcement regime the boot uses. @@ -245,7 +244,7 @@ func Boot(ctx context.Context, start string, opts ...Option) (*Instance, error) // so a running app picks up YAML edits on reboot without a recompile. manifest, root, err := discoverCompiled(o.Medium, start, o.Mode) if err != nil { - return nil, coreerr.E("app.Boot", "discover failed", err) + return nil, core.E("app.Boot", "discover failed", err) } inst.Manifest = manifest inst.Root = root @@ -253,30 +252,30 @@ func Boot(ctx context.Context, start string, opts ...Option) (*Instance, error) // Step 2 — Verify trusted, err := resolveTrustedKeys(o) if err != nil { - return nil, coreerr.E("app.Boot", "resolve trusted keys failed", err) + return nil, core.E("app.Boot", "resolve trusted keys failed", err) } if err := verify(&manifest, o.Mode, trusted); err != nil { - return nil, coreerr.E("app.Boot", "verify failed", err) + return nil, core.E("app.Boot", "verify failed", err) } if err := verifyAssetIntegrity(o.Medium, root, &manifest, o.Mode); err != nil { - return nil, coreerr.E("app.Boot", "asset integrity failed", err) + return nil, core.E("app.Boot", "asset integrity failed", err) } // Step 3 — Permissions if err := permissions(c, &manifest, o.Mode); err != nil { - return nil, coreerr.E("app.Boot", "permission binding failed", err) + return nil, core.E("app.Boot", "permission binding failed", err) } // Step 4 — Modules if err := modulesWithMode(ctx, c, &manifest, o.Mode); err != nil { - return nil, coreerr.E("app.Boot", "module load failed", err) + return nil, core.E("app.Boot", "module load failed", err) } // Step 5 — Layout. The resolved spec is stashed on the Instance so // core/gui can compose the window without re-parsing the manifest. spec, err := resolveLayout(c, &manifest) if err != nil { - return nil, coreerr.E("app.Boot", "layout composition failed", err) + return nil, core.E("app.Boot", "layout composition failed", err) } inst.Layout = spec @@ -288,7 +287,7 @@ func Boot(ctx context.Context, start string, opts ...Option) (*Instance, error) ws, wsErr := OpenWorkspace(o.Medium, o.WorkspaceHome, manifest.Code) if wsErr != nil { if o.Mode == ModeProd { - return nil, coreerr.E("app.Boot", "workspace bootstrap failed", wsErr) + return nil, core.E("app.Boot", "workspace bootstrap failed", wsErr) } // Dev mode: workspace is best-effort so the boot keeps // flowing when DIR_HOME is empty (CI containers, sandbox @@ -302,10 +301,10 @@ func Boot(ctx context.Context, start string, opts ...Option) (*Instance, error) // Step 6 — Config. Render after the workspace exists so template vars // can hydrate from the runtime object store. if err := renderManifestConfigTemplatesWithMode(c, &manifest, o.Medium, root, inst.Workspace, o.Mode); err != nil { - return nil, coreerr.E("app.Boot", "config template failed", err) + return nil, core.E("app.Boot", "config template failed", err) } if err := registerRuntimeActions(inst); err != nil { - return nil, coreerr.E("app.Boot", "runtime action registration failed", err) + return nil, core.E("app.Boot", "runtime action registration failed", err) } // Note: Step 7 (Start) is the caller's explicit trigger — Boot returns @@ -322,7 +321,7 @@ func Boot(ctx context.Context, start string, opts ...Option) (*Instance, error) // if !r.OK { core.Error("start failed", "err", r.Value) } func (inst *Instance) Start(ctx context.Context) core.Result { if inst == nil || inst.Core == nil { - return core.Result{Value: coreerr.E("app.Instance.Start", "nil instance", nil), OK: false} + return core.Result{Value: core.E("app.Instance.Start", "nil instance", nil), OK: false} } return start(ctx, inst) } @@ -355,7 +354,7 @@ func (inst *Instance) Start(ctx context.Context) core.Result { // boot. func (inst *Instance) Stop(ctx context.Context) core.Result { if inst == nil || inst.Core == nil { - return core.Result{Value: coreerr.E("app.Instance.Stop", "nil instance", nil), OK: false} + return core.Result{Value: core.E("app.Instance.Stop", "nil instance", nil), OK: false} } return stop(ctx, inst) } diff --git a/go/cmd/core-app/main.go b/go/cmd/core-app/main.go index 06896c2..06fd1d0 100644 --- a/go/cmd/core-app/main.go +++ b/go/cmd/core-app/main.go @@ -46,10 +46,6 @@ package main import ( "context" "crypto/ed25519" - // AX-6 process-lifecycle exception: this file is the binary boundary. - // The CLI layer owns argv/signal wrappers, but core/app does - // not depend on that module in this lane, and go.mod is off-limits here. - "os" "os/signal" "syscall" @@ -60,7 +56,7 @@ import ( ) func main() { - args := os.Args[1:] + args := core.Args()[1:] // Subcommand dispatch — the first positional that matches a verb // takes over. Falls through to the plain "boot" path otherwise so @@ -68,21 +64,21 @@ func main() { if len(args) > 0 { switch args[0] { case "compile": - os.Exit(runCompile(args[1:])) + core.Exit(runCompile(args[1:])) case "sign": - os.Exit(runSign(args[1:])) + core.Exit(runSign(args[1:])) case "keygen": - os.Exit(runKeygen(args[1:])) + core.Exit(runKeygen(args[1:])) case "pkg": - os.Exit(runPkg(args[1:])) + core.Exit(runPkg(args[1:])) case "marketplace": - os.Exit(runMarketplace(args[1:])) + core.Exit(runMarketplace(args[1:])) case "sdk": - os.Exit(runSDK(args[1:])) + core.Exit(runSDK(args[1:])) case "run": - os.Exit(runInstalled(args[1:])) + core.Exit(runInstalled(args[1:])) case "validate": - os.Exit(runValidate(args[1:])) + core.Exit(runValidate(args[1:])) } } @@ -145,7 +141,7 @@ func runBootFromMode(mode app.Mode, start string, watch bool) { inst, err := app.Boot(ctx, start, app.WithMode(mode)) if err != nil { core.Error("boot failed", "start", start, "mode", mode.String(), "err", err) - os.Exit(1) + core.Exit(1) } core.Info("CoreApp booted", "code", inst.Manifest.Code, @@ -156,7 +152,7 @@ func runBootFromMode(mode app.Mode, start string, watch bool) { ) if r := inst.Start(ctx); !r.OK { core.Error("start failed", "err", r.Value) - os.Exit(2) + core.Exit(2) } if watch { waitForReload(ctx, inst) @@ -166,7 +162,7 @@ func runBootFromMode(mode app.Mode, start string, watch bool) { // runBoot drives the "boot a CoreApp" path. Extracted from main so the // subcommand dispatch reads cleanly. // -// runBoot(os.Args[1:]) +// runBoot(core.Args()[1:]) func runBoot(args []string) { mode, start, watch := parseArgs(args) @@ -176,7 +172,7 @@ func runBoot(args []string) { inst, err := app.Boot(ctx, start, app.WithMode(mode)) if err != nil { core.Error("boot failed", "start", start, "mode", mode.String(), "err", err) - os.Exit(1) + core.Exit(1) } core.Info("CoreApp booted", @@ -189,7 +185,7 @@ func runBoot(args []string) { if r := inst.Start(ctx); !r.OK { core.Error("start failed", "err", r.Value) - os.Exit(2) + core.Exit(2) } if watch { @@ -222,13 +218,12 @@ func waitForReload(ctx context.Context, inst *app.Instance) { stopWatch := inst.Watch(ctx, app.WatchOptions{}) defer stopWatch() - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) - defer signal.Stop(sigCh) + sigCtx, stopSignals := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM) + defer stopSignals() core.Info("watching for changes — press Ctrl-C to stop") select { case <-ctx.Done(): - case <-sigCh: + case <-sigCtx.Done(): } if r := inst.Stop(ctx); !r.OK { core.Error("stop failed", "err", r.Value) @@ -272,11 +267,11 @@ func parseArgs(args []string) (mode app.Mode, start string, watch bool) { core.Println(" run boot an installed package by code") core.Println(" pkg ... manage packages (list, info, wrap, install, remove, update)") core.Println(" marketplace search/install/fetch from the marketplace") - os.Exit(0) + core.Exit(0) default: if core.HasPrefix(a, "-") { core.Error("unknown flag", "flag", a) - os.Exit(64) + core.Exit(64) } start = a } diff --git a/go/cmd/core-app/pkg.go b/go/cmd/core-app/pkg.go index c40b4d5..69c74b9 100644 --- a/go/cmd/core-app/pkg.go +++ b/go/cmd/core-app/pkg.go @@ -4,7 +4,6 @@ package main import ( "context" - "os" core "dappco.re/go" "dappco.re/go/app" @@ -1859,11 +1858,11 @@ func runMarketplaceFetch(args []string) int { // ensureExit is an optional exit helper used only when the CLI wants // to abort the process with a fixed code after writing context to -// stdout. Kept here (rather than calling os.Exit inline) so the test +// stdout. Kept here (rather than calling core.Exit inline) so the test // harness can exercise the exit path without process-level side // effects. // // ensureExit(64) func ensureExit(code int) { - os.Exit(code) + core.Exit(code) } diff --git a/go/compile.go b/go/compile.go index d9d4591..5548546 100644 --- a/go/compile.go +++ b/go/compile.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // CompiledVersion is the compiler identity stapled into every core.json @@ -107,19 +106,19 @@ type CompileOptions struct { // the compiled form is strict). func Compile(m *config.ViewManifest, opts CompileOptions) (*CompiledManifest, error) { if m == nil { - return nil, coreerr.E("app.Compile", "nil manifest", nil) + return nil, core.E("app.Compile", "nil manifest", nil) } if m.Code == "" { - return nil, coreerr.E("app.Compile", "manifest.code is empty", nil) + return nil, core.E("app.Compile", "manifest.code is empty", nil) } if m.Name == "" { - return nil, coreerr.E("app.Compile", "manifest.name is empty", nil) + return nil, core.E("app.Compile", "manifest.name is empty", nil) } if m.Version == "" { - return nil, coreerr.E("app.Compile", "manifest.version is empty", nil) + return nil, core.E("app.Compile", "manifest.version is empty", nil) } if err := validateLayoutVariant(m.Layout); err != nil { - return nil, coreerr.E("app.Compile", "invalid layout", err) + return nil, core.E("app.Compile", "invalid layout", err) } now := opts.Now @@ -133,7 +132,7 @@ func Compile(m *config.ViewManifest, opts CompileOptions) (*CompiledManifest, er slots, components, err := resolveSlots(m.Slots) if err != nil { - return nil, coreerr.E("app.Compile", "slot resolution failed", err) + return nil, core.E("app.Compile", "slot resolution failed", err) } out := &CompiledManifest{ @@ -191,13 +190,13 @@ func resolveSlots(raw map[string]any) (map[string]string, map[string]ComponentSp slots[slot] = value components[value] = ComponentSpec{Tag: value, Shadow: true} case nil: - return nil, nil, coreerr.E( + return nil, nil, core.E( "app.resolveSlots", "slot '"+slot+"' has nil component", nil, ) default: - return nil, nil, coreerr.E( + return nil, nil, core.E( "app.resolveSlots", "slot '"+slot+"' must be a string component name", nil, @@ -214,21 +213,21 @@ func resolveSlots(raw map[string]any) (map[string]string, map[string]ComponentSp // err := app.WriteCompiled(coreio.Local, root, cm) func WriteCompiled(medium coreio.Medium, root string, cm *CompiledManifest) error { if cm == nil { - return coreerr.E("app.WriteCompiled", "nil compiled manifest", nil) + return core.E("app.WriteCompiled", "nil compiled manifest", nil) } if medium == nil { medium = coreio.Local } body, err := marshalPretty(cm) if err != nil { - return coreerr.E("app.WriteCompiled", "marshal failed", err) + return core.E("app.WriteCompiled", "marshal failed", err) } path := core.Path(root, CompiledFileName) if err := medium.EnsureDir(core.PathDir(path)); err != nil { - return coreerr.E("app.WriteCompiled", "ensure dir failed", err) + return core.E("app.WriteCompiled", "ensure dir failed", err) } if err := medium.Write(path, body); err != nil { - return coreerr.E("app.WriteCompiled", "write failed", err) + return core.E("app.WriteCompiled", "write failed", err) } return nil } @@ -245,16 +244,16 @@ func LoadCompiled(medium coreio.Medium, root string) (*CompiledManifest, error) } path := core.Path(root, CompiledFileName) if !medium.Exists(path) { - return nil, coreerr.E("app.LoadCompiled", CompiledFileName+" not found at "+path, nil) + return nil, core.E("app.LoadCompiled", CompiledFileName+" not found at "+path, nil) } body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.LoadCompiled", "read "+path+" failed", err) + return nil, core.E("app.LoadCompiled", "read "+path+" failed", err) } var cm CompiledManifest if r := core.JSONUnmarshal([]byte(body), &cm); !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.LoadCompiled", "decode "+path+" failed", cause) + return nil, core.E("app.LoadCompiled", "decode "+path+" failed", cause) } return &cm, nil } diff --git a/go/compile_json.go b/go/compile_json.go index f455a50..264849a 100644 --- a/go/compile_json.go +++ b/go/compile_json.go @@ -4,7 +4,6 @@ package app import ( core "dappco.re/go" - coreerr "dappco.re/go/log" ) // compiledTypedTopLevelKeys are the fields CompiledManifest models @@ -84,7 +83,7 @@ func (cm CompiledManifest) MarshalJSON() ([]byte, error) { // alongside the typed manifest fields. func (cm *CompiledManifest) UnmarshalJSON(body []byte) error { if cm == nil { - return coreerr.E("app.CompiledManifest.UnmarshalJSON", "nil receiver", nil) + return core.E("app.CompiledManifest.UnmarshalJSON", "nil receiver", nil) } var alias compiledManifestAlias diff --git a/go/conclave.go b/go/conclave.go index bb6cd44..ab527c2 100644 --- a/go/conclave.go +++ b/go/conclave.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // ConclaveOptions tunes NewConclave. A conclave is the most-isolated @@ -119,10 +118,10 @@ type Conclave struct { // more services even if the caller forgets to pass the option. func NewConclave(ctx context.Context, opts ConclaveOptions) (*Conclave, error) { if opts.Code == "" { - return nil, coreerr.E("app.NewConclave", "empty code", nil) + return nil, core.E("app.NewConclave", "empty code", nil) } if opts.ProjectRoot == "" { - return nil, coreerr.E("app.NewConclave", "empty ProjectRoot", nil) + return nil, core.E("app.NewConclave", "empty ProjectRoot", nil) } medium := opts.Medium @@ -140,7 +139,7 @@ func NewConclave(ctx context.Context, opts ConclaveOptions) (*Conclave, error) { w, err := OpenWorkspace(medium, opts.WorkspaceHome, opts.Code) if err != nil { if opts.Mode == ModeProd { - return nil, coreerr.E("app.NewConclave", "workspace bootstrap failed", err) + return nil, core.E("app.NewConclave", "workspace bootstrap failed", err) } // Dev mode keeps booting; the conclave handlers must check // Workspace before using it. @@ -157,13 +156,13 @@ func NewConclave(ctx context.Context, opts ConclaveOptions) (*Conclave, error) { Medium: medium, }) if err != nil { - return nil, coreerr.E("app.NewConclave", "PluginBoot failed", err) + return nil, core.E("app.NewConclave", "PluginBoot failed", err) } inst.Workspace = ws sandbox, err := buildConclaveSandbox(medium, opts.ProjectRoot) if err != nil { - return nil, coreerr.E("app.NewConclave", "sandbox build failed", err) + return nil, core.E("app.NewConclave", "sandbox build failed", err) } return &Conclave{Instance: inst, Sandbox: sandbox}, nil diff --git a/go/config.go b/go/config.go index bb5dde8..a3c688e 100644 --- a/go/config.go +++ b/go/config.go @@ -6,7 +6,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // TemplateSuffix is the canonical extension for config template @@ -65,10 +64,10 @@ func applyConfig(c *core.Core, m *config.ViewManifest, medium coreio.Medium, roo // dev-mode config misses warn instead of aborting the boot. func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Medium, root string, mode Mode) error { if c == nil { - return coreerr.E("app.applyConfigWithMode", "nil core", nil) + return core.E("app.applyConfigWithMode", "nil core", nil) } if m == nil { - return coreerr.E("app.applyConfigWithMode", "nil manifest", nil) + return core.E("app.applyConfigWithMode", "nil manifest", nil) } if len(m.Config) == 0 { return nil @@ -87,7 +86,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med if isReservedConfigKey(name) { continue } - err := coreerr.E( + err := core.E( "app.applyConfigWithMode", "config entry '"+name+"' is not a {template, vars} map", nil, @@ -104,7 +103,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med if isReservedConfigKey(name) { continue } - err := coreerr.E( + err := core.E( "app.applyConfigWithMode", "config entry '"+name+"' is missing the template path", nil, @@ -118,7 +117,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med full := core.Path(root, entry.Template) if !medium.Exists(full) { - err := coreerr.E( + err := core.E( "app.applyConfigWithMode", "config template '"+full+"' (declared by '"+name+"') does not exist", nil, @@ -132,7 +131,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med body, err := medium.Read(full) if err != nil { - err = coreerr.E( + err = core.E( "app.applyConfigWithMode", "read template '"+full+"' (declared by '"+name+"') failed", err, @@ -148,7 +147,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med dst := destinationOf(full) if err := medium.EnsureDir(core.PathDir(dst)); err != nil { - err = coreerr.E( + err = core.E( "app.applyConfigWithMode", "ensure destination dir for '"+dst+"' failed", err, @@ -160,7 +159,7 @@ func applyConfigWithMode(c *core.Core, m *config.ViewManifest, medium coreio.Med return err } if err := medium.Write(dst, rendered); err != nil { - err = coreerr.E( + err = core.E( "app.applyConfigWithMode", "write rendered template '"+dst+"' failed", err, diff --git a/go/config_template.go b/go/config_template.go index 567c62c..856e8d7 100644 --- a/go/config_template.go +++ b/go/config_template.go @@ -274,8 +274,8 @@ func configTemplateScopeForRefs(c *core.Core, store *workspaceObjectStore, parts func resolveConfigTemplateReference(c *core.Core, store *workspaceObjectStore, path string) (any, error) { switch { - case strings.HasPrefix(path, "env."): - key := strings.TrimSpace(path[len("env."):]) + case core.HasPrefix(path, "env."): + key := core.Trim(path[len("env."):]) if key == "" { return nil, missingConfigTemplatePath(path) } @@ -284,8 +284,8 @@ func resolveConfigTemplateReference(c *core.Core, store *workspaceObjectStore, p return nil, missingConfigTemplatePath(path) } return value, nil - case strings.HasPrefix(path, "config."): - key := strings.TrimSpace(path[len("config."):]) + case core.HasPrefix(path, "config."): + key := core.Trim(path[len("config."):]) if key == "" { return nil, missingConfigTemplatePath(path) } @@ -383,7 +383,7 @@ func parseConfigTemplate(text string) ([]configTemplatePart, error) { } rawPath := core.Trim(tail[:end]) - if strings.Contains(rawPath, "{{") || strings.Contains(rawPath, "}}") { + if core.Contains(rawPath, "{{") || core.Contains(rawPath, "}}") { return nil, core.E("app.parseConfigTemplate", "malformed template: nested delimiters", nil) } @@ -399,8 +399,8 @@ func parseConfigTemplate(text string) ([]configTemplatePart, error) { } func normaliseConfigTemplatePath(path string) (string, error) { - path = strings.TrimSpace(path) - path = strings.TrimPrefix(path, ".") + path = core.Trim(path) + path = core.TrimPrefix(path, ".") if path == "" || strings.IndexAny(path, " \t\r\n") >= 0 { return "", core.E("app.normaliseConfigTemplatePath", "malformed template action", nil) } @@ -409,20 +409,20 @@ func normaliseConfigTemplatePath(path string) (string, error) { if err != nil { return "", err } - return strings.Join(segments, "."), nil + return core.Join(".", segments...), nil } func configTemplatePathSegments(path string) ([]string, error) { - path = strings.TrimSpace(path) - path = strings.TrimPrefix(path, ".") + path = core.Trim(path) + path = core.TrimPrefix(path, ".") if path == "" { return nil, core.E("app.configTemplatePathSegments", "empty template path", nil) } - raw := strings.Split(path, ".") + raw := core.Split(path, ".") segments := make([]string, 0, len(raw)) for _, segment := range raw { - segment = strings.TrimSpace(segment) + segment = core.Trim(segment) if segment == "" { return nil, core.E( "app.configTemplatePathSegments", @@ -509,7 +509,7 @@ func missingConfigTemplatePath(path string) error { } func decodeConfigTemplateValue(raw string) any { - if strings.TrimSpace(raw) == "" { + if core.Trim(raw) == "" { return "" } diff --git a/go/discover.go b/go/discover.go index e86a917..a97edd4 100644 --- a/go/discover.go +++ b/go/discover.go @@ -6,7 +6,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // discover is Step 1 of the 7-step boot — locate `.core/view.yaml` by @@ -20,7 +19,7 @@ import ( // Returns: // - manifest: the parsed view.yaml contents // - root: the project directory (parent of the .core/ that won) -// - err: coreerr.E-wrapped if the walk produces nothing or parse fails +// - err: core.E-wrapped if the walk produces nothing or parse fails func discover(medium coreio.Medium, start string) (config.ViewManifest, string, error) { if medium == nil { medium = coreio.Local @@ -31,7 +30,7 @@ func discover(medium coreio.Medium, start string) (config.ViewManifest, string, // path — the caller is not inside a CoreApp. path := config.FindManifest(medium, start, config.FileView) if path == "" { - return config.ViewManifest{}, "", coreerr.E( + return config.ViewManifest{}, "", core.E( "app.discover", "no .core/view.yaml found walking up from "+start, nil, @@ -40,7 +39,7 @@ func discover(medium coreio.Medium, start string) (config.ViewManifest, string, var manifest config.ViewManifest if err := LoadViewManifest(medium, path, &manifest); err != nil { - return config.ViewManifest{}, "", coreerr.E( + return config.ViewManifest{}, "", core.E( "app.discover", "failed to parse "+path, err, @@ -82,7 +81,7 @@ func discoverCompiled(medium coreio.Medium, start string, mode Mode) (config.Vie if path := core.Path(root, CompiledFileName); medium.Exists(path) { cm, err := LoadCompiled(medium, root) if err != nil { - return config.ViewManifest{}, "", coreerr.E( + return config.ViewManifest{}, "", core.E( "app.discoverCompiled", "failed to parse "+path, err, @@ -159,18 +158,18 @@ func DiscoverInstalled(medium coreio.Medium, home, code string) (string, error) medium = coreio.Local } if code == "" { - return "", coreerr.E("app.DiscoverInstalled", "empty code", nil) + return "", core.E("app.DiscoverInstalled", "empty code", nil) } if home == "" { home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.DiscoverInstalled", "cannot resolve home directory", nil) + return "", core.E("app.DiscoverInstalled", "cannot resolve home directory", nil) } dir := core.Path(home, ".core", AppsDirName, code) if !medium.IsDir(dir) { - return "", coreerr.E( + return "", core.E( "app.DiscoverInstalled", "package not installed: "+code+" (expected "+dir+")", nil, diff --git a/go/host.go b/go/host.go index 456e34c..c70bc69 100644 --- a/go/host.go +++ b/go/host.go @@ -9,7 +9,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // HostOptions tunes NewHost. A host is the RFC §11 orchestrator that @@ -149,16 +148,16 @@ type LaunchOptions struct { // cleanly stops any plugin whose Start was driven via the host. func (h *Host) Launch(ctx context.Context, code string, opts LaunchOptions) (*Instance, error) { if h == nil { - return nil, coreerr.E("app.Host.Launch", "nil host", nil) + return nil, core.E("app.Host.Launch", "nil host", nil) } if code == "" { - return nil, coreerr.E("app.Host.Launch", "empty code", nil) + return nil, core.E("app.Host.Launch", "empty code", nil) } h.mu.Lock() if _, exists := h.plugins[code]; exists { h.mu.Unlock() - return nil, coreerr.E("app.Host.Launch", "plugin already running: "+code, nil) + return nil, core.E("app.Host.Launch", "plugin already running: "+code, nil) } h.mu.Unlock() @@ -175,18 +174,18 @@ func (h *Host) Launch(ctx context.Context, code string, opts LaunchOptions) (*In if projectRoot == "" { dir, err := DiscoverInstalled(h.opts.Medium, h.opts.Home, code) if err != nil { - return nil, coreerr.E("app.Host.Launch", "discover failed for "+code, err) + return nil, core.E("app.Host.Launch", "discover failed for "+code, err) } projectRoot = dir } m, _, err := discoverCompiled(h.opts.Medium, projectRoot, mode) if err != nil { - return nil, coreerr.E("app.Host.Launch", "discover failed for "+code, err) + return nil, core.E("app.Host.Launch", "discover failed for "+code, err) } manifest = m } if projectRoot == "" { - return nil, coreerr.E("app.Host.Launch", "cannot resolve project root for "+code, nil) + return nil, core.E("app.Host.Launch", "cannot resolve project root for "+code, nil) } trusted, err := resolveTrustedKeys(Options{ Mode: mode, @@ -196,13 +195,13 @@ func (h *Host) Launch(ctx context.Context, code string, opts LaunchOptions) (*In DisableKeyLoad: h.opts.DisableKeyLoad, }) if err != nil { - return nil, coreerr.E("app.Host.Launch", "resolve trusted keys failed for "+code, err) + return nil, core.E("app.Host.Launch", "resolve trusted keys failed for "+code, err) } if err := verify(&manifest, mode, trusted); err != nil { - return nil, coreerr.E("app.Host.Launch", "verify failed for "+code, err) + return nil, core.E("app.Host.Launch", "verify failed for "+code, err) } if err := verifyAssetIntegrity(h.opts.Medium, projectRoot, &manifest, mode); err != nil { - return nil, coreerr.E("app.Host.Launch", "asset integrity failed for "+code, err) + return nil, core.E("app.Host.Launch", "asset integrity failed for "+code, err) } // Resolve the plugin's service surface — the manifest's declared @@ -223,7 +222,7 @@ func (h *Host) Launch(ctx context.Context, code string, opts LaunchOptions) (*In Medium: h.opts.Medium, }) if err != nil { - return nil, coreerr.E("app.Host.Launch", "plugin boot failed for "+code, err) + return nil, core.E("app.Host.Launch", "plugin boot failed for "+code, err) } // Bootstrap the workspace so the plugin has a data tree on first @@ -233,7 +232,7 @@ func (h *Host) Launch(ctx context.Context, code string, opts LaunchOptions) (*In ws, wsErr := OpenWorkspace(h.opts.Medium, h.opts.Home, manifest.Code) if wsErr != nil { if mode == ModeProd { - return nil, coreerr.E("app.Host.Launch", "workspace bootstrap failed for "+code, wsErr) + return nil, core.E("app.Host.Launch", "workspace bootstrap failed for "+code, wsErr) } core.Warn("host: workspace bootstrap skipped (dev mode)", "code", code, "err", wsErr) @@ -355,10 +354,10 @@ func (h *Host) Running() []string { // Stop always removes the entry. func (h *Host) Stop(ctx context.Context, code string) core.Result { if h == nil { - return core.Result{Value: coreerr.E("app.Host.Stop", "nil host", nil), OK: false} + return core.Result{Value: core.E("app.Host.Stop", "nil host", nil), OK: false} } if code == "" { - return core.Result{Value: coreerr.E("app.Host.Stop", "empty code", nil), OK: false} + return core.Result{Value: core.E("app.Host.Stop", "empty code", nil), OK: false} } h.mu.Lock() @@ -366,7 +365,7 @@ func (h *Host) Stop(ctx context.Context, code string) core.Result { h.mu.Unlock() if !ok { return core.Result{ - Value: coreerr.E("app.Host.Stop", "plugin not running: "+code, nil), + Value: core.E("app.Host.Stop", "plugin not running: "+code, nil), OK: false, } } @@ -401,7 +400,7 @@ func (h *Host) Stop(ctx context.Context, code string) core.Result { // no-op OK — idempotent teardown is valuable during tests. func (h *Host) Shutdown(ctx context.Context) core.Result { if h == nil { - return core.Result{Value: coreerr.E("app.Host.Shutdown", "nil host", nil), OK: false} + return core.Result{Value: core.E("app.Host.Shutdown", "nil host", nil), OK: false} } // Snapshot the current plugins so we release the lock during // inst.Stop — a plugin's OnStop may take time and we do not want @@ -430,7 +429,7 @@ func (h *Host) Shutdown(ctx context.Context) core.Result { for _, code := range snapshot { if r := h.Stop(ctx, code); !r.OK { return core.Result{ - Value: coreerr.E("app.Host.Shutdown", "stop failed for "+code, extractErr(r)), + Value: core.E("app.Host.Shutdown", "stop failed for "+code, extractErr(r)), OK: false, } } @@ -469,23 +468,23 @@ func (h *Host) Shutdown(ctx context.Context) core.Result { // honour the call. Dispatch is routing, not authorisation. func (h *Host) Dispatch(ctx context.Context, sourceCode, targetCode, action string, opts core.Options) core.Result { if h == nil { - return core.Result{Value: coreerr.E("app.Host.Dispatch", "nil host", nil), OK: false} + return core.Result{Value: core.E("app.Host.Dispatch", "nil host", nil), OK: false} } if sourceCode == "" { return core.Result{ - Value: coreerr.E("app.Host.Dispatch", "empty sourceCode — plugin must identify itself", nil), + Value: core.E("app.Host.Dispatch", "empty sourceCode — plugin must identify itself", nil), OK: false, } } if targetCode == "" { return core.Result{ - Value: coreerr.E("app.Host.Dispatch", "empty targetCode", nil), + Value: core.E("app.Host.Dispatch", "empty targetCode", nil), OK: false, } } if action == "" { return core.Result{ - Value: coreerr.E("app.Host.Dispatch", "empty action", nil), + Value: core.E("app.Host.Dispatch", "empty action", nil), OK: false, } } @@ -493,20 +492,20 @@ func (h *Host) Dispatch(ctx context.Context, sourceCode, targetCode, action stri inst, ok := h.Get(targetCode) if !ok { return core.Result{ - Value: coreerr.E("app.Host.Dispatch", "target plugin not running: "+targetCode, nil), + Value: core.E("app.Host.Dispatch", "target plugin not running: "+targetCode, nil), OK: false, } } if inst.Core == nil { return core.Result{ - Value: coreerr.E("app.Host.Dispatch", "target plugin has no Core: "+targetCode, nil), + Value: core.E("app.Host.Dispatch", "target plugin has no Core: "+targetCode, nil), OK: false, } } if !inst.Core.Action(action).Exists() { return core.Result{ - Value: coreerr.E( + Value: core.E( "app.Host.Dispatch", "target "+targetCode+" did not register handler for "+action, nil, diff --git a/go/integrity.go b/go/integrity.go index 34f37c7..f4eeb70 100644 --- a/go/integrity.go +++ b/go/integrity.go @@ -11,7 +11,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const manifestAssetHashKey = "asset_hash" @@ -23,7 +22,7 @@ const manifestAssetHashKey = "asset_hash" // signature-bound hash. func bindWrappedAssetHash(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.bindWrappedAssetHash", "nil manifest", nil) + return core.E("app.bindWrappedAssetHash", "nil manifest", nil) } switch packageTypeFromManifest(manifest) { case PackageTypeElectron, PackageTypePWA: @@ -41,7 +40,7 @@ func bindWrappedAssetHash(medium coreio.Medium, dest string, manifest *config.Vi sum, files, err := assetTreeHash(medium, dest) if err != nil { - return coreerr.E("app.bindWrappedAssetHash", "asset tree hash failed", err) + return core.E("app.bindWrappedAssetHash", "asset tree hash failed", err) } if files == 0 { setManifestAssetHash(manifest, "") @@ -56,7 +55,7 @@ func bindWrappedAssetHash(medium coreio.Medium, dest string, manifest *config.Vi // the check is skipped for backwards compatibility with older wraps. func verifyAssetIntegrity(medium coreio.Medium, root string, manifest *config.ViewManifest, mode Mode) error { if manifest == nil { - return coreerr.E("app.verifyAssetIntegrity", "nil manifest", nil) + return core.E("app.verifyAssetIntegrity", "nil manifest", nil) } if mode == ModeDev { return nil @@ -67,10 +66,10 @@ func verifyAssetIntegrity(medium coreio.Medium, root string, manifest *config.Vi } sum, _, err := assetTreeHash(medium, root) if err != nil { - return coreerr.E("app.verifyAssetIntegrity", "asset tree hash failed", err) + return core.E("app.verifyAssetIntegrity", "asset tree hash failed", err) } if sum != want { - return coreerr.E( + return core.E( "app.verifyAssetIntegrity", "asset tree hash mismatch for "+manifest.Code, nil, @@ -117,16 +116,16 @@ func assetTreeHash(medium coreio.Medium, root string) (string, int, error) { medium = coreio.Local } if root == "" { - return "", 0, coreerr.E("app.assetTreeHash", "empty root", nil) + return "", 0, core.E("app.assetTreeHash", "empty root", nil) } if !medium.IsDir(root) { - return "", 0, coreerr.E("app.assetTreeHash", "root is not a directory: "+root, nil) + return "", 0, core.E("app.assetTreeHash", "root is not a directory: "+root, nil) } hasher := sha256.New() files, err := hashAssetDir(medium, hasher, root, root) if err != nil { - return "", files, coreerr.E("app.assetTreeHash", "hash walk failed", err) + return "", files, core.E("app.assetTreeHash", "hash walk failed", err) } return hex.EncodeToString(hasher.Sum(nil)), files, nil } diff --git a/go/layout.go b/go/layout.go index 1c09356..7a01d9b 100644 --- a/go/layout.go +++ b/go/layout.go @@ -5,7 +5,6 @@ package app import ( core "dappco.re/go" "dappco.re/go/config" - coreerr "dappco.re/go/log" ) // LayoutSpec is the resolved form of a manifest's HLCRF layout. It @@ -75,10 +74,10 @@ func layout(c *core.Core, m *config.ViewManifest) error { // spec, err := resolveLayout(c, m) func resolveLayout(c *core.Core, m *config.ViewManifest) (*LayoutSpec, error) { if c == nil { - return nil, coreerr.E("app.layout", "nil core", nil) + return nil, core.E("app.layout", "nil core", nil) } if m == nil { - return nil, coreerr.E("app.layout", "nil manifest", nil) + return nil, core.E("app.layout", "nil manifest", nil) } if m.Layout == "" { // Headless CLI app — no layout to compose. @@ -86,7 +85,7 @@ func resolveLayout(c *core.Core, m *config.ViewManifest) (*LayoutSpec, error) { } if err := validateLayoutVariant(m.Layout); err != nil { - return nil, coreerr.E("app.layout", "invalid layout variant", err) + return nil, core.E("app.layout", "invalid layout variant", err) } spec := &LayoutSpec{ @@ -113,7 +112,7 @@ func resolveLayout(c *core.Core, m *config.ViewManifest) (*LayoutSpec, error) { comp, ok := component.(string) if !ok { - return nil, coreerr.E( + return nil, core.E( "app.layout", "slot '"+slot+"' must name a string component", nil, @@ -163,7 +162,7 @@ func validateLayoutVariant(v string) error { case 'H', 'L', 'C', 'R', 'F': continue default: - return coreerr.E( + return core.E( "app.validateLayoutVariant", "unknown slot character '"+string(v[i])+"' in layout '"+v+"'", nil, diff --git a/go/marketplace.go b/go/marketplace.go index 65ab18c..9e63590 100644 --- a/go/marketplace.go +++ b/go/marketplace.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // MarketplaceIndexFileName is the top-level index file every category @@ -80,21 +79,21 @@ func LoadMarketplaceIndex(medium coreio.Medium, root string) (*MarketplaceIndex, medium = coreio.Local } if root == "" { - return nil, coreerr.E("app.LoadMarketplaceIndex", "empty root", nil) + return nil, core.E("app.LoadMarketplaceIndex", "empty root", nil) } path := core.Path(root, MarketplaceIndexFileName) if !medium.Exists(path) { - return nil, coreerr.E("app.LoadMarketplaceIndex", "index not found: "+path, nil) + return nil, core.E("app.LoadMarketplaceIndex", "index not found: "+path, nil) } body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.LoadMarketplaceIndex", "read failed: "+path, err) + return nil, core.E("app.LoadMarketplaceIndex", "read failed: "+path, err) } var idx MarketplaceIndex r := core.JSONUnmarshal([]byte(body), &idx) if !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.LoadMarketplaceIndex", "decode failed: "+path, cause) + return nil, core.E("app.LoadMarketplaceIndex", "decode failed: "+path, cause) } return &idx, nil } @@ -108,21 +107,21 @@ func LoadMarketplaceCategory(medium coreio.Medium, root, category string) (*Mark medium = coreio.Local } if root == "" || category == "" { - return nil, coreerr.E("app.LoadMarketplaceCategory", "empty root or category", nil) + return nil, core.E("app.LoadMarketplaceCategory", "empty root or category", nil) } path := core.Path(root, category, MarketplaceIndexFileName) if !medium.Exists(path) { - return nil, coreerr.E("app.LoadMarketplaceCategory", "category index not found: "+path, nil) + return nil, core.E("app.LoadMarketplaceCategory", "category index not found: "+path, nil) } body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.LoadMarketplaceCategory", "read failed: "+path, err) + return nil, core.E("app.LoadMarketplaceCategory", "read failed: "+path, err) } var cat MarketplaceCategoryIndex r := core.JSONUnmarshal([]byte(body), &cat) if !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.LoadMarketplaceCategory", "decode failed: "+path, cause) + return nil, core.E("app.LoadMarketplaceCategory", "decode failed: "+path, cause) } return &cat, nil } @@ -229,7 +228,7 @@ func MarketplaceCategories(medium coreio.Medium, root string) ([]string, error) // loader; caller should treat it as "run marketplace fetch". func MarketplaceBrowse(medium coreio.Medium, root, category string) ([]MarketplaceListing, error) { if core.Trim(category) == "" { - return nil, coreerr.E("app.MarketplaceBrowse", "empty category", nil) + return nil, core.E("app.MarketplaceBrowse", "empty category", nil) } idx, err := LoadMarketplaceIndex(medium, root) if err != nil { @@ -243,7 +242,7 @@ func MarketplaceBrowse(medium coreio.Medium, root, category string) ([]Marketpla } } if !known { - return nil, coreerr.E( + return nil, core.E( "app.MarketplaceBrowse", "unknown category '"+category+"' — run `core marketplace categories` for the valid set", nil, @@ -275,7 +274,7 @@ func MarketplaceBrowse(medium coreio.Medium, root, category string) ([]Marketpla // listing, err := app.MarketplaceResolve(medium, root, "photo-browser") func MarketplaceResolve(medium coreio.Medium, root, code string) (*MarketplaceListing, error) { if code == "" { - return nil, coreerr.E("app.MarketplaceResolve", "empty code", nil) + return nil, core.E("app.MarketplaceResolve", "empty code", nil) } idx, err := LoadMarketplaceIndex(medium, root) if err != nil { @@ -298,7 +297,7 @@ func MarketplaceResolve(medium coreio.Medium, root, code string) (*MarketplaceLi } } } - return nil, coreerr.E("app.MarketplaceResolve", "no marketplace entry with code "+code, nil) + return nil, core.E("app.MarketplaceResolve", "no marketplace entry with code "+code, nil) } // listingMatches performs a case-insensitive substring match across the @@ -344,18 +343,18 @@ type MarketplaceFetchOptions struct { // existing directory. func MarketplaceFetch(ctx context.Context, c *core.Core, opts MarketplaceFetchOptions) error { if c == nil { - return coreerr.E("app.MarketplaceFetch", "nil core", nil) + return core.E("app.MarketplaceFetch", "nil core", nil) } if opts.URL == "" { - return coreerr.E("app.MarketplaceFetch", "empty marketplace URL", nil) + return core.E("app.MarketplaceFetch", "empty marketplace URL", nil) } if opts.Dir == "" { - return coreerr.E("app.MarketplaceFetch", "empty marketplace dir", nil) + return core.E("app.MarketplaceFetch", "empty marketplace dir", nil) } proc := c.Process() if proc == nil { - return coreerr.E("app.MarketplaceFetch", "core.Process() is nil", nil) + return core.E("app.MarketplaceFetch", "core.Process() is nil", nil) } medium := coreio.Local @@ -363,17 +362,17 @@ func MarketplaceFetch(ctx context.Context, c *core.Core, opts MarketplaceFetchOp // Existing clone → pull. r := proc.RunIn(ctx, opts.Dir, "git", "pull", "--depth=1", "--ff-only") if !r.OK { - return coreerr.E("app.MarketplaceFetch", "git pull failed", extractErr(r)) + return core.E("app.MarketplaceFetch", "git pull failed", extractErr(r)) } return nil } if err := medium.EnsureDir(core.PathDir(opts.Dir)); err != nil { - return coreerr.E("app.MarketplaceFetch", "ensure parent dir failed", err) + return core.E("app.MarketplaceFetch", "ensure parent dir failed", err) } r := proc.Run(ctx, "git", "clone", "--depth=1", opts.URL, opts.Dir) if !r.OK { - return coreerr.E("app.MarketplaceFetch", "git clone failed", extractErr(r)) + return core.E("app.MarketplaceFetch", "git clone failed", extractErr(r)) } return nil } @@ -393,7 +392,7 @@ func MarketplaceFetch(ctx context.Context, c *core.Core, opts MarketplaceFetchOp // }) func MarketplaceInstall(ctx context.Context, c *core.Core, opts MarketplaceInstallOptions) (string, error) { if c == nil { - return "", coreerr.E("app.MarketplaceInstall", "nil core", nil) + return "", core.E("app.MarketplaceInstall", "nil core", nil) } listing, err := MarketplaceResolve(coreio.Local, opts.Root, opts.Code) if err != nil { @@ -405,13 +404,13 @@ func MarketplaceInstall(ctx context.Context, c *core.Core, opts MarketplaceInsta home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.MarketplaceInstall", "cannot resolve home dir", nil) + return "", core.E("app.MarketplaceInstall", "cannot resolve home dir", nil) } dest := core.Path(home, ".core", AppsDirName, listing.Code) medium := coreio.Local if medium.IsDir(dest) && !opts.Force { - return dest, coreerr.E( + return dest, core.E( "app.MarketplaceInstall", "already installed at "+dest+" (use Force to replace)", nil, @@ -437,7 +436,7 @@ func MarketplaceInstall(ctx context.Context, c *core.Core, opts MarketplaceInsta Code: listing.Code, }) if m == nil { - return dest, coreerr.E("app.MarketplaceInstall", "WrapPWA returned nil", nil) + return dest, core.E("app.MarketplaceInstall", "WrapPWA returned nil", nil) } installed, err := InstallWrappedPWA(medium, m, PkgInstallOptions{ Home: home, @@ -497,7 +496,7 @@ func MarketplaceInstall(ctx context.Context, c *core.Core, opts MarketplaceInsta } return dest, nil } - return dest, coreerr.E("app.MarketplaceInstall", "unreachable type switch", nil) + return dest, core.E("app.MarketplaceInstall", "unreachable type switch", nil) } // installElectronListing implements the RFC §16.2 marketplace Electron @@ -528,10 +527,10 @@ func MarketplaceInstall(ctx context.Context, c *core.Core, opts MarketplaceInsta // asset cannot be auto-extracted. func installElectronListing(ctx context.Context, c *core.Core, listing *MarketplaceListing, home string, force bool) (string, error) { if listing == nil { - return "", coreerr.E("app.installElectronListing", "nil listing", nil) + return "", core.E("app.installElectronListing", "nil listing", nil) } if listing.Repo == "" { - return "", coreerr.E( + return "", core.E( "app.installElectronListing", "listing "+listing.Code+" has no repo — cannot resolve Electron release", nil, @@ -559,7 +558,7 @@ func installElectronListing(ctx context.Context, c *core.Core, listing *Marketpl ScratchDir: scratch, }) if err != nil { - return dest, coreerr.E("app.installElectronListing", "wrap repo failed", err) + return dest, core.E("app.installElectronListing", "wrap repo failed", err) } installed, err := InstallWrappedElectron(medium, manifest, PkgInstallOptions{ Home: home, @@ -573,7 +572,7 @@ func installElectronListing(ctx context.Context, c *core.Core, listing *Marketpl } } if err != nil { - return installed, coreerr.E("app.installElectronListing", "install failed", err) + return installed, core.E("app.installElectronListing", "install failed", err) } return installed, nil } @@ -612,7 +611,7 @@ func verifyListingAfterInstall(medium coreio.Medium, dest string, listing *Marke // standpoint, so we delete the destination so the next install // attempt starts clean. if cleanupErr := medium.DeleteAll(dest); cleanupErr != nil { - return coreerr.E("app.verifyListingAfterInstall", "verify failed and cleanup failed", err) + return core.E("app.verifyListingAfterInstall", "verify failed and cleanup failed", err) } return err } @@ -635,24 +634,24 @@ type MarketplaceInstallOptions struct { // err := installNativeFromRepo(ctx, c, listing, dest) func installNativeFromRepo(ctx context.Context, c *core.Core, listing *MarketplaceListing, dest string) error { if listing == nil || listing.Repo == "" { - return coreerr.E("app.installNativeFromRepo", "empty repo in listing", nil) + return core.E("app.installNativeFromRepo", "empty repo in listing", nil) } medium := coreio.Local if medium.IsDir(dest) { if err := medium.DeleteAll(dest); err != nil { - return coreerr.E("app.installNativeFromRepo", "remove existing failed", err) + return core.E("app.installNativeFromRepo", "remove existing failed", err) } } if err := medium.EnsureDir(core.PathDir(dest)); err != nil { - return coreerr.E("app.installNativeFromRepo", "ensure dir failed", err) + return core.E("app.installNativeFromRepo", "ensure dir failed", err) } proc := c.Process() if proc == nil { - return coreerr.E("app.installNativeFromRepo", "core.Process() is nil", nil) + return core.E("app.installNativeFromRepo", "core.Process() is nil", nil) } r := proc.Run(ctx, "git", "clone", "--depth=1", listing.Repo, dest) if !r.OK { - return coreerr.E("app.installNativeFromRepo", "git clone failed", extractErr(r)) + return core.E("app.installNativeFromRepo", "git clone failed", extractErr(r)) } // Stamp the source + category into .core/view.yaml so `core pkg list` @@ -759,7 +758,7 @@ func extractErr(r core.Result) error { if e, ok := r.Value.(error); ok { return e } - return coreerr.E("app.extractErr", core.Sprint(r.Value), nil) + return core.E("app.extractErr", core.Sprint(r.Value), nil) } // MarketplaceUpdateOptions tunes MarketplaceUpdate. The zero value pulls @@ -815,10 +814,10 @@ type MarketplaceUpdateOptions struct { // listing URL so the operator can re-issue the wrap call. func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdateOptions) (string, error) { if c == nil { - return "", coreerr.E("app.MarketplaceUpdate", "nil core", nil) + return "", core.E("app.MarketplaceUpdate", "nil core", nil) } if opts.Code == "" { - return "", coreerr.E("app.MarketplaceUpdate", "empty code", nil) + return "", core.E("app.MarketplaceUpdate", "empty code", nil) } home := opts.Home @@ -826,13 +825,13 @@ func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdate home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.MarketplaceUpdate", "cannot resolve home dir", nil) + return "", core.E("app.MarketplaceUpdate", "cannot resolve home dir", nil) } medium := coreio.Local dest := core.Path(home, ".core", AppsDirName, opts.Code) if !medium.IsDir(dest) { - return "", coreerr.E("app.MarketplaceUpdate", "package not installed: "+opts.Code, nil) + return "", core.E("app.MarketplaceUpdate", "package not installed: "+opts.Code, nil) } // Resolve the listing first so we know the upstream type (native / @@ -864,7 +863,7 @@ func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdate // pull never persists. Failure of the rollback itself is // surfaced alongside the original verify error. if rbErr := rollbackNativeRepo(ctx, c, dest); rbErr != nil { - return dest, coreerr.E( + return dest, core.E( "app.MarketplaceUpdate", "verify failed and rollback failed for "+listing.Code, err, @@ -884,7 +883,7 @@ func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdate Code: listing.Code, }) if manifest == nil { - return dest, coreerr.E("app.MarketplaceUpdate", "WrapPWA returned nil", nil) + return dest, core.E("app.MarketplaceUpdate", "WrapPWA returned nil", nil) } _, err = InstallWrappedPWA(medium, manifest, PkgInstallOptions{ Home: home, @@ -922,7 +921,7 @@ func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdate // because the source is a local directory the operator owns. return dest, nil } - return dest, coreerr.E("app.MarketplaceUpdate", "unreachable type switch", nil) + return dest, core.E("app.MarketplaceUpdate", "unreachable type switch", nil) } // pullNativeFromRepo refreshes a git-cloned install in place and resets @@ -943,11 +942,11 @@ func MarketplaceUpdate(ctx context.Context, c *core.Core, opts MarketplaceUpdate // dirty working copy can never block a security update. func pullNativeFromRepo(ctx context.Context, c *core.Core, listing *MarketplaceListing, dest string) error { if listing == nil || listing.Repo == "" { - return coreerr.E("app.pullNativeFromRepo", "empty repo in listing", nil) + return core.E("app.pullNativeFromRepo", "empty repo in listing", nil) } medium := coreio.Local if !medium.IsDir(core.Path(dest, ".git")) { - return coreerr.E( + return core.E( "app.pullNativeFromRepo", "destination is not a git working copy: "+dest, nil, @@ -955,13 +954,13 @@ func pullNativeFromRepo(ctx context.Context, c *core.Core, listing *MarketplaceL } proc := c.Process() if proc == nil { - return coreerr.E("app.pullNativeFromRepo", "core.Process() is nil", nil) + return core.E("app.pullNativeFromRepo", "core.Process() is nil", nil) } if r := proc.RunIn(ctx, dest, "git", "fetch", "--depth=1", "origin"); !r.OK { - return coreerr.E("app.pullNativeFromRepo", "git fetch failed", extractErr(r)) + return core.E("app.pullNativeFromRepo", "git fetch failed", extractErr(r)) } if r := proc.RunIn(ctx, dest, "git", "reset", "--hard", "FETCH_HEAD"); !r.OK { - return coreerr.E("app.pullNativeFromRepo", "git reset --hard failed", extractErr(r)) + return core.E("app.pullNativeFromRepo", "git reset --hard failed", extractErr(r)) } return nil } @@ -973,17 +972,17 @@ func pullNativeFromRepo(ctx context.Context, c *core.Core, listing *MarketplaceL // err := rollbackNativeRepo(ctx, c, dest) func rollbackNativeRepo(ctx context.Context, c *core.Core, dest string) error { if c == nil { - return coreerr.E("app.rollbackNativeRepo", "nil core", nil) + return core.E("app.rollbackNativeRepo", "nil core", nil) } if dest == "" { - return coreerr.E("app.rollbackNativeRepo", "empty dest", nil) + return core.E("app.rollbackNativeRepo", "empty dest", nil) } proc := c.Process() if proc == nil { - return coreerr.E("app.rollbackNativeRepo", "core.Process() is nil", nil) + return core.E("app.rollbackNativeRepo", "core.Process() is nil", nil) } if r := proc.RunIn(ctx, dest, "git", "reset", "--hard", "ORIG_HEAD"); !r.OK { - return coreerr.E("app.rollbackNativeRepo", "git reset --hard ORIG_HEAD failed", extractErr(r)) + return core.E("app.rollbackNativeRepo", "git reset --hard ORIG_HEAD failed", extractErr(r)) } return nil } diff --git a/go/marketplace_verify.go b/go/marketplace_verify.go index 6edf915..6e11d25 100644 --- a/go/marketplace_verify.go +++ b/go/marketplace_verify.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // VerifyListing checks that the manifest installed at `dest` from the @@ -34,10 +33,10 @@ import ( // entry. func VerifyListing(medium coreio.Medium, dest string, listing *MarketplaceListing) error { if listing == nil { - return coreerr.E("app.VerifyListing", "nil listing", nil) + return core.E("app.VerifyListing", "nil listing", nil) } if dest == "" { - return coreerr.E("app.VerifyListing", "empty dest", nil) + return core.E("app.VerifyListing", "empty dest", nil) } if medium == nil { medium = coreio.Local @@ -45,7 +44,7 @@ func VerifyListing(medium coreio.Medium, dest string, listing *MarketplaceListin manifestPath := core.Path(dest, ".core", "view.yaml") if !medium.Exists(manifestPath) { - return coreerr.E( + return core.E( "app.VerifyListing", "installed manifest missing for listing "+listing.Code+": "+manifestPath, nil, @@ -54,7 +53,7 @@ func VerifyListing(medium coreio.Medium, dest string, listing *MarketplaceListin var manifest config.ViewManifest if err := LoadViewManifest(medium, manifestPath, &manifest); err != nil { - return coreerr.E( + return core.E( "app.VerifyListing", "parse installed manifest for "+listing.Code+" failed", err, @@ -70,7 +69,7 @@ func VerifyListing(medium coreio.Medium, dest string, listing *MarketplaceListin pub, err := parsePublicKey(listing.SignKey) if err != nil { - return coreerr.E( + return core.E( "app.VerifyListing", "listing "+listing.Code+" sign_key decode failed", err, @@ -78,7 +77,7 @@ func VerifyListing(medium coreio.Medium, dest string, listing *MarketplaceListin } if err := verifyWithKey(&manifest, pub); err != nil { - return coreerr.E( + return core.E( "app.VerifyListing", "listing "+listing.Code+" signature did not match pinned sign_key", err, @@ -98,18 +97,18 @@ func VerifyListingBytes(body []byte, hexKey string) error { return nil } if len(body) == 0 { - return coreerr.E("app.VerifyListingBytes", "empty manifest body", nil) + return core.E("app.VerifyListingBytes", "empty manifest body", nil) } pub, err := parsePublicKey(hexKey) if err != nil { - return coreerr.E("app.VerifyListingBytes", "sign_key decode failed", err) + return core.E("app.VerifyListingBytes", "sign_key decode failed", err) } var manifest config.ViewManifest if err := yamlUnmarshal(body, &manifest); err != nil { - return coreerr.E("app.VerifyListingBytes", "parse manifest body failed", err) + return core.E("app.VerifyListingBytes", "parse manifest body failed", err) } if err := verifyWithKey(&manifest, pub); err != nil { - return coreerr.E("app.VerifyListingBytes", "signature did not match pinned sign_key", err) + return core.E("app.VerifyListingBytes", "signature did not match pinned sign_key", err) } return nil } diff --git a/go/permissions.go b/go/permissions.go index aa4052a..3e9944d 100644 --- a/go/permissions.go +++ b/go/permissions.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" - coreerr "dappco.re/go/log" ) // Named Action prefixes gated by manifest permissions. Keeping the @@ -160,10 +159,10 @@ type actionGate struct { // `./photos/` must not admit `./photos/../etc/passwd`). func permissions(c *core.Core, m *config.ViewManifest, mode Mode) error { if c == nil { - return coreerr.E("app.permissions", "nil core", nil) + return core.E("app.permissions", "nil core", nil) } if m == nil { - return coreerr.E("app.permissions", "nil manifest", nil) + return core.E("app.permissions", "nil manifest", nil) } checker := newCheckerForManifest(m, mode) diff --git a/go/pkg.go b/go/pkg.go index f8c772c..06dfd8a 100644 --- a/go/pkg.go +++ b/go/pkg.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // AppsDirName is the component that follows `$DIR_HOME/.core/` for the @@ -87,7 +86,7 @@ func PkgList(medium coreio.Medium, home string) ([]PkgEntry, error) { medium = coreio.Local } if home == "" { - return nil, coreerr.E("app.PkgList", "empty home directory", nil) + return nil, core.E("app.PkgList", "empty home directory", nil) } appsDir := core.Path(home, ".core", AppsDirName) if !medium.IsDir(appsDir) { @@ -96,7 +95,7 @@ func PkgList(medium coreio.Medium, home string) ([]PkgEntry, error) { entries, err := medium.List(appsDir) if err != nil { - return nil, coreerr.E("app.PkgList", "list apps dir failed", err) + return nil, core.E("app.PkgList", "list apps dir failed", err) } var out []PkgEntry @@ -174,7 +173,7 @@ func InstalledApps(medium coreio.Medium, home string) ([]InstalledApp, error) { medium = coreio.Local } if home == "" { - return nil, coreerr.E("app.InstalledApps", "empty home directory", nil) + return nil, core.E("app.InstalledApps", "empty home directory", nil) } appsDir := core.Path(home, ".core", AppsDirName) if !medium.IsDir(appsDir) { @@ -182,7 +181,7 @@ func InstalledApps(medium coreio.Medium, home string) ([]InstalledApp, error) { } entries, err := medium.List(appsDir) if err != nil { - return nil, coreerr.E("app.InstalledApps", "list apps dir failed", err) + return nil, core.E("app.InstalledApps", "list apps dir failed", err) } var out []InstalledApp for _, entry := range entries { @@ -316,16 +315,16 @@ func PkgInfo(medium coreio.Medium, home, name string) (*PkgDetails, error) { medium = coreio.Local } if home == "" { - return nil, coreerr.E("app.PkgInfo", "empty home directory", nil) + return nil, core.E("app.PkgInfo", "empty home directory", nil) } if name == "" { - return nil, coreerr.E("app.PkgInfo", "empty package name", nil) + return nil, core.E("app.PkgInfo", "empty package name", nil) } appPath := core.Path(home, ".core", AppsDirName, name) viewPath := core.Path(appPath, ".core", "view.yaml") if !medium.Exists(viewPath) { - return nil, coreerr.E( + return nil, core.E( "app.PkgInfo", "package not installed: "+name+" (expected "+viewPath+")", nil, @@ -334,12 +333,12 @@ func PkgInfo(medium coreio.Medium, home, name string) (*PkgDetails, error) { var manifest config.ViewManifest if err := LoadViewManifest(medium, viewPath, &manifest); err != nil { - return nil, coreerr.E("app.PkgInfo", "parse manifest failed", err) + return nil, core.E("app.PkgInfo", "parse manifest failed", err) } entry, err := pkgEntryFromManifest(medium, viewPath, appPath) if err != nil { - return nil, coreerr.E("app.PkgInfo", "project entry failed", err) + return nil, core.E("app.PkgInfo", "project entry failed", err) } info := &PkgDetails{ @@ -529,23 +528,23 @@ func PkgRemoveWith(medium coreio.Medium, home, name string, opts PkgRemoveOption medium = coreio.Local } if home == "" { - return coreerr.E("app.PkgRemoveWith", "empty home directory", nil) + return core.E("app.PkgRemoveWith", "empty home directory", nil) } if name == "" || core.Contains(name, "/") || core.Contains(name, "\\") { - return coreerr.E("app.PkgRemoveWith", "invalid package name: "+name, nil) + return core.E("app.PkgRemoveWith", "invalid package name: "+name, nil) } appPath := core.Path(home, ".core", AppsDirName, name) if !medium.IsDir(appPath) { - return coreerr.E("app.PkgRemoveWith", "package not installed: "+name, nil) + return core.E("app.PkgRemoveWith", "package not installed: "+name, nil) } if err := medium.DeleteAll(appPath); err != nil { - return coreerr.E("app.PkgRemoveWith", "delete failed: "+appPath, err) + return core.E("app.PkgRemoveWith", "delete failed: "+appPath, err) } if opts.Purge { dataPath := core.Path(home, ".core", DataDirName, name) if medium.IsDir(dataPath) { if err := medium.DeleteAll(dataPath); err != nil { - return coreerr.E("app.PkgRemoveWith", "purge data tree failed: "+dataPath, err) + return core.E("app.PkgRemoveWith", "purge data tree failed: "+dataPath, err) } } } @@ -617,13 +616,13 @@ func InstallWrappedWeb(medium coreio.Medium, manifest *config.ViewManifest, opts // dest, err := installWrap(medium, manifest, opts) func installWrap(medium coreio.Medium, manifest *config.ViewManifest, opts PkgInstallOptions) (string, error) { if manifest == nil { - return "", coreerr.E("app.installWrap", "nil manifest", nil) + return "", core.E("app.installWrap", "nil manifest", nil) } if medium == nil { medium = coreio.Local } if manifest.Code == "" { - return "", coreerr.E("app.installWrap", "manifest.code is empty", nil) + return "", core.E("app.installWrap", "manifest.code is empty", nil) } home := opts.Home @@ -631,20 +630,20 @@ func installWrap(medium coreio.Medium, manifest *config.ViewManifest, opts PkgIn home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.installWrap", "cannot resolve home directory", nil) + return "", core.E("app.installWrap", "cannot resolve home directory", nil) } dest := core.Path(home, ".core", AppsDirName, manifest.Code) if medium.IsDir(dest) { if !opts.Force { - return dest, coreerr.E( + return dest, core.E( "app.installWrap", "already installed at "+dest+" (use Force to replace)", nil, ) } if err := medium.DeleteAll(dest); err != nil { - return dest, coreerr.E("app.installWrap", "remove existing failed", err) + return dest, core.E("app.installWrap", "remove existing failed", err) } } // Record provenance in Config so `core pkg list` can show it. @@ -655,22 +654,22 @@ func installWrap(medium coreio.Medium, manifest *config.ViewManifest, opts PkgIn manifest.Config["source"] = opts.Source } if err := stageWrappedAssets(medium, dest, opts.AssetSource); err != nil { - return dest, coreerr.E("app.installWrap", "materialise wrap failed", err) + return dest, core.E("app.installWrap", "materialise wrap failed", err) } if err := materializeWrappedRuntimeAssets(medium, dest, manifest); err != nil { - return dest, coreerr.E("app.installWrap", "materialise runtime assets failed", err) + return dest, core.E("app.installWrap", "materialise runtime assets failed", err) } if err := bindWrappedAssetHash(medium, dest, manifest); err != nil { - return dest, coreerr.E("app.installWrap", "bind asset hash failed", err) + return dest, core.E("app.installWrap", "bind asset hash failed", err) } // Wrapped installs are distribution artifacts, not dev drafts. Sign // them AFTER the install-specific mutations (source stamp, asset // hash) so prod-mode verification covers the final on-disk artifact. if err := signWrappedManifest(medium, manifest, home, opts); err != nil { - return dest, coreerr.E("app.installWrap", "sign wrapped manifest failed", err) + return dest, core.E("app.installWrap", "sign wrapped manifest failed", err) } if err := writeWrappedManifest(medium, dest, manifest); err != nil { - return dest, coreerr.E("app.installWrap", "materialise wrap failed", err) + return dest, core.E("app.installWrap", "materialise wrap failed", err) } return dest, nil } @@ -705,7 +704,7 @@ func WriteWrappedApp(medium coreio.Medium, dest string, manifest *config.ViewMan // signature to the final manifest bytes. func WriteWrappedAppWithOptions(medium coreio.Medium, dest string, manifest *config.ViewManifest, opts WriteWrappedOptions) error { if manifest == nil { - return coreerr.E("app.WriteWrappedAppWithOptions", "nil manifest", nil) + return core.E("app.WriteWrappedAppWithOptions", "nil manifest", nil) } if medium == nil { medium = coreio.Local @@ -714,10 +713,10 @@ func WriteWrappedAppWithOptions(medium coreio.Medium, dest string, manifest *con return err } if err := materializeWrappedRuntimeAssets(medium, dest, manifest); err != nil { - return coreerr.E("app.WriteWrappedAppWithOptions", "materialise runtime assets failed", err) + return core.E("app.WriteWrappedAppWithOptions", "materialise runtime assets failed", err) } if err := bindWrappedAssetHash(medium, dest, manifest); err != nil { - return coreerr.E("app.WriteWrappedAppWithOptions", "bind asset hash failed", err) + return core.E("app.WriteWrappedAppWithOptions", "bind asset hash failed", err) } if opts.SignKeyPath != "" || opts.SignDefault { if err := signWrappedManifest(medium, manifest, opts.Home, PkgInstallOptions{ @@ -725,7 +724,7 @@ func WriteWrappedAppWithOptions(medium coreio.Medium, dest string, manifest *con SignKeyPath: opts.SignKeyPath, SignDefault: opts.SignDefault, }); err != nil { - return coreerr.E("app.WriteWrappedAppWithOptions", "sign wrapped manifest failed", err) + return core.E("app.WriteWrappedAppWithOptions", "sign wrapped manifest failed", err) } } return writeWrappedManifest(medium, dest, manifest) @@ -736,52 +735,52 @@ func stageWrappedAssets(medium coreio.Medium, dest, assetSource string) error { medium = coreio.Local } if dest == "" { - return coreerr.E("app.stageWrappedAssets", "empty dest", nil) + return core.E("app.stageWrappedAssets", "empty dest", nil) } if assetSource == "" { return nil } if !medium.IsDir(assetSource) { - return coreerr.E( + return core.E( "app.stageWrappedAssets", "asset source is not a directory: "+assetSource, nil, ) } if err := copyTree(medium, assetSource, dest); err != nil { - return coreerr.E("app.stageWrappedAssets", "copy asset tree failed", err) + return core.E("app.stageWrappedAssets", "copy asset tree failed", err) } return nil } func writeWrappedManifest(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.writeWrappedManifest", "nil manifest", nil) + return core.E("app.writeWrappedManifest", "nil manifest", nil) } if medium == nil { medium = coreio.Local } if dest == "" { - return coreerr.E("app.writeWrappedManifest", "empty dest", nil) + return core.E("app.writeWrappedManifest", "empty dest", nil) } path := core.Path(dest, ".core", "view.yaml") if err := medium.EnsureDir(core.PathDir(path)); err != nil { - return coreerr.E("app.writeWrappedManifest", "ensure dir failed", err) + return core.E("app.writeWrappedManifest", "ensure dir failed", err) } body, err := yamlMarshalBytes(manifest) if err != nil { - return coreerr.E("app.writeWrappedManifest", "marshal failed", err) + return core.E("app.writeWrappedManifest", "marshal failed", err) } if err := medium.Write(path, string(body)); err != nil { - return coreerr.E("app.writeWrappedManifest", "write failed", err) + return core.E("app.writeWrappedManifest", "write failed", err) } return nil } func signWrappedManifest(medium coreio.Medium, manifest *config.ViewManifest, home string, opts PkgInstallOptions) error { if manifest == nil { - return coreerr.E("app.signWrappedManifest", "nil manifest", nil) + return core.E("app.signWrappedManifest", "nil manifest", nil) } if medium == nil { medium = coreio.Local @@ -790,24 +789,24 @@ func signWrappedManifest(medium coreio.Medium, manifest *config.ViewManifest, ho case opts.SignKeyPath != "": priv, err := LoadPrivateKey(medium, opts.SignKeyPath) if err != nil { - return coreerr.E("app.signWrappedManifest", "load explicit private key failed", err) + return core.E("app.signWrappedManifest", "load explicit private key failed", err) } if err := SignManifest(manifest, priv); err != nil { - return coreerr.E("app.signWrappedManifest", "sign with explicit key failed", err) + return core.E("app.signWrappedManifest", "sign with explicit key failed", err) } return nil case opts.SignDefault: priv, err := ensureDefaultPrivateKey(medium, home) if err != nil { - return coreerr.E("app.signWrappedManifest", "resolve default key failed", err) + return core.E("app.signWrappedManifest", "resolve default key failed", err) } if err := SignManifest(manifest, priv); err != nil { - return coreerr.E("app.signWrappedManifest", "sign with default key failed", err) + return core.E("app.signWrappedManifest", "sign with default key failed", err) } return nil case manifest.Sign == "": if err := signManifestForHome(medium, home, manifest); err != nil { - return coreerr.E("app.signWrappedManifest", "auto-sign failed", err) + return core.E("app.signWrappedManifest", "auto-sign failed", err) } } return nil @@ -829,21 +828,21 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st medium = coreio.Local } if home == "" { - return "", coreerr.E("app.PkgUpdate", "empty home directory", nil) + return "", core.E("app.PkgUpdate", "empty home directory", nil) } if name == "" { - return "", coreerr.E("app.PkgUpdate", "empty package name", nil) + return "", core.E("app.PkgUpdate", "empty package name", nil) } appPath := core.Path(home, ".core", AppsDirName, name) viewPath := core.Path(appPath, ".core", "view.yaml") if !medium.Exists(viewPath) { - return "", coreerr.E("app.PkgUpdate", "package not installed: "+name, nil) + return "", core.E("app.PkgUpdate", "package not installed: "+name, nil) } var manifest config.ViewManifest if err := LoadViewManifest(medium, viewPath, &manifest); err != nil { - return "", coreerr.E("app.PkgUpdate", "parse manifest failed", err) + return "", core.E("app.PkgUpdate", "parse manifest failed", err) } var source string @@ -853,7 +852,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st } } if source == "" { - return "", coreerr.E("app.PkgUpdate", "no source recorded for "+name, nil) + return "", core.E("app.PkgUpdate", "no source recorded for "+name, nil) } if ctx == nil { @@ -878,13 +877,13 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st defer func() { _ = medium.DeleteAll(scratch) }() } if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "PWA repo refresh failed", err) + return appPath, core.E("app.PkgUpdate", "PWA repo refresh failed", err) } targetURL = core.Path(assetSource, "manifest.json") } else { pwa, err = loadPWASource(ctx, medium, url) if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "PWA refetch failed", err) + return appPath, core.E("app.PkgUpdate", "PWA refetch failed", err) } if path, ok := localPWASourcePath(medium, url); ok { assetSource = core.PathDir(path) @@ -896,7 +895,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st } else { pwa, err = loadPWASource(ctx, medium, url) if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "PWA refetch failed", err) + return appPath, core.E("app.PkgUpdate", "PWA refetch failed", err) } if path, ok := localPWASourcePath(medium, url); ok { assetSource = core.PathDir(path) @@ -911,7 +910,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st Version: string(manifest.Version), }) if updated == nil { - return appPath, coreerr.E("app.PkgUpdate", "WrapPWA returned nil", nil) + return appPath, core.E("app.PkgUpdate", "WrapPWA returned nil", nil) } _, err = installWrap(medium, updated, PkgInstallOptions{ Home: home, @@ -930,7 +929,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st // so we re-run WrapWeb against the recorded path. if dir, ok := stripPrefix(source, "wrap:web:"); ok { if !medium.IsDir(dir) { - return appPath, coreerr.E( + return appPath, core.E( "app.PkgUpdate", "web source directory missing: "+dir+" (recorded by `pkg wrap --web`)", nil, @@ -942,7 +941,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st Version: string(manifest.Version), }) if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "web rewrap failed", err) + return appPath, core.E("app.PkgUpdate", "web rewrap failed", err) } if _, err := installWrap(medium, updated, PkgInstallOptions{ Home: home, @@ -968,7 +967,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st } return installed, nil } - return appPath, coreerr.E( + return appPath, core.E( "app.PkgUpdate", "electron source not a directory: "+dir+" (re-extract the release first)", nil, @@ -976,7 +975,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st } pkgPath := core.Path(dir, "package.json") if !medium.Exists(pkgPath) { - return appPath, coreerr.E( + return appPath, core.E( "app.PkgUpdate", "package.json missing under electron source: "+pkgPath, nil, @@ -984,21 +983,21 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st } body, err := medium.Read(pkgPath) if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "read package.json failed", err) + return appPath, core.E("app.PkgUpdate", "read package.json failed", err) } var pkg ElectronPackageJSON r := core.JSONUnmarshal([]byte(body), &pkg) if !r.OK { cause, _ := r.Value.(error) - return appPath, coreerr.E("app.PkgUpdate", "decode package.json failed", cause) + return appPath, core.E("app.PkgUpdate", "decode package.json failed", cause) } scan, err := ScanElectronRenderer(medium, dir) if err != nil { - return appPath, coreerr.E("app.PkgUpdate", "scan renderer failed", err) + return appPath, core.E("app.PkgUpdate", "scan renderer failed", err) } updated := WrapElectron(&pkg, scan, WrapElectronOptions{Code: manifest.Code}) if updated == nil { - return appPath, coreerr.E("app.PkgUpdate", "WrapElectron returned nil", nil) + return appPath, core.E("app.PkgUpdate", "WrapElectron returned nil", nil) } updated.Version = manifest.Version if updated.Name == "" { @@ -1020,7 +1019,7 @@ func PkgUpdate(ctx context.Context, medium coreio.Medium, home, name string) (st // re-running install manually. if path, ok := stripPrefix(source, "local:"); ok { if !medium.IsDir(path) { - return appPath, coreerr.E( + return appPath, core.E( "app.PkgUpdate", "local source missing: "+path, nil, @@ -1053,13 +1052,13 @@ func loadPWASource(ctx context.Context, medium coreio.Medium, source string) (*P if path, ok := localPWASourcePath(medium, source); ok { body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.loadPWASource", "read local manifest failed", err) + return nil, core.E("app.loadPWASource", "read local manifest failed", err) } var pwa PWAManifest r := core.JSONUnmarshal([]byte(body), &pwa) if !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.loadPWASource", "decode local manifest failed", cause) + return nil, core.E("app.loadPWASource", "decode local manifest failed", cause) } return &pwa, nil } @@ -1092,7 +1091,7 @@ func installElectronRepoSource(ctx context.Context, medium coreio.Medium, home, home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.installElectronRepoSource", "cannot resolve home directory", nil) + return "", core.E("app.installElectronRepoSource", "cannot resolve home directory", nil) } scratch := core.Path(home, ".core", ".wrap", "repo-"+slugify(coalesce(code, ref))) @@ -1103,7 +1102,7 @@ func installElectronRepoSource(ctx context.Context, medium coreio.Medium, home, ScratchDir: scratch, }) if err != nil { - return "", coreerr.E("app.installElectronRepoSource", "wrap repo failed", err) + return "", core.E("app.installElectronRepoSource", "wrap repo failed", err) } installed, err := InstallWrappedElectron(medium, manifest, PkgInstallOptions{ Home: home, @@ -1117,7 +1116,7 @@ func installElectronRepoSource(ctx context.Context, medium coreio.Medium, home, } } if err != nil { - return installed, coreerr.E("app.installElectronRepoSource", "install failed", err) + return installed, core.E("app.installElectronRepoSource", "install failed", err) } return installed, nil } @@ -1250,15 +1249,15 @@ func PkgInstallLocal(medium coreio.Medium, src string, opts PkgInstallOptions) ( medium = coreio.Local } if src == "" { - return "", coreerr.E("app.PkgInstallLocal", "empty source", nil) + return "", core.E("app.PkgInstallLocal", "empty source", nil) } if !medium.IsDir(src) { - return "", coreerr.E("app.PkgInstallLocal", "source is not a directory: "+src, nil) + return "", core.E("app.PkgInstallLocal", "source is not a directory: "+src, nil) } manifestPath := core.Path(src, ".core", "view.yaml") if !medium.Exists(manifestPath) { - return "", coreerr.E( + return "", core.E( "app.PkgInstallLocal", "source has no .core/view.yaml: "+src, nil, @@ -1267,10 +1266,10 @@ func PkgInstallLocal(medium coreio.Medium, src string, opts PkgInstallOptions) ( var manifest config.ViewManifest if err := LoadViewManifest(medium, manifestPath, &manifest); err != nil { - return "", coreerr.E("app.PkgInstallLocal", "parse source manifest failed", err) + return "", core.E("app.PkgInstallLocal", "parse source manifest failed", err) } if manifest.Code == "" { - return "", coreerr.E("app.PkgInstallLocal", "source manifest.code is empty", nil) + return "", core.E("app.PkgInstallLocal", "source manifest.code is empty", nil) } home := opts.Home @@ -1278,25 +1277,25 @@ func PkgInstallLocal(medium coreio.Medium, src string, opts PkgInstallOptions) ( home = core.Env("DIR_HOME") } if home == "" { - return "", coreerr.E("app.PkgInstallLocal", "cannot resolve home directory", nil) + return "", core.E("app.PkgInstallLocal", "cannot resolve home directory", nil) } dest := core.Path(home, ".core", AppsDirName, manifest.Code) if medium.IsDir(dest) { if !opts.Force { - return dest, coreerr.E( + return dest, core.E( "app.PkgInstallLocal", "already installed at "+dest+" (use Force to replace)", nil, ) } if err := medium.DeleteAll(dest); err != nil { - return dest, coreerr.E("app.PkgInstallLocal", "remove existing failed", err) + return dest, core.E("app.PkgInstallLocal", "remove existing failed", err) } } if err := copyTree(medium, src, dest); err != nil { - return dest, coreerr.E("app.PkgInstallLocal", "copy tree failed", err) + return dest, core.E("app.PkgInstallLocal", "copy tree failed", err) } // Stamp the source so `pkg list` shows where the install came from. diff --git a/go/pkg_electron.go b/go/pkg_electron.go index 74cb09a..e290798 100644 --- a/go/pkg_electron.go +++ b/go/pkg_electron.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // ElectronPackageJSON is the subset of an Electron app's package.json we @@ -74,7 +73,7 @@ func ScanElectronRenderer(medium coreio.Medium, dir string) (*ElectronScanResult medium = coreio.Local } if dir == "" { - return nil, coreerr.E("app.ScanElectronRenderer", "empty dir", nil) + return nil, core.E("app.ScanElectronRenderer", "empty dir", nil) } res := &ElectronScanResult{} @@ -97,7 +96,7 @@ func ScanElectronRenderer(medium coreio.Medium, dir string) (*ElectronScanResult walk(p) } }); err != nil { - return nil, coreerr.E("app.ScanElectronRenderer", "walk failed", err) + return nil, core.E("app.ScanElectronRenderer", "walk failed", err) } // Sort the IPC channel list for stable test output. @@ -402,18 +401,18 @@ func WrapElectronRepo(ctx context.Context, medium coreio.Medium, ref string, opt medium = coreio.Local } if ref == "" { - return nil, "", coreerr.E("app.WrapElectronRepo", "empty repo reference", nil) + return nil, "", core.E("app.WrapElectronRepo", "empty repo reference", nil) } if opts.ScratchDir == "" { - return nil, "", coreerr.E("app.WrapElectronRepo", "empty scratch dir", nil) + return nil, "", core.E("app.WrapElectronRepo", "empty scratch dir", nil) } host, owner, repo, ok := ParseGitHubRepo(ref) if !ok { - return nil, "", coreerr.E("app.WrapElectronRepo", "cannot parse repo reference: "+ref, nil) + return nil, "", core.E("app.WrapElectronRepo", "cannot parse repo reference: "+ref, nil) } if !isGitHubReleaseHost(host) { - return nil, "", coreerr.E( + return nil, "", core.E( "app.WrapElectronRepo", "repo host does not expose GitHub releases: "+host, nil, @@ -421,20 +420,20 @@ func WrapElectronRepo(ctx context.Context, medium coreio.Medium, ref string, opt } if medium.IsDir(opts.ScratchDir) { if err := medium.DeleteAll(opts.ScratchDir); err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "clear scratch dir failed", err) + return nil, "", core.E("app.WrapElectronRepo", "clear scratch dir failed", err) } } if err := medium.EnsureDir(opts.ScratchDir); err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "ensure scratch dir failed", err) + return nil, "", core.E("app.WrapElectronRepo", "ensure scratch dir failed", err) } rel, err := FetchElectronRelease(ctx, host, owner, repo) if err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "release fetch failed", err) + return nil, "", core.E("app.WrapElectronRepo", "release fetch failed", err) } asset, ok := SelectRendererAsset(rel) if !ok { - return nil, "", coreerr.E( + return nil, "", core.E( "app.WrapElectronRepo", "release "+rel.TagName+" has no renderer-shaped asset", nil, @@ -443,14 +442,14 @@ func WrapElectronRepo(ctx context.Context, medium coreio.Medium, ref string, opt archivePath, err := DownloadAsset(ctx, medium, asset, opts.ScratchDir) if err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "asset download failed", err) + return nil, "", core.E("app.WrapElectronRepo", "asset download failed", err) } rendererDir := opts.ScratchDir if isArchivePath(asset.Name) { rendererDir = ArchiveExtractedDir(opts.ScratchDir, asset.Name) if err := ExtractArchive(medium, archivePath, rendererDir); err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "archive extract failed", err) + return nil, "", core.E("app.WrapElectronRepo", "archive extract failed", err) } } @@ -481,12 +480,12 @@ func WrapElectronRepo(ctx context.Context, medium coreio.Medium, ref string, opt } scan, err := ScanElectronRenderer(medium, rendererDir) if err != nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "renderer scan failed", err) + return nil, "", core.E("app.WrapElectronRepo", "renderer scan failed", err) } manifest := WrapElectron(&pkg, scan, WrapElectronOptions{Code: opts.Code}) if manifest == nil { - return nil, "", coreerr.E("app.WrapElectronRepo", "WrapElectron returned nil", nil) + return nil, "", core.E("app.WrapElectronRepo", "WrapElectron returned nil", nil) } if manifest.Code == "" || manifest.Code == "electron-app" { manifest.Code = slugify(coalesce(opts.Code, repo)) @@ -534,7 +533,7 @@ func isGitHubReleaseHost(host string) bool { // err := app.WriteElectronWrap(coreio.Local, "/.../apps/bitwarden", manifest) func WriteElectronWrap(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.WriteElectronWrap", "nil manifest", nil) + return core.E("app.WriteElectronWrap", "nil manifest", nil) } return writeWrappedManifest(medium, dest, manifest) } diff --git a/go/pkg_electron_extract.go b/go/pkg_electron_extract.go index 5aadf0f..da04218 100644 --- a/go/pkg_electron_extract.go +++ b/go/pkg_electron_extract.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // ExtractZip unpacks a downloaded zip archive into `dest`. Used by @@ -37,29 +36,29 @@ func ExtractZip(medium coreio.Medium, archive, dest string) error { medium = coreio.Local } if archive == "" { - return coreerr.E("app.ExtractZip", "empty archive path", nil) + return core.E("app.ExtractZip", "empty archive path", nil) } if dest == "" { - return coreerr.E("app.ExtractZip", "empty dest path", nil) + return core.E("app.ExtractZip", "empty dest path", nil) } if !medium.Exists(archive) { - return coreerr.E("app.ExtractZip", "archive not found: "+archive, nil) + return core.E("app.ExtractZip", "archive not found: "+archive, nil) } if err := medium.EnsureDir(dest); err != nil { - return coreerr.E("app.ExtractZip", "ensure dest dir failed", err) + return core.E("app.ExtractZip", "ensure dest dir failed", err) } body, err := medium.Read(archive) if err != nil { - return coreerr.E("app.ExtractZip", "read archive failed", err) + return core.E("app.ExtractZip", "read archive failed", err) } if body == "" { - return coreerr.E("app.ExtractZip", "archive is empty: "+archive, nil) + return core.E("app.ExtractZip", "archive is empty: "+archive, nil) } r, err := zip.NewReader(stringReaderAt(body), int64(len(body))) if err != nil { - return coreerr.E("app.ExtractZip", "parse zip failed", err) + return core.E("app.ExtractZip", "parse zip failed", err) } for _, f := range r.File { @@ -87,7 +86,7 @@ func extractZipEntry(medium coreio.Medium, f *zip.File, dest string) error { // Skip absolute paths and parent traversals — the joined path must // stay within `dest`. if core.PathIsAbs(name) || core.HasPrefix(name, "..") || core.Contains(name, "../") { - return coreerr.E( + return core.E( "app.ExtractZip", "refusing zip entry outside dest: "+name, nil, @@ -102,7 +101,7 @@ func extractZipEntry(medium coreio.Medium, f *zip.File, dest string) error { if !core.HasPrefix(target, cleanDest+sep) && target != cleanDest { // Belt-and-braces — the previous PathIsAbs / `..` checks should // catch this, but verify the resolved path before any write. - return coreerr.E( + return core.E( "app.ExtractZip", "refusing zip entry outside dest after join: "+name, nil, @@ -112,7 +111,7 @@ func extractZipEntry(medium coreio.Medium, f *zip.File, dest string) error { // Directory entries end with '/'. Create and continue. if f.FileInfo().IsDir() { if err := medium.EnsureDir(target); err != nil { - return coreerr.E("app.ExtractZip", "ensure dir failed: "+target, err) + return core.E("app.ExtractZip", "ensure dir failed: "+target, err) } return nil } @@ -125,21 +124,21 @@ func extractZipEntry(medium coreio.Medium, f *zip.File, dest string) error { } if err := medium.EnsureDir(core.PathDir(target)); err != nil { - return coreerr.E("app.ExtractZip", "ensure parent dir failed: "+target, err) + return core.E("app.ExtractZip", "ensure parent dir failed: "+target, err) } rc, err := f.Open() if err != nil { - return coreerr.E("app.ExtractZip", "open entry failed: "+name, err) + return core.E("app.ExtractZip", "open entry failed: "+name, err) } defer func() { _ = rc.Close() }() body, err := io.ReadAll(rc) if err != nil { - return coreerr.E("app.ExtractZip", "read entry failed: "+name, err) + return core.E("app.ExtractZip", "read entry failed: "+name, err) } if err := medium.Write(target, string(body)); err != nil { - return coreerr.E("app.ExtractZip", "write entry failed: "+target, err) + return core.E("app.ExtractZip", "write entry failed: "+target, err) } return nil } diff --git a/go/pkg_electron_extract_tar.go b/go/pkg_electron_extract_tar.go index 8827c49..d4820fb 100644 --- a/go/pkg_electron_extract_tar.go +++ b/go/pkg_electron_extract_tar.go @@ -9,7 +9,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // ExtractTar unpacks a downloaded `.tar` (uncompressed) or `.tar.gz` / @@ -38,29 +37,29 @@ func ExtractTar(medium coreio.Medium, archive, dest string) error { medium = coreio.Local } if archive == "" { - return coreerr.E("app.ExtractTar", "empty archive path", nil) + return core.E("app.ExtractTar", "empty archive path", nil) } if dest == "" { - return coreerr.E("app.ExtractTar", "empty dest path", nil) + return core.E("app.ExtractTar", "empty dest path", nil) } if !medium.Exists(archive) { - return coreerr.E("app.ExtractTar", "archive not found: "+archive, nil) + return core.E("app.ExtractTar", "archive not found: "+archive, nil) } if err := medium.EnsureDir(dest); err != nil { - return coreerr.E("app.ExtractTar", "ensure dest dir failed", err) + return core.E("app.ExtractTar", "ensure dest dir failed", err) } body, err := medium.Read(archive) if err != nil { - return coreerr.E("app.ExtractTar", "read archive failed", err) + return core.E("app.ExtractTar", "read archive failed", err) } if body == "" { - return coreerr.E("app.ExtractTar", "archive is empty: "+archive, nil) + return core.E("app.ExtractTar", "archive is empty: "+archive, nil) } reader, err := openTarReader(archive, body) if err != nil { - return coreerr.E("app.ExtractTar", "open tar reader failed", err) + return core.E("app.ExtractTar", "open tar reader failed", err) } for { @@ -69,7 +68,7 @@ func ExtractTar(medium coreio.Medium, archive, dest string) error { break } if err != nil { - return coreerr.E("app.ExtractTar", "read tar header failed", err) + return core.E("app.ExtractTar", "read tar header failed", err) } if err := extractTarEntry(medium, reader, hdr, dest); err != nil { return err @@ -148,7 +147,7 @@ func extractTarEntry(medium coreio.Medium, reader *tar.Reader, hdr *tar.Header, // Reject absolute paths and parent traversals — the joined target // must stay inside `dest`. if core.PathIsAbs(name) || core.HasPrefix(name, "..") || core.Contains(name, "../") { - return coreerr.E( + return core.E( "app.ExtractTar", "refusing tar entry outside dest: "+name, nil, @@ -161,7 +160,7 @@ func extractTarEntry(medium coreio.Medium, reader *tar.Reader, hdr *tar.Header, sep = "/" } if !core.HasPrefix(target, cleanDest+sep) && target != cleanDest { - return coreerr.E( + return core.E( "app.ExtractTar", "refusing tar entry outside dest after join: "+name, nil, @@ -171,19 +170,19 @@ func extractTarEntry(medium coreio.Medium, reader *tar.Reader, hdr *tar.Header, switch hdr.Typeflag { case tar.TypeDir: if err := medium.EnsureDir(target); err != nil { - return coreerr.E("app.ExtractTar", "ensure dir failed: "+target, err) + return core.E("app.ExtractTar", "ensure dir failed: "+target, err) } return nil case tar.TypeReg, tar.TypeRegA: if err := medium.EnsureDir(core.PathDir(target)); err != nil { - return coreerr.E("app.ExtractTar", "ensure parent dir failed: "+target, err) + return core.E("app.ExtractTar", "ensure parent dir failed: "+target, err) } body, err := io.ReadAll(reader) if err != nil { - return coreerr.E("app.ExtractTar", "read entry failed: "+name, err) + return core.E("app.ExtractTar", "read entry failed: "+name, err) } if err := medium.Write(target, string(body)); err != nil { - return coreerr.E("app.ExtractTar", "write entry failed: "+target, err) + return core.E("app.ExtractTar", "write entry failed: "+target, err) } return nil default: @@ -205,7 +204,7 @@ func extractTarEntry(medium coreio.Medium, reader *tar.Reader, hdr *tar.Header, // caller rather than silently no-oping. func ExtractArchive(medium coreio.Medium, archive, dest string) error { if archive == "" { - return coreerr.E("app.ExtractArchive", "empty archive path", nil) + return core.E("app.ExtractArchive", "empty archive path", nil) } low := core.Lower(archive) switch { @@ -216,7 +215,7 @@ func ExtractArchive(medium coreio.Medium, archive, dest string) error { core.HasSuffix(low, ".tar"): return ExtractTar(medium, archive, dest) } - return coreerr.E( + return core.E( "app.ExtractArchive", "unsupported archive format: "+archive+" (supported: .zip, .tar, .tar.gz, .tgz)", nil, diff --git a/go/pkg_electron_fetch.go b/go/pkg_electron_fetch.go index 3a26feb..1bb8bef 100644 --- a/go/pkg_electron_fetch.go +++ b/go/pkg_electron_fetch.go @@ -10,7 +10,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // electronReleaseTimeout caps the GitHub release HTTP call so a slow @@ -61,7 +60,7 @@ type GitHubRelease struct { // for each renderer asset you actually need. func FetchElectronRelease(ctx context.Context, host, owner, repo string) (*GitHubRelease, error) { if owner == "" || repo == "" { - return nil, coreerr.E("app.FetchElectronRelease", "owner and repo are required", nil) + return nil, core.E("app.FetchElectronRelease", "owner and repo are required", nil) } if host == "" { host = "github.com" @@ -77,12 +76,12 @@ func FetchElectronRelease(ctx context.Context, host, owner, repo string) (*GitHu // rel, err := app.FetchElectronReleaseURL(ctx, srv.URL+"/rel.json") func FetchElectronReleaseURL(ctx context.Context, url string) (*GitHubRelease, error) { if url == "" { - return nil, coreerr.E("app.FetchElectronReleaseURL", "empty URL", nil) + return nil, core.E("app.FetchElectronReleaseURL", "empty URL", nil) } req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - return nil, coreerr.E("app.FetchElectronReleaseURL", "request build failed", err) + return nil, core.E("app.FetchElectronReleaseURL", "request build failed", err) } req.Header.Set("Accept", "application/vnd.github+json") req.Header.Set("X-GitHub-Api-Version", "2022-11-28") @@ -90,12 +89,12 @@ func FetchElectronReleaseURL(ctx context.Context, url string) (*GitHubRelease, e client := &http.Client{Timeout: electronReleaseTimeout} resp, err := client.Do(req) if err != nil { - return nil, coreerr.E("app.FetchElectronReleaseURL", "HTTP GET failed", err) + return nil, core.E("app.FetchElectronReleaseURL", "HTTP GET failed", err) } defer func() { _ = resp.Body.Close() }() if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return nil, coreerr.E( + return nil, core.E( "app.FetchElectronReleaseURL", "non-2xx status: "+core.Sprint(resp.StatusCode)+" for "+url, nil, @@ -104,14 +103,14 @@ func FetchElectronReleaseURL(ctx context.Context, url string) (*GitHubRelease, e body, err := io.ReadAll(resp.Body) if err != nil { - return nil, coreerr.E("app.FetchElectronReleaseURL", "read body failed", err) + return nil, core.E("app.FetchElectronReleaseURL", "read body failed", err) } var rel GitHubRelease r := core.JSONUnmarshal(body, &rel) if !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.FetchElectronReleaseURL", "decode release JSON failed", cause) + return nil, core.E("app.FetchElectronReleaseURL", "decode release JSON failed", cause) } return &rel, nil } @@ -202,10 +201,10 @@ func hasPlatformMarker(low string) bool { // bundles do not balloon memory. func DownloadAsset(ctx context.Context, medium coreio.Medium, asset GitHubAsset, dir string) (string, error) { if asset.DownloadURL == "" { - return "", coreerr.E("app.DownloadAsset", "empty asset URL", nil) + return "", core.E("app.DownloadAsset", "empty asset URL", nil) } if dir == "" { - return "", coreerr.E("app.DownloadAsset", "empty directory", nil) + return "", core.E("app.DownloadAsset", "empty directory", nil) } if medium == nil { medium = coreio.Local @@ -213,18 +212,18 @@ func DownloadAsset(ctx context.Context, medium coreio.Medium, asset GitHubAsset, req, err := http.NewRequestWithContext(ctx, http.MethodGet, asset.DownloadURL, nil) if err != nil { - return "", coreerr.E("app.DownloadAsset", "request build failed", err) + return "", core.E("app.DownloadAsset", "request build failed", err) } client := &http.Client{Timeout: electronReleaseTimeout} resp, err := client.Do(req) if err != nil { - return "", coreerr.E("app.DownloadAsset", "HTTP GET failed", err) + return "", core.E("app.DownloadAsset", "HTTP GET failed", err) } defer func() { _ = resp.Body.Close() }() if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return "", coreerr.E( + return "", core.E( "app.DownloadAsset", "non-2xx status: "+core.Sprint(resp.StatusCode), nil, @@ -232,16 +231,16 @@ func DownloadAsset(ctx context.Context, medium coreio.Medium, asset GitHubAsset, } if err := medium.EnsureDir(dir); err != nil { - return "", coreerr.E("app.DownloadAsset", "ensure dir failed", err) + return "", core.E("app.DownloadAsset", "ensure dir failed", err) } dest := core.Path(dir, asset.Name) body, err := io.ReadAll(resp.Body) if err != nil { - return "", coreerr.E("app.DownloadAsset", "read body failed", err) + return "", core.E("app.DownloadAsset", "read body failed", err) } if err := medium.Write(dest, string(body)); err != nil { - return "", coreerr.E("app.DownloadAsset", "write failed", err) + return "", core.E("app.DownloadAsset", "write failed", err) } return dest, nil } diff --git a/go/pkg_pwa.go b/go/pkg_pwa.go index c1cadc2..29d89bb 100644 --- a/go/pkg_pwa.go +++ b/go/pkg_pwa.go @@ -13,7 +13,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // PWAIcon is one entry in a PWA manifest's icons array. The wrapper @@ -70,7 +69,7 @@ const pwaFetchTimeout = 15 * time.Second // // Rules: // -// - Returns a coreerr.E-wrapped error for non-2xx responses, network +// - Returns a core.E-wrapped error for non-2xx responses, network // failures, and decode errors. // // - Trims whitespace from the URL so CLI shells pasting trailing @@ -84,7 +83,7 @@ const pwaFetchTimeout = 15 * time.Second func FetchPWAManifest(ctx context.Context, url string) (*PWAManifest, error) { url = core.Trim(url) if url == "" { - return nil, coreerr.E("app.FetchPWAManifest", "empty URL", nil) + return nil, core.E("app.FetchPWAManifest", "empty URL", nil) } candidates := pwaManifestCandidates(url) @@ -117,9 +116,9 @@ func FetchPWAManifest(ctx context.Context, url string) (*PWAManifest, error) { } if lastErr == nil { - lastErr = coreerr.E("app.FetchPWAManifest", "no manifest candidates resolved", nil) + lastErr = core.E("app.FetchPWAManifest", "no manifest candidates resolved", nil) } - return nil, coreerr.E("app.FetchPWAManifest", "manifest fetch failed for "+url, lastErr) + return nil, core.E("app.FetchPWAManifest", "manifest fetch failed for "+url, lastErr) } // WrapPWAOptions tunes WrapPWA. A zero value is fine — the canonical @@ -333,16 +332,16 @@ func pwaWindowMode(display string) string { // err := app.WritePWAWrap(coreio.Local, "/Users/me/.core/apps/play", manifest) func WritePWAWrap(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.WritePWAWrap", "nil manifest", nil) + return core.E("app.WritePWAWrap", "nil manifest", nil) } if medium == nil { medium = coreio.Local } if err := materializeWrappedRuntimeAssets(medium, dest, manifest); err != nil { - return coreerr.E("app.WritePWAWrap", "materialise runtime assets failed", err) + return core.E("app.WritePWAWrap", "materialise runtime assets failed", err) } if err := writeWrappedManifest(medium, dest, manifest); err != nil { - return coreerr.E("app.WritePWAWrap", "write failed", err) + return core.E("app.WritePWAWrap", "write failed", err) } return nil } @@ -402,20 +401,20 @@ func applyPWAPermissionMapping(m *config.ViewManifest, perms []string) { func fetchPWAURL(ctx context.Context, url string) ([]byte, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - return nil, coreerr.E("app.fetchPWAURL", "request build failed", err) + return nil, core.E("app.fetchPWAURL", "request build failed", err) } req.Header.Set("Accept", "application/manifest+json, application/json") client := &http.Client{Timeout: pwaFetchTimeout} resp, err := client.Do(req) if err != nil { - return nil, coreerr.E("app.fetchPWAURL", "HTTP GET failed", err) + return nil, core.E("app.fetchPWAURL", "HTTP GET failed", err) } if resp.StatusCode < 200 || resp.StatusCode >= 300 { if closeErr := resp.Body.Close(); closeErr != nil { core.Warn("app.fetchPWAURL: response body close failed", "url", url, "err", closeErr) } - return nil, coreerr.E( + return nil, core.E( "app.fetchPWAURL", "non-2xx status: "+core.Sprint(resp.StatusCode), nil, @@ -425,7 +424,7 @@ func fetchPWAURL(ctx context.Context, url string) ([]byte, error) { body := core.ReadAll(resp.Body) if !body.OK { cause, _ := body.Value.(error) - return nil, coreerr.E("app.fetchPWAURL", "read body failed", cause) + return nil, core.E("app.fetchPWAURL", "read body failed", cause) } payload, _ := body.Value.(string) return []byte(payload), nil @@ -440,10 +439,10 @@ func decodePWAManifest(body []byte) (*PWAManifest, error) { r := core.JSONUnmarshal(body, &m) if !r.OK { cause, _ := r.Value.(error) - return nil, coreerr.E("app.decodePWAManifest", "decode manifest body failed", cause) + return nil, core.E("app.decodePWAManifest", "decode manifest body failed", cause) } if m.StartURL == "" && m.Name == "" && m.ShortName == "" { - return nil, coreerr.E("app.decodePWAManifest", "body is not a web app manifest", nil) + return nil, core.E("app.decodePWAManifest", "body is not a web app manifest", nil) } return &m, nil } diff --git a/go/pkg_repo.go b/go/pkg_repo.go index 087e037..208f5b4 100644 --- a/go/pkg_repo.go +++ b/go/pkg_repo.go @@ -7,7 +7,6 @@ import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // FetchRepoSource downloads and extracts a GitHub-style repository @@ -18,10 +17,10 @@ import ( func FetchRepoSource(ctx context.Context, medium coreio.Medium, ref, scratchDir string) (string, error) { host, owner, repo, ok := ParseGitHubRepo(ref) if !ok { - return "", coreerr.E("app.FetchRepoSource", "cannot parse repo reference: "+ref, nil) + return "", core.E("app.FetchRepoSource", "cannot parse repo reference: "+ref, nil) } if !isGitHubReleaseHost(host) { - return "", coreerr.E( + return "", core.E( "app.FetchRepoSource", "repo host does not expose GitHub archives: "+host, nil, @@ -41,10 +40,10 @@ func FetchRepoSourceURL(ctx context.Context, medium coreio.Medium, url, scratchD medium = coreio.Local } if url == "" { - return "", coreerr.E("app.FetchRepoSourceURL", "empty archive URL", nil) + return "", core.E("app.FetchRepoSourceURL", "empty archive URL", nil) } if scratchDir == "" { - return "", coreerr.E("app.FetchRepoSourceURL", "empty scratch dir", nil) + return "", core.E("app.FetchRepoSourceURL", "empty scratch dir", nil) } if archiveName == "" { archiveName = "source.zip" @@ -52,11 +51,11 @@ func FetchRepoSourceURL(ctx context.Context, medium coreio.Medium, url, scratchD if medium.IsDir(scratchDir) { if err := medium.DeleteAll(scratchDir); err != nil { - return "", coreerr.E("app.FetchRepoSourceURL", "clear scratch dir failed", err) + return "", core.E("app.FetchRepoSourceURL", "clear scratch dir failed", err) } } if err := medium.EnsureDir(scratchDir); err != nil { - return "", coreerr.E("app.FetchRepoSourceURL", "ensure scratch dir failed", err) + return "", core.E("app.FetchRepoSourceURL", "ensure scratch dir failed", err) } archivePath, err := DownloadAsset(ctx, medium, GitHubAsset{ @@ -64,17 +63,17 @@ func FetchRepoSourceURL(ctx context.Context, medium coreio.Medium, url, scratchD DownloadURL: url, }, scratchDir) if err != nil { - return "", coreerr.E("app.FetchRepoSourceURL", "archive download failed", err) + return "", core.E("app.FetchRepoSourceURL", "archive download failed", err) } extractDir := ArchiveExtractedDir(scratchDir, archiveName) if err := ExtractArchive(medium, archivePath, extractDir); err != nil { - return "", coreerr.E("app.FetchRepoSourceURL", "archive extract failed", err) + return "", core.E("app.FetchRepoSourceURL", "archive extract failed", err) } root, err := resolveRepoSourceRoot(medium, extractDir) if err != nil { - return "", coreerr.E("app.FetchRepoSourceURL", "resolve project root failed", err) + return "", core.E("app.FetchRepoSourceURL", "resolve project root failed", err) } return root, nil } @@ -95,17 +94,17 @@ func LoadRepoPWAManifest(ctx context.Context, medium coreio.Medium, ref, scratch } path, ok := FindLocalPWAManifest(medium, root) if !ok { - return nil, "", coreerr.E("app.LoadRepoPWAManifest", "PWA manifest not found under "+root, nil) + return nil, "", core.E("app.LoadRepoPWAManifest", "PWA manifest not found under "+root, nil) } body, err := medium.Read(path) if err != nil { - return nil, "", coreerr.E("app.LoadRepoPWAManifest", "read PWA manifest failed", err) + return nil, "", core.E("app.LoadRepoPWAManifest", "read PWA manifest failed", err) } var manifest PWAManifest r := core.JSONUnmarshal([]byte(body), &manifest) if !r.OK { cause, _ := r.Value.(error) - return nil, "", coreerr.E("app.LoadRepoPWAManifest", "decode PWA manifest failed", cause) + return nil, "", core.E("app.LoadRepoPWAManifest", "decode PWA manifest failed", cause) } return &manifest, root, nil } @@ -131,10 +130,10 @@ func resolveRepoSourceRoot(medium coreio.Medium, dir string) (string, error) { medium = coreio.Local } if dir == "" { - return "", coreerr.E("app.resolveRepoSourceRoot", "empty directory", nil) + return "", core.E("app.resolveRepoSourceRoot", "empty directory", nil) } if !medium.IsDir(dir) { - return "", coreerr.E("app.resolveRepoSourceRoot", "not a directory: "+dir, nil) + return "", core.E("app.resolveRepoSourceRoot", "not a directory: "+dir, nil) } cur := dir diff --git a/go/pkg_type.go b/go/pkg_type.go index aa60e70..0e0ecdf 100644 --- a/go/pkg_type.go +++ b/go/pkg_type.go @@ -5,7 +5,6 @@ package app import ( core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // PackageType enumerates the wrapping modes `core pkg` understands. Each @@ -206,7 +205,7 @@ func detectsLocalPWA(body string) bool { // // return errDetect("./path") func errDetect(where string) error { - return coreerr.E( + return core.E( "app.DetectPackageType", "cannot determine package type at "+where+" (no .core/view.yaml, manifest.json, manifest.webmanifest, package.json, or index.html)", nil, diff --git a/go/pkg_web.go b/go/pkg_web.go index d039ece..6ca3baf 100644 --- a/go/pkg_web.go +++ b/go/pkg_web.go @@ -3,12 +3,9 @@ package app import ( - "strings" - core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // WrapWebOptions tunes the plain-web wrap. Web wrapping is the @@ -42,10 +39,10 @@ func WrapWeb(medium coreio.Medium, dir string, opts WrapWebOptions) (*config.Vie medium = coreio.Local } if dir == "" { - return nil, coreerr.E("app.WrapWeb", "empty directory", nil) + return nil, core.E("app.WrapWeb", "empty directory", nil) } if !medium.IsDir(dir) { - return nil, coreerr.E("app.WrapWeb", "not a directory: "+dir, nil) + return nil, core.E("app.WrapWeb", "not a directory: "+dir, nil) } entry := opts.Entry @@ -55,7 +52,7 @@ func WrapWeb(medium coreio.Medium, dir string, opts WrapWebOptions) (*config.Vie entryPath := core.Path(dir, entry) if !medium.Exists(entryPath) { - return nil, coreerr.E("app.WrapWeb", "entry not found: "+entryPath, nil) + return nil, core.E("app.WrapWeb", "entry not found: "+entryPath, nil) } code := core.Trim(opts.Code) @@ -102,7 +99,7 @@ func WrapWeb(medium coreio.Medium, dir string, opts WrapWebOptions) (*config.Vie // err := app.WriteWebWrap(coreio.Local, dest, manifest) func WriteWebWrap(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.WriteWebWrap", "nil manifest", nil) + return core.E("app.WriteWebWrap", "nil manifest", nil) } return writeWrappedManifest(medium, dest, manifest) } @@ -112,8 +109,18 @@ func defaultWebWrapName(dir string) string { if base == "" { return "" } - base = strings.NewReplacer("-", " ", "_", " ", ".", " ").Replace(base) - parts := strings.Fields(base) + base = core.Replace(base, "-", " ") + base = core.Replace(base, "_", " ") + base = core.Replace(base, ".", " ") + rawParts := core.Split(base, " ") + parts := make([]string, 0, len(rawParts)) + for _, raw := range rawParts { + part := core.Trim(raw) + if part == "" { + continue + } + parts = append(parts, part) + } if len(parts) == 0 { return "" } @@ -121,7 +128,7 @@ func defaultWebWrapName(dir string) string { if part == "" { continue } - parts[i] = strings.ToUpper(part[:1]) + part[1:] + parts[i] = core.Upper(part[:1]) + part[1:] } - return strings.Join(parts, " ") + return core.Join(" ", parts...) } diff --git a/go/plugin.go b/go/plugin.go index 4240c6c..f5351bf 100644 --- a/go/plugin.go +++ b/go/plugin.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // PluginOptions tunes PluginBoot. Plugins are isolated `core.New()` @@ -69,10 +68,10 @@ type PluginOptions struct { // stays inside its directory. func PluginBoot(ctx context.Context, opts PluginOptions) (*Instance, error) { if opts.ProjectRoot == "" { - return nil, coreerr.E("app.PluginBoot", "empty ProjectRoot", nil) + return nil, core.E("app.PluginBoot", "empty ProjectRoot", nil) } if opts.Manifest.Code == "" { - return nil, coreerr.E("app.PluginBoot", "manifest.code is empty", nil) + return nil, core.E("app.PluginBoot", "manifest.code is empty", nil) } medium := opts.Medium @@ -100,24 +99,24 @@ func PluginBoot(ctx context.Context, opts PluginOptions) (*Instance, error) { // trustworthy before calling PluginBoot. Step 7 (Start) is the // caller's explicit trigger. if err := permissions(c, &inst.Manifest, opts.Mode); err != nil { - return nil, coreerr.E("app.PluginBoot", "permission binding failed", err) + return nil, core.E("app.PluginBoot", "permission binding failed", err) } if err := modulesWithMode(ctx, c, &inst.Manifest, opts.Mode); err != nil { // modulesWithMode already short-circuits the dev path internally // (logs + returns nil); a non-nil error here is therefore a // genuine prod failure and should bubble up. - return nil, coreerr.E("app.PluginBoot", "module load failed", err) + return nil, core.E("app.PluginBoot", "module load failed", err) } spec, err := resolveLayout(c, &inst.Manifest) if err != nil { - return nil, coreerr.E("app.PluginBoot", "layout composition failed", err) + return nil, core.E("app.PluginBoot", "layout composition failed", err) } inst.Layout = spec if err := applyConfigWithMode(c, &inst.Manifest, medium, opts.ProjectRoot, opts.Mode); err != nil { - return nil, coreerr.E("app.PluginBoot", "config template failed", err) + return nil, core.E("app.PluginBoot", "config template failed", err) } if err := registerRuntimeActions(inst); err != nil { - return nil, coreerr.E("app.PluginBoot", "runtime action registration failed", err) + return nil, core.E("app.PluginBoot", "runtime action registration failed", err) } return inst, nil diff --git a/go/pwa_runtime.go b/go/pwa_runtime.go index f7c7253..c5d8aca 100644 --- a/go/pwa_runtime.go +++ b/go/pwa_runtime.go @@ -3,14 +3,11 @@ package app import ( - "encoding/json" - "path/filepath" "strings" core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const ( @@ -111,18 +108,18 @@ func materializeWrappedRuntimeAssets(medium coreio.Medium, dest string, manifest func materializePWARuntimeAssets(medium coreio.Medium, dest string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.materializePWARuntimeAssets", "nil manifest", nil) + return core.E("app.materializePWARuntimeAssets", "nil manifest", nil) } if medium == nil { medium = coreio.Local } if dest == "" { - return coreerr.E("app.materializePWARuntimeAssets", "empty dest", nil) + return core.E("app.materializePWARuntimeAssets", "empty dest", nil) } pwaCfg := ensurePWARuntimeConfig(manifest) if pwaCfg == nil { - return coreerr.E("app.materializePWARuntimeAssets", "pwa config unavailable", nil) + return core.E("app.materializePWARuntimeAssets", "pwa config unavailable", nil) } for path, body := range map[string]string{ @@ -130,10 +127,10 @@ func materializePWARuntimeAssets(medium coreio.Medium, dest string, manifest *co core.Path(dest, pwaBootstrapFile): renderPWABootstrap(manifest, pwaCfg), } { if err := medium.EnsureDir(core.PathDir(path)); err != nil { - return coreerr.E("app.materializePWARuntimeAssets", "ensure dir failed", err) + return core.E("app.materializePWARuntimeAssets", "ensure dir failed", err) } if err := medium.Write(path, body); err != nil { - return coreerr.E("app.materializePWARuntimeAssets", "write runtime asset failed", err) + return core.E("app.materializePWARuntimeAssets", "write runtime asset failed", err) } } if err := injectPWABootstrap(medium, dest, manifest); err != nil { @@ -148,8 +145,8 @@ func renderPWAServiceWorker(manifest *config.ViewManifest, pwaCfg map[string]any "version": coalesce(string(manifest.Version), "0.1.0"), "pwa": pwaCfg, } - body, _ := json.Marshal(payload) - return `const CORE_PWA = ` + string(body) + `; + body := core.JSONMarshalString(payload) + return `const CORE_PWA = ` + body + `; const SW = CORE_PWA.pwa && CORE_PWA.pwa.service_worker ? CORE_PWA.pwa.service_worker : {}; const CACHE_NAME = "core-pwa-" + CORE_PWA.code + "-" + CORE_PWA.version; const PRECACHE = Array.isArray(SW.cache) ? SW.cache.filter(Boolean) : ["./core.json", "./core-pwa.js"]; @@ -228,9 +225,9 @@ func renderPWABootstrap(manifest *config.ViewManifest, pwaCfg map[string]any) st "version": coalesce(string(manifest.Version), "0.1.0"), "pwa": pwaCfg, } - body, _ := json.Marshal(payload) + body := core.JSONMarshalString(payload) return `(() => { - const CORE_PWA = ` + string(body) + `; + const CORE_PWA = ` + body + `; const PWA = CORE_PWA.pwa || {}; const STORE = PWA.store_mirror || {}; const SYNC = PWA.sync || {}; @@ -489,14 +486,14 @@ func injectPWABootstrap(medium coreio.Medium, dest string, manifest *config.View } body, err := medium.Read(path) if err != nil { - return coreerr.E("app.injectPWABootstrap", "read html entry failed", err) + return core.E("app.injectPWABootstrap", "read html entry failed", err) } - if strings.Contains(body, "data-core-pwa") { + if core.Contains(body, "data-core-pwa") { return nil } tag := `` - lower := strings.ToLower(body) + lower := core.Lower(body) if idx := strings.LastIndex(lower, ""); idx >= 0 { body = body[:idx] + tag + "\n" + body[idx:] } else if idx := strings.LastIndex(lower, ""); idx >= 0 { @@ -505,7 +502,7 @@ func injectPWABootstrap(medium coreio.Medium, dest string, manifest *config.View body += "\n" + tag + "\n" } if err := medium.Write(path, body); err != nil { - return coreerr.E("app.injectPWABootstrap", "write html entry failed", err) + return core.E("app.injectPWABootstrap", "write html entry failed", err) } return nil } @@ -526,7 +523,7 @@ func pwaBootstrapTarget(medium coreio.Medium, dest string, manifest *config.View continue } seen[candidate] = true - ext := strings.ToLower(filepath.Ext(candidate)) + ext := core.Lower(core.PathExt(candidate)) if ext != ".html" && ext != ".htm" { continue } @@ -543,8 +540,8 @@ func pwaBootstrapTarget(medium coreio.Medium, dest string, manifest *config.View if entry.IsDir() { continue } - name := strings.ToLower(entry.Name()) - if strings.HasSuffix(name, ".html") || strings.HasSuffix(name, ".htm") { + name := core.Lower(entry.Name()) + if core.HasSuffix(name, ".html") || core.HasSuffix(name, ".htm") { return core.Path(dest, entry.Name()) } } @@ -559,22 +556,22 @@ func pwaBootstrapCandidatesFromURL(raw string) []string { path := raw if isLocalSource(raw) { path = trimLocalPrefix(raw) - } else if idx := strings.Index(raw, "://"); idx >= 0 { + } else if core.Contains(raw, "://") { if parsed, ok := splitURLPath(raw); ok { path = parsed } } - path = strings.TrimPrefix(path, "/") - path = strings.TrimPrefix(path, "./") - path = strings.TrimPrefix(path, "../") + path = core.TrimPrefix(path, "/") + path = core.TrimPrefix(path, "./") + path = core.TrimPrefix(path, "../") if path == "" { return nil } out := []string{path} - if filepath.Ext(path) == "" { + if core.PathExt(path) == "" { out = append(out, core.Path(path, "index.html")) } - out = append(out, filepath.Base(path)) + out = append(out, core.PathBase(path)) return out } diff --git a/go/registry.go b/go/registry.go index 0997899..bbf4166 100644 --- a/go/registry.go +++ b/go/registry.go @@ -8,7 +8,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" - coreerr "dappco.re/go/log" ) // ModuleFactory returns a CoreOption that wires a named module onto a @@ -141,7 +140,7 @@ func resolveModulesFromRegistry(names []string) ([]ModuleFactory, []string) { // if err := applyModuleFactories(c, factories); err != nil { return err } func applyModuleFactories(c *core.Core, factories []ModuleFactory) error { if c == nil { - return coreerr.E("app.applyModuleFactories", "nil core", nil) + return core.E("app.applyModuleFactories", "nil core", nil) } for _, f := range factories { if f == nil { @@ -158,7 +157,7 @@ func applyModuleFactories(c *core.Core, factories []ModuleFactory) error { // caller can fail-fast on a misbehaving factory. if r := opt(c); !r.OK { cause, _ := r.Value.(error) - return coreerr.E("app.applyModuleFactories", "module option failed", cause) + return core.E("app.applyModuleFactories", "module option failed", cause) } } return nil @@ -173,10 +172,10 @@ func applyModuleFactories(c *core.Core, factories []ModuleFactory) error { // err := loadModules(ctx, c, &manifest, ModeProd) func loadModules(_ context.Context, c *core.Core, m *config.ViewManifest, mode Mode) error { if c == nil { - return coreerr.E("app.loadModules", "nil core", nil) + return core.E("app.loadModules", "nil core", nil) } if m == nil { - return coreerr.E("app.loadModules", "nil manifest", nil) + return core.E("app.loadModules", "nil manifest", nil) } if len(m.Modules) == 0 { return nil @@ -196,7 +195,7 @@ func loadModules(_ context.Context, c *core.Core, m *config.ViewManifest, mode M // capability the host does not advertise, so silently dropping it // would leave the app crashing later when it dispatches an action. if mode == ModeProd { - return coreerr.E( + return core.E( "app.loadModules", "unresolved module(s): "+core.Join(", ", missing...), nil, diff --git a/go/runtime.go b/go/runtime.go index c1fadf4..b7c4386 100644 --- a/go/runtime.go +++ b/go/runtime.go @@ -4,21 +4,17 @@ package app import ( "context" - "encoding/json" - "errors" "io" "net/http" neturl "net/url" "os/exec" "path" "runtime" - "strings" "sync" "time" core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) type runtimeBindings struct { @@ -32,10 +28,10 @@ type runtimeBindings struct { func registerRuntimeActions(inst *Instance) error { if inst == nil { - return coreerr.E("app.registerRuntimeActions", "nil instance", nil) + return core.E("app.registerRuntimeActions", "nil instance", nil) } if inst.Core == nil { - return coreerr.E("app.registerRuntimeActions", "nil core", nil) + return core.E("app.registerRuntimeActions", "nil core", nil) } if inst.runtime != nil { return nil @@ -118,7 +114,7 @@ func (rt *runtimeBindings) shutdown() { func (rt *runtimeBindings) workspaceStore() (*workspaceObjectStore, error) { if rt == nil { - return nil, coreerr.E("app.runtimeBindings.workspaceStore", "nil runtime", nil) + return nil, core.E("app.runtimeBindings.workspaceStore", "nil runtime", nil) } rt.storeMu.Lock() defer rt.storeMu.Unlock() @@ -127,7 +123,7 @@ func (rt *runtimeBindings) workspaceStore() (*workspaceObjectStore, error) { } if rt.store != nil { if err := rt.store.Close(); err != nil { - return nil, coreerr.E("app.runtimeBindings.workspaceStore", "close previous store failed", err) + return nil, core.E("app.runtimeBindings.workspaceStore", "close previous store failed", err) } rt.store = nil } @@ -263,7 +259,7 @@ func (rt *runtimeBindings) handleStoreDelete(_ context.Context, opts core.Option } func (rt *runtimeBindings) handleNetFetch(ctx context.Context, opts core.Options) core.Result { - rawURL := strings.TrimSpace(opts.String("url")) + rawURL := core.Trim(opts.String("url")) if rawURL == "" { return resultError("app.runtime.handleNetFetch", "url is required", nil) } @@ -275,7 +271,7 @@ func (rt *runtimeBindings) handleNetFetch(ctx context.Context, opts core.Options return resultError("app.runtime.handleNetFetch", "access denied", err) } - method := strings.ToUpper(strings.TrimSpace(opts.String("method"))) + method := core.Upper(core.Trim(opts.String("method"))) body := opts.String("body") if method == "" { if body != "" { @@ -285,7 +281,7 @@ func (rt *runtimeBindings) handleNetFetch(ctx context.Context, opts core.Options } } - req, err := http.NewRequestWithContext(ctx, method, rawURL, strings.NewReader(body)) + req, err := http.NewRequestWithContext(ctx, method, rawURL, core.NewReader(body)) if err != nil { return resultError("app.runtime.handleNetFetch", "build request failed", err) } @@ -311,7 +307,7 @@ func (rt *runtimeBindings) handleNetFetch(ctx context.Context, opts core.Options } func (rt *runtimeBindings) handleNetWS(_ context.Context, opts core.Options) core.Result { - rawURL := strings.TrimSpace(opts.String("url")) + rawURL := core.Trim(opts.String("url")) if rawURL == "" { return resultError("app.runtime.handleNetWS", "url is required", nil) } @@ -324,12 +320,12 @@ func (rt *runtimeBindings) handleNetWS(_ context.Context, opts core.Options) cor } func (rt *runtimeBindings) handleBrainRecall(ctx context.Context, opts core.Options) core.Result { - query := strings.TrimSpace(opts.String("query")) + query := core.Trim(opts.String("query")) if query == "" { return resultError("app.runtime.handleBrainRecall", "query is required", nil) } - endpoint := strings.TrimSpace(core.Env("OPENBRAIN_URL")) + endpoint := core.Trim(core.Env("OPENBRAIN_URL")) if endpoint == "" { endpoint = "https://api.openbrain/recall" } @@ -360,7 +356,7 @@ func (rt *runtimeBindings) handleBrainRecall(ctx context.Context, opts core.Opti body, _ := payload["body"].(string) var decoded any - if err := json.Unmarshal([]byte(body), &decoded); err != nil { + if r := core.JSONUnmarshal([]byte(body), &decoded); !r.OK { return resultValue(map[string]any{"memories": []any{body}}) } switch value := decoded.(type) { @@ -377,7 +373,7 @@ func (rt *runtimeBindings) handleBrainRecall(ctx context.Context, opts core.Opti } func (rt *runtimeBindings) handleProcessRun(ctx context.Context, opts core.Options) core.Result { - command := strings.TrimSpace(opts.String("command")) + command := core.Trim(opts.String("command")) if command == "" { return resultError("app.runtime.handleProcessRun", "command is required", nil) } @@ -396,8 +392,8 @@ func (rt *runtimeBindings) handleProcessRun(ctx context.Context, opts core.Optio } func (rt *runtimeBindings) handleProcessAdd(_ context.Context, opts core.Options) core.Result { - command := strings.TrimSpace(opts.String("command")) - key := strings.TrimSpace(opts.String("key")) + command := core.Trim(opts.String("command")) + key := core.Trim(opts.String("key")) if key == "" || command == "" { return resultError("app.runtime.handleProcessAdd", "key and command are required", nil) } @@ -415,7 +411,7 @@ func (rt *runtimeBindings) handleProcessAdd(_ context.Context, opts core.Options } func (rt *runtimeBindings) handleProcessStart(ctx context.Context, opts core.Options) core.Result { - started, err := rt.processes.start(ctx, strings.TrimSpace(opts.String("key"))) + started, err := rt.processes.start(ctx, core.Trim(opts.String("key"))) if err != nil { return resultError("app.runtime.handleProcessStart", "start failed", err) } @@ -423,7 +419,7 @@ func (rt *runtimeBindings) handleProcessStart(ctx context.Context, opts core.Opt } func (rt *runtimeBindings) handleProcessStop(_ context.Context, opts core.Options) core.Result { - stopped, err := rt.processes.stop(strings.TrimSpace(opts.String("key"))) + stopped, err := rt.processes.stop(core.Trim(opts.String("key"))) if err != nil { return resultError("app.runtime.handleProcessStop", "stop failed", err) } @@ -431,7 +427,7 @@ func (rt *runtimeBindings) handleProcessStop(_ context.Context, opts core.Option } func (rt *runtimeBindings) handleProcessKill(_ context.Context, opts core.Options) core.Result { - killed, err := rt.processes.kill(strings.TrimSpace(opts.String("key"))) + killed, err := rt.processes.kill(core.Trim(opts.String("key"))) if err != nil { return resultError("app.runtime.handleProcessKill", "kill failed", err) } @@ -443,7 +439,7 @@ func (rt *runtimeBindings) handleProcessList(_ context.Context, _ core.Options) } func (rt *runtimeBindings) handleProcessGet(_ context.Context, opts core.Options) core.Result { - info, err := rt.processes.info(strings.TrimSpace(opts.String("key"))) + info, err := rt.processes.info(core.Trim(opts.String("key"))) if err != nil { return resultError("app.runtime.handleProcessGet", "lookup failed", err) } @@ -451,7 +447,7 @@ func (rt *runtimeBindings) handleProcessGet(_ context.Context, opts core.Options } func (rt *runtimeBindings) handleProcessStdout(_ context.Context, opts core.Options) core.Result { - stdout, err := rt.processes.stdoutValue(strings.TrimSpace(opts.String("key"))) + stdout, err := rt.processes.stdoutValue(core.Trim(opts.String("key"))) if err != nil { return resultError("app.runtime.handleProcessStdout", "read stdout failed", err) } @@ -459,7 +455,7 @@ func (rt *runtimeBindings) handleProcessStdout(_ context.Context, opts core.Opti } func (rt *runtimeBindings) handleProcessStdinWrite(_ context.Context, opts core.Options) core.Result { - if err := rt.processes.writeStdin(strings.TrimSpace(opts.String("key")), opts.String("data")); err != nil { + if err := rt.processes.writeStdin(core.Trim(opts.String("key")), opts.String("data")); err != nil { return resultError("app.runtime.handleProcessStdinWrite", "write stdin failed", err) } return core.Result{OK: true} @@ -498,7 +494,7 @@ func (rt *runtimeBindings) handleGUIDialogSave(_ context.Context, opts core.Opti } func (rt *runtimeBindings) handleGUIBrowserOpen(_ context.Context, opts core.Options) core.Result { - if err := openBrowser(strings.TrimSpace(opts.String("url"))); err != nil { + if err := openBrowser(core.Trim(opts.String("url"))); err != nil { return resultError("app.runtime.handleGUIBrowserOpen", "open browser failed", err) } return core.Result{OK: true} @@ -527,15 +523,15 @@ func (rt *runtimeBindings) handleGUIClipboardWrite(_ context.Context, opts core. } func (rt *runtimeBindings) handleDeviceLocation(_ context.Context, _ core.Options) core.Result { - lat := strings.TrimSpace(core.Env("CORE_DEVICE_LATITUDE")) - lng := strings.TrimSpace(core.Env("CORE_DEVICE_LONGITUDE")) + lat := core.Trim(core.Env("CORE_DEVICE_LATITUDE")) + lng := core.Trim(core.Env("CORE_DEVICE_LONGITUDE")) if lat == "" || lng == "" { return resultError("app.runtime.handleDeviceLocation", "device location not configured for this host", nil) } return resultValue(map[string]any{ "latitude": lat, "longitude": lng, - "accuracy": strings.TrimSpace(core.Env("CORE_DEVICE_ACCURACY")), + "accuracy": core.Trim(core.Env("CORE_DEVICE_ACCURACY")), }) } @@ -548,11 +544,11 @@ func (rt *runtimeBindings) handleDeviceMicrophone(_ context.Context, _ core.Opti } func (rt *runtimeBindings) handleI18NTranslate(_ context.Context, opts core.Options) core.Result { - key := strings.TrimSpace(opts.String("key")) + key := core.Trim(opts.String("key")) if key == "" { return resultError("app.runtime.handleI18NTranslate", "key is required", nil) } - if locale := strings.TrimSpace(opts.String("locale")); locale != "" { + if locale := core.Trim(opts.String("locale")); locale != "" { if r := rt.inst.Core.I18n().SetLanguage(locale); !r.OK { return resultError("app.runtime.handleI18NTranslate", "set language failed", extractErr(r)) } @@ -565,24 +561,24 @@ func (rt *runtimeBindings) handleI18NTranslate(_ context.Context, opts core.Opti } func (rt *runtimeBindings) normalisedProjectPath(raw string) (string, string, error) { - raw = strings.TrimSpace(strings.ReplaceAll(raw, "\\", "/")) + raw = core.Trim(core.Replace(raw, "\\", "/")) if raw == "" { - return "", "", coreerr.E("app.runtime.normalisedProjectPath", "path is required", nil) + return "", "", core.E("app.runtime.normalisedProjectPath", "path is required", nil) } access := raw - if strings.HasPrefix(access, "/") { + if core.HasPrefix(access, "/") { access = "." + access } - if !strings.HasPrefix(access, "./") && !strings.HasPrefix(access, "../") && access != "." && access != ".." { + if !core.HasPrefix(access, "./") && !core.HasPrefix(access, "../") && access != "." && access != ".." { access = "./" + access } access = path.Clean(access) if access == "." { access = "./" - } else if access != ".." && !strings.HasPrefix(access, "./") && !strings.HasPrefix(access, "../") { + } else if access != ".." && !core.HasPrefix(access, "./") && !core.HasPrefix(access, "../") { access = "./" + access } - mediumPath := strings.TrimPrefix(access, "./") + mediumPath := core.TrimPrefix(access, "./") if mediumPath == "." { mediumPath = "" } @@ -591,7 +587,7 @@ func (rt *runtimeBindings) normalisedProjectPath(raw string) (string, string, er func (rt *runtimeBindings) projectMediumPath(rel string) (coreio.Medium, string, error) { if rt == nil || rt.inst == nil { - return nil, "", coreerr.E("app.runtime.projectMediumPath", "nil runtime", nil) + return nil, "", core.E("app.runtime.projectMediumPath", "nil runtime", nil) } if rt.inst.medium == coreio.Local { medium, err := coreio.NewSandboxed(rt.inst.Root) @@ -604,7 +600,7 @@ func (rt *runtimeBindings) projectMediumPath(rel string) (coreio.Medium, string, } func (rt *runtimeBindings) processDir(raw string) (string, error) { - raw = strings.TrimSpace(raw) + raw = core.Trim(raw) if raw == "" { return rt.inst.Root, nil } @@ -624,7 +620,7 @@ func resultValue(value any) core.Result { func resultError(op, message string, err error) core.Result { return core.Result{ - Value: coreerr.E(op, message, err), + Value: core.E(op, message, err), OK: false, } } @@ -673,7 +669,7 @@ func stringMap(result core.Result) map[string]string { func openBrowser(rawURL string) error { if rawURL == "" { - return coreerr.E("app.runtime.openBrowser", "url is required", nil) + return core.E("app.runtime.openBrowser", "url is required", nil) } cmd, err := platformCommand(rawURL, "open", "xdg-open", "rundll32", "url.dll,FileProtocolHandler") if err != nil { @@ -690,7 +686,7 @@ func sendNotification(title, body string) error { case "linux": return exec.Command("notify-send", title, body).Run() default: - return coreerr.E("app.runtime.sendNotification", "notifications not supported on this host", nil) + return core.E("app.runtime.sendNotification", "notifications not supported on this host", nil) } } @@ -701,9 +697,9 @@ func readClipboard() (string, error) { } out, err := cmd.Output() if err != nil { - return "", coreerr.E("app.runtime.readClipboard", "clipboard command failed", err) + return "", core.E("app.runtime.readClipboard", "clipboard command failed", err) } - return strings.TrimSuffix(string(out), "\n"), nil + return core.TrimSuffix(string(out), "\n"), nil } func writeClipboard(text string) error { @@ -716,13 +712,13 @@ func writeClipboard(text string) error { } return pipeCommand("xclip", text, "-selection", "clipboard") default: - return coreerr.E("app.runtime.writeClipboard", "clipboard write not supported on this host", nil) + return core.E("app.runtime.writeClipboard", "clipboard write not supported on this host", nil) } } func runDialogConfirm(message string) (bool, error) { if runtime.GOOS != "darwin" { - return false, coreerr.E("app.runtime.runDialogConfirm", "confirm dialog not supported on this host", nil) + return false, core.E("app.runtime.runDialogConfirm", "confirm dialog not supported on this host", nil) } if message == "" { message = "Continue?" @@ -735,17 +731,17 @@ func runDialogConfirm(message string) (bool, error) { out, err := cmd.Output() if err != nil { var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if core.As(err, &exitErr) { return false, nil } - return false, coreerr.E("app.runtime.runDialogConfirm", "osascript failed", err) + return false, core.E("app.runtime.runDialogConfirm", "osascript failed", err) } - return strings.TrimSpace(string(out)) == "OK", nil + return core.Trim(string(out)) == "OK", nil } func runDialogOpen(title string) (string, error) { if runtime.GOOS != "darwin" { - return "", coreerr.E("app.runtime.runDialogOpen", "open dialog not supported on this host", nil) + return "", core.E("app.runtime.runDialogOpen", "open dialog not supported on this host", nil) } if title == "" { title = "Choose a file" @@ -756,14 +752,14 @@ func runDialogOpen(title string) (string, error) { "-e", "POSIX path of selectedFile", ).Output() if err != nil { - return "", coreerr.E("app.runtime.runDialogOpen", "osascript failed", err) + return "", core.E("app.runtime.runDialogOpen", "osascript failed", err) } - return strings.TrimSpace(string(out)), nil + return core.Trim(string(out)), nil } func runDialogSave(title, defaultName string) (string, error) { if runtime.GOOS != "darwin" { - return "", coreerr.E("app.runtime.runDialogSave", "save dialog not supported on this host", nil) + return "", core.E("app.runtime.runDialogSave", "save dialog not supported on this host", nil) } if title == "" { title = "Save file" @@ -777,16 +773,16 @@ func runDialogSave(title, defaultName string) (string, error) { "-e", "POSIX path of selectedFile", ).Output() if err != nil { - return "", coreerr.E("app.runtime.runDialogSave", "osascript failed", err) + return "", core.E("app.runtime.runDialogSave", "osascript failed", err) } - return strings.TrimSpace(string(out)), nil + return core.Trim(string(out)), nil } func pipeCommand(name, input string, args ...string) error { cmd := exec.Command(name, args...) - cmd.Stdin = strings.NewReader(input) + cmd.Stdin = core.NewReader(input) if err := cmd.Run(); err != nil { - return coreerr.E("app.runtime.pipeCommand", "command failed: "+name, err) + return core.E("app.runtime.pipeCommand", "command failed: "+name, err) } return nil } @@ -810,10 +806,10 @@ func platformCommand(argument, darwin, linux, windows string, windowsArgs ...str } return exec.Command(windows, args...), nil default: - return nil, coreerr.E("app.runtime.platformCommand", "unsupported host OS", nil) + return nil, core.E("app.runtime.platformCommand", "unsupported host OS", nil) } } func appleScriptString(value string) string { - return "\"" + strings.ReplaceAll(value, "\"", "\\\"") + "\"" + return "\"" + core.Replace(value, "\"", "\\\"") + "\"" } diff --git a/go/runtime_process.go b/go/runtime_process.go index 4c4e84e..27b6014 100644 --- a/go/runtime_process.go +++ b/go/runtime_process.go @@ -5,16 +5,14 @@ package app import ( "bytes" "context" - "errors" "io" - "os" "os/exec" "runtime" "sync" "syscall" "time" - coreerr "dappco.re/go/log" + core "dappco.re/go" ) type managedProcesses struct { @@ -66,7 +64,7 @@ func (procs *managedProcesses) runOnce(ctx context.Context, command string, args cmd.Dir = dir } if len(env) > 0 { - cmd.Env = append(os.Environ(), env...) + cmd.Env = append(core.Environ(), env...) } stdout := cmd.Stdout.(*bytes.Buffer) stderr := cmd.Stderr.(*bytes.Buffer) @@ -76,7 +74,7 @@ func (procs *managedProcesses) runOnce(ctx context.Context, command string, args if err != nil { var exitErr *exec.ExitError if !errorAs(err, &exitErr) { - return nil, coreerr.E("app.managedProcesses.runOnce", "start process failed", err) + return nil, core.E("app.managedProcesses.runOnce", "start process failed", err) } if exitCode < 0 { exitCode = exitErr.ExitCode() @@ -91,10 +89,10 @@ func (procs *managedProcesses) runOnce(ctx context.Context, command string, args func (procs *managedProcesses) add(key, command string, args, env []string, dir string) error { if procs == nil { - return coreerr.E("app.managedProcesses.add", "nil registry", nil) + return core.E("app.managedProcesses.add", "nil registry", nil) } if key == "" { - return coreerr.E("app.managedProcesses.add", "key is required", nil) + return core.E("app.managedProcesses.add", "key is required", nil) } procs.mu.Lock() defer procs.mu.Unlock() @@ -114,7 +112,7 @@ func (procs *managedProcesses) start(ctx context.Context, key string) (bool, err entry, ok := procs.entries[key] if !ok { procs.mu.Unlock() - return false, coreerr.E("app.managedProcesses.start", "process not found: "+key, nil) + return false, core.E("app.managedProcesses.start", "process not found: "+key, nil) } if entry.running { procs.mu.Unlock() @@ -128,16 +126,16 @@ func (procs *managedProcesses) start(ctx context.Context, key string) (bool, err cmd.Dir = entry.dir } if len(entry.env) > 0 { - cmd.Env = append(os.Environ(), entry.env...) + cmd.Env = append(core.Environ(), entry.env...) } stdin, err := cmd.StdinPipe() if err != nil { procs.mu.Unlock() - return false, coreerr.E("app.managedProcesses.start", "open stdin failed", err) + return false, core.E("app.managedProcesses.start", "open stdin failed", err) } if err := cmd.Start(); err != nil { procs.mu.Unlock() - return false, coreerr.E("app.managedProcesses.start", "start failed", err) + return false, core.E("app.managedProcesses.start", "start failed", err) } entry.stdout.Reset() @@ -174,7 +172,7 @@ func (procs *managedProcesses) stop(key string) (bool, error) { entry, ok := procs.entries[key] if !ok { procs.mu.Unlock() - return false, coreerr.E("app.managedProcesses.stop", "process not found: "+key, nil) + return false, core.E("app.managedProcesses.stop", "process not found: "+key, nil) } cmd := entry.cmd running := entry.running @@ -187,7 +185,7 @@ func (procs *managedProcesses) stop(key string) (bool, error) { return procs.kill(key) } if err := cmd.Process.Signal(syscall.SIGTERM); err != nil { - return false, coreerr.E("app.managedProcesses.stop", "signal failed", err) + return false, core.E("app.managedProcesses.stop", "signal failed", err) } deadline := time.Now().Add(5 * time.Second) @@ -208,7 +206,7 @@ func (procs *managedProcesses) kill(key string) (bool, error) { entry, ok := procs.entries[key] if !ok { procs.mu.Unlock() - return false, coreerr.E("app.managedProcesses.kill", "process not found: "+key, nil) + return false, core.E("app.managedProcesses.kill", "process not found: "+key, nil) } cmd := entry.cmd running := entry.running @@ -217,7 +215,7 @@ func (procs *managedProcesses) kill(key string) (bool, error) { return false, nil } if err := cmd.Process.Kill(); err != nil { - return false, coreerr.E("app.managedProcesses.kill", "kill failed", err) + return false, core.E("app.managedProcesses.kill", "kill failed", err) } return true, nil } @@ -227,7 +225,7 @@ func (procs *managedProcesses) info(key string) (map[string]any, error) { defer procs.mu.Unlock() entry, ok := procs.entries[key] if !ok { - return nil, coreerr.E("app.managedProcesses.info", "process not found: "+key, nil) + return nil, core.E("app.managedProcesses.info", "process not found: "+key, nil) } return entry.info(), nil } @@ -255,7 +253,7 @@ func (procs *managedProcesses) stdoutValue(key string) (string, error) { defer procs.mu.Unlock() entry, ok := procs.entries[key] if !ok { - return "", coreerr.E("app.managedProcesses.stdoutValue", "process not found: "+key, nil) + return "", core.E("app.managedProcesses.stdoutValue", "process not found: "+key, nil) } return entry.stdout.String(), nil } @@ -265,15 +263,15 @@ func (procs *managedProcesses) writeStdin(key, data string) error { entry, ok := procs.entries[key] if !ok { procs.mu.Unlock() - return coreerr.E("app.managedProcesses.writeStdin", "process not found: "+key, nil) + return core.E("app.managedProcesses.writeStdin", "process not found: "+key, nil) } stdin := entry.stdin procs.mu.Unlock() if stdin == nil { - return coreerr.E("app.managedProcesses.writeStdin", "stdin unavailable for "+key, nil) + return core.E("app.managedProcesses.writeStdin", "stdin unavailable for "+key, nil) } if _, err := io.WriteString(stdin, data); err != nil { - return coreerr.E("app.managedProcesses.writeStdin", "write failed", err) + return core.E("app.managedProcesses.writeStdin", "write failed", err) } return nil } @@ -290,7 +288,7 @@ func (entry *managedProcess) info() map[string]any { } } -func exitCodeOf(state *os.ProcessState) int { +func exitCodeOf(state interface{ ExitCode() int }) int { if state == nil { return -1 } @@ -298,5 +296,5 @@ func exitCodeOf(state *os.ProcessState) int { } func errorAs(err error, target any) bool { - return errors.As(err, target) + return core.As(err, target) } diff --git a/go/runtime_store.go b/go/runtime_store.go index f94353c..06fc1d6 100644 --- a/go/runtime_store.go +++ b/go/runtime_store.go @@ -8,13 +8,11 @@ import ( "crypto/sha256" "encoding/base64" "encoding/hex" - "path/filepath" "sync" core "dappco.re/go" "dappco.re/go/io/sigil" corestore "dappco.re/go/io/store" - coreerr "dappco.re/go/log" "golang.org/x/crypto/argon2" // Note: AX-6 - password KDF primitive required to slow offline workspace-password attacks. ) @@ -76,7 +74,7 @@ func (store *workspaceObjectStore) Close() error { func (store *workspaceObjectStore) Get(group, key string) (string, error) { if group == "" || key == "" { - return "", coreerr.E("app.workspaceObjectStore.Get", "group and key are required", nil) + return "", core.E("app.workspaceObjectStore.Get", "group and key are required", nil) } store.mu.Lock() defer store.mu.Unlock() @@ -85,18 +83,18 @@ func (store *workspaceObjectStore) Get(group, key string) (string, error) { } value, err := store.kv.Get(store.hashLocked("group", group), store.hashLocked("key", group+":"+key)) if err != nil { - return "", coreerr.E("app.workspaceObjectStore.Get", "read failed", err) + return "", core.E("app.workspaceObjectStore.Get", "read failed", err) } decoded, err := store.decryptLocked(value) if err != nil { - return "", coreerr.E("app.workspaceObjectStore.Get", "decrypt failed", err) + return "", core.E("app.workspaceObjectStore.Get", "decrypt failed", err) } return decoded, nil } func (store *workspaceObjectStore) Set(group, key, value string) error { if group == "" || key == "" { - return coreerr.E("app.workspaceObjectStore.Set", "group and key are required", nil) + return core.E("app.workspaceObjectStore.Set", "group and key are required", nil) } store.mu.Lock() defer store.mu.Unlock() @@ -105,17 +103,17 @@ func (store *workspaceObjectStore) Set(group, key, value string) error { } encoded, err := store.encryptLocked(value) if err != nil { - return coreerr.E("app.workspaceObjectStore.Set", "encrypt failed", err) + return core.E("app.workspaceObjectStore.Set", "encrypt failed", err) } if err := store.kv.Set(store.hashLocked("group", group), store.hashLocked("key", group+":"+key), encoded); err != nil { - return coreerr.E("app.workspaceObjectStore.Set", "write failed", err) + return core.E("app.workspaceObjectStore.Set", "write failed", err) } return nil } func (store *workspaceObjectStore) Delete(group, key string) error { if group == "" || key == "" { - return coreerr.E("app.workspaceObjectStore.Delete", "group and key are required", nil) + return core.E("app.workspaceObjectStore.Delete", "group and key are required", nil) } store.mu.Lock() defer store.mu.Unlock() @@ -123,17 +121,17 @@ func (store *workspaceObjectStore) Delete(group, key string) error { return err } if err := store.kv.Delete(store.hashLocked("group", group), store.hashLocked("key", group+":"+key)); err != nil { - return coreerr.E("app.workspaceObjectStore.Delete", "delete failed", err) + return core.E("app.workspaceObjectStore.Delete", "delete failed", err) } return nil } func (store *workspaceObjectStore) ensureLocked() error { if store == nil { - return coreerr.E("app.workspaceObjectStore.ensureLocked", "nil store", nil) + return core.E("app.workspaceObjectStore.ensureLocked", "nil store", nil) } if store.ws == nil { - return coreerr.E("app.workspaceObjectStore.ensureLocked", "workspace unavailable", nil) + return core.E("app.workspaceObjectStore.ensureLocked", "workspace unavailable", nil) } if store.kv != nil && store.sigil != nil && len(store.enc) == workspaceSecretKeyBytes && @@ -148,14 +146,14 @@ func (store *workspaceObjectStore) ensureLocked() error { dbPath := store.ws.Resolve(WorkspaceLayoutStore, workspaceStoreDBName) kv, err := corestore.New(corestore.Options{Path: dbPath}) if err != nil { - return coreerr.E("app.workspaceObjectStore.ensureLocked", "open store database failed", err) + return core.E("app.workspaceObjectStore.ensureLocked", "open store database failed", err) } cipherSigil, err := sigil.NewChaChaPolySigil(keys.encryption, &sigil.ShuffleMaskObfuscator{}) if err != nil { if closeErr := kv.Close(); closeErr != nil { - return coreerr.E("app.workspaceObjectStore.ensureLocked", "initialise sigil failed and close failed", err) + return core.E("app.workspaceObjectStore.ensureLocked", "initialise sigil failed and close failed", err) } - return coreerr.E("app.workspaceObjectStore.ensureLocked", "initialise sigil failed", err) + return core.E("app.workspaceObjectStore.ensureLocked", "initialise sigil failed", err) } store.kv = kv @@ -205,11 +203,11 @@ func deriveWorkspaceSecret(ws *Workspace) ([]byte, error) { func deriveWorkspaceSecrets(ws *Workspace) (workspaceSecretKeys, error) { if ws == nil { - return workspaceSecretKeys{}, coreerr.E("app.deriveWorkspaceSecrets", "nil workspace", nil) + return workspaceSecretKeys{}, core.E("app.deriveWorkspaceSecrets", "nil workspace", nil) } salt, err := ensureWorkspaceSecretSalt(ws) if err != nil { - return workspaceSecretKeys{}, coreerr.E("app.deriveWorkspaceSecrets", "resolve workspace salt failed", err) + return workspaceSecretKeys{}, core.E("app.deriveWorkspaceSecrets", "resolve workspace salt failed", err) } switch secret := core.Trim(core.Env("CORE_WORKSPACE_KEY")); secret { @@ -225,11 +223,11 @@ func deriveWorkspaceSecrets(ws *Workspace) (workspaceSecretKeys, error) { home := workspaceHomeFromRoot(ws.Root) if home == "" { - return workspaceSecretKeys{}, coreerr.E("app.deriveWorkspaceSecrets", "cannot resolve workspace home", nil) + return workspaceSecretKeys{}, core.E("app.deriveWorkspaceSecrets", "cannot resolve workspace home", nil) } priv, err := ensureDefaultPrivateKey(ws.medium, home) if err != nil { - return workspaceSecretKeys{}, coreerr.E("app.deriveWorkspaceSecrets", "resolve workspace key failed", err) + return workspaceSecretKeys{}, core.E("app.deriveWorkspaceSecrets", "resolve workspace key failed", err) } return deriveWorkspaceSecretMaterial(ws.Code, workspaceSecretMaterialKeyfile, []byte(priv), salt) } @@ -249,7 +247,7 @@ func deriveWorkspaceSecretMaterial(code string, mode workspaceSecretMaterialMode ) return deriveWorkspaceSecretSubKeys(code, mode, master, salt) default: - return workspaceSecretKeys{}, coreerr.E("app.deriveWorkspaceSecretMaterial", "unknown secret material mode", nil) + return workspaceSecretKeys{}, core.E("app.deriveWorkspaceSecretMaterial", "unknown secret material mode", nil) } } @@ -269,7 +267,7 @@ func deriveWorkspaceSecretSubKey(code string, mode workspaceSecretMaterialMode, info := "core.app.workspace.v1\x00" + string(mode) + "\x00" + purpose + "\x00" + code key, err := hkdf.Key(sha256.New, material, salt, info, workspaceSecretKeyBytes) if err != nil { - return nil, coreerr.E("app.deriveWorkspaceSecretSubKey", "HKDF-SHA256 failed", err) + return nil, core.E("app.deriveWorkspaceSecretSubKey", "HKDF-SHA256 failed", err) } return key, nil } @@ -280,5 +278,6 @@ func workspaceHomeFromRoot(root string) string { return "" } // /.core/data/ - return filepath.Dir(filepath.Dir(filepath.Dir(filepath.Clean(root)))) + clean := core.CleanPath(root, string(core.PathSeparator)) + return core.PathDir(core.PathDir(core.PathDir(clean))) } diff --git a/go/sdk.go b/go/sdk.go index b9eb664..8d616cf 100644 --- a/go/sdk.go +++ b/go/sdk.go @@ -6,7 +6,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // SDKLanguage selects which client SDK the generator emits. Each language @@ -654,10 +653,10 @@ type SDKCatalogueEntry struct { // permissions (or unfiltered if IncludeAllPrimitives=true). func SDKGenerate(medium coreio.Medium, root string, m *config.ViewManifest, opts SDKGenerateOptions) error { if m == nil { - return coreerr.E("app.SDKGenerate", "nil manifest", nil) + return core.E("app.SDKGenerate", "nil manifest", nil) } if root == "" { - return coreerr.E("app.SDKGenerate", "empty root", nil) + return core.E("app.SDKGenerate", "empty root", nil) } if medium == nil { medium = coreio.Local @@ -687,14 +686,14 @@ func SDKGenerate(medium coreio.Medium, root string, m *config.ViewManifest, opts for _, lang := range languages { body, file, err := renderSDK(lang, m, actions) if err != nil { - return coreerr.E("app.SDKGenerate", "render "+lang.String()+" failed", err) + return core.E("app.SDKGenerate", "render "+lang.String()+" failed", err) } dest := core.Path(outDir, lang.String(), file) if err := medium.EnsureDir(core.PathDir(dest)); err != nil { - return coreerr.E("app.SDKGenerate", "ensure dir "+core.PathDir(dest)+" failed", err) + return core.E("app.SDKGenerate", "ensure dir "+core.PathDir(dest)+" failed", err) } if err := medium.Write(dest, body); err != nil { - return coreerr.E("app.SDKGenerate", "write "+dest+" failed", err) + return core.E("app.SDKGenerate", "write "+dest+" failed", err) } } return nil @@ -719,7 +718,7 @@ func renderSDK(lang SDKLanguage, m *config.ViewManifest, actions []SDKAction) (s case SDKLanguagePython: return RenderPython(m, actions), "sdk.py", nil } - return "", "", coreerr.E("app.renderSDK", "unsupported language: "+lang.String(), nil) + return "", "", core.E("app.renderSDK", "unsupported language: "+lang.String(), nil) } // RenderOpenAPI produces an OpenAPI 3.1 document describing the manifest's @@ -733,13 +732,13 @@ func renderSDK(lang SDKLanguage, m *config.ViewManifest, actions []SDKAction) (s // WriteCompiled uses so a diff review of generated specs stays readable. func RenderOpenAPI(m *config.ViewManifest, actions []SDKAction) (string, error) { if m == nil { - return "", coreerr.E("app.RenderOpenAPI", "nil manifest", nil) + return "", core.E("app.RenderOpenAPI", "nil manifest", nil) } doc := openAPIDoc(m, actions) r := core.JSONMarshal(doc) if !r.OK { cause, _ := r.Value.(error) - return "", coreerr.E("app.RenderOpenAPI", "marshal failed", cause) + return "", core.E("app.RenderOpenAPI", "marshal failed", cause) } raw, _ := r.Value.([]byte) return indentJSON(raw), nil diff --git a/go/sign.go b/go/sign.go index a7d0710..4eff36a 100644 --- a/go/sign.go +++ b/go/sign.go @@ -9,7 +9,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // DefaultKeyName is the filename convention for the user's default app @@ -37,31 +36,31 @@ func Sign(medium coreio.Medium, path string, priv ed25519.PrivateKey) error { medium = coreio.Local } if path == "" { - return coreerr.E("app.Sign", "empty manifest path", nil) + return core.E("app.Sign", "empty manifest path", nil) } if len(priv) != ed25519.PrivateKeySize { - return coreerr.E("app.Sign", "invalid private key length", nil) + return core.E("app.Sign", "invalid private key length", nil) } if !medium.Exists(path) { - return coreerr.E("app.Sign", "manifest not found at "+path, nil) + return core.E("app.Sign", "manifest not found at "+path, nil) } var manifest config.ViewManifest if err := LoadViewManifest(medium, path, &manifest); err != nil { - return coreerr.E("app.Sign", "parse "+path+" failed", err) + return core.E("app.Sign", "parse "+path+" failed", err) } if err := signManifest(&manifest, priv); err != nil { - return coreerr.E("app.Sign", "signManifest failed", err) + return core.E("app.Sign", "signManifest failed", err) } out, err := yamlMarshalBytes(&manifest) if err != nil { - return coreerr.E("app.Sign", "marshal signed manifest failed", err) + return core.E("app.Sign", "marshal signed manifest failed", err) } if err := medium.Write(path, string(out)); err != nil { - return coreerr.E("app.Sign", "write "+path+" failed", err) + return core.E("app.Sign", "write "+path+" failed", err) } return nil } @@ -89,7 +88,7 @@ func DefaultPrivateKeyPath() string { func LoadDefaultPrivateKey(medium coreio.Medium) (ed25519.PrivateKey, error) { path := DefaultPrivateKeyPath() if path == "" { - return nil, coreerr.E("app.LoadDefaultPrivateKey", "DIR_HOME is empty — cannot resolve default key", nil) + return nil, core.E("app.LoadDefaultPrivateKey", "DIR_HOME is empty — cannot resolve default key", nil) } return loadDefaultPrivateKeyAtPath(medium, path) } @@ -103,7 +102,7 @@ func loadDefaultPrivateKeyAtPath(medium coreio.Medium, path string) (ed25519.Pri medium = coreio.Local } if !medium.Exists(path) { - return nil, coreerr.E( + return nil, core.E( "app.loadDefaultPrivateKeyAtPath", "default key not found — run `core-app keygen --dir "+ core.PathDir(path)+" --name "+core.TrimSuffix(DefaultKeyName, ".key")+"`", @@ -126,21 +125,21 @@ func LoadPrivateKey(medium coreio.Medium, path string) (ed25519.PrivateKey, erro medium = coreio.Local } if path == "" { - return nil, coreerr.E("app.LoadPrivateKey", "empty path", nil) + return nil, core.E("app.LoadPrivateKey", "empty path", nil) } if !medium.Exists(path) { - return nil, coreerr.E("app.LoadPrivateKey", "private key not found at "+path, nil) + return nil, core.E("app.LoadPrivateKey", "private key not found at "+path, nil) } body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.LoadPrivateKey", "read "+path+" failed", err) + return nil, core.E("app.LoadPrivateKey", "read "+path+" failed", err) } raw, err := hex.DecodeString(core.Trim(body)) if err != nil { - return nil, coreerr.E("app.LoadPrivateKey", "decode hex failed", err) + return nil, core.E("app.LoadPrivateKey", "decode hex failed", err) } if len(raw) != ed25519.PrivateKeySize { - return nil, coreerr.E("app.LoadPrivateKey", "wrong ed25519 private key size", nil) + return nil, core.E("app.LoadPrivateKey", "wrong ed25519 private key size", nil) } return ed25519.PrivateKey(raw), nil } @@ -155,16 +154,16 @@ func WritePrivateKey(medium coreio.Medium, path string, priv ed25519.PrivateKey) medium = coreio.Local } if path == "" { - return coreerr.E("app.WritePrivateKey", "empty path", nil) + return core.E("app.WritePrivateKey", "empty path", nil) } if len(priv) != ed25519.PrivateKeySize { - return coreerr.E("app.WritePrivateKey", "invalid private key length", nil) + return core.E("app.WritePrivateKey", "invalid private key length", nil) } if err := medium.EnsureDir(core.PathDir(path)); err != nil { - return coreerr.E("app.WritePrivateKey", "ensure dir failed", err) + return core.E("app.WritePrivateKey", "ensure dir failed", err) } if err := medium.Write(path, hex.EncodeToString(priv)); err != nil { - return coreerr.E("app.WritePrivateKey", "write failed", err) + return core.E("app.WritePrivateKey", "write failed", err) } return nil } @@ -178,16 +177,16 @@ func WritePublicKey(medium coreio.Medium, path string, pub ed25519.PublicKey) er medium = coreio.Local } if path == "" { - return coreerr.E("app.WritePublicKey", "empty path", nil) + return core.E("app.WritePublicKey", "empty path", nil) } if len(pub) != ed25519.PublicKeySize { - return coreerr.E("app.WritePublicKey", "invalid public key length", nil) + return core.E("app.WritePublicKey", "invalid public key length", nil) } if err := medium.EnsureDir(core.PathDir(path)); err != nil { - return coreerr.E("app.WritePublicKey", "ensure dir failed", err) + return core.E("app.WritePublicKey", "ensure dir failed", err) } if err := medium.Write(path, hex.EncodeToString(pub)); err != nil { - return coreerr.E("app.WritePublicKey", "write failed", err) + return core.E("app.WritePublicKey", "write failed", err) } return nil } @@ -217,14 +216,14 @@ func Keygen(medium coreio.Medium, dir, name string) (privPath, pubPath string, e medium = coreio.Local } if dir == "" { - return "", "", coreerr.E("app.Keygen", "empty directory", nil) + return "", "", core.E("app.Keygen", "empty directory", nil) } if name == "" { name = "default" } pub, priv, keyErr := ed25519.GenerateKey(nil) if keyErr != nil { - return "", "", coreerr.E("app.Keygen", "ed25519.GenerateKey failed", keyErr) + return "", "", core.E("app.Keygen", "ed25519.GenerateKey failed", keyErr) } privPath = core.Path(dir, name+".key") pubPath = core.Path(dir, name+".pub") @@ -243,14 +242,14 @@ func Keygen(medium coreio.Medium, dir, name string) (privPath, pubPath string, e // bootable in prod mode without a separate `keygen` pre-step. func signManifestForHome(medium coreio.Medium, home string, manifest *config.ViewManifest) error { if manifest == nil { - return coreerr.E("app.signManifestForHome", "nil manifest", nil) + return core.E("app.signManifestForHome", "nil manifest", nil) } priv, err := ensureDefaultPrivateKey(medium, home) if err != nil { - return coreerr.E("app.signManifestForHome", "resolve default key failed", err) + return core.E("app.signManifestForHome", "resolve default key failed", err) } if err := SignManifest(manifest, priv); err != nil { - return coreerr.E("app.signManifestForHome", "sign failed", err) + return core.E("app.signManifestForHome", "sign failed", err) } return nil } @@ -265,7 +264,7 @@ func ensureDefaultPrivateKey(medium coreio.Medium, home string) (ed25519.Private } privPath := defaultPrivateKeyPathForHome(home) if privPath == "" { - return nil, coreerr.E("app.ensureDefaultPrivateKey", "empty home directory", nil) + return nil, core.E("app.ensureDefaultPrivateKey", "empty home directory", nil) } pubPath := defaultPublicKeyPathForHome(home) @@ -280,12 +279,12 @@ func ensureDefaultPrivateKey(medium coreio.Medium, home string) (ed25519.Private if !hasPub && pubPath != "" { pub, _ := priv.Public().(ed25519.PublicKey) if err := WritePublicKey(medium, pubPath, pub); err != nil { - return nil, coreerr.E("app.ensureDefaultPrivateKey", "write derived public key failed", err) + return nil, core.E("app.ensureDefaultPrivateKey", "write derived public key failed", err) } } return priv, nil case hasPub: - return nil, coreerr.E( + return nil, core.E( "app.ensureDefaultPrivateKey", "default public key exists without matching private key at "+privPath, nil, @@ -293,7 +292,7 @@ func ensureDefaultPrivateKey(medium coreio.Medium, home string) (ed25519.Private default: keysDir := core.PathDir(privPath) if _, _, err := Keygen(medium, keysDir, core.TrimSuffix(DefaultKeyName, ".key")); err != nil { - return nil, coreerr.E("app.ensureDefaultPrivateKey", "keygen failed", err) + return nil, core.E("app.ensureDefaultPrivateKey", "keygen failed", err) } return loadDefaultPrivateKeyAtPath(medium, privPath) } diff --git a/go/start.go b/go/start.go index 8fbdf11..9b7067c 100644 --- a/go/start.go +++ b/go/start.go @@ -6,7 +6,6 @@ import ( "context" core "dappco.re/go" - coreerr "dappco.re/go/log" ) // start is Step 7 of the 7-step boot — unblock the app's entry point. @@ -45,7 +44,7 @@ import ( func start(ctx context.Context, inst *Instance) core.Result { if inst == nil || inst.Core == nil { return core.Result{ - Value: coreerr.E("app.start", "nil instance or core", nil), + Value: core.E("app.start", "nil instance or core", nil), OK: false, } } @@ -58,7 +57,7 @@ func start(ctx context.Context, inst *Instance) core.Result { if !inst.started { if r := c.ServiceStartup(ctx, nil); !r.OK { return core.Result{ - Value: coreerr.E("app.start", "service startup failed", extractErr(r)), + Value: core.E("app.start", "service startup failed", extractErr(r)), OK: false, } } @@ -101,7 +100,7 @@ func start(ctx context.Context, inst *Instance) core.Result { func stop(ctx context.Context, inst *Instance) core.Result { if inst == nil || inst.Core == nil { return core.Result{ - Value: coreerr.E("app.stop", "nil instance or core", nil), + Value: core.E("app.stop", "nil instance or core", nil), OK: false, } } @@ -133,7 +132,7 @@ func stop(ctx context.Context, inst *Instance) core.Result { if r := c.ServiceShutdown(ctx); !r.OK { return core.Result{ - Value: coreerr.E("app.stop", "service shutdown failed", extractErr(r)), + Value: core.E("app.stop", "service shutdown failed", extractErr(r)), OK: false, } } diff --git a/go/validate.go b/go/validate.go index 2b14400..12dab29 100644 --- a/go/validate.go +++ b/go/validate.go @@ -5,7 +5,6 @@ package app import ( core "dappco.re/go" "dappco.re/go/config" - coreerr "dappco.re/go/log" ) // ValidateOptions tunes ValidateManifest. Zero values produce the @@ -360,5 +359,5 @@ func ValidateManifestErr(m *config.ViewManifest, opts ValidateOptions) error { if field == "" { field = "" } - return coreerr.E("app.ValidateManifest", field+": "+first.Message, nil) + return core.E("app.ValidateManifest", field+": "+first.Message, nil) } diff --git a/go/verify.go b/go/verify.go index 13df4f4..4c5d164 100644 --- a/go/verify.go +++ b/go/verify.go @@ -10,7 +10,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) // verify is Step 2 of the 7-step boot — confirm the manifest's ed25519 @@ -38,7 +37,7 @@ import ( // validates the signature. func verify(m *config.ViewManifest, mode Mode, trusted []ed25519.PublicKey) error { if m == nil { - return coreerr.E("app.verify", "nil manifest", nil) + return core.E("app.verify", "nil manifest", nil) } if mode == ModeDev { @@ -48,25 +47,25 @@ func verify(m *config.ViewManifest, mode Mode, trusted []ed25519.PublicKey) erro } if m.Sign == "" { - return coreerr.E("app.verify", "unsigned manifest rejected in prod mode", nil) + return core.E("app.verify", "unsigned manifest rejected in prod mode", nil) } // Decode the signature so a malformed base64 fails fast. sig, err := base64.StdEncoding.DecodeString(m.Sign) if err != nil { - return coreerr.E("app.verify", "decode signature failed", err) + return core.E("app.verify", "decode signature failed", err) } if len(sig) != ed25519.SignatureSize { - return coreerr.E("app.verify", "signature is not an ed25519 signature", nil) + return core.E("app.verify", "signature is not an ed25519 signature", nil) } msg, err := signableBytes(m) if err != nil { - return coreerr.E("app.verify", "canonical marshal failed", err) + return core.E("app.verify", "canonical marshal failed", err) } if len(trusted) == 0 { - return coreerr.E( + return core.E( "app.verify", "no trusted keys available — set WithPublicKey or populate $DIR_HOME/.core/keys/", nil, @@ -82,7 +81,7 @@ func verify(m *config.ViewManifest, mode Mode, trusted []ed25519.PublicKey) erro } } - return coreerr.E( + return core.E( "app.verify", "signature does not match any trusted key ("+core.Sprint(len(trusted))+" checked)", nil, @@ -102,7 +101,7 @@ func verify(m *config.ViewManifest, mode Mode, trusted []ed25519.PublicKey) erro // msg, _ := signableBytes(&manifest) func signableBytes(m *config.ViewManifest) ([]byte, error) { if m == nil { - return nil, coreerr.E("app.signableBytes", "nil manifest", nil) + return nil, core.E("app.signableBytes", "nil manifest", nil) } tmp := *m tmp.Sign = "" @@ -118,25 +117,25 @@ func signableBytes(m *config.ViewManifest) ([]byte, error) { // err := verifyWithKey(&manifest, pub) func verifyWithKey(m *config.ViewManifest, pub ed25519.PublicKey) error { if m == nil { - return coreerr.E("app.verifyWithKey", "nil manifest", nil) + return core.E("app.verifyWithKey", "nil manifest", nil) } if m.Sign == "" { - return coreerr.E("app.verifyWithKey", "no signature present", nil) + return core.E("app.verifyWithKey", "no signature present", nil) } if len(pub) != ed25519.PublicKeySize { - return coreerr.E("app.verifyWithKey", "invalid public key length", nil) + return core.E("app.verifyWithKey", "invalid public key length", nil) } sig, err := base64.StdEncoding.DecodeString(m.Sign) if err != nil { - return coreerr.E("app.verifyWithKey", "decode signature failed", err) + return core.E("app.verifyWithKey", "decode signature failed", err) } msg, err := signableBytes(m) if err != nil { - return coreerr.E("app.verifyWithKey", "canonical marshal failed", err) + return core.E("app.verifyWithKey", "canonical marshal failed", err) } if !ed25519.Verify(pub, msg, sig) { - return coreerr.E("app.verifyWithKey", "signature does not match manifest content", nil) + return core.E("app.verifyWithKey", "signature does not match manifest content", nil) } return nil } @@ -148,14 +147,14 @@ func verifyWithKey(m *config.ViewManifest, pub ed25519.PublicKey) error { // pub, err := parsePublicKey("3b6a…") func parsePublicKey(hexKey string) (ed25519.PublicKey, error) { if hexKey == "" { - return nil, coreerr.E("app.parsePublicKey", "empty key", nil) + return nil, core.E("app.parsePublicKey", "empty key", nil) } raw, err := hex.DecodeString(hexKey) if err != nil { - return nil, coreerr.E("app.parsePublicKey", "decode hex failed", err) + return nil, core.E("app.parsePublicKey", "decode hex failed", err) } if len(raw) != ed25519.PublicKeySize { - return nil, coreerr.E("app.parsePublicKey", "wrong ed25519 public key size", nil) + return nil, core.E("app.parsePublicKey", "wrong ed25519 public key size", nil) } return ed25519.PublicKey(raw), nil } @@ -169,14 +168,14 @@ func parsePublicKey(hexKey string) (ed25519.PublicKey, error) { // _ = signManifest(&manifest, priv) func signManifest(m *config.ViewManifest, priv ed25519.PrivateKey) error { if m == nil { - return coreerr.E("app.signManifest", "nil manifest", nil) + return core.E("app.signManifest", "nil manifest", nil) } if len(priv) != ed25519.PrivateKeySize { - return coreerr.E("app.signManifest", "invalid private key length", nil) + return core.E("app.signManifest", "invalid private key length", nil) } msg, err := signableBytes(m) if err != nil { - return coreerr.E("app.signManifest", "canonical marshal failed", err) + return core.E("app.signManifest", "canonical marshal failed", err) } m.Sign = base64.StdEncoding.EncodeToString(ed25519.Sign(priv, msg)) return nil @@ -221,7 +220,7 @@ func resolveTrustedKeys(o Options) ([]ed25519.PublicKey, error) { if o.PublicKeyHex != "" { pub, err := parsePublicKey(o.PublicKeyHex) if err != nil { - return nil, coreerr.E("app.resolveTrustedKeys", "explicit key decode failed", err) + return nil, core.E("app.resolveTrustedKeys", "explicit key decode failed", err) } keys = append(keys, pub) } @@ -240,7 +239,7 @@ func resolveTrustedKeys(o Options) ([]ed25519.PublicKey, error) { entries, err := medium.List(o.TrustedKeysDir) if err != nil { - return nil, coreerr.E("app.resolveTrustedKeys", "list trusted keys dir failed", err) + return nil, core.E("app.resolveTrustedKeys", "list trusted keys dir failed", err) } for _, entry := range entries { name := entry.Name() @@ -250,11 +249,11 @@ func resolveTrustedKeys(o Options) ([]ed25519.PublicKey, error) { path := core.Path(o.TrustedKeysDir, name) body, err := medium.Read(path) if err != nil { - return nil, coreerr.E("app.resolveTrustedKeys", "read key "+path+" failed", err) + return nil, core.E("app.resolveTrustedKeys", "read key "+path+" failed", err) } pub, err := parsePublicKey(core.Trim(body)) if err != nil { - return nil, coreerr.E("app.resolveTrustedKeys", "decode key "+path+" failed", err) + return nil, core.E("app.resolveTrustedKeys", "decode key "+path+" failed", err) } keys = append(keys, pub) } diff --git a/go/workspace.go b/go/workspace.go index a22084c..67dd5e2 100644 --- a/go/workspace.go +++ b/go/workspace.go @@ -9,7 +9,6 @@ import ( "dappco.re/go/config" coreio "dappco.re/go/io" "dappco.re/go/io/cube" - coreerr "dappco.re/go/log" ) // DataDirName is the component that follows `$DIR_HOME/.core/` for the @@ -101,13 +100,13 @@ func OpenWorkspace(medium coreio.Medium, home, code string) (*Workspace, error) medium = coreio.Local } if code == "" { - return nil, coreerr.E("app.OpenWorkspace", "empty app code", nil) + return nil, core.E("app.OpenWorkspace", "empty app code", nil) } if home == "" { home = core.Env("DIR_HOME") } if home == "" { - return nil, coreerr.E("app.OpenWorkspace", "cannot resolve home directory", nil) + return nil, core.E("app.OpenWorkspace", "cannot resolve home directory", nil) } root := core.Path(home, ".core", DataDirName, code) @@ -120,7 +119,7 @@ func OpenWorkspace(medium coreio.Medium, home, code string) (*Workspace, error) WorkspaceLayoutTmp, } { if err := medium.EnsureDir(ws.Path(layout)); err != nil { - return nil, coreerr.E("app.OpenWorkspace", "ensure layout dir failed: "+string(layout), err) + return nil, core.E("app.OpenWorkspace", "ensure layout dir failed: "+string(layout), err) } } return ws, nil @@ -183,7 +182,7 @@ func (w *Workspace) Resolve(layout WorkspaceLayout, rel string) string { // underlying medium is returned unchanged so tests compose naturally. func (w *Workspace) Sandboxed() (coreio.Medium, error) { if w == nil { - return nil, coreerr.E("app.Workspace.Sandboxed", "nil workspace", nil) + return nil, core.E("app.Workspace.Sandboxed", "nil workspace", nil) } if w.medium != coreio.Local { // Mock and memory mediums have no notion of an OS root — @@ -203,16 +202,16 @@ func (w *Workspace) Sandboxed() (coreio.Medium, error) { func (w *Workspace) openSandboxed() (coreio.Medium, error) { sandbox, err := coreio.NewSandboxed(w.Root) if err != nil { - return nil, coreerr.E("app.Workspace.Sandboxed", "sandbox workspace failed", err) + return nil, core.E("app.Workspace.Sandboxed", "sandbox workspace failed", err) } secret, err := deriveWorkspaceSecret(w) if err != nil { - return nil, coreerr.E("app.Workspace.Sandboxed", "derive workspace key failed", err) + return nil, core.E("app.Workspace.Sandboxed", "derive workspace key failed", err) } defer zeroBytes(secret) encrypted, err := cube.New(cube.Options{Inner: sandbox, Key: secret}) if err != nil { - return nil, coreerr.E("app.Workspace.Sandboxed", "encrypt workspace medium failed", err) + return nil, core.E("app.Workspace.Sandboxed", "encrypt workspace medium failed", err) } return encrypted, nil } @@ -231,13 +230,13 @@ func zeroBytes(data []byte) { // err := ws.Wipe() func (w *Workspace) Wipe() error { if w == nil { - return coreerr.E("app.Workspace.Wipe", "nil workspace", nil) + return core.E("app.Workspace.Wipe", "nil workspace", nil) } if !w.medium.IsDir(w.Root) { return nil } if err := w.medium.DeleteAll(w.Root); err != nil { - return coreerr.E("app.Workspace.Wipe", "delete workspace failed: "+w.Root, err) + return core.E("app.Workspace.Wipe", "delete workspace failed: "+w.Root, err) } return nil } @@ -249,7 +248,7 @@ func (w *Workspace) Wipe() error { // ws, err := app.WorkspaceForManifest(coreio.Local, home, &inst.Manifest) func WorkspaceForManifest(medium coreio.Medium, home string, m *config.ViewManifest) (*Workspace, error) { if m == nil { - return nil, coreerr.E("app.WorkspaceForManifest", "nil manifest", nil) + return nil, core.E("app.WorkspaceForManifest", "nil manifest", nil) } return OpenWorkspace(medium, home, m.Code) } diff --git a/go/workspace_crypto_metadata.go b/go/workspace_crypto_metadata.go index 74c86d3..1eb401d 100644 --- a/go/workspace_crypto_metadata.go +++ b/go/workspace_crypto_metadata.go @@ -4,15 +4,12 @@ package app import ( "crypto/rand" // Note: AX-6 - workspace KDF salts require cryptographic randomness; no core CSPRNG wrapper exists. - "errors" "io" "io/fs" - "os" // Note: AX-6 - O_CREATE|O_EXCL is required for atomic salt-file creation; no core primitive exists. "time" core "dappco.re/go" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" ) const ( @@ -23,7 +20,17 @@ const ( ) var ( - openWorkspaceCryptoMetadataFile = os.OpenFile + openWorkspaceCryptoMetadataFile = func(path string, flag int, perm core.FileMode) (*core.OSFile, error) { + r := core.OpenFile(path, flag, perm) + if !r.OK { + return nil, coreResultError(r) + } + file, ok := r.Value.(*core.OSFile) + if !ok { + return nil, core.E("app.openWorkspaceCryptoMetadataFile", "open returned non-file", nil) + } + return file, nil + } writeWorkspaceCryptoMetadataBody = func(w io.Writer, body string) error { _, err := io.WriteString(w, body) return err @@ -51,13 +58,13 @@ func ensureWorkspaceSecretSalt(ws *Workspace) ([]byte, error) { salt := make([]byte, workspaceSecretSaltBytes) if _, err := rand.Read(salt); err != nil { - return nil, coreerr.E("app.ensureWorkspaceSecretSalt", "generate workspace salt failed", err) + return nil, core.E("app.ensureWorkspaceSecretSalt", "generate workspace salt failed", err) } metadata.Version = 1 metadata.Salt = core.Base64Encode(salt) if err := writeWorkspaceCryptoMetadata(ws, metadata); err != nil { - if errors.Is(err, fs.ErrExist) { + if core.Is(err, fs.ErrExist) { return readWorkspaceSecretSaltAfterCreateRace(ws) } return nil, err @@ -70,7 +77,7 @@ func ensureWorkspaceSecretSalt(ws *Workspace) ([]byte, error) { func readWorkspaceCryptoMetadata(ws *Workspace) (workspaceCryptoMetadata, error) { if ws == nil { - return workspaceCryptoMetadata{}, coreerr.E("app.readWorkspaceCryptoMetadata", "nil workspace", nil) + return workspaceCryptoMetadata{}, core.E("app.readWorkspaceCryptoMetadata", "nil workspace", nil) } medium := workspaceMetadataMedium(ws) @@ -81,13 +88,13 @@ func readWorkspaceCryptoMetadata(ws *Workspace) (workspaceCryptoMetadata, error) body, err := medium.Read(path) if err != nil { - return workspaceCryptoMetadata{}, coreerr.E("app.readWorkspaceCryptoMetadata", "read workspace crypto metadata failed", err) + return workspaceCryptoMetadata{}, core.E("app.readWorkspaceCryptoMetadata", "read workspace crypto metadata failed", err) } metadata := workspaceCryptoMetadata{} result := core.JSONUnmarshalString(body, &metadata) if !result.OK { - return workspaceCryptoMetadata{}, coreerr.E("app.readWorkspaceCryptoMetadata", "parse workspace crypto metadata failed", coreResultError(result)) + return workspaceCryptoMetadata{}, core.E("app.readWorkspaceCryptoMetadata", "parse workspace crypto metadata failed", coreResultError(result)) } if metadata.Version == 0 { metadata.Version = 1 @@ -97,7 +104,7 @@ func readWorkspaceCryptoMetadata(ws *Workspace) (workspaceCryptoMetadata, error) func writeWorkspaceCryptoMetadata(ws *Workspace, metadata workspaceCryptoMetadata) error { if ws == nil { - return coreerr.E("app.writeWorkspaceCryptoMetadata", "nil workspace", nil) + return core.E("app.writeWorkspaceCryptoMetadata", "nil workspace", nil) } if metadata.Version == 0 { metadata.Version = 1 @@ -105,19 +112,19 @@ func writeWorkspaceCryptoMetadata(ws *Workspace, metadata workspaceCryptoMetadat result := core.JSONMarshal(metadata) if !result.OK { - return coreerr.E("app.writeWorkspaceCryptoMetadata", "marshal workspace crypto metadata failed", coreResultError(result)) + return core.E("app.writeWorkspaceCryptoMetadata", "marshal workspace crypto metadata failed", coreResultError(result)) } body, ok := result.Value.([]byte) if !ok { - return coreerr.E("app.writeWorkspaceCryptoMetadata", "marshal workspace crypto metadata returned non-bytes", nil) + return core.E("app.writeWorkspaceCryptoMetadata", "marshal workspace crypto metadata returned non-bytes", nil) } medium := workspaceMetadataMedium(ws) if err := medium.EnsureDir(ws.Root); err != nil { - return coreerr.E("app.writeWorkspaceCryptoMetadata", "ensure workspace root failed", err) + return core.E("app.writeWorkspaceCryptoMetadata", "ensure workspace root failed", err) } if err := createWorkspaceCryptoMetadata(medium, workspaceCryptoMetadataPath(ws), string(body)); err != nil { - return coreerr.E("app.writeWorkspaceCryptoMetadata", "write workspace crypto metadata failed", err) + return core.E("app.writeWorkspaceCryptoMetadata", "write workspace crypto metadata failed", err) } return nil } @@ -130,22 +137,22 @@ func createWorkspaceCryptoMetadata(medium coreio.Medium, path, body string) erro return medium.WriteMode(path, body, 0600) } - file, err := openWorkspaceCryptoMetadataFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600) + file, err := openWorkspaceCryptoMetadataFile(path, core.O_CREATE|core.O_EXCL|core.O_WRONLY, 0600) if err != nil { return err } if err := writeWorkspaceCryptoMetadataBody(file, body); err != nil { if closeErr := file.Close(); closeErr != nil { - return coreerr.E("app.createWorkspaceCryptoMetadata", "write failed and close failed", err) + return core.E("app.createWorkspaceCryptoMetadata", "write failed and close failed", err) } - if removeErr := os.Remove(path); removeErr != nil { - return coreerr.E("app.createWorkspaceCryptoMetadata", "write failed and cleanup failed", err) + if remove := core.Remove(path); !remove.OK { + return core.E("app.createWorkspaceCryptoMetadata", "write failed and cleanup failed", coreResultError(remove)) } return err } if err := file.Close(); err != nil { - if removeErr := os.Remove(path); removeErr != nil { - return coreerr.E("app.createWorkspaceCryptoMetadata", "close failed and cleanup failed", err) + if remove := core.Remove(path); !remove.OK { + return core.E("app.createWorkspaceCryptoMetadata", "close failed and cleanup failed", coreResultError(remove)) } return err } @@ -173,7 +180,7 @@ func readWorkspaceSecretSaltAfterCreateRace(ws *Workspace) ([]byte, error) { if lastErr != nil { return nil, lastErr } - return nil, coreerr.E("app.ensureWorkspaceSecretSalt", "workspace salt race winner did not persist salt", nil) + return nil, core.E("app.ensureWorkspaceSecretSalt", "workspace salt race winner did not persist salt", nil) } func workspaceCryptoMetadataFileExists(ws *Workspace) bool { @@ -186,14 +193,14 @@ func workspaceCryptoMetadataFileExists(ws *Workspace) bool { func decodeWorkspaceSecretSalt(encoded string) ([]byte, error) { result := core.Base64Decode(core.Trim(encoded)) if !result.OK { - return nil, coreerr.E("app.decodeWorkspaceSecretSalt", "decode workspace salt failed", coreResultError(result)) + return nil, core.E("app.decodeWorkspaceSecretSalt", "decode workspace salt failed", coreResultError(result)) } salt, ok := result.Value.([]byte) if !ok { - return nil, coreerr.E("app.decodeWorkspaceSecretSalt", "decoded workspace salt returned non-bytes", nil) + return nil, core.E("app.decodeWorkspaceSecretSalt", "decoded workspace salt returned non-bytes", nil) } if len(salt) != workspaceSecretSaltBytes { - return nil, coreerr.E("app.decodeWorkspaceSecretSalt", "workspace salt length is invalid", nil) + return nil, core.E("app.decodeWorkspaceSecretSalt", "workspace salt length is invalid", nil) } out := make([]byte, len(salt)) copy(out, salt) diff --git a/go/yaml.go b/go/yaml.go index 6331a7d..fe1ab28 100644 --- a/go/yaml.go +++ b/go/yaml.go @@ -6,7 +6,6 @@ import ( core "dappco.re/go" "dappco.re/go/config" coreio "dappco.re/go/io" - coreerr "dappco.re/go/log" "gopkg.in/yaml.v3" // Note: AX-6 — centralized YAML codec wrapper; manifest serialisation requires gopkg.in/yaml.v3 (no core.YAML primitive available yet) ) @@ -126,14 +125,14 @@ func LoadViewManifest(medium coreio.Medium, path string, dst *config.ViewManifes medium = coreio.Local } if path == "" { - return coreerr.E("app.LoadViewManifest", "empty path", nil) + return core.E("app.LoadViewManifest", "empty path", nil) } body, err := medium.Read(path) if err != nil { - return coreerr.E("app.LoadViewManifest", "read "+path+" failed", err) + return core.E("app.LoadViewManifest", "read "+path+" failed", err) } if err := UnmarshalViewManifest([]byte(body), dst); err != nil { - return coreerr.E("app.LoadViewManifest", "parse "+path+" failed", err) + return core.E("app.LoadViewManifest", "parse "+path+" failed", err) } return nil } @@ -144,7 +143,7 @@ func LoadViewManifest(medium coreio.Medium, path string, dst *config.ViewManifes // the rest of core/app can consume one consistent shape. func UnmarshalViewManifest(body []byte, dst *config.ViewManifest) error { if dst == nil { - return coreerr.E("app.UnmarshalViewManifest", "nil destination", nil) + return core.E("app.UnmarshalViewManifest", "nil destination", nil) } if err := yamlUnmarshalImpl(body, dst); err != nil { return err