Files
XcodeGen/Sources/ProjectSpec/SpecValidation.swift
T
Keith Smiley b6ef82b3df Add new option for disabling validations
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.
2018-01-05 11:41:33 -08:00

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)
}
}
}