8000 fix(mapper): honor the documented per-smell disabled override by LiinaSuoniemi · Pull Request #77 · habit-hooks/habit-hooks · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions docs/habit-mapper.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,113 @@ habit-mapper

🖥️ ✅

### A disabled smell is neither coached nor counted

`disabled` drops the smell before routing: no guide renders for it, and it cannot
fail the run. Here the enforced `too-many-parameters` is disabled, so only the
suggested `warning-comment` coaches and the run stays green.

📄.habit-hooks/config.toml
```toml
[smells.too-many-parameters]
disabled = true
```

📄.habit-hooks/generic/guides/warning-comment.md
```markdown
{% for v in issues -%}
{{ v.details.file }}:{{ v.details.line }} {{ v.details.message }}
{% endfor %}
Resolve or remove these markers before merging.
```

⌨️
```json
[
{
"smell": "too-many-parameters",
"details": { "maxAllowed": 3 },
"issues": [
{
"key": "src/billing.ts",
"details": {
"file": "src/billing.ts",
"line": 2,
"actual": 4,
"signature": "bill(customer, items, discount, tax)"
}
}
]
},
{
"smell": "warning-comment",
"details": {},
"issues": [
{
"key": "src/api.ts",
"details": { "file": "src/api.ts", "line": 14, "message": "TODO handle retry" }
}
]
}
]
```

```bash
habit-mapper
```

🖥️ ✅
```text
── warning-comment (1 issue) ──

src/api.ts:14 TODO handle retry

Resolve or remove these markers before merging.
```

### Disabling every reported smell leaves a clean run

With its only smell disabled there is nothing left to coach, so the run renders
the no-findings guide, exactly as if the sensor had never reported it.

📄.habit-hooks/config.toml
```toml
[smells.too-many-parameters]
disabled = true
```

⌨️
```json
[
{
"smell": "too-many-parameters",
"details": { "maxAllowed": 3 },
"issues": [
{
"key": "src/billing.ts",
"details": {
"file": "src/billing.ts",
"line": 2,
"actual": 4,
"signature": "bill(customer, items, discount, tax)"
}
}
]
}
]
```

```bash
habit-mapper
```

🖥️ ✅
```text
✅ Habit Hooks: automated checks passed.

Habit Hooks catches structural smells, not correctness or design. If no reviewer sub-agent has reviewed this change set, run one before declaring done.
```

## Executable guides

A guide with a non-`.md` extension is run by the **fix runner** registered for
Expand Down
16 changes: 13 additions & 3 deletions src/habit_hooks/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class Rendered:
stderr: str = ""


def is_disabled(smell: str, config: Config) -> bool:
override = config.smells.get(smell)
return bool(override and override.disabled)


def severity_of(smell: str, config: Config) -> str:
override = config.smells.get(smell)
if override and override.severity:
Expand Down Expand Up @@ -89,6 +94,12 @@ def render_clean(config: Config, resolver: Resolver) -> Rendered:
return Rendered(text=guide.read_text(), blocks=False)


def write_stderr(rendered: list[Rendered]) -> None:
for r in rendered:
if r.stderr:
sys.stderr.write(r.stderr)


def banner(finding: dict) -> str:
count = len(finding["issues"])
noun = "issue" if count == 1 else "issues"
Expand All @@ -98,6 +109,7 @@ def banner(finding: dict) -> str:
def run(findings: list[dict], project_dir: Path) -> int:
config = load_config(project_dir)
resolver = Resolver.discover(project_dir)
findings = [f for f in findings if not is_disabled(f["smell"], config)]
if not findings:
clean = render_clean(config, resolver)
sys.stdout.write(clean.text)
Expand All @@ -111,9 +123,7 @@ def run(findings: list[dict], project_dir: Path) -> int:
body = "\n\n".join(blocks)
if body:
sys.stdout.write(body + "\n")
for r in rendered:
if r.stderr:
sys.stderr.write(r.stderr)
write_stderr(rendered)
return 1 if any(r.blocks for r in rendered) else 0


Expand Down
0