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
196 changes: 196 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
name: Windows CI

on:
push:
branches: [main, dev]
paths:
- 'windows/**'
- '.github/workflows/windows.yml'
pull_request:
branches: [main, dev]
paths:
- 'windows/**'
- '.github/workflows/windows.yml'

jobs:
build:
name: Build & Test
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24"
cache-dependency-path: windows/go.sum

- name: Build Go binaries
working-directory: windows
run: |
go build -o bin/analyze.exe ./cmd/analyze/
go build -o bin/status.exe ./cmd/status/
- name: Run Go tests
working-directory: windows
run: go test -v ./...

- name: Validate PowerShell syntax
shell: pwsh
run: |
$scripts = Get-ChildItem -Path windows -Filter "*.ps1" -Recurse
$errors = @()
foreach ($script in $scripts) {
$parseErrors = $null
$null = [System.Management.Automation.Language.Parser]::ParseFile(
$script.FullName,
[ref]$null,
[ref]$parseErrors
)
if ($parseErrors) {
Write-Host "ERROR: $($script.FullName)" -ForegroundColor Red
foreach ($err in $parseErrors) {
Write-Host " $($err.Message)" -ForegroundColor Red
}
$errors += $script.FullName
} else {
Write-Host "OK: $($script.Name)" -ForegroundColor Green
}
}
if ($errors.Count -gt 0) {
Write-Host "`n$($errors.Count) script(s) have syntax errors!" -ForegroundColor Red
exit 1
}
pester:
name: Pester Tests
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Install Pester
shell: pwsh
run: |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name Pester -MinimumVersion 5.0.0 -Force -SkipPublisherCheck
- name: Run Pester tests
shell: pwsh
run: |
Import-Module Pester -MinimumVersion 5.0.0
$config = New-PesterConfiguration
$config.Run.Path = "windows/tests"
$config.Run.Exit = $true
$config.Output.Verbosity = "Detailed"
$config.TestResult.Enabled = $true
$config.TestResult.OutputPath = "windows/test-results.xml"
$config.TestResult.OutputFormat = "NUnitXml"
Invoke-Pester -Configuration $config
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: pester-results
path: windows/test-results.xml

compatibility:
name: Windows Compatibility
strategy:
matrix:
os: [windows-2022, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- name: Test PowerShell 5.1
shell: powershell
run: |
Write-Host "Testing on ${{ matrix.os }} with PowerShell $($PSVersionTable.PSVersion)"
# Test main entry point
$result = & powershell -ExecutionPolicy Bypass -File "windows\mole.ps1" -ShowHelp 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "mole.ps1 -ShowHelp failed" -ForegroundColor Red
exit 1
}
Write-Host "✓ mole.ps1 works on ${{ matrix.os }}"
- name: Test command scripts
shell: powershell
run: |
$commands = @("clean", "uninstall", "optimize", "purge", "analyze", "status")
foreach ($cmd in $commands) {
$scriptPath = "windows\bin\$cmd.ps1"
if (Test-Path $scriptPath) {
$result = & powershell -ExecutionPolicy Bypass -File $scriptPath -ShowHelp 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "✗ $cmd.ps1 failed" -ForegroundColor Red
exit 1
}
Write-Host "✓ $cmd.ps1 works"
}
}
security:
name: Security Checks
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Check for unsafe patterns
shell: pwsh
run: |
Write-Host "Checking for unsafe removal patterns..."
$unsafePatterns = @(
"Remove-Item.*-Recurse.*-Force.*\\\$env:SystemRoot",
"Remove-Item.*-Recurse.*-Force.*C:\\Windows",
"Remove-Item.*-Recurse.*-Force.*C:\\Program Files"
)
$files = Get-ChildItem -Path windows -Filter "*.ps1" -Recurse
$issues = @()
foreach ($file in $files) {
$content = Get-Content $file.FullName -Raw
foreach ($pattern in $unsafePatterns) {
if ($content -match $pattern) {
$issues += "$($file.Name): matches unsafe pattern"
}
}
}
if ($issues.Count -gt 0) {
Write-Host "Unsafe patterns found:" -ForegroundColor Red
$issues | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
exit 1
}
Write-Host "✓ No unsafe patterns found" -ForegroundColor Green
- name: Verify protection checks
shell: pwsh
run: |
Write-Host "Verifying protection logic..."
# Source file_ops to get Test-IsProtectedPath
. windows\lib\core\base.ps1
. windows\lib\core\file_ops.ps1
$protectedPaths = @(
"C:\Windows",
"C:\Windows\System32",
"C:\Program Files",
"C:\Program Files (x86)"
)
foreach ($path in $protectedPaths) {
if (-not (Test-ProtectedPath -Path $path)) {
Write-Host "✗ $path should be protected!" -ForegroundColor Red
exit 1
}
Write-Host "✓ $path is protected" -ForegroundColor Green
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@ bin/status-darwin-*
tests/tmp-*/
tests/*.tmp
tests/*.log

session.json
run_tests.ps1
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@
- **Disk insights**: Visualizes usage, manages large files, **rebuilds caches**, and refreshes system services
- **Live monitoring**: Real-time stats for CPU, GPU, memory, disk, and network to **diagnose performance issues**

## Platform Support

Mole is designed for **macOS**. For Windows users, check out the `windows/` directory which provides a native Windows port with the same features:

**Windows Installation:**
```powershell
irm https://raw.githubusercontent.com/tw93/mole/main/windows/install.ps1 | iex
```

**Windows Features:**
- Deep system cleanup (temp files, caches, logs, Windows Update cache)
- Smart app uninstaller with leftover detection
- System optimization and service refresh
- Developer artifact cleanup (node_modules, target, .venv, etc.)
- Disk analysis and real-time monitoring tools (TUI)

Built with PowerShell and Go for native Windows performance. Run `mole` after installation.

## Quick Start

**Install by Brew, recommended:**
Expand Down
16 changes: 16 additions & 0 deletions windows/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Windows Mole - .gitignore

# Build artifacts
bin/*.exe

# Go build cache
.gocache/

# IDE files
.idea/
.vscode/
*.code-workspace

# Test artifacts
*.test
coverage.out
44 changes: 44 additions & 0 deletions windows/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Mole Windows - Makefile
# Build Go tools for Windows

.PHONY: all build clean analyze status

# Default target
all: build

# Build both tools
build: analyze status

# Build analyze tool
analyze:
@echo "Building analyze..."
@go build -o bin/analyze.exe ./cmd/analyze/

# Build status tool
status:
@echo "Building status..."
@go build -o bin/status.exe ./cmd/status/

# Clean build artifacts
clean:
@echo "Cleaning..."
@rm -f bin/analyze.exe bin/status.exe

# Install (copy to PATH)
install: build
@echo "Installing to $(USERPROFILE)/bin..."
@mkdir -p "$(USERPROFILE)/bin"
@cp bin/analyze.exe "$(USERPROFILE)/bin/"
@cp bin/status.exe "$(USERPROFILE)/bin/"

# Run tests
test:
@go test -v ./...

# Format code
fmt:
@go fmt ./...

# Vet code
vet:
@go vet ./...
Loading