Skip to content

Commit

Permalink
Add option to output relative paths. Closes #638
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Nov 22, 2023
1 parent ffe85b3 commit df4568b
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

##### Enhancements

- None.
- Added the `--relative-results` option to output result paths relative to the current directory.

##### Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion Sources/Frontend/Commands/ScanBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ final class ScanBehavior {
results = try block(project)
let interval = logger.beginInterval("result:output")
let filteredResults = OutputDeclarationFilter().filter(results)
let output = try configuration.outputFormat.formatter.init().format(filteredResults)
let output = try configuration.outputFormat.formatter.init(configuration: configuration).format(filteredResults)
logger.info("", canQuiet: true)
logger.info(output, canQuiet: false)
logger.endInterval(interval)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Frontend/Commands/ScanCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ struct ScanCommand: FrontendCommand {
@Flag(help: "Skip the project build step")
var skipBuild: Bool = defaultConfiguration.$skipBuild.defaultValue

@Flag(help: "Output result paths relative to the current directory")
var relativeResults: Bool = defaultConfiguration.$relativeResults.defaultValue

@Flag(help: "Exit with non-zero status if any unused code is found")
var strict: Bool = defaultConfiguration.$strict.defaultValue

Expand Down Expand Up @@ -134,6 +137,7 @@ struct ScanCommand: FrontendCommand {
configuration.apply(\.$skipBuild, skipBuild)
configuration.apply(\.$cleanBuild, cleanBuild)
configuration.apply(\.$buildArguments, buildArguments)
configuration.apply(\.$relativeResults, relativeResults)

try scanBehavior.main { project in
try Scan().perform(project: project)
Expand Down
10 changes: 9 additions & 1 deletion Sources/PeripheryKit/Formatters/CheckstyleFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import Foundation
import Shared
import SystemPackage

final class CheckstyleFormatter: OutputFormatter {
let configuration: Configuration
lazy var currentFilePath: FilePath = { .current }()

init(configuration: Configuration) {
self.configuration = configuration
}

func format(_ results: [ScanResult]) -> String {
let parts = results.flatMap { describe($0, colored: false) }
let xml = [
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<checkstyle version=\"4.3\">",
parts
.group(by: { ($0.0.file.path.string).escapedForXML() })
.group(by: { outputPath($0.0).string.escapedForXML() })
.sorted(by: { $0.key < $1.key })
.map(generateForFile).joined(),
"\n</checkstyle>"
Expand Down
13 changes: 10 additions & 3 deletions Sources/PeripheryKit/Formatters/CodeClimateFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Foundation
import Shared
import SystemPackage

final class CodeClimateFormatter: OutputFormatter {

let configuration: Configuration
lazy var currentFilePath: FilePath = { .current }()

init(configuration: Configuration) {
self.configuration = configuration
}

func format(_ results: [PeripheryKit.ScanResult]) throws -> String {
var jsonObject: [Any] = []

Expand All @@ -11,7 +19,7 @@ final class CodeClimateFormatter: OutputFormatter {
]

let location: [AnyHashable: Any] = [
"path": result.declaration.location.file.path.url.relativePath,
"path": outputPath(result.declaration.location).url.relativePath,
"lines": lines
]

Expand Down Expand Up @@ -44,5 +52,4 @@ final class CodeClimateFormatter: OutputFormatter {
let json = String(data: data, encoding: .utf8)
return json ?? ""
}

}
11 changes: 10 additions & 1 deletion Sources/PeripheryKit/Formatters/CsvFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Foundation
import Shared
import SystemPackage

final class CsvFormatter: OutputFormatter {
let configuration: Configuration
lazy var currentFilePath: FilePath = { .current }()

init(configuration: Configuration) {
self.configuration = configuration
}

func format(_ results: [ScanResult]) -> String {
var lines: [String] = ["Kind,Name,Modifiers,Attributes,Accessibility,IDs,Location,Hints"]

Expand Down Expand Up @@ -55,6 +63,7 @@ final class CsvFormatter: OutputFormatter {
let joinedModifiers = attributes.joined(separator: "|")
let joinedAttributes = modifiers.joined(separator: "|")
let joinedUsrs = usrs.joined(separator: "|")
return "\(kind),\(name ?? ""),\(joinedModifiers),\(joinedAttributes),\(accessibility ?? ""),\(joinedUsrs),\(location),\(hint ?? "")"
let path = outputPath(location)
return "\(kind),\(name ?? ""),\(joinedModifiers),\(joinedAttributes),\(accessibility ?? ""),\(joinedUsrs),\(path),\(hint ?? "")"
}
}
12 changes: 10 additions & 2 deletions Sources/PeripheryKit/Formatters/JsonFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Foundation
import Shared
import SystemPackage

final class JsonFormatter: OutputFormatter {
let configuration: Configuration
lazy var currentFilePath: FilePath = { .current }()

init(configuration: Configuration) {
self.configuration = configuration
}

func format(_ results: [ScanResult]) throws -> String {
var jsonObject: [Any] = []

Expand All @@ -15,7 +23,7 @@ final class JsonFormatter: OutputFormatter {
"accessibility": result.declaration.accessibility.value.rawValue,
"ids": Array(result.declaration.usrs),
"hints": [describe(result.annotation)],
"location": result.declaration.location.description
"location": outputPath(result.declaration.location).string
]
jsonObject.append(object)

Expand All @@ -30,7 +38,7 @@ final class JsonFormatter: OutputFormatter {
"accessibility": "",
"ids": [ref.usr],
"hints": [redundantConformanceHint],
"location": ref.location.description
"location": outputPath(ref.location).string
]
jsonObject.append(object)
}
Expand Down
15 changes: 14 additions & 1 deletion Sources/PeripheryKit/Formatters/OutputFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import Foundation
import Shared
import SystemPackage

public protocol OutputFormatter: AnyObject {
init()
var configuration: Configuration { get }
var currentFilePath: FilePath { get }
init(configuration: Configuration)
func format(_ results: [ScanResult]) throws -> String
}

Expand Down Expand Up @@ -55,6 +58,16 @@ extension OutputFormatter {

return [(result.declaration.location, description)] + secondaryResults
}

func outputPath(_ location: SourceLocation) -> FilePath {
var path = location.file.path.lexicallyNormalized()

if configuration.relativeResults {
path = path.relativeTo(currentFilePath)
}

return path
}
}

public extension OutputFormat {
Expand Down
18 changes: 13 additions & 5 deletions Sources/PeripheryKit/Formatters/XcodeFormatter.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Foundation
import Shared
import SystemPackage

final class XcodeFormatter: OutputFormatter {
let configuration: Configuration
lazy var currentFilePath: FilePath = { .current }()

init(configuration: Configuration) {
self.configuration = configuration
}

func format(_ results: [ScanResult]) throws -> String {
guard results.count > 0 else {
return colorize("* ", .boldGreen) + colorize("No unused code detected.", .bold)
Expand All @@ -18,14 +26,14 @@ final class XcodeFormatter: OutputFormatter {
// MARK: - Private

private func prefix(for location: SourceLocation) -> String {
let absPath = location.file.path.lexicallyNormalized()
let path = absPath.removingLastComponent().string
let file = colorize(absPath.lastComponent?.stem ?? "", .bold)
let ext = absPath.extension ?? "swift"
let path = outputPath(location)
let dir = path.removingLastComponent()
let file = colorize(path.lastComponent?.stem ?? "", .bold)
let ext = path.extension ?? "swift"
let lineNum = colorize(String(location.line), .bold)
let column = location.column
let warning = colorize("warning:", .boldYellow)

return "\(path)/\(file).\(ext):\(lineNum):\(column): \(warning) "
return "\(dir)/\(file).\(ext):\(lineNum):\(column): \(warning) "
}
}
10 changes: 10 additions & 0 deletions Sources/Shared/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public final class Configuration {
@Setting(key: "clean_build", defaultValue: false)
public var cleanBuild: Bool

@Setting(key: "relative_results", defaultValue: false)
public var relativeResults: Bool

// Non user facing.
public var guidedSetup: Bool = false

Expand Down Expand Up @@ -209,6 +212,10 @@ public final class Configuration {
config[$buildArguments.key] = buildArguments
}

if $relativeResults.hasNonDefaultValue {
config[$relativeResults.key] = relativeResults
}

return try Yams.dump(object: config)
}

Expand Down Expand Up @@ -279,6 +286,8 @@ public final class Configuration {
$cleanBuild.assign(value)
case $buildArguments.key:
$buildArguments.assign(value)
case $relativeResults.key:
$relativeResults.assign(value)
default:
logger.warn("\(path.string): invalid key '\(key)'")
}
Expand Down Expand Up @@ -313,6 +322,7 @@ public final class Configuration {
$skipBuild.reset()
$cleanBuild.reset()
$buildArguments.reset()
$relativeResults.reset()
}

// MARK: - Helpers
Expand Down

0 comments on commit df4568b

Please sign in to comment.