Skip to content

Commit

Permalink
ProjectsUseXCConfigRule, TargetsUseXCConfigRule
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Jan 22, 2024
1 parent 7a5e565 commit 0222a54
Show file tree
Hide file tree
Showing 12 changed files with 862 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ opt_in_rules:
- embedded_build_setting # checks for build settings in the project file
- groups_sorted # checks that all group contents are alphabetically sorted
- implicit_dependencies # checks for any schemes that have "Find Implicit Dependencies" enabled
- targets_use_xcconfig # checks for any targets without a XCConfig file set
- projects_use_xcconfig # checks for any projects without a XCConfig file set

# Other rules make sense for all projects by default. You must opt-out of those.
disabled_rules:
Expand Down
25 changes: 25 additions & 0 deletions Sources/XCLinting/Rules/ProjectsUseXCConfigRule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// File.swift
//
//
// Created by Matthew Massicotte on 2024-01-22.
//

import Foundation

/// Detect projects that do not use XCConfigs.
struct ProjectsUseXCConfigRule {
func run(_ environment: XCLinter.Environment) throws -> [Violation] {
var violations = [Violation]()

for project in environment.project.pbxproj.projects {
for config in project.buildConfigurationList?.buildConfigurations ?? [] {
if config.baseConfiguration?.path == nil {
violations.append(.init("No xcconfig set for \(project.name), \(config.name)"))
}
}
}

return violations
}
}
22 changes: 22 additions & 0 deletions Sources/XCLinting/Rules/TargetsUseXCConfigRule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation

import XcodeProj
import XCConfig

/// Detect targets that do not use XCConfigs.
struct TargetsUseXCConfigRule {
func run(_ environment: XCLinter.Environment) throws -> [Violation] {
var violations = [Violation]()

// check targets
environment.project.pbxproj.enumerateBuildConfigurations { name, configList in
for config in configList.buildConfigurations {
if config.baseConfiguration?.path == nil {
violations.append(.init("No xcconfig set for \(name), \(config.name)"))
}
}
}

return violations
}
}
2 changes: 2 additions & 0 deletions Sources/XCLinting/XCLinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,7 @@ extension XCLinter {
"groups_sorted": groupsAreSortedRule,
"validate_build_settings": { try ValidateBuildSettingsRule().run($0) },
"implicit_dependencies": { try ImplicitDependenciesRule().run($0) },
"targets_use_xcconfig": { try TargetsUseXCConfigRule().run($0) },
"projects_use_xcconfig": { try ProjectsUseXCConfigRule().run($0) },
]
}
39 changes: 39 additions & 0 deletions Tests/XCLintTests/ProjectsUseXCConfigRuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import XCTest

@testable import XCLinting
import XcodeProj

final class ProjectsUseXCConfigRuleTests: XCTestCase {
func testProjectsWithoutXCConfigs() throws {
let url = try Bundle.module.testDataURL(named: "StockMacOSApp.xcodeproj")

let project = try XcodeProj(pathString: url.path)

let env = XCLinter.Environment(
project: project,
projectRootURL: url,
configuration: Configuration()
)

let violations = try ProjectsUseXCConfigRule().run(env)

XCTAssertFalse(violations.isEmpty)
}

func testProjectsWithOnlyXCConfigs() throws {
let url = try Bundle.module.testDataURL(named: "ProjectsUseXCConfigFiles.xcodeproj")

let project = try XcodeProj(pathString: url.path)

let env = XCLinter.Environment(
project: project,
projectRootURL: url,
configuration: Configuration()
)

let violations = try ProjectsUseXCConfigRule().run(env)

XCTAssertTrue(violations.isEmpty)
}
}

38 changes: 38 additions & 0 deletions Tests/XCLintTests/TargetsUseXCConfigRuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import XCTest

@testable import XCLinting
import XcodeProj

final class TargetsUseXCConfigRuleTests: XCTestCase {
func testTargetsWithoutXCConfigs() throws {
let url = try Bundle.module.testDataURL(named: "StockMacOSApp.xcodeproj")

let project = try XcodeProj(pathString: url.path)

let env = XCLinter.Environment(
project: project,
projectRootURL: url,
configuration: Configuration()
)

let violations = try TargetsUseXCConfigRule().run(env)

XCTAssertFalse(violations.isEmpty)
}

func testTargetsWithOnlyXCConfigs() throws {
let url = try Bundle.module.testDataURL(named: "TargetsUseXCConfigFiles.xcodeproj")

let project = try XcodeProj(pathString: url.path)

let env = XCLinter.Environment(
project: project,
projectRootURL: url,
configuration: Configuration()
)

let violations = try TargetsUseXCConfigRule().run(env)

XCTAssertTrue(violations.isEmpty)
}
}
Loading

0 comments on commit 0222a54

Please sign in to comment.