import groovy.json.JsonSlurper plugins { id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } rootProject.name = 'ca-skeleton' File repositoryRoot = settingsDir.parentFile.canonicalFile File moduleRegistryFile = new File(settingsDir, 'config/architecture/modules.json') if (!moduleRegistryFile.isFile()) { throw new GradleException("Missing module registry: ${moduleRegistryFile}") } def moduleRegistry = new JsonSlurper().parse(moduleRegistryFile) if (!(moduleRegistry instanceof Map)) { throw new GradleException("Module registry root must be a JSON object: ${moduleRegistryFile}") } if (!(moduleRegistry.modules instanceof List) || moduleRegistry.modules.isEmpty()) { throw new GradleException("Module registry has no modules: ${moduleRegistryFile}") } int expectedModuleCount = 19 if (moduleRegistry.modules.size() != expectedModuleCount) { throw new GradleException( "Module registry must contain exactly ${expectedModuleCount} modules, " + "but found ${moduleRegistry.modules.size()}: ${moduleRegistryFile}") } Set moduleIds = new LinkedHashSet<>() Set gradlePaths = new LinkedHashSet<>() Set sourceDirectoryPaths = new LinkedHashSet<>() String repositoryRootPrefix = repositoryRoot.path + File.separator List> validatedModules = moduleRegistry.modules.withIndex().collect { rawModule, index -> if (!(rawModule instanceof Map)) { throw new GradleException("Module registry entry ${index} must be a JSON object.") } Map module = rawModule as Map ['id', 'gradle_path', 'source_path'].each { field -> if (!(module[field] instanceof String) || (module[field] as String).isBlank()) { throw new GradleException( "Module registry entry ${index} needs a nonblank string '${field}'.") } } if (!(module.allowed_dependencies instanceof List)) { throw new GradleException( "Module registry entry '${module.id}' needs an 'allowed_dependencies' list.") } String id = module.id as String String gradlePath = module.gradle_path as String String sourcePath = module.source_path as String List allowedDependencies = module.allowed_dependencies.withIndex().collect { dependencyId, dependencyIndex -> if (!(dependencyId instanceof String) || (dependencyId as String).isBlank()) { throw new GradleException( "Module registry entry '${id}' has a non-string or blank allowed dependency " + "at index ${dependencyIndex}.") } dependencyId as String } if (!moduleIds.add(id)) { throw new GradleException("Module registry contains duplicate module id '${id}'.") } if (!gradlePath.startsWith(':')) { throw new GradleException( "Module registry entry '${id}' has Gradle path '${gradlePath}' that does not start with ':'.") } if (!gradlePaths.add(gradlePath)) { throw new GradleException("Module registry contains duplicate Gradle path '${gradlePath}'.") } if (new File(sourcePath).isAbsolute()) { throw new GradleException( "Module registry entry '${id}' source path must be repository-root-relative: '${sourcePath}'.") } File sourceDirectory = new File(repositoryRoot, sourcePath).canonicalFile if (!sourceDirectory.path.startsWith(repositoryRootPrefix)) { throw new GradleException( "Module registry entry '${id}' source path escapes the repository root: '${sourcePath}'.") } if (!sourceDirectory.isDirectory()) { throw new GradleException( "Module registry entry '${id}' source path is not an existing directory: ${sourceDirectory}") } if (!sourceDirectoryPaths.add(sourceDirectory.path)) { throw new GradleException( "Module registry entry '${id}' resolves to duplicate or aliased canonical source directory: " + "${sourceDirectory}") } [ id : id, gradle_path : gradlePath, source_directory : sourceDirectory, allowed_dependencies: allowedDependencies ] } validatedModules.each { module -> module.allowed_dependencies.each { dependencyId -> if (dependencyId == module.id) { throw new GradleException( "Module registry entry '${module.id}' must not depend on itself.") } if (module.id != 'sample-portfolio' && dependencyId == 'sample-portfolio') { throw new GradleException( "Production module registry entry '${module.id}' must not allow a dependency on " + "'sample-portfolio'.") } if (!moduleIds.contains(dependencyId)) { throw new GradleException( "Module registry entry '${module.id}' references unknown allowed dependency id " + "'${dependencyId}'.") } } } validatedModules.each { module -> include module.gradle_path project(module.gradle_path).projectDir = module.source_directory }