mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-03 20:13:03 +00:00
102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os/exec"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
const desloppifyAttribution = "Powered by peteromallet/desloppify"
|
|
|
|
const missingDesloppifyGuidance = `desloppify was not found in PATH.
|
|
|
|
Install or update desloppify, then scan this codebase for code quality issues
|
|
(dead code, duplication, complexity, smells). It tracks findings persistently
|
|
across sessions and reports a health score.
|
|
|
|
Requires Python 3.11+. Install from PyPI:
|
|
pip install --upgrade desloppify
|
|
pip install --upgrade "desloppify[full]"
|
|
desloppify update-skill codex
|
|
|
|
Use Devour wrappers (delegates to desloppify):
|
|
devour quality scan --path .
|
|
devour quality status
|
|
devour quality next
|
|
|
|
Direct equivalent commands:
|
|
desloppify scan --path .
|
|
desloppify status
|
|
desloppify next
|
|
|
|
--path is the directory to scan ("." for project root).
|
|
Language is auto-detected. To override:
|
|
desloppify --lang python scan --path .
|
|
Note: --lang goes BEFORE the subcommand.
|
|
|
|
Fix findings, then resolve and rescan:
|
|
desloppify resolve fixed <id> --note "what changed" --attest "I have actually [DESCRIBE THE CONCRETE CHANGE YOU MADE] and I am not gaming the score by resolving without fixing."
|
|
|
|
For false positives or intentional debt:
|
|
desloppify resolve wontfix <id> --note "reason" --attest "I have actually verified this is intentional/false-positive and I am not gaming the score by resolving without fixing."
|
|
|
|
If subjective scores feel stale or inflated:
|
|
desloppify scan --path . --reset-subjective
|
|
|
|
Run regularly (for example before each push). If desloppify itself looks wrong
|
|
or confusing, capture a repro and consider filing upstream:
|
|
git clone https://github.com/peteromallet/desloppify.git /tmp/desloppify`
|
|
|
|
func runDesloppifyFromCommand(cmd *cobra.Command, args []string, withAttribution bool) error {
|
|
return runDesloppifyWithIO(
|
|
cmd.Context(),
|
|
cmd.InOrStdin(),
|
|
cmd.OutOrStdout(),
|
|
cmd.ErrOrStderr(),
|
|
args,
|
|
withAttribution,
|
|
)
|
|
}
|
|
|
|
func runDesloppifyWithIO(
|
|
ctx context.Context,
|
|
stdin io.Reader,
|
|
stdout io.Writer,
|
|
stderr io.Writer,
|
|
args []string,
|
|
withAttribution bool,
|
|
) error {
|
|
if withAttribution {
|
|
fmt.Fprintf(stderr, "devour quality/review is %s\n", desloppifyAttribution)
|
|
}
|
|
|
|
binaryPath, err := exec.LookPath("desloppify")
|
|
if err != nil {
|
|
printDesloppifyInstallGuidance(stderr)
|
|
return fmt.Errorf("desloppify is required: %w", err)
|
|
}
|
|
|
|
run := exec.CommandContext(ctx, binaryPath, args...)
|
|
run.Stdin = stdin
|
|
run.Stdout = stdout
|
|
run.Stderr = stderr
|
|
|
|
if err := run.Run(); err != nil {
|
|
var exitErr *exec.ExitError
|
|
if errors.As(err, &exitErr) {
|
|
return err
|
|
}
|
|
return fmt.Errorf("failed to run desloppify: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func printDesloppifyInstallGuidance(stderr io.Writer) {
|
|
fmt.Fprintln(stderr, missingDesloppifyGuidance)
|
|
}
|