Skip to content

Commit e2ed9c9

Browse files
jgamblinclaude
andcommitted
fix: resolve all ruff and mypy issues
Fix line-length violations (E501), unused imports (F401), unused variables (F841), ambiguous variable name (E741), and mypy type errors. Add uv.lock to .gitignore. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 76c0863 commit e2ed9c9

21 files changed

Lines changed: 85 additions & 51 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ build/
88
.mypy_cache/
99
.pytest_cache/
1010
.ruff_cache/
11+
uv.lock

src/macos_maid/cli.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
import json
66
from pathlib import Path
7+
from typing import cast
78

89
import click
910

1011
from macos_maid import __version__
1112
from macos_maid.audit_log import AuditLog
1213
from macos_maid.config import generate_default_config_yaml, load_config
1314
from macos_maid.modules import get_all_modules
15+
from macos_maid.modules.base import CleanResult, ScanResult
1416
from macos_maid.reporter import Reporter
1517
from macos_maid.runner import ModuleRunner
1618
from macos_maid.system import detect_platform
@@ -109,9 +111,9 @@ def clean(
109111
results = runner.run_clean()
110112

111113
if dry_run:
112-
click.echo(reporter.format_dry_run(results))
114+
click.echo(reporter.format_dry_run(cast(dict[str, ScanResult], results)))
113115
else:
114-
click.echo(reporter.format_clean(results))
116+
click.echo(reporter.format_clean(cast(dict[str, CleanResult], results)))
115117
audit_log.save(DEFAULT_LOG_DIR)
116118

117119

@@ -180,9 +182,9 @@ def report(
180182
audit_results = runner.run_audit()
181183

182184
if dry_run:
183-
click.echo(reporter.format_dry_run(clean_results))
185+
click.echo(reporter.format_dry_run(cast(dict[str, ScanResult], clean_results)))
184186
else:
185-
click.echo(reporter.format_clean(clean_results))
187+
click.echo(reporter.format_clean(cast(dict[str, CleanResult], clean_results)))
186188

187189
click.echo("")
188190
click.echo(reporter.format_audit(audit_results))

src/macos_maid/modules/app_audit.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
from __future__ import annotations
1212

13-
import os
1413
import subprocess
1514
from pathlib import Path
15+
from typing import Any
1616

1717
from macos_maid.modules.base import (
1818
AuditResult,
@@ -87,7 +87,10 @@ def audit(self) -> AuditResult:
8787
severity="info",
8888
title="Unsigned Application",
8989
detail=f"{app_name} is unsigned but appears to be sandboxed",
90-
remediation="Consider verifying the source and reinstalling from official channels if available",
90+
remediation=(
91+
"Consider verifying the source and reinstalling"
92+
" from official channels if available"
93+
),
9194
)
9295
)
9396

@@ -100,7 +103,10 @@ def audit(self) -> AuditResult:
100103
severity="warn",
101104
title="Unsigned Application with Elevated Permissions",
102105
detail=f"{app_name} is unsigned and may have elevated permissions",
103-
remediation=f"Review {app_name} carefully. Consider removing or replacing with a signed version.",
106+
remediation=(
107+
f"Review {app_name} carefully."
108+
" Consider removing or replacing with a signed version."
109+
),
104110
)
105111
)
106112

@@ -218,13 +224,13 @@ def _check_elevated_perms(self, app_path: str) -> bool:
218224
except Exception:
219225
return False
220226

221-
def _get_applications(self) -> list[dict]:
227+
def _get_applications(self) -> list[dict[str, Any]]:
222228
"""Scan /Applications for .app bundles and check their signing status.
223229
224230
Returns:
225231
List of dicts with keys: path, signed, from_app_store, has_elevated_perms
226232
"""
227-
apps = []
233+
apps: list[dict[str, Any]] = []
228234
applications_dir = Path("/Applications")
229235

230236
if not applications_dir.exists():

src/macos_maid/modules/network.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def _check_firewall_enabled(self) -> bool:
7878
text=True,
7979
check=True,
8080
)
81-
# Output is like "Firewall is enabled. (State = 1)" or "Firewall is disabled. (State = 0)"
81+
# "Firewall is enabled. (State = 1)" or "...disabled. (State = 0)"
8282
return "enabled" in result.stdout.lower()
8383
except subprocess.CalledProcessError:
8484
return False
@@ -157,7 +157,9 @@ def audit(self) -> AuditResult:
157157
severity="fail",
158158
title="Firewall Status",
159159
detail="macOS Application Firewall is disabled",
160-
remediation="Enable firewall in System Preferences > Security & Privacy > Firewall",
160+
remediation=(
161+
"Enable firewall in System Preferences > Security & Privacy > Firewall"
162+
),
161163
)
162164
)
163165

src/macos_maid/modules/privacy.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,10 @@ def audit(self) -> AuditResult:
216216
severity="info",
217217
title=f"{human_name} Permission",
218218
detail=f"{len(apps)} app(s) have {human_name} access: {app_list}",
219-
remediation=f"Review {human_name} permissions in System Preferences > Security & Privacy > Privacy",
219+
remediation=(
220+
f"Review {human_name} permissions in"
221+
" System Preferences > Security & Privacy > Privacy"
222+
),
220223
)
221224
)
222225

@@ -230,7 +233,11 @@ def audit(self) -> AuditResult:
230233
Finding(
231234
severity="info",
232235
title="Old Downloads Files",
233-
detail=f"Found {len(old_downloads)} file(s) in Downloads older than {self.downloads_older_than} days ({size_mb:.1f} MB)",
236+
detail=(
237+
f"Found {len(old_downloads)} file(s) in Downloads"
238+
f" older than {self.downloads_older_than} days"
239+
f" ({size_mb:.1f} MB)"
240+
),
234241
remediation="Review and manually clean up old files in ~/Downloads",
235242
)
236243
)

src/macos_maid/modules/system_integrity.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ def _check_sip(self) -> Finding:
8080
severity="fail",
8181
title="System Integrity Protection",
8282
detail="SIP is disabled",
83-
remediation="Enable SIP by booting into Recovery Mode and running 'csrutil enable'",
83+
remediation=(
84+
"Enable SIP by booting into Recovery Mode and running 'csrutil enable'"
85+
),
8486
)
8587
except Exception as e:
8688
return Finding(
@@ -113,7 +115,9 @@ def _check_filevault(self) -> Finding:
113115
severity="fail",
114116
title="FileVault Encryption",
115117
detail="FileVault is off",
116-
remediation="Enable FileVault in System Preferences > Security & Privacy > FileVault",
118+
remediation=(
119+
"Enable FileVault in System Preferences > Security & Privacy > FileVault"
120+
),
117121
)
118122
except Exception as e:
119123
return Finding(
@@ -193,7 +197,11 @@ def _check_xprotect(self) -> Finding:
193197
severity="warn",
194198
title="XProtect",
195199
detail=f"Could not check XProtect status: {e}",
196-
remediation="Verify XProtect manually with 'system_profiler SPInstallHistoryDataType | grep -i xprotect'",
200+
remediation=(
201+
"Verify XProtect manually with"
202+
" 'system_profiler SPInstallHistoryDataType"
203+
" | grep -i xprotect'"
204+
),
197205
)
198206

199207
def _check_firewall(self) -> Finding:
@@ -219,12 +227,18 @@ def _check_firewall(self) -> Finding:
219227
severity="fail",
220228
title="Firewall",
221229
detail="Firewall is disabled",
222-
remediation="Enable firewall in System Preferences > Security & Privacy > Firewall",
230+
remediation=(
231+
"Enable firewall in System Preferences > Security & Privacy > Firewall"
232+
),
223233
)
224234
except Exception as e:
225235
return Finding(
226236
severity="warn",
227237
title="Firewall",
228238
detail=f"Could not check firewall status: {e}",
229-
remediation="Verify firewall manually with '/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate'",
239+
remediation=(
240+
"Verify firewall manually with"
241+
" '/usr/libexec/ApplicationFirewall/"
242+
"socketfilterfw --getglobalstate'"
243+
),
230244
)

src/macos_maid/modules/tools.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ def audit(self) -> AuditResult:
7474
Finding(
7575
severity="info",
7676
title="Lynis Not Installed",
77-
detail="Install Lynis for comprehensive system security auditing. Install with: brew install lynis",
77+
detail=(
78+
"Install Lynis for comprehensive system security"
79+
" auditing. Install with: brew install lynis"
80+
),
7881
remediation=None,
7982
)
8083
)
@@ -98,7 +101,10 @@ def audit(self) -> AuditResult:
98101
Finding(
99102
severity="info",
100103
title="Osquery Not Installed",
101-
detail="Install osquery for system querying and monitoring. Install with: brew install osquery",
104+
detail=(
105+
"Install osquery for system querying and"
106+
" monitoring. Install with: brew install osquery"
107+
),
102108
remediation=None,
103109
)
104110
)
@@ -229,7 +235,7 @@ def _run_lynis(self) -> list[Finding]:
229235
remediation="Try running 'lynis audit system --quick' manually",
230236
)
231237
)
232-
except Exception as e:
238+
except Exception:
233239
raise # Re-raise to be caught by audit()
234240

235241
return findings
@@ -277,7 +283,10 @@ def _run_osquery_check(self) -> list[Finding]:
277283
Finding(
278284
severity="warn",
279285
title="Unsigned Processes Detected",
280-
detail=f"Found {len(unsigned_processes)} unsigned processes: {', '.join(process_names)}",
286+
detail=(
287+
f"Found {len(unsigned_processes)} unsigned"
288+
f" processes: {', '.join(process_names)}"
289+
),
281290
remediation="Investigate and remove suspicious unsigned processes",
282291
)
283292
)
@@ -307,7 +316,8 @@ def _run_osquery_check(self) -> list[Finding]:
307316
listeners = json.loads(result.stdout)
308317
if listeners:
309318
listener_info = [
310-
f"{l.get('name', 'unknown')}:{l.get('port', '?')}" for l in listeners[:5]
319+
f"{item.get('name', 'unknown')}:{item.get('port', '?')}"
320+
for item in listeners[:5]
311321
]
312322
findings.append(
313323
Finding(
@@ -338,7 +348,9 @@ def _run_knockknock_check(self) -> list[Finding]:
338348
Finding(
339349
severity="info",
340350
title="KnockKnock Available",
341-
detail="KnockKnock is installed. Run it manually to scan for persistent malware.",
351+
detail=(
352+
"KnockKnock is installed. Run it manually to scan for persistent malware."
353+
),
342354
remediation=None,
343355
)
344356
)

src/macos_maid/reporter.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88

99
import json
1010
from datetime import datetime, timezone
11-
from typing import Union
1211

13-
from macos_maid.modules.base import AuditResult, CleanResult, Finding, ScanResult
12+
from macos_maid.modules.base import AuditResult, CleanResult, ScanResult
1413
from macos_maid.system import Platform
1514

1615

@@ -35,7 +34,11 @@ def __init__(self, platform: Platform, output_format: str = "terminal") -> None:
3534
def _header(self) -> str:
3635
p = self._platform
3736
date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
38-
return f"MacOS Maid Report — {date}\nmacOS {p.macos_name} {'.'.join(str(v) for v in p.macos_version)} | {p.arch} | {p.filesystem.upper()}"
37+
ver = ".".join(str(v) for v in p.macos_version)
38+
return (
39+
f"MacOS Maid Report — {date}\n"
40+
f"macOS {p.macos_name} {ver} | {p.arch} | {p.filesystem.upper()}"
41+
)
3942

4043
def format_clean(self, results: dict[str, CleanResult]) -> str:
4144
if self._format == "json":

src/macos_maid/runner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from __future__ import annotations
99

10-
from typing import Any, Union
10+
from typing import Any
1111

1212
from macos_maid.audit_log import AuditLog
1313
from macos_maid.modules.base import AuditResult, CleanResult, Module, ScanResult
@@ -48,7 +48,7 @@ def _filter_modules(self, require_sudo_check: bool = True) -> list[Module]:
4848

4949
return filtered
5050

51-
def run_clean(self) -> dict[str, Union[ScanResult, CleanResult]]:
51+
def run_clean(self) -> dict[str, ScanResult | CleanResult]:
5252
"""Run cleanup on all matching modules.
5353
5454
Returns ScanResult per module in dry-run mode, CleanResult otherwise.

tests/modules/test_app_audit.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# tests/modules/test_app_audit.py
22
"""Tests for app audit module."""
33

4-
from unittest.mock import MagicMock, patch
5-
6-
import pytest
4+
from unittest.mock import patch
75

86
from macos_maid.modules.app_audit import AppAuditModule
97

0 commit comments

Comments
 (0)