mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
b6ef82b3df
This gives us an entry point for disabling specific project.yml validations that sometimes shouldn't apply. The first example is missingConfigs, which, if you use your .yml file in multiple projects, can be too strict if the projects have different top level configurations.
153 lines
6.3 KiB
Swift
153 lines
6.3 KiB
Swift
import Foundation
|
|
import PathKit
|
|
|
|
extension ProjectSpec {
|
|
|
|
public enum ValidationType: String {
|
|
case missingConfigs
|
|
}
|
|
|
|
public func validate() throws {
|
|
|
|
var errors: [SpecValidationError.ValidationError] = []
|
|
|
|
func validateSettings(_ settings: Settings) -> [SpecValidationError.ValidationError] {
|
|
var errors: [SpecValidationError.ValidationError] = []
|
|
for group in settings.groups {
|
|
if let settings = settingGroups[group] {
|
|
errors += validateSettings(settings)
|
|
} else {
|
|
errors.append(.invalidSettingsGroup(group))
|
|
}
|
|
}
|
|
for config in settings.configSettings.keys {
|
|
if !configs.contains(where: { $0.name.lowercased().contains(config.lowercased()) }) {
|
|
if !options.disabledValidations.contains(.missingConfigs) {
|
|
errors.append(.invalidBuildSettingConfig(config))
|
|
}
|
|
}
|
|
}
|
|
return errors
|
|
}
|
|
|
|
errors += validateSettings(settings)
|
|
|
|
for fileGroup in fileGroups {
|
|
if !(basePath + fileGroup).exists {
|
|
errors.append(.invalidFileGroup(fileGroup))
|
|
}
|
|
}
|
|
|
|
for (config, configFile) in configFiles {
|
|
if !(basePath + configFile).exists {
|
|
errors.append(.invalidConfigFile(configFile: configFile, config: config))
|
|
}
|
|
if !options.disabledValidations.contains(.missingConfigs) && getConfig(config) == nil {
|
|
errors.append(.invalidConfigFileConfig(config))
|
|
}
|
|
}
|
|
|
|
for settings in settingGroups.values {
|
|
errors += validateSettings(settings)
|
|
}
|
|
|
|
for target in targets {
|
|
for dependency in target.dependencies {
|
|
if dependency.type == .target, getTarget(dependency.reference) == nil {
|
|
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
|
|
}
|
|
}
|
|
|
|
for (config, configFile) in target.configFiles {
|
|
if !(basePath + configFile).exists {
|
|
errors.append(.invalidTargetConfigFile(target: target.name, configFile: configFile, config: config))
|
|
}
|
|
if !options.disabledValidations.contains(.missingConfigs) && getConfig(config) == nil {
|
|
errors.append(.invalidConfigFileConfig(config))
|
|
}
|
|
}
|
|
|
|
for source in target.sources {
|
|
let sourcePath = basePath + source.path
|
|
if !source.optional && !sourcePath.exists {
|
|
errors.append(.invalidTargetSource(target: target.name, source: sourcePath.string))
|
|
}
|
|
}
|
|
|
|
if let scheme = target.scheme {
|
|
|
|
for configVariant in scheme.configVariants {
|
|
if !configs.contains(where: { $0.name.contains(configVariant) && $0.type == .debug }) {
|
|
errors.append(.invalidTargetSchemeConfigVariant(
|
|
target: target.name,
|
|
configVariant: configVariant,
|
|
configType: .debug
|
|
))
|
|
}
|
|
if !configs.contains(where: { $0.name.contains(configVariant) && $0.type == .release }) {
|
|
errors.append(.invalidTargetSchemeConfigVariant(
|
|
target: target.name,
|
|
configVariant: configVariant,
|
|
configType: .release
|
|
))
|
|
}
|
|
}
|
|
|
|
if scheme.configVariants.isEmpty {
|
|
if !configs.contains(where: { $0.type == .debug }) {
|
|
errors.append(.missingConfigForTargetScheme(target: target.name, configType: .debug))
|
|
}
|
|
if !configs.contains(where: { $0.type == .release }) {
|
|
errors.append(.missingConfigForTargetScheme(target: target.name, configType: .release))
|
|
}
|
|
}
|
|
|
|
for testTarget in scheme.testTargets {
|
|
if getTarget(testTarget) == nil {
|
|
errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget))
|
|
}
|
|
}
|
|
}
|
|
|
|
let scripts = target.prebuildScripts + target.postbuildScripts
|
|
for script in scripts {
|
|
if case let .path(pathString) = script.script {
|
|
let scriptPath = basePath + pathString
|
|
if !scriptPath.exists {
|
|
errors.append(.invalidBuildScriptPath(target: target.name, name: script.name, path: pathString))
|
|
}
|
|
}
|
|
}
|
|
|
|
errors += validateSettings(target.settings)
|
|
}
|
|
|
|
for scheme in schemes {
|
|
for buildTarget in scheme.build.targets {
|
|
if getTarget(buildTarget.target) == nil {
|
|
errors.append(.invalidSchemeTarget(scheme: scheme.name, target: buildTarget.target))
|
|
}
|
|
}
|
|
if let buildAction = scheme.run, getConfig(buildAction.config) == nil {
|
|
errors.append(.invalidSchemeConfig(scheme: scheme.name, config: buildAction.config))
|
|
}
|
|
if let buildAction = scheme.test, getConfig(buildAction.config) == nil {
|
|
errors.append(.invalidSchemeConfig(scheme: scheme.name, config: buildAction.config))
|
|
}
|
|
if let buildAction = scheme.profile, getConfig(buildAction.config) == nil {
|
|
errors.append(.invalidSchemeConfig(scheme: scheme.name, config: buildAction.config))
|
|
}
|
|
if let buildAction = scheme.analyze, getConfig(buildAction.config) == nil {
|
|
errors.append(.invalidSchemeConfig(scheme: scheme.name, config: buildAction.config))
|
|
}
|
|
if let buildAction = scheme.archive, getConfig(buildAction.config) == nil {
|
|
errors.append(.invalidSchemeConfig(scheme: scheme.name, config: buildAction.config))
|
|
}
|
|
}
|
|
|
|
if !errors.isEmpty {
|
|
throw SpecValidationError(errors: errors)
|
|
}
|
|
}
|
|
}
|