Compare commits
1 Commits
b960ca37a8
...
efb0cea1c2
| Author | SHA1 | Date | |
|---|---|---|---|
| efb0cea1c2 |
25
TODO.md
25
TODO.md
@@ -20,15 +20,22 @@ or delete the branch.
|
||||
# Completed Steps
|
||||
|
||||
- 2026-08-09: Finished the lint remediation under the canonical
|
||||
`.golangci.yml` (issue #61, which also unblocks issue #59). Fixed the
|
||||
last 80 findings behavior-preservingly — `wsl_v5` 60, `sqlclosecheck`
|
||||
10, `gosec` 4, `prealloc` 3, `revive` 3 — so `make check` now exits 0
|
||||
on `main`. The `sqlclosecheck` sites now close `sql.Rows` in a
|
||||
deferred closure instead of via the `CloseRows` helper, which the
|
||||
linter could not see through; the four `gosec` and three `revive`
|
||||
findings carry per-site `//nolint` directives with justifications, and
|
||||
the package-rename question behind the `revive` ones is tracked in
|
||||
issue #76.
|
||||
`.golangci.yml` (issue #61, which also unblocks issue #59). The
|
||||
remaining findings were fixed behavior-preservingly: `wsl_v5`
|
||||
whitespace, `sqlclosecheck`, and `prealloc`. The `sqlclosecheck` sites
|
||||
now close `sql.Rows` in a deferred closure instead of via the
|
||||
`CloseRows` helper, which the linter could not see through. Only the
|
||||
`revive` package-name findings remain suppressed, with per-site
|
||||
`//nolint` directives; the package-rename question behind them is
|
||||
tracked in issue #76. Verified with `script/cibuild`, which exits 0 —
|
||||
that is the only trustworthy gate, because `script/lint` runs whatever
|
||||
`golangci-lint` happens to be on `PATH` rather than the pinned
|
||||
v2.12.2 that CI and the `Dockerfile` use, so `make check` can report
|
||||
green on findings CI still fails. That tooling gap is tracked in issue
|
||||
#78.
|
||||
- 2026-08-09: The earlier next step "reconcile the uncommitted
|
||||
`ARCHITECTURE.md` edits on `main`" needed no work: the working tree is
|
||||
clean and `ARCHITECTURE.md` is committed on `main`.
|
||||
- 2026-08-07: Updated golangci-lint to v2.12.2 everywhere it is pinned
|
||||
(`Dockerfile` lint stage, `Makefile` deps target), replaced
|
||||
`.golangci.yml` with the canonical config (v2 schema, `default: all`),
|
||||
|
||||
@@ -69,10 +69,8 @@ func Initialize(cfg Config) {
|
||||
Level: level,
|
||||
}
|
||||
|
||||
// Check if stdout is a TTY. term.IsTerminal takes an int, and a file
|
||||
// descriptor always fits in one on every platform Go supports; a
|
||||
// closed file yields -1, which IsTerminal reports as not a terminal.
|
||||
if term.IsTerminal(int(os.Stdout.Fd())) { //nolint:gosec // G115: fd fits in int
|
||||
// Check if stdout is a TTY.
|
||||
if term.IsTerminal(int(os.Stdout.Fd())) {
|
||||
// Use colorized TTY handler
|
||||
logger = slog.New(NewTTYHandler(os.Stdout, opts))
|
||||
} else {
|
||||
|
||||
@@ -624,9 +624,10 @@ func (s *Scanner) collectBatchFlushData(
|
||||
|
||||
collectStart := time.Now()
|
||||
|
||||
// Every pending file contributes at least one file-chunk and one
|
||||
// chunk-file mapping, so the file count is a safe lower bound for the
|
||||
// initial capacity of both slices.
|
||||
// A pending file contributes one mapping of each kind per chunk, and
|
||||
// an empty file contributes none, so the file count is only a rough
|
||||
// starting capacity for the mapping slices; append grows them as
|
||||
// needed. It is exact for the file and file-ID slices.
|
||||
allFileChunks := make([]database.FileChunk, 0, len(canFlush))
|
||||
allChunkFiles := make([]database.ChunkFile, 0, len(canFlush))
|
||||
allFileIDs := make([]types.FileID, 0, len(canFlush))
|
||||
|
||||
@@ -113,10 +113,7 @@ func shouldColor(w io.Writer) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// term.IsTerminal takes an int, and a file descriptor always fits in
|
||||
// one on every platform Go supports; a closed file yields -1, which
|
||||
// IsTerminal reports as not a terminal.
|
||||
return term.IsTerminal(int(f.Fd())) //nolint:gosec // G115: fd fits in int
|
||||
return term.IsTerminal(int(f.Fd()))
|
||||
}
|
||||
|
||||
// ───────────────────────── message methods ─────────────────────────
|
||||
|
||||
@@ -306,10 +306,6 @@ func (v *Vaultik) decryptAndLoadDatabase(reader io.ReadCloser) (*tempDB, error)
|
||||
return nil, fmt.Errorf("failed to create temp file: %w", err)
|
||||
}
|
||||
|
||||
// tempPath is generated by os.CreateTemp above and never derives from
|
||||
// user input, but gosec's G703 taint analysis treats every path that
|
||||
// originates from an *os.File as tainted, so the os.Remove calls
|
||||
// below carry per-site nolint directives.
|
||||
tempPath := tempFile.Name()
|
||||
|
||||
// Stream decompress directly to file
|
||||
@@ -318,7 +314,7 @@ func (v *Vaultik) decryptAndLoadDatabase(reader io.ReadCloser) (*tempDB, error)
|
||||
written, err := io.Copy(tempFile, decompressor)
|
||||
if err != nil {
|
||||
_ = tempFile.Close()
|
||||
_ = os.Remove(tempPath) //nolint:gosec // G703: path from os.CreateTemp
|
||||
_ = os.Remove(tempPath)
|
||||
|
||||
return nil, fmt.Errorf("failed to decompress database: %w", err)
|
||||
}
|
||||
@@ -330,7 +326,7 @@ func (v *Vaultik) decryptAndLoadDatabase(reader io.ReadCloser) (*tempDB, error)
|
||||
// Open the database
|
||||
db, err := sql.Open("sqlite", tempPath)
|
||||
if err != nil {
|
||||
_ = os.Remove(tempPath) //nolint:gosec // G703: path from os.CreateTemp
|
||||
_ = os.Remove(tempPath)
|
||||
|
||||
return nil, fmt.Errorf("failed to open database: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user