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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ jobs:
$BINARY_PATH . --verbose --exclude-tests

echo "=== Testing JSON Output ==="
$BINARY_PATH . --json --no-color --exclude-tests > output.json
$BINARY_PATH . --output-format json --no-color --exclude-tests > output.json
cat output.json | python3 -m json.tool > /dev/null || (echo "❌ Invalid JSON output" && exit 1)
echo "✅ JSON output is valid"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ jobs:
$BINARY_PATH . --verbose --exclude-tests

echo "=== Testing JSON Output ==="
$BINARY_PATH . --json --no-color --exclude-tests > output.json
$BINARY_PATH . --output-format json --no-color --exclude-tests > output.json
cat output.json | python3 -m json.tool > /dev/null || (echo "❌ Invalid JSON output" && exit 1)
echo "✅ JSON output is valid"

Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- **CLI Interface Simplification**
- Removed redundant `--json` flag in favor of unified `--output-format json` option
- Consolidated output format selection into single `--output-format` parameter supporting `terminal`, `json`, `xcode`, and `github-actions`
- Renamed `default` output format to `terminal` for better clarity and descriptiveness
- Simplified CLI interface with consistent format selection pattern

### Added
- **Multi-Platform Binary Target Distribution**
- Cross-platform artifact bundles for Swift Package Manager with pre-compiled binaries
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ swift run swift-dependency-audit /path/to/package
swift run swift-dependency-audit --whitelist "Foundation,SwiftUI,AppKit,UIKit"

# Options
swift run swift-dependency-audit --no-color --verbose --json
swift run swift-dependency-audit --no-color --verbose --output-format json
swift run swift-dependency-audit --target MyTarget --exclude-tests
```

Expand All @@ -136,7 +136,7 @@ All core features have been implemented and tested:
```bash
swift run swift-dependency-audit --help
swift run swift-dependency-audit /path/to/package
swift run swift-dependency-audit --verbose --json
swift run swift-dependency-audit --verbose --output-format json
swift run swift-dependency-audit --whitelist "Foundation,SwiftUI,AppKit"
```

Expand Down
3 changes: 1 addition & 2 deletions PROJECT_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ OPTIONS:
--verbose, -v Enable verbose output
--target <name> Analyze specific target only
--exclude-tests Skip test targets
--json Output results in JSON format
--quiet, -q Only show problems, suppress success messages
--whitelist <list> Comma-separated list of system imports to ignore (e.g., Foundation,SwiftUI,AppKit)
--output-format <format> Output format: default, xcode, or github-actions (default: default)
--output-format <format> Output format: terminal, JSON, xcode, or github-actions (default: terminal)
--help, -h Show help information
--version Show version
```
Expand Down
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,21 @@ swift run swift-dependency-audit /path/to/package
### Command Line Options

```
USAGE: swift-dependency-audit [<path>] [--no-color] [--verbose] [--target <target>] [--exclude-tests] [--json] [--quiet] [--whitelist <whitelist>] [--output-format <output-format>]
USAGE: swift-dependency-audit [<path>] [--no-color] [--verbose] [--target <target>] [--exclude-tests] [--quiet] [--whitelist <whitelist>] [--output-format <output-format>]

ARGUMENTS:
<path> Path to Package.swift or package directory (default: current directory)
<path> Path to Package.swift or package directory (default: current directory)

OPTIONS:
--no-color Disable colored output
-v, --verbose Enable verbose output
--target <target> Analyze specific target only
--exclude-tests Skip test targets
--json Output results in JSON format
-q, --quiet Only show problems, suppress success messages
--whitelist <whitelist> Comma-separated list of system imports to ignore
(e.g., Foundation,SwiftUI,AppKit)
--output-format <format> Output format: default, xcode, or github-actions
(default: default)
--version Show the version.
-h, --help Show help information.
--no-color Disable colored output
-v, --verbose Enable verbose output
--target <target> Analyze specific target only
--exclude-tests Skip test targets
-q, --quiet Only show problems, suppress success messages
--whitelist <whitelist> Comma-separated list of system imports to ignore (e.g., Foundation,SwiftUI,AppKit)
--output-format <format> Output format: terminal, json, xcode, or github-actions (default: terminal)
--version Show the version.
-h, --help Show help information.
```

### Examples
Expand All @@ -72,7 +69,7 @@ OPTIONS:
swift run swift-dependency-audit --verbose --whitelist "Foundation,SwiftUI,AppKit,UIKit"

# JSON output for CI/automation
swift run swift-dependency-audit --json --no-color
swift run swift-dependency-audit --output-format json --no-color

# Analyze only a specific target
swift run swift-dependency-audit --target MyLibrary
Expand Down
50 changes: 24 additions & 26 deletions Sources/SwiftDependencyAudit/DependentImportScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ private func getGitVersion() -> String? {
}

public enum OutputFormat: String, CaseIterable, ExpressibleByArgument {
case `default` = "default"
case terminal = "terminal"
case json = "json"
case xcode = "xcode"
case githubActions = "github-actions"
}
Expand Down Expand Up @@ -84,8 +85,6 @@ public struct SwiftDependencyAudit: AsyncParsableCommand {
@Flag(name: .long, help: "Skip test targets")
public var excludeTests = false

@Flag(name: .long, help: "Output results in JSON format")
public var json = false

@Flag(name: [.short, .long], help: "Only show problems, suppress success messages")
public var quiet = false
Expand All @@ -97,8 +96,8 @@ public struct SwiftDependencyAudit: AsyncParsableCommand {

@Option(
name: .long,
help: "Output format: default, xcode, or github-actions")
public var outputFormat: OutputFormat = .default
help: "Output format: terminal, json, xcode, or github-actions")
public var outputFormat: OutputFormat = .terminal

public func run() async throws {
// Configure color output
Expand All @@ -114,15 +113,15 @@ public struct SwiftDependencyAudit: AsyncParsableCommand {
let analyzer = DependencyAnalyzer()
let processor = ParallelProcessor()

if verbose && !json {
if verbose && outputFormat != .json {
let message = ColorOutput.info("Parsing package at: \(path)")
print(message)
}

// Parse package
let packageInfo = try await parser.parsePackage(at: path)

if verbose && !json {
if verbose && outputFormat != .json {
let message = ColorOutput.info(
"Found \(packageInfo.targets.count) target(s) in package '\(packageInfo.name)'")
print(message)
Expand All @@ -144,7 +143,7 @@ public struct SwiftDependencyAudit: AsyncParsableCommand {
targetsToAnalyze = targetsToAnalyze.filter { $0.type != .test }
}

if verbose && !json {
if verbose && outputFormat != .json {
let message = ColorOutput.info(
"Analyzing \(targetsToAnalyze.count) target(s)")
print(message)
Expand All @@ -156,26 +155,25 @@ public struct SwiftDependencyAudit: AsyncParsableCommand {
customWhitelist: customWhitelist)

// Generate and output report
if json {
let jsonReport = try await analyzer.generateJSONReport(
let report: String
switch outputFormat {
case .terminal:
report = await analyzer.generateReport(
for: results, packageName: packageInfo.name, verbose: verbose, quiet: quiet)
case .json:
report = try await analyzer.generateJSONReport(
for: results, packageName: packageInfo.name, quiet: quiet)
print(jsonReport)
} else {
let report: String
switch outputFormat {
case .default:
report = await analyzer.generateReport(
for: results, packageName: packageInfo.name, verbose: verbose, quiet: quiet)
case .xcode:
report = await analyzer.generateXcodeReport(
for: results, packagePath: path)
case .githubActions:
report = await analyzer.generateGitHubActionsReport(
for: results, packagePath: path)
}
print(report)
case .xcode:
report = await analyzer.generateXcodeReport(
for: results, packagePath: path)
case .githubActions:
report = await analyzer.generateGitHubActionsReport(
for: results, packagePath: path)
}
print(report)

// Exit with error code if issues found
// Exit with error code if issues found (except for JSON format)
if outputFormat != .json {
let hasIssues = results.contains { $0.hasIssues }
if hasIssues {
throw ExitCode.failure
Expand Down