Update golangci-lint to v2.12.2 with canonical config (closes #60)
All checks were successful
check / check (push) Successful in 53s
All checks were successful
check / check (push) Successful in 53s
- Add canonical .golangci.yml (v2 schema, default: all, project thresholds for lll/funlen/cyclop/dupl) - Bump golangci-lint pins from v2.0.2 to v2.12.2 in Makefile (go install, new /v2 module path) and Dockerfile (tagged+digest Debian image pin) - Fix all lint findings surfaced by the new linter set across cmd/mfer, internal/bork, internal/cli, internal/log, and mfer: static sentinel errors (err113), context-aware HTTP and exec (noctx), guarded integer conversions and stricter permissions (gosec), named constants (mnd, goconst), function decomposition (funlen, cyclop, gocognit, nestif), declaration ordering (funcorder), t.Parallel/t.TempDir/t.Setenv adoption in tests (paralleltest, usetesting), protobuf getters (protogetter), plus formatting and style cleanups (wsl_v5, nlreturn, lll, revive, testifylint, and others) - Serialize CLI runs in tests behind a mutex so parallel tests do not cross-wire the process-global logger's captured output The decompositions are behavior-preserving. In particular: - REPO_POLICIES.md is untouched and stays byte-identical to the authoritative copy in the prompts repo - the mfer.manifest type stays unexported; whether to export it is an open owner design question (README question 13) - directories created by fetch keep mode 0755, because fetched trees are content meant to be readable by other uids - an absent MFFilePath.Mtime is handled explicitly and identically in freshen, list, and export rather than being read as the Unix epoch, which would classify every entry as changed and rewrite the manifest on every freshen - every user-visible error message renders byte-identically to what it did before, with the err113 sentinels wrapped mid-sentence where needed; the rendered strings are now pinned by tests Also fixes an argument-injection defect the lint pass surfaced: key IDs reach gpg as bare positional arguments, so a key ID beginning with "-" was parsed by gpg as an option. All positional arguments now follow an explicit "--" end-of-options marker. The symlink-escape gap in fetch's path handling, which sanitizePath does not and cannot address, is filed separately as #86.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// Package log provides leveled logging with progress output helpers
|
||||
// on top of apex/log and pterm.
|
||||
package log
|
||||
|
||||
import (
|
||||
@@ -52,6 +54,11 @@ func (l Level) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// callerSkip is the runtime.Caller stack depth from the public Debug
|
||||
// helpers to the caller of the log package.
|
||||
const callerSkip = 2
|
||||
|
||||
//nolint:gochecknoglobals // package-level logger state by design
|
||||
var (
|
||||
// mu protects the output writers and level
|
||||
mu sync.RWMutex
|
||||
@@ -60,7 +67,7 @@ var (
|
||||
// stderr is the writer for log output
|
||||
stderr io.Writer = os.Stderr
|
||||
// currentLevel is our log level (includes Verbose)
|
||||
currentLevel Level = InfoLevel
|
||||
currentLevel = InfoLevel
|
||||
)
|
||||
|
||||
// SetOutput configures the output writers for the log package.
|
||||
@@ -68,8 +75,10 @@ var (
|
||||
func SetOutput(out, err io.Writer) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
stdout = out
|
||||
stderr = err
|
||||
|
||||
pterm.SetDefaultOutput(out)
|
||||
}
|
||||
|
||||
@@ -77,6 +86,7 @@ func SetOutput(out, err io.Writer) {
|
||||
func GetStdout() io.Writer {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
return stdout
|
||||
}
|
||||
|
||||
@@ -84,6 +94,7 @@ func GetStdout() io.Writer {
|
||||
func GetStderr() io.Writer {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
return stderr
|
||||
}
|
||||
|
||||
@@ -91,6 +102,7 @@ func GetStderr() io.Writer {
|
||||
func DisableStyling() {
|
||||
pterm.DisableColor()
|
||||
pterm.DisableStyling()
|
||||
|
||||
pterm.Debug.Prefix.Text = ""
|
||||
pterm.Info.Prefix.Text = ""
|
||||
pterm.Success.Prefix.Text = ""
|
||||
@@ -102,7 +114,9 @@ func DisableStyling() {
|
||||
// Init initializes the logger with the CLI handler and default log level.
|
||||
func Init() {
|
||||
mu.RLock()
|
||||
|
||||
w := stderr
|
||||
|
||||
mu.RUnlock()
|
||||
log.SetHandler(acli.New(w))
|
||||
log.SetLevel(log.DebugLevel) // Let apex/log pass everything; we filter ourselves
|
||||
@@ -112,11 +126,12 @@ func Init() {
|
||||
func isEnabled(l Level) bool {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
return l >= currentLevel
|
||||
}
|
||||
|
||||
// Fatalf logs a formatted message at fatal level.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
func Fatalf(format string, args ...any) {
|
||||
if isEnabled(FatalLevel) {
|
||||
log.Fatalf(format, args...)
|
||||
}
|
||||
@@ -130,7 +145,7 @@ func Fatal(arg string) {
|
||||
}
|
||||
|
||||
// Errorf logs a formatted message at error level.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
func Errorf(format string, args ...any) {
|
||||
if isEnabled(ErrorLevel) {
|
||||
log.Errorf(format, args...)
|
||||
}
|
||||
@@ -144,7 +159,7 @@ func Error(arg string) {
|
||||
}
|
||||
|
||||
// Warnf logs a formatted message at warn level.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
func Warnf(format string, args ...any) {
|
||||
if isEnabled(WarnLevel) {
|
||||
log.Warnf(format, args...)
|
||||
}
|
||||
@@ -158,7 +173,7 @@ func Warn(arg string) {
|
||||
}
|
||||
|
||||
// Infof logs a formatted message at info level.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
func Infof(format string, args ...any) {
|
||||
if isEnabled(InfoLevel) {
|
||||
log.Infof(format, args...)
|
||||
}
|
||||
@@ -172,7 +187,7 @@ func Info(arg string) {
|
||||
}
|
||||
|
||||
// Verbosef logs a formatted message at verbose level.
|
||||
func Verbosef(format string, args ...interface{}) {
|
||||
func Verbosef(format string, args ...any) {
|
||||
if isEnabled(VerboseLevel) {
|
||||
log.Infof(format, args...)
|
||||
}
|
||||
@@ -186,16 +201,16 @@ func Verbose(arg string) {
|
||||
}
|
||||
|
||||
// Debugf logs a formatted message at debug level with caller location.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
func Debugf(format string, args ...any) {
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(fmt.Sprintf(format, args...), 2)
|
||||
DebugReal(fmt.Sprintf(format, args...), callerSkip)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug logs a message at debug level with caller location.
|
||||
func Debug(arg string) {
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(arg, 2)
|
||||
DebugReal(arg, callerSkip)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,18 +219,20 @@ func DebugReal(arg string, cs int) {
|
||||
if !isEnabled(DebugLevel) {
|
||||
return
|
||||
}
|
||||
|
||||
_, callerFile, callerLine, ok := runtime.Caller(cs)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
tag := fmt.Sprintf("%s:%d: ", filepath.Base(callerFile), callerLine)
|
||||
log.Debug(tag + arg)
|
||||
}
|
||||
|
||||
// Dump logs a spew dump of the arguments at debug level.
|
||||
func Dump(args ...interface{}) {
|
||||
func Dump(args ...any) {
|
||||
if isEnabled(DebugLevel) {
|
||||
DebugReal(spew.Sdump(args...), 2)
|
||||
DebugReal(spew.Sdump(args...), callerSkip)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,6 +263,7 @@ func SetLevelFromVerbosity(l int) {
|
||||
func SetLevel(l Level) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
currentLevel = l
|
||||
}
|
||||
|
||||
@@ -253,6 +271,7 @@ func SetLevel(l Level) {
|
||||
func GetLevel() Level {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
|
||||
return currentLevel
|
||||
}
|
||||
|
||||
@@ -263,7 +282,7 @@ func WithError(e error) *log.Entry {
|
||||
|
||||
// Progressf prints a progress message that overwrites the current line.
|
||||
// Use ProgressDone() when progress is complete to move to the next line.
|
||||
func Progressf(format string, args ...interface{}) {
|
||||
func Progressf(format string, args ...any) {
|
||||
pterm.Printf("\r"+format, args...)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user