-
-
Save claudiouzelac/6cf4cf053c6d3b201be5f3b6460d0642 to your computer and use it in GitHub Desktop.
Bazel workspace generation script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
plugins { | |
id "com.github.ben-manes.versions" version "0.15.0" | |
id "io.spring.dependency-management" version "1.0.3.RELEASE" | |
} | |
apply plugin: 'base' | |
group = 'com.example' | |
version = '0.0.0' | |
description = """ | |
Dependency management and generation of java dependency configuration for Bazel project. | |
""" | |
repositories { | |
jcenter() | |
} | |
configurations { | |
generate | |
} | |
ext['awaitility.version'] = '3.0.0' | |
ext['cucumber-jvm.version'] = '1.2.5' | |
ext['guava.version'] = '23.0' | |
ext['jfairy.version'] = '0.5.7' | |
ext['jool.version'] = '0.9.12' | |
ext['log4j2.version'] = '2.8.1' | |
ext['okhttp3.version'] = '3.8.1' | |
ext['postgresql.version'] = '42.1.4' | |
ext['selenium.version'] = '3.5.2' | |
ext['spring-boot.version'] = '1.5.6.RELEASE' | |
ext['spring-boot-admin-server.version'] = '1.5.3' | |
ext['spring-cloud.version'] = 'Dalston.SR3' | |
ext['testcontainers.version'] = '1.4.2' | |
ext['truth.version'] = '0.35' | |
dependencyManagement { | |
imports { | |
mavenBom 'org.springframework.boot:spring-boot-dependencies:' + ext['spring-boot.version'] | |
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:' + ext['spring-cloud.version'] | |
} | |
dependencies { | |
dependency group: 'com.codeborne', name: 'phantomjsdriver', version: '1.4.3' | |
dependency group: 'com.google.guava', name: 'guava', version: ext['guava.version'] | |
dependency group: 'com.google.truth', name: 'truth', version: ext['truth.version'] | |
dependencySet(group: 'com.squareup.okhttp3', version: ext['okhttp3.version']) { | |
entry 'logging-interceptor' | |
entry 'mockwebserver' | |
entry 'okhttp' | |
} | |
dependencySet(group: 'de.codecentric', version: ext['spring-boot-admin-server.version']) { | |
entry('spring-boot-admin-server') { | |
exclude group: 'ch.qos.logback', name: 'logback-classic' | |
exclude group: 'ch.qos.logback', name: 'logback-core' | |
exclude group: 'org.slf4j', name: 'log4j-over-slf4j' | |
} | |
entry 'spring-boot-admin-server-ui' | |
entry 'spring-boot-admin-starter-client' | |
} | |
dependencySet(group: 'info.cukes', version: '1.2.5') { | |
entry 'cucumber-java8' | |
entry 'cucumber-junit' | |
entry 'cucumber-picocontainer' | |
} | |
dependency group: 'io.codearte.jfairy', name: 'jfairy', version: ext['jfairy.version'] | |
dependency group: 'org.awaitility', name: 'awaitility', version: ext['awaitility.version'] | |
dependency group: 'org.jooq', name: 'jool', version: ext['jool.version'] | |
dependencySet(group: 'org.springframework.boot', version: ext['spring-boot.version']) { | |
entry('spring-boot-starter') { | |
exclude group: 'org.springframework.boot', name: 'spring-boot-starter-logging' | |
} | |
} | |
dependency group: 'org.seleniumhq.selenium', name: 'selenium-java', version: ext['selenium.version'] | |
dependencySet(group: 'org.testcontainers', version: ext['testcontainers.version']) { | |
entry 'selenium' | |
entry 'testcontainers' | |
} | |
} | |
} | |
dependencies { | |
generate 'com.google.guava:guava' | |
generate 'com.google.truth:truth' | |
generate 'com.h2database:h2' | |
generate 'com.querydsl:querydsl-apt' | |
generate 'com.querydsl:querydsl-jpa' | |
generate 'com.squareup.okhttp3:logging-interceptor' | |
generate 'com.squareup.okhttp3:mockwebserver' | |
generate 'com.squareup.okhttp3:okhttp' | |
generate 'io.codearte.jfairy:jfairy' | |
generate 'info.cukes:cucumber-java8' | |
generate 'info.cukes:cucumber-junit' | |
generate 'info.cukes:cucumber-picocontainer' | |
generate 'javax.servlet:javax.servlet-api' | |
generate 'org.awaitility:awaitility' | |
generate 'org.jooq:jool' | |
generate 'org.postgresql:postgresql' | |
generate 'org.projectlombok:lombok' | |
generate 'org.seleniumhq.selenium:selenium-java' | |
generate 'org.springframework.boot:spring-boot-loader' | |
generate 'org.springframework.boot:spring-boot-starter' | |
generate 'org.springframework.boot:spring-boot-starter-actuator' | |
generate 'org.springframework.boot:spring-boot-starter-data-jpa' | |
generate 'org.springframework.boot:spring-boot-starter-data-rest' | |
generate 'org.springframework.boot:spring-boot-starter-hateoas' | |
generate 'org.springframework.boot:spring-boot-starter-log4j2' | |
generate 'org.springframework.boot:spring-boot-starter-security' | |
generate 'org.springframework.boot:spring-boot-starter-test' | |
generate 'org.springframework.boot:spring-boot-starter-web' | |
generate 'org.springframework.boot:spring-boot-starter-websocket' | |
generate 'org.springframework.cloud:spring-cloud-starter-eureka' | |
generate 'org.springframework.cloud:spring-cloud-starter-eureka-server' | |
generate 'org.springframework.cloud:spring-cloud-starter-zuul' | |
generate 'org.springframework.data:spring-data-rest-hal-browser' | |
generate 'org.testcontainers:selenium' | |
generate 'org.testcontainers:testcontainers' | |
} | |
task generateWorkspace() { | |
SortedMap<ModuleVersionIdentifier, SortedSet<ModuleVersionIdentifier>> moduleDependencies = new TreeMap<>(new Comparator<ModuleVersionIdentifier>() { | |
@Override | |
int compare(ModuleVersionIdentifier o1, ModuleVersionIdentifier o2) { | |
return getBazelIdentifier(o1) <=> getBazelIdentifier(o2) | |
} | |
}) | |
configurations.generate.resolvedConfiguration.firstLevelModuleDependencies.each { dep -> | |
collectDependencies(moduleDependencies, dep) | |
} | |
Map<ModuleVersionIdentifier, String> moduleSourceSha256 = new HashMap<>(); | |
SortedSet<ResolvedArtifact> resolvedArtifacts = new TreeSet<>(new Comparator<ResolvedArtifact>() { | |
@Override | |
int compare(ResolvedArtifact o1, ResolvedArtifact o2) { | |
return getBazelIdentifier(o1.moduleVersion.id) <=> getBazelIdentifier(o2.moduleVersion.id) | |
} | |
}) | |
resolvedArtifacts.addAll(configurations.generate.resolvedConfiguration.resolvedArtifacts.findAll { resolvedArtifact -> | |
configurations.generate.incoming.resolutionResult.allDependencies*.selected.toSet().any { | |
(resolvedArtifact.moduleVersion.id == it.moduleVersion) | |
} | |
}) | |
resolvedArtifacts.each { | |
ArtifactResolutionResult sourcesQueryResult = dependencies.createArtifactResolutionQuery() | |
.forComponents(it.id.componentIdentifier) | |
.withArtifacts(JvmLibrary, SourcesArtifact) | |
.execute() | |
Set<ResolvedArtifactResult> sourcesArtifacts = sourcesQueryResult.resolvedComponents.collectMany { | |
it.getArtifacts(SourcesArtifact) | |
}.toSet() | |
if (sourcesArtifacts.size() == 1) { | |
moduleSourceSha256.put(it.moduleVersion.id, sha256(sourcesArtifacts.first().file)) | |
} else if (sourcesArtifacts.size() > 1) { | |
println("Artifact had multiple sources artifacts! ${it.moduleVersion.id}") | |
} | |
} | |
generateWorkspaceFile(resolvedArtifacts, moduleSourceSha256) | |
generateBuildFile(moduleDependencies, moduleSourceSha256) | |
} | |
private void collectDependencies(SortedMap<ModuleVersionIdentifier, SortedSet<ModuleVersionIdentifier>> moduleDependencies, ResolvedDependency dep) { | |
if (!moduleDependencies.containsKey(dep.module.id)) { | |
SortedSet<ModuleVersionIdentifier> childDependencies = new TreeSet<>(new Comparator<ModuleVersionIdentifier>() { | |
@Override | |
int compare(ModuleVersionIdentifier o1, ModuleVersionIdentifier o2) { | |
return getBazelIdentifier(o1) <=> getBazelIdentifier(o2) | |
} | |
}) | |
childDependencies.addAll(dep.children.collect { it.module.id }) | |
moduleDependencies.put(dep.module.id, childDependencies) | |
dep.children.each { collectDependencies(moduleDependencies, it) } | |
} | |
} | |
private void generateWorkspaceFile(SortedSet<ResolvedArtifact> resolvedArtifacts, Map<ModuleVersionIdentifier, String> moduleSourceSha256) { | |
def generateWorkspace = file("generate_workspace.bzl") | |
String generateWorkspaceContent = "def generated_maven_jars():\n" | |
resolvedArtifacts.each { a -> | |
def module = a.moduleVersion.id | |
def name = getBazelIdentifier(module) | |
def artifact = module.toString() | |
def sha256 = sha256(a.file) | |
generateWorkspaceContent += bzl_maven_jar(name, "https://jcenter.bintray.com", artifact, sha256) | |
if (moduleSourceSha256.containsKey(module)) { | |
generateWorkspaceContent += bzl_maven_jar("${name}_src", "https://jcenter.bintray.com", "${artifact}:sources", moduleSourceSha256.get(module)) | |
} | |
} | |
generateWorkspace.text = generateWorkspaceContent | |
} | |
private static String sha256(file) { | |
java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256"); | |
file.eachByte 4096, { bytes, size -> md.update(bytes, 0, size) } | |
return md.digest().collect { String.format "%02x", it }.join() | |
} | |
private void generateBuildFile(Map<ModuleVersionIdentifier, Set<ModuleVersionIdentifier>> modules, Map<ModuleVersionIdentifier, Boolean> moduleSourceSha256) { | |
def build = file("BUILD") | |
String buildContent = "licenses([\"notice\"])\n\n" | |
modules.each { module, dependencies -> | |
buildContent += bzl_java_library(getBazelIdentifier(module), dependencies.collect { getBazelIdentifier(it) }, moduleSourceSha256.containsKey(module)) | |
} | |
build.text = buildContent | |
} | |
private static String getBazelIdentifier(ModuleVersionIdentifier id) { | |
id.group.replaceAll("[^\\w]", "_") + "_" + id.name.replaceAll("[^\\w]", "_") | |
} | |
private static String bzl_maven_jar(name, repoUrl, artifactId, sha256) { | |
Object artifactUrl = getArtifactUrl(artifactId, repoUrl) | |
return """ native.http_file( | |
name = "${name}", | |
urls = ["${artifactUrl}.jar"], | |
sha256 = "${sha256}", | |
) | |
""" | |
} | |
private static Object getArtifactUrl(artifactId, repoUrl) { | |
def group, artifact, version, classifier, file_version | |
String[] parts = artifactId.split(':') | |
if (parts.length == 4) { | |
(group, artifact, version, classifier) = parts | |
file_version = version + '-' + classifier | |
} else { | |
(group, artifact, version) = parts | |
file_version = version | |
} | |
return [repoUrl, | |
group.replace('.', '/'), | |
artifact, | |
version, | |
artifact + '-' + file_version].join('/') | |
} | |
private static String bzl_java_library(name, dependencies, Boolean hasSources) { | |
String deps = "" | |
dependencies.each { | |
deps += "\n \":${it}\"," | |
} | |
if (hasSources) { | |
return """native.java_import( | |
name = "${name}", | |
visibility = ["//visibility:public"], | |
jars = ["@${name}//file"], | |
runtime_deps = [${deps} | |
], | |
srcjar = "@${name}_src//file", | |
) | |
""" | |
} else { | |
return """native.java_import( | |
name = "${name}", | |
visibility = ["//visibility:public"], | |
jars = ["@${name}//file"], | |
runtime_deps = [${deps} | |
], | |
) | |
""" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment