Commit graph

12 commits

Author SHA1 Message Date
Snider
2d6415b3aa feat: embed.go and data.go return Result throughout
Mount, MountEmbed, Open, ReadFile, ReadString, Sub, GetAsset,
GetAssetBytes, ScanAssets, GeneratePack, Extract → all return Result.

Data.ReadFile, ReadString, List, ListNames, Extract → Result.
Data.New uses Mount's Result internally.

Internal helpers (WalkDir callback, copyFile) stay error — they're
not public API.

231 tests, 77.4% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 14:13:47 +00:00
Snider
94f2e54abe feat: IPC, task, lifecycle all return Result
Action, Query, QueryAll, Perform → Result
QueryHandler, TaskHandler → func returning Result
RegisterAction/RegisterActions → handler returns Result
ServiceStartup, ServiceShutdown → Result
LogError, LogWarn → Result
ACTION, QUERY, QUERYALL, PERFORM aliases → Result

Tests updated to match new signatures.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:59:45 +00:00
Snider
f5611b1002 refactor: AX audit fixes — no direct strings/fmt, full type names
Direct strings import removed from: data.go, error.go, fs.go
  → uses Split, SplitN, TrimPrefix, TrimSuffix, HasPrefix, Replace, Contains, Join

Direct fmt import removed from: fs.go
  → uses Print() from utils.go

fmt.Errorf in panic recovery → NewError(fmt.Sprint("panic: ", r))

Abbreviated type names renamed:
  ConfigOpts → ConfigOptions
  LogOpts → LogOptions
  RotationLogOpts → RotationLogOptions

embed.go keeps strings import (strings.NewReader, strings.Builder).
error.go keeps fmt import (fmt.Sprint for panic values).

232 tests, 77.8% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:47:23 +00:00
Snider
5d67088080 feat: Service as typed struct, Result without generics
Service is now a proper struct with OnStart/OnStop/OnReload lifecycle
functions — not a registry wrapping any. Packages create Service{} with
typed fields, same pattern as Command and Option.

Result drops generics — Value is any. The struct is the container,
Value is the generic. No more Result[T] ceremony.

Service(name, Service{}) to register, Service(name) to get — both
return Result. ServiceFactory returns Result not (any, error).

NewWithFactories/NewRuntime return Result.

232 tests, 77.8% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:30:22 +00:00
Snider
f1d6c2a174 feat: Join() reclaimed for strings — ErrorJoin for errors
core.Join("/", "deploy", "to", "homelab") → "deploy/to/homelab"
core.Join(".", "cmd", "deploy", "description") → "cmd.deploy.description"

Join builds via Concat — same hook point for security/validation.
errors.Join wrapper renamed to ErrorJoin.
JoinPath now delegates to Join("/", ...).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:42:10 +00:00
Snider
e12526dca6 feat: string.go — core string primitives, same pattern as array.go
HasPrefix, HasSuffix, TrimPrefix, TrimSuffix, Contains, Split, SplitN,
StringJoin, Replace, Lower, Upper, Trim, RuneCount.

utils.go and command.go now use string.go helpers — zero direct
strings import in either file.

234 tests, 79.8% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:29:15 +00:00
Snider
8854d5c79f feat: utils.go — FilterArgs, ParseFlag with short/long flag rules
- FilterArgs: removes empty strings and Go test runner flags
- ParseFlag: single dash (-v, -🔥) must be 1 char, double dash (--verbose) must be 2+ chars
- Cli.Run() now uses FilterArgs and ParseFlag — no test flag awareness in surface layer
- Invalid flags silently ignored (e.g. -verbose, --v)

221 tests, 79.7% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:15:57 +00:00
Snider
c61a2d3dfe test: 214 tests, 79% coverage — GeneratePack with real files, SetOutput, crash reports
Hit compress/compressFile via GeneratePack with actual asset files on disk.
Added SetOutput log test. Crash report test covers Reports() graceful nil.

Remaining 0%: getAllFiles (group dir scan), appendReport (unexported filePath).
Both are internal plumbing — public API is fully covered.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:10:41 +00:00
Snider
afc235796f feat: Command DTO + Cli surface — AX-native CLI primitives
Command is now a DTO with no root/child awareness:
- Path-based registration: c.Command("deploy/to/homelab", handler)
- Description is an i18n key derived from path: cmd.deploy.to.homelab.description
- Lifecycle: Run(), Start(), Stop(), Restart(), Reload(), Signal()
- All return core.Result — errors flow through Core internally
- Parent commands auto-created from path segments

Cli is now a surface layer that reads from Core's command registry:
- Resolves os.Args to command path
- Parses flags into Options (--port=8080 → Option{K:"port", V:"8080"})
- Calls command action with parsed Options
- Banner and help use i18n

Old Clir code preserved in tests/testdata/cli_clir.go.bak for reference.

211 tests, 77.5% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:08:19 +00:00
Snider
b2d07e7883 test: 200 tests, 50.2% coverage — Data, I18n, Fs, Log, Embed, Runtime
New tests: Data List/ListNames/Extract, I18n with mock Translator,
Fs full surface (EnsureDir, IsDir, IsFile, Exists, List, Stat, Open,
Create, Append, ReadStream, WriteStream, Delete, DeleteAll, Rename),
Log all levels + Security + Username + Default + LogErr + LogPan,
Embed ScanAssets + GeneratePack + MountEmbed, Runtime ServiceName,
Core LogError/LogWarn/Must helpers.

Fixes: NewCommand inits flagset, New() wires Cli root command + app.

Remaining 0% (excluding CLI/App): compress, getAllFiles (internal),
Reports/appendReport (needs ErrorPanic filePath), SetOutput (trivial).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 10:49:33 +00:00
Snider
1ca010e1fb test: rewrite test suite for AX primitives API
164 tests, 41.3% coverage. Tests written against the public API only
(external test package, no _test.go in pkg/core/).

Covers: New(Options), Data, Drive, Config, Service, Error, IPC,
Fs, Cli, Lock, Array, Log, App, Runtime, Task.

Fixes: NewCommand now inits flagset, New() wires Cli root command.

Old tests removed — they referenced With*, RegisterService, and
other patterns that no longer exist.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 08:42:38 +00:00
Snider
8199727537 feat: restructure Core as unified struct with DTO pattern
Complete architectural overhaul of pkg/core:
- All subsystem types renamed to idiomatic Go (no stutter)
- Core struct: App, Embed, Fs, Config, ErrPan, ErrLog, Cli, Service, Lock, Ipc, I18n
- Exports consolidated in core.go, contracts/options in contract.go
- Service() unified get/register: c.Service(), c.Service("name"), c.Service("name", svc)
- Lock() named mutex map: c.Lock("srv"), c.Lock("ipc")
- Error system: Err/ErrLog/ErrPan + Log/LogErr/LogPan (shared ErrSink interface)
- CoreCommand with optional description (i18n resolves from command path)
- Tests moved to tests/ directory (black-box package core_test)
- Removed: ServiceFor/MustServiceFor, global instance, Display/Workspace/Crypt interfaces
- New files: app.go, fs.go, ipc.go, lock.go, i18n.go, task.go, runtime.go, contract.go

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 09:12:29 +00:00