Skip to content

feat: add cog doctor command#2923

Draft
markphelps wants to merge 19 commits intomainfrom
cog-doctor
Draft

feat: add cog doctor command#2923
markphelps wants to merge 19 commits intomainfrom
cog-doctor

Conversation

@markphelps
Copy link
Copy Markdown
Contributor

@markphelps markphelps commented Apr 9, 2026

Summary

Adds a cog doctor command that diagnoses and auto-fixes common project issues across config, Python code, and environment.

  • Report mode (default): Runs all checks and reports findings with file/line references
  • Fix mode (--fix): Automatically applies safe fixes to Python source files

Checks included

Check Group Severity Auto-fix
Config parsing Config Error No
Config schema validation Config Error No
Deprecated config fields Config Warning No
Predict reference validity Config Error No
Pydantic BaseModel workaround Python Error Yes
Deprecated imports Python Error Yes
Missing type annotations Python Warning No
Docker availability Environment Error No
Python version mismatch Environment Warning No

Motivation

Users upgrading cog versions (especially to 0.17+) hit breaking changes that manifest as confusing build/runtime errors. For example, output classes using pydantic.BaseModel with arbitrary_types_allowed=True instead of cog.BaseModel, or deprecated imports like ExperimentalFeatureWarning. There was no single command to find and fix these.

Extensibility

Adding a new check is one file + one line of registration:

  1. Create pkg/doctor/check_<group>_<name>.go implementing the Check interface
  2. Add one line to AllChecks() in registry.go

Design

Python analysis uses the existing tree-sitter parser (pkg/schema/python/) — no Python subprocess needed.

Replace if-else chain with switch statement (gocritic) and use
strings.Join instead of string concatenation in a loop (modernize).
Add 8 txtar integration tests covering:
- Clean project (no issues found, exit 0)
- Pydantic BaseModel detection (exit 1)
- Pydantic BaseModel auto-fix with --fix
- Deprecated imports detection (exit 1)
- Deprecated imports auto-fix with --fix
- Missing predict class reference (exit 1)
- Exit code 1 when predict file is missing
- Deprecated config fields as warnings (exit 0)
Copy link
Copy Markdown

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm Bonk, and I've done a quick review of your PR.

Adds a cog doctor command to diagnose and auto-fix common project issues. The implementation is solid with good test coverage and follows existing patterns.

One potential issue with error handling in runner.go:

}

parser := sitter.NewParser()
parser.SetLanguage(python.GetLanguage())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context.Background() here creates a new root context, ignoring any cancellation signals from the caller. Since the Run function receives a context parameter, consider using that instead:

Suggested change
parser.SetLanguage(python.GetLanguage())
tree, err := parser.ParseCtx(ctx, nil, source)

@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 9, 2026

I've submitted my review on PR #2923 with one suggestion about using the passed context instead of context.Background() in the runner. The PR is well-structured with good test coverage and follows existing patterns.

github run

@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 9, 2026

LGTM

github run

…ate config loading, improve fix robustness

Critical fixes:
- HasErrors() now accounts for check internal errors (exit code 1)
- hasArbitraryTypesAllowed uses tree-sitter AST instead of string matching (no false positives)
- addToCogImport handles missing 'from cog import' line
- Config loading consolidated onto CheckContext (eliminates 4x redundant Load calls)

High priority fixes:
- Respect --file flag instead of hardcoding cog.yaml
- Handle 'import pydantic' module-level style in fix
- Deprecated imports fix uses tree-sitter re-scan instead of fragile string matching
- ConfigPredictRefCheck reuses cached Python files from ctx.PythonFiles
- model_config fix preserves other ConfigDict kwargs

Medium fixes:
- Docker/Python exec commands have 5-second timeout
- Multi-line parenthesized imports handled by fix
- File permissions preserved (not hardcoded to 0o644)
- printDoctorResults counts per-finding consistently
Copy link
Copy Markdown

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds a cog doctor command to diagnose and auto-fix common project issues. The implementation is solid with good test coverage and follows existing patterns.

One potential issue with error handling in runner.go:


parser := sitter.NewParser()
parser.SetLanguage(python.GetLanguage())
tree, err := parser.ParseCtx(context.Background(), nil, source)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context.Background() here creates a new root context, ignoring any cancellation signals from the caller. Since the Run function receives a context parameter, consider using that instead:

Suggested change
tree, err := parser.ParseCtx(context.Background(), nil, source)
tree, err := parser.ParseCtx(ctx, nil, source)

@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 9, 2026

I've submitted my review on PR #2923 with one suggestion about using the passed context instead of context.Background() in the runner. The PR is well-structured with good test coverage and follows existing patterns.

github run

Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
@ask-bonk
Copy link
Copy Markdown

ask-bonk bot commented Apr 9, 2026

I've already submitted my review on PR #2923. My previous review identified one issue with using context.Background() instead of the passed context in pkg/doctor/runner.go:152.

The PR is well-structured with good test coverage and follows existing patterns. The suggestion has been provided to the author.

No further action needed from me.

github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant