Skip to content

Commit

Permalink
Support excluding all file types from indexing. Closes #373
Browse files Browse the repository at this point in the history
  • Loading branch information
ileitch committed Jul 23, 2021
1 parent a523e66 commit 16b0a31
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 55 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
##### Enhancements

- SwiftUI @(UI/NS)ApplicationDelegateAdaptor wrapped properties and now retained.
- All file types can now be excluded from indexing.

##### Bug Fixes

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,15 +395,15 @@ You're ready to roll. You should now see the new scheme in the dropdown. Select

## Excluding Files

Both exclusion options described below accept a path glob, either absolute or relative to your project directory. You may specify multiple globs by separating them with a pipe character, e.g `"Foo.swift|{Bar,Baz}.swift|path/to/*.swift"`. Recursive (`**`) globs are not supported at this time.
Both exclusion options described below accept a Bash v4 style path glob, either absolute or relative to your project directory. You may specify multiple globs by separating them with a pipe character, e.g `"Sources/Single.swift|**/Generated/*.swift|**/*.{xib,storyboard}"`.

### Excluding Results

To exclude the results from certain files, pass the `--report-exclude <globs>` option to the `scan` command.

### Excluding Indexed Files

To exclude files from being indexed, pass the `--index-exclude <glob>` option to the `scan` command. Excluding files from the index phase means that any declarations and references contained within the files will not be seen by Periphery. Periphery will be behave as if the files do not exist. This option can be used to exclude generated code that holds references to non-generated code.
To exclude files from being indexed, pass the `--index-exclude <globs>` option to the `scan` command. Excluding files from the index phase means that any declarations and references contained within the files will not be seen by Periphery. Periphery will be behave as if the files do not exist. For example, this option can be used to exclude generated code that holds references to non-generated code, or exclude all `.xib` and `.storyboard` files that hold references to code.

## Continuous Integration

Expand Down
15 changes: 15 additions & 0 deletions Sources/PeripheryKit/Indexer/IndexExcludable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation
import SystemPackage
import Shared

protocol IndexExcludable {
var configuration: Configuration { get }
func filterIndexExcluded(from files: Set<FilePath>) -> (included: Set<FilePath>, excluded: Set<FilePath>)
}

extension IndexExcludable {
func filterIndexExcluded(from files: Set<FilePath>) -> (included: Set<FilePath>, excluded: Set<FilePath>) {
let included = files.filter { !configuration.indexExcludeSourceFiles.contains($0) }
return (included, files.subtracting(included))
}
}
23 changes: 16 additions & 7 deletions Sources/PeripheryKit/Indexer/InfoPlistIndexer.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import Shared
import SystemPackage

public final class InfoPlistIndexer {
public final class InfoPlistIndexer: IndexExcludable {
public static func make(infoPlistFiles: Set<FilePath>, graph: SourceGraph) -> Self {
return self.init(infoPlistFiles: infoPlistFiles,
graph: graph,
logger: inject())
return self.init(
infoPlistFiles: infoPlistFiles,
graph: graph,
logger: inject(),
configuration: inject()
)
}

private let infoPlistFiles: Set<FilePath>
private let graph: SourceGraph
private let logger: Logger

required init(infoPlistFiles: Set<FilePath>, graph: SourceGraph, logger: Logger) {
let configuration: Configuration

required init(infoPlistFiles: Set<FilePath>, graph: SourceGraph, logger: Logger, configuration: Configuration) {
self.infoPlistFiles = infoPlistFiles
self.graph = graph
self.logger = logger
self.configuration = configuration
}

public func perform() throws {
try JobPool(jobs: Array(infoPlistFiles)).forEach { [weak self] path in
let (includedFiles, excludedFiles) = filterIndexExcluded(from: infoPlistFiles)
excludedFiles.forEach { self.logger.debug("[index:infoplist] Excluding \($0.string)") }

try JobPool(jobs: Array(includedFiles)).forEach { [weak self] path in
guard let self = self else { return }

let elapsed = try Benchmark.measure {
Expand All @@ -28,7 +37,7 @@ public final class InfoPlistIndexer {
.forEach { self.graph.add($0) }
}

self.logger.debug("[index:infoplist] \(path.string) (\(elapsed))s")
self.logger.debug("[index:infoplist] \(path.string) (\(elapsed)s)")
}
}
}
23 changes: 16 additions & 7 deletions Sources/PeripheryKit/Indexer/XCDataModelIndexer.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import Shared
import SystemPackage

public final class XCDataModelIndexer {
public final class XCDataModelIndexer: IndexExcludable {
public static func make(files: Set<FilePath>, graph: SourceGraph) -> Self {
return self.init(files: files,
graph: graph,
logger: inject())
return self.init(
files: files,
graph: graph,
logger: inject(),
configuration: inject()
)
}

private let files: Set<FilePath>
private let graph: SourceGraph
private let logger: Logger

required init(files: Set<FilePath>, graph: SourceGraph, logger: Logger) {
let configuration: Configuration

required init(files: Set<FilePath>, graph: SourceGraph, logger: Logger, configuration: Configuration) {
self.files = files
self.graph = graph
self.logger = logger
self.configuration = configuration
}

public func perform() throws {
try JobPool(jobs: Array(files)).forEach { [weak self] path in
let (includedFiles, excludedFiles) = filterIndexExcluded(from: files)
excludedFiles.forEach { self.logger.debug("[index:xcdatamodel] Excluding \($0.string)") }

try JobPool(jobs: Array(includedFiles)).forEach { [weak self] path in
guard let self = self else { return }

let elapsed = try Benchmark.measure {
Expand All @@ -28,7 +37,7 @@ public final class XCDataModelIndexer {
.forEach { self.graph.add($0) }
}

self.logger.debug("[index:xcdatamodel] \(path.string) (\(elapsed))s")
self.logger.debug("[index:xcdatamodel] \(path.string) (\(elapsed)s)")
}
}
}
23 changes: 16 additions & 7 deletions Sources/PeripheryKit/Indexer/XCMappingModelIndexer.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import Shared
import SystemPackage

public final class XCMappingModelIndexer {
public final class XCMappingModelIndexer: IndexExcludable {
public static func make(files: Set<FilePath>, graph: SourceGraph) -> Self {
return self.init(files: files,
graph: graph,
logger: inject())
return self.init(
files: files,
graph: graph,
logger: inject(),
configuration: inject()
)
}

private let files: Set<FilePath>
private let graph: SourceGraph
private let logger: Logger

required init(files: Set<FilePath>, graph: SourceGraph, logger: Logger) {
let configuration: Configuration

required init(files: Set<FilePath>, graph: SourceGraph, logger: Logger, configuration: Configuration) {
self.files = files
self.graph = graph
self.logger = logger
self.configuration = configuration
}

public func perform() throws {
try JobPool(jobs: Array(files)).forEach { [weak self] path in
let (includedFiles, excludedFiles) = filterIndexExcluded(from: files)
excludedFiles.forEach { self.logger.debug("[index:xcmappingmodel] Excluding \($0.string)") }

try JobPool(jobs: Array(includedFiles)).forEach { [weak self] path in
guard let self = self else { return }

let elapsed = try Benchmark.measure {
Expand All @@ -28,7 +37,7 @@ public final class XCMappingModelIndexer {
.forEach { self.graph.add($0) }
}

self.logger.debug("[index:xcmappingmodel] \(path.string) (\(elapsed))s")
self.logger.debug("[index:xcmappingmodel] \(path.string) (\(elapsed)s)")
}
}
}
23 changes: 16 additions & 7 deletions Sources/PeripheryKit/Indexer/XibIndexer.swift
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import Shared
import SystemPackage

public final class XibIndexer {
public final class XibIndexer: IndexExcludable {
public static func make(xibFiles: Set<FilePath>, graph: SourceGraph) -> Self {
return self.init(xibFiles: xibFiles,
graph: graph,
logger: inject())
return self.init(
xibFiles: xibFiles,
graph: graph,
logger: inject(),
configuration: inject()
)
}

private let xibFiles: Set<FilePath>
private let graph: SourceGraph
private let logger: Logger

required init(xibFiles: Set<FilePath>, graph: SourceGraph, logger: Logger) {
let configuration: Configuration

required init(xibFiles: Set<FilePath>, graph: SourceGraph, logger: Logger, configuration: Configuration) {
self.xibFiles = xibFiles
self.graph = graph
self.logger = logger
self.configuration = configuration
}

public func perform() throws {
try JobPool(jobs: Array(xibFiles)).forEach { [weak self] xibPath in
let (includedFiles, excludedFiles) = filterIndexExcluded(from: xibFiles)
excludedFiles.forEach { self.logger.debug("[index:xib] Excluding \($0.string)") }

try JobPool(jobs: Array(includedFiles)).forEach { [weak self] xibPath in
guard let self = self else { return }

let elapsed = try Benchmark.measure {
Expand All @@ -28,7 +37,7 @@ public final class XibIndexer {
.forEach { self.graph.add($0) }
}

self.logger.debug("[index:xib] \(xibPath.string) (\(elapsed))s")
self.logger.debug("[index:xib] \(xibPath.string) (\(elapsed)s)")
}
}
}
10 changes: 10 additions & 0 deletions Sources/Shared/Extensions/FilePath+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ public extension FilePath {
Self(fileManagager.currentDirectoryPath)
}

static func makeAbsolute(_ path: String, relativeTo relativePath: FilePath = .current) -> FilePath {
var filePath = FilePath(path)

if filePath.isRelative {
filePath = relativePath.appending(path)
}

return filePath
}

var exists: Bool {
fileManager.fileExists(atPath: lexicallyNormalized().string)
}
Expand Down
4 changes: 0 additions & 4 deletions Sources/XcodeSupport/XcodeProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ final class XcodeProject: XcodeProjectlike {
return try make(path: path)
}

static func make(path: String) throws -> XcodeProject {
return try make(path: FilePath(path))
}

static func make(path: FilePath) throws -> XcodeProject {
if let cached = cache[path] {
return cached
Expand Down
4 changes: 2 additions & 2 deletions Sources/XcodeSupport/XcodeProjectDriver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public final class XcodeProjectDriver {
let project: XcodeProjectlike

if let workspacePath = configuration.workspace {
project = try XcodeWorkspace.make(path: workspacePath)
project = try XcodeWorkspace.make(path: .makeAbsolute(workspacePath))
} else if let projectPath = configuration.project {
project = try XcodeProject.make(path: projectPath)
project = try XcodeProject.make(path: .makeAbsolute(projectPath))
} else {
throw PeripheryError.usageError("Expected --workspace or --project option.")
}
Expand Down
34 changes: 18 additions & 16 deletions Sources/XcodeSupport/XcodeProjectSetupGuide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,23 @@ public final class XcodeProjectSetupGuide: SetupGuideHelpers, ProjectSetupGuide
.filter { !podSchemes.contains($0.name) }
}

private func identifyWorkspace() -> String? {
var workspace: String?
private func identifyWorkspace() -> FilePath? {
var workspacePath: FilePath?
let paths = workspacePaths()

if paths.count > 1 {
print(colorize("Found multiple workspaces, please select the one that defines the schemes for building your project:", .bold))
let workspaces = paths.map { $0.relativeTo(FilePath.current).string }
workspace = select(single: workspaces)
let workspaces = paths.map { $0.relativeTo(.current).string }
let workspace = select(single: workspaces)
workspacePath = FilePath.makeAbsolute(workspace)
print("")
} else {
workspace = paths.last?.string.trimmed
workspacePath = paths.first
}

if let workspace = workspace {
configuration.workspace = workspace
return workspace
if let workspacePath = workspacePath {
configuration.workspace = workspacePath.relativeTo(.current).string
return workspacePath
}

return nil
Expand All @@ -123,22 +124,23 @@ public final class XcodeProjectSetupGuide: SetupGuideHelpers, ProjectSetupGuide
}
}

private func identifyProject() -> String? {
var project: String?
private func identifyProject() -> FilePath? {
var projectPath: FilePath?
let paths = projectPaths()

if paths.count > 1 {
print(colorize("Found multiple projects, please select the one that defines the schemes for building your project:", .bold))
let projects = paths.map { $0.relativeTo(FilePath.current).string }.sorted()
project = select(single: projects)
let projects = paths.map { $0.relativeTo(.current).string }.sorted()
let project = select(single: projects)
projectPath = FilePath.makeAbsolute(project)
print("")
} else {
project = paths.first?.string.trimmed
projectPath = paths.first
}

if let project = project {
configuration.project = project
return project
if let projectPath = projectPath {
configuration.project = projectPath.relativeTo(.current).string
return projectPath
}

return nil
Expand Down
6 changes: 3 additions & 3 deletions Sources/XcodeSupport/XcodeWorkspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PeripheryKit
import Shared

final class XcodeWorkspace: XcodeProjectlike {
static func make(path: String) throws -> Self {
static func make(path: FilePath) throws -> Self {
return try self.init(path: path,
xcodebuild: inject(),
configuration: inject(),
Expand All @@ -22,10 +22,10 @@ final class XcodeWorkspace: XcodeProjectlike {

private(set) var targets: Set<XcodeTarget> = []

required init(path: String, xcodebuild: Xcodebuild, configuration: Configuration, logger: Logger) throws {
required init(path: FilePath, xcodebuild: Xcodebuild, configuration: Configuration, logger: Logger) throws {
logger.debug("[xcode:workspace] Loading \(path)")

self.path = FilePath(path)
self.path = path
self.xcodebuild = xcodebuild
self.configuration = configuration
self.sourceRoot = self.path.removingLastComponent()
Expand Down

0 comments on commit 16b0a31

Please sign in to comment.