Archive experimental OpenSpec changes
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-04-15
|
||||
@@ -0,0 +1,66 @@
|
||||
## Implementation
|
||||
|
||||
### Log File Location
|
||||
- Path: `/var/log/declpac.log`
|
||||
- Single merged log file (stdout + stderr intermingled in order of arrival)
|
||||
|
||||
### State-Modifying Functions (need logging)
|
||||
1. `SyncPackages()` - `pacman -S --needed <packages>`
|
||||
2. `InstallAUR()` - `git clone` + `makepkg -si --noconfirm`
|
||||
3. `MarkAllAsDeps()` - `pacman -D --asdeps`
|
||||
4. `MarkAsExplicit()` - `pacman -D --asexplicit <packages>`
|
||||
5. `CleanupOrphans()` - `pacman -Rns`
|
||||
|
||||
### Functions to Skip (read-only)
|
||||
- `DryRun()` - queries only
|
||||
- `getInstalledCount()` - pacman -Qq
|
||||
|
||||
### Execution Patterns
|
||||
|
||||
| Pattern | Functions | How |
|
||||
|---------|------------|-----|
|
||||
| Streaming | MarkAllAsDeps, MarkAsExplicit, InstallAUR | `io.MultiWriter` to tee to both terminal and log |
|
||||
| Captured | SyncPackages, CleanupOrphans | capture with `CombinedOutput()`, write to log, write to terminal |
|
||||
|
||||
### Error Handling
|
||||
- Write error to log BEFORE returning from function
|
||||
- Print error to stderr so user sees it
|
||||
|
||||
### Dependencies
|
||||
- Add to imports: `io`, `os`, `path/filepath`
|
||||
|
||||
### Structure
|
||||
|
||||
```go
|
||||
// pkg/state/state.go
|
||||
var logFile *os.File
|
||||
|
||||
func OpenLog() error {
|
||||
logPath := filepath.Join("/var/log", "declpac.log")
|
||||
f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logFile = f
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetLogWriter() io.Writer {
|
||||
return logFile
|
||||
}
|
||||
|
||||
func Close() error {
|
||||
if logFile == nil {
|
||||
return nil
|
||||
}
|
||||
return logFile.Close()
|
||||
}
|
||||
```
|
||||
|
||||
### Flow in Sync() or main entrypoint
|
||||
1. Call `OpenLog()` at program start, defer close
|
||||
2. Each state-modifying function uses `state.GetLogWriter()` via MultiWriter
|
||||
|
||||
### Wire into main.go
|
||||
- Open log at start of `run()`
|
||||
- Pass log writer to pacman package (via exported function or global)
|
||||
@@ -0,0 +1,26 @@
|
||||
## Why
|
||||
|
||||
The tool exits without saving the full pacman output, making debugging difficult
|
||||
when operations fail. Users need a persistent log of all pacman operations for
|
||||
debugging and audit.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add state directory initialization creating `~/.local/state/declpac` if not exists
|
||||
- Open/manage a single log file at `$XDG_STATE_HOME/declpac` (e.g., `~/.local/state/declpac/declpac`)
|
||||
- Instrument all state-modifying exec calls in `pkg/pacman/pacman.go` to tee or append output to this file
|
||||
- Skip debug messages (internal timing logs)
|
||||
- Capture and write errors before returning
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- Operation logging: Persist stdout/stderr from all pacman operations
|
||||
|
||||
### Modified Capabilities
|
||||
- None
|
||||
|
||||
## Impact
|
||||
|
||||
- `pkg/pacman/pacman.go`: Instrument all state-modifying functions to write to log file
|
||||
- New module: May create `pkg/state/state.go` or similar for log file management
|
||||
@@ -0,0 +1,45 @@
|
||||
## Tasks
|
||||
|
||||
- [x] 1. Create state module
|
||||
|
||||
Create `pkg/state/state.go`:
|
||||
- `OpenLog()` - opens `/var/log/declpac.log` in append mode
|
||||
- `GetLogWriter()` - returns the raw log file writer (for MultiWriter)
|
||||
- `Write(msg []byte)` - writes message with timestamp + dashes separator
|
||||
- `Close()` - closes the file
|
||||
|
||||
- [x] 2. Wire into main.go
|
||||
|
||||
In `cmd/declpac/main.go` `run()`:
|
||||
- Call `OpenLog()` at start
|
||||
- `defer Close()` log
|
||||
|
||||
- [x] 3. Instrument pkg/pacman
|
||||
|
||||
Modify `pkg/pacman/pacman.go`:
|
||||
|
||||
All state-modifying functions use `state.Write()` instead of `state.GetLogWriter().Write()`:
|
||||
|
||||
```
|
||||
// OLD
|
||||
state.GetLogWriter().Write(output)
|
||||
|
||||
// NEW
|
||||
state.Write(output) // auto-prepends timestamp
|
||||
```
|
||||
|
||||
**Functions updated:**
|
||||
- `SyncPackages()` - write output with timestamp
|
||||
- `CleanupOrphans()` - write output with timestamp
|
||||
- `MarkAllAsDeps()` - write operation name with timestamp before running
|
||||
- `MarkAsExplicit()` - write operation name with timestamp before running
|
||||
- `InstallAUR()` - write "Cloning ..." and "Building package..." with timestamps
|
||||
- Error handling - `state.Write([]byte("error: ..."))` for all error paths
|
||||
|
||||
- [x] 4. Add io import
|
||||
|
||||
Add `io` to imports in pacman.go
|
||||
|
||||
- [x] 5. Test
|
||||
|
||||
Run a sync operation and verify log file created at `/var/log/declpac.log`
|
||||
Reference in New Issue
Block a user