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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

##### Enhancements

* None.
* New `strict` option to exit with non-zero status if any unused code is found.
[Cihat Gündüz](https://github.com/Dschee)\
[#22](https://github.com/peripheryapp/periphery/issues/22)\
[#23](https://github.com/peripheryapp/periphery/pull/23)

##### Bug Fixes

Expand Down
8 changes: 7 additions & 1 deletion Sources/PeripheryKit/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class Configuration: Singleton {
var aggressive: Bool = false
var updateCheck: Bool = true
var diagnosisConsole: Bool = false
var strict: Bool = false

// Non user facing.
var guidedSetup: Bool = false
Expand All @@ -53,7 +54,8 @@ public class Configuration: Singleton {
"quiet": quiet,
"aggressive": aggressive,
"disable_update_check": !updateCheck,
"diagnose": diagnosisConsole
"diagnose": diagnosisConsole,
"strict": strict
]

return try Yams.dump(object: config)
Expand Down Expand Up @@ -132,6 +134,10 @@ public class Configuration: Singleton {
if let value = yaml["disable_update_check"] as? Bool {
self.updateCheck = !value
}

if let value = yaml["strict"] as? Bool {
self.strict = value
}
}

// MARK: - Helpers
Expand Down
8 changes: 6 additions & 2 deletions Sources/PeripheryKit/Frontend/Commands/ScanBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,18 @@ class ScanBehavior {
"Periphery is a very precise tool, false positives often turn out to be correct after further investigation."
)
}

updateChecker.notifyIfAvailable()

if !filteredDeclarations.isEmpty && configuration.strict {
throw PeripheryKitError.foundIssues(count: filteredDeclarations.count)
}
} catch let error as PeripheryKitError {
return .failure(error)
} catch {
return .failure(.underlyingError(error))
}

updateChecker.notifyIfAvailable()

if configuration.diagnosisConsole, let graph = result.graph {
let console = DiagnosisConsole(graph: graph)
console.start()
Expand Down
18 changes: 14 additions & 4 deletions Sources/PeripheryKit/Frontend/Commands/ScanCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ public struct ScanCommand: CommandProtocol {
configuration.schemes = options.schemes
}

if options.strict.explicit {
configuration.strict = options.strict.value
}

do {
if let formatName = options.format {
configuration.outputFormat = try OutputFormat.make(named: formatName)
Expand Down Expand Up @@ -121,9 +125,10 @@ public struct ScanOptions: OptionsProtocol {
let disableUpdateCheck: BoolValue
let saveBuildLog: String?
let useBuildLog: String?
let strict: BoolValue

public static func create(_ config: String?) -> (_ workspace: String?) -> (_ project: String?) -> (_ schemes: String) -> (_ targets: String) -> (_ retainPublic: BoolValue) -> (_ retainObjcAnnotated: BoolValue) -> (_ retainUnusedProtocolFuncParams: BoolValue) -> (_ aggressive: BoolValue) -> (_ format: String?) -> (_ indexExclude: String?) -> (_ reportExclude: String?) -> (_ saveBuildLog: String?) -> (_ useBuildLog: String?) -> (_ diagnose: BoolValue) -> (_ verbose: BoolValue) -> (_ quiet: BoolValue) -> (_ disableUpdateCheck: BoolValue) -> ScanOptions {
return { workspace in { project in { schemes in { targets in { retainPublic in { retainObjcAnnotated in { retainUnusedProtocolFuncParams in { aggressive in { format in { indexExclude in { reportExclude in { saveBuildLog in { useBuildLog in { diagnose in { verbose in { quiet in { disableUpdateCheck in
public static func create(_ config: String?) -> (_ workspace: String?) -> (_ project: String?) -> (_ schemes: String) -> (_ targets: String) -> (_ retainPublic: BoolValue) -> (_ retainObjcAnnotated: BoolValue) -> (_ retainUnusedProtocolFuncParams: BoolValue) -> (_ aggressive: BoolValue) -> (_ format: String?) -> (_ indexExclude: String?) -> (_ reportExclude: String?) -> (_ saveBuildLog: String?) -> (_ useBuildLog: String?) -> (_ diagnose: BoolValue) -> (_ verbose: BoolValue) -> (_ quiet: BoolValue) -> (_ disableUpdateCheck: BoolValue) -> (_ strict: BoolValue) -> ScanOptions {
return { workspace in { project in { schemes in { targets in { retainPublic in { retainObjcAnnotated in { retainUnusedProtocolFuncParams in { aggressive in { format in { indexExclude in { reportExclude in { saveBuildLog in { useBuildLog in { diagnose in { verbose in { quiet in { disableUpdateCheck in { strict in
return self.init(config: config,
workspace: workspace,
project: project,
Expand All @@ -141,8 +146,9 @@ public struct ScanOptions: OptionsProtocol {
quiet: quiet,
disableUpdateCheck: disableUpdateCheck,
saveBuildLog: saveBuildLog,
useBuildLog: useBuildLog)
}}}}}}}}}}}}}}}}}
useBuildLog: useBuildLog,
strict: strict)
}}}}}}}}}}}}}}}}}}
}

public static func evaluate(_ mode: CommandMode) -> Result<ScanOptions, CommandantError<PeripheryKitError>> {
Expand Down Expand Up @@ -221,6 +227,10 @@ public struct ScanOptions: OptionsProtocol {
<*> mode <| Option(key: "disable-update-check",
defaultValue: BoolValue(!config.updateCheck),
usage: "Disable checking for updates")

<*> mode <| Option(key: "strict",
defaultValue: BoolValue(config.strict),
usage: "Exit with non-zero status if any unused code is found")
}

private static func parse(_ option: String?, _ delimiter: Character) -> [String] {
Expand Down
16 changes: 13 additions & 3 deletions Sources/PeripheryKit/Frontend/Commands/ScanSyntaxCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public struct ScanSyntaxCommand: CommandProtocol {
configuration.reportExclude = options.exclude
}

if options.strict.explicit {
configuration.strict = options.strict.value
}

do {
if let formatName = options.format {
configuration.outputFormat = try OutputFormat.make(named: formatName)
Expand All @@ -51,17 +55,19 @@ public struct ScanSyntaxOptions: OptionsProtocol {
let exclude: [String]
let verbose: BoolValue
let quiet: BoolValue
let strict: BoolValue
let path: String

public static func create(_ config: String?) -> (_ format: String?) -> (_ exclude: String?) -> (_ verbose: BoolValue) -> (_ quiet: BoolValue) -> (_ path: String) -> ScanSyntaxOptions {
return { format in { exclude in { verbose in { quiet in { path in
public static func create(_ config: String?) -> (_ format: String?) -> (_ exclude: String?) -> (_ verbose: BoolValue) -> (_ quiet: BoolValue) -> (_ strict: BoolValue) -> (_ path: String) -> ScanSyntaxOptions {
return { format in { exclude in { verbose in { quiet in { strict in { path in
return self.init(config: config,
format: format,
exclude: parse(exclude, "|"),
verbose: verbose,
quiet: quiet,
strict: strict,
path: path)
}}}}}
}}}}}}
}

public static func evaluate(_ m: CommandMode) -> Result<ScanSyntaxOptions, CommandantError<PeripheryKitError>> {
Expand Down Expand Up @@ -89,6 +95,10 @@ public struct ScanSyntaxOptions: OptionsProtocol {
defaultValue: BoolValue(config.quiet),
usage: "Only output results")

<*> m <| Option(key: "strict",
defaultValue: BoolValue(config.strict),
usage: "Exit with non-zero status if any unused code is found")

<*> m <| Argument(usage: "Path glob to scan")
}

Expand Down
3 changes: 3 additions & 0 deletions Sources/PeripheryKit/PeripheryKitError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum PeripheryKitError: Error, LocalizedError, CustomStringConvertible {
case buildLogError(message: String)
case xcodebuildNotConfigured
case pathDoesNotExist(path: String)
case foundIssues(count: Int)

public var errorDescription: String? {
switch self {
Expand Down Expand Up @@ -62,6 +63,8 @@ public enum PeripheryKitError: Error, LocalizedError, CustomStringConvertible {
return "Xcode is not configured for command-line use. Please run 'sudo xcode-select -s /Applications/Xcode.app'."
case .pathDoesNotExist(let path):
return "No such file or directory: \(path)."
case .foundIssues(let count):
return "Found \(count) \(count > 1 ? "issues" : "issue")."
}
}

Expand Down