import java.util.zip.ZipEntry import java.util.zip.ZipInputStream plugins { id 'java' id 'com.google.cloud.tools.jib' version '3.4.2' id 'application' } application { mainClass = 'com.example.DbSetup' } repositories { mavenCentral() } dependencies { implementation 'org.postgresql:postgresql:42.7.3' } def containername = "mtg-search-db" def dbName = "mtgsearch" def dbUser = "dbuser" def dbPass = "dbpass" def psqlZipFile = new File("$rootDir\\AllPrintings.psql.zip") def psqlFile = new File("$rootDir\\AllPrintings\\AllPrintings.psql") jib { from { image = 'postgres:17' // base image } to { image = "hub.docker.com/$containername:latest" auth { username = System.getenv("DOCKER_USER")?:"" password = System.getenv("DOCKER_PASS")?:"" } } container { // Jib runs as rootless by default; PostgreSQL needs a few tweaks entrypoint = ['docker-entrypoint.sh'] args = ['postgres'] environment = [ POSTGRES_USER: dbUser, POSTGRES_PASSWORD: dbPass, POSTGRES_DB: dbName ] ports = ['5432'] } } // Custom Gradle task to run database setup logic tasks.register('runDbSetup', JavaExec) { dependsOn classes mainClass.set('com.example.DbSetup') classpath = sourceSets.main.runtimeClasspath environment 'POSTGRES_USER', dbUser environment 'POSTGRES_PASSWORD', dbPass environment 'POSTGRES_DB', dbName environment 'PSQL_FILE', psqlFile.canonicalPath } // Ensure setup runs before building the Docker image tasks.named('jib') { dependsOn('runDbSetup') } tasks.register('startPostgresContainer', Exec) { commandLine 'docker', 'run', '-d', '--name', "$containername", '-e', "POSTGRES_USER=$dbUser", '-e', "POSTGRES_PASSWORD=$dbPass", '-e', "POSTGRES_DB=$dbName", '-p', '5432:5432', 'postgres:17' } tasks.register('stopPostgresContainer', Exec) { commandLine 'docker', 'rm', '-f', containername } // Hook the lifecycle tasks.named('runDbSetup') { dependsOn('startPostgresContainer') finalizedBy('stopPostgresContainer') } tasks.register('getLatestMTGJson') { outputs.files files("AllPrintings.psql.zip.sha256","AllPrintings.psql.zip") outputs.upToDateWhen { def url = new URL("https://mtgjson.com/api/v5/AllPrintings.psql.zip.sha256") def urlHash = url.text // Groovy shortcut to read text from URL def file = new File('AllPrintings.psql.zip.sha256') if(file.exists()) { def fileHash = file.text def equal = urlHash == fileHash if(!equal){ println("AllPrintings.psql.zip.sha256 out of date") } return equal } println("AllPrintings.psql.zip.sha256 not found") return false } doLast { def url = new URL("https://mtgjson.com/api/v5/AllPrintings.psql.zip") println("Downloading $url to $psqlZipFile") psqlZipFile.withOutputStream { out -> out << url.openStream() } url = new URL("https://mtgjson.com/api/v5/AllPrintings.psql.zip.sha256") def file = new File("AllPrintings.psql.zip.sha256") println("Downloading $url to $file") file.withOutputStream { out -> out << url.openStream() } } } tasks.register("unzipAllPrintings"){ dependsOn("getLatestMTGJson") doLast { def destinationDir = new File("AllPrintings") // Ensure the destination directory exists destinationDir.mkdirs() psqlZipFile.withInputStream { fis -> new ZipInputStream(fis).with { zis -> ZipEntry entry while ((entry = zis.nextEntry) != null) { def outputFile = new File(destinationDir, entry.name) if (entry.isDirectory()) { outputFile.mkdirs() } else { outputFile.parentFile.mkdirs() // Ensure parent directories exist outputFile.withOutputStream { fos -> fos << zis // Copy the entry's content } } zis.closeEntry() } } } println "Successfully unzipped ${psqlZipFile.name} to ${destinationDir.absolutePath}" } }