Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions braintrust-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Placeholder subproject for the Braintrust OpenAPI-generated client.
//
// The fetchOpenApiSpec task downloads openapi/spec.yaml from the pinned commit
// of https://github.com/braintrustdata/braintrust-openapi into
// build/openapi/spec.yaml, then generateOpenApiSources runs the OpenAPI
// generator (native Java library) to produce sources under
// build/generated/openapi/src/main/java, which are compiled as part of the
// main source set.
//
// Future work will wire this generated client in to replace the hand-rolled
// BraintrustApiClient.HttpImpl.
//
// Pin the ref in gradle.properties:
// braintrustOpenApiRef=<sha-or-branch>
//
// To point at a local checkout instead of fetching:
// BRAINTRUST_OPENAPI_ROOT=/path/to/braintrust-openapi ./gradlew braintrust-api:compileJava

plugins {
id 'java'
id 'org.openapi.generator' version '7.14.0'
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

repositories {
mavenCentral()
}

// ── Spec fetch ───────────────────────────────────────────────────────────────

def openApiRef = project.property('braintrustOpenApiRef')
def openApiSpecDir = layout.buildDirectory.dir('openapi')
def openApiSpecFile = openApiSpecDir.map { it.file('spec.yaml') }

tasks.register('fetchOpenApiSpec', Exec) {
description = 'Fetches openapi/spec.yaml from the pinned braintrust-openapi ref.'
group = 'Build'

def localRoot = System.getenv('BRAINTRUST_OPENAPI_ROOT')

inputs.property('openApiRef', openApiRef)
outputs.dir(openApiSpecDir)

def outDir = openApiSpecDir.get().asFile

if (localRoot) {
commandLine 'bash', '-c',
"mkdir -p '${outDir}' && cp '${localRoot}/openapi/spec.yaml' '${outDir}/spec.yaml'"
} else {
commandLine 'bash', "${rootProject.projectDir}/scripts/openapi-fetch.sh",
openApiRef, outDir.absolutePath
}
}

// ── Code generation ──────────────────────────────────────────────────────────

def generatedSourcesDir = layout.buildDirectory.dir('generated/openapi')

openApiGenerate {
generatorName = 'java'
library = 'native'

// Custom templates that fix a generator bug where anyOf schemas with
// generic container variants (List<Foo>, Map<K,V>) produce invalid Java
// (e.g. `List<Foo>.class`, `getList<Foo>()`). See anyof_model.mustache.
templateDir = "${projectDir}/src/main/resources/templates/Java"

inputSpec = openApiSpecFile.get().asFile.absolutePath

outputDir = generatedSourcesDir.get().asFile.absolutePath

apiPackage = 'dev.braintrust.openapi.api'
modelPackage = 'dev.braintrust.openapi.model'
invokerPackage = 'dev.braintrust.openapi'

configOptions = [
// Use javax (not jakarta) — we're on Java 17 without EE migration
useJakartaEe : 'false',
// Dates as java.time types
dateLibrary : 'java8',
// Bearer token auth — SDK users supply a Braintrust API key
useRuntimeException : 'true',
serializationLibrary : 'jackson',

// Skip boilerplate we don't need yet
generateApiTests : 'false',
generateModelTests : 'false',
generateApiDocumentation : 'false',
generateModelDocumentation : 'false',
]

// The FunctionData anyOf has an inline schema with title:"prompt" which the generator
// names "Prompt", overwriting the real components/schemas/Prompt full object with a
// stub containing only the type discriminator. Remap it so the real Prompt generates
// correctly as a full POJO with slug, prompt_data, etc.
inlineSchemaNameMappings = [
'prompt': 'FunctionDataPrompt',
]

// Don't generate a full Maven project skeleton — just the sources
globalProperties = [
apis : '',
models : '',
supportingFiles : '',
apiTests : 'false',
modelTests : 'false',
apiDocs : 'false',
modelDocs : 'false',
]

}

// Wire fetch → generate → compile
tasks.named('openApiGenerate') {
dependsOn tasks.named('fetchOpenApiSpec')
}

tasks.named('compileJava') {
dependsOn tasks.named('openApiGenerate')
}

// Add the generated sources to the main source set
sourceSets {
main {
java {
srcDir generatedSourcesDir.map { it.dir('src/main/java') }
}
}
}

// ── Dependencies ─────────────────────────────────────────────────────────────

dependencies {
// Required by the openapi-generator native Java library
implementation "com.fasterxml.jackson.core:jackson-databind:${rootProject.ext.jacksonVersion}"
implementation "com.fasterxml.jackson.core:jackson-annotations:${rootProject.ext.jacksonVersion}"
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.ext.jacksonVersion}"
implementation 'org.openapitools:jackson-databind-nullable:0.2.10'

// @Nullable / @javax.annotation annotations used by generated code
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'

testImplementation "org.junit.jupiter:junit-jupiter-api:${rootProject.ext.junitVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${rootProject.ext.junitVersion}"
}
Loading
Loading