Skip to content

Commit 175b685

Browse files
author
Jeremy Jeanne
committed
Fix improve Gradle 9 compatibility
Signed-off-by: Jeremy Jeanne <jeremy.jeanne@4dconcept.fr>
1 parent 4236769 commit 175b685

2 files changed

Lines changed: 174 additions & 80 deletions

File tree

build.gradle

Lines changed: 173 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,105 @@
1+
buildscript {
2+
repositories {
3+
mavenCentral()
4+
}
5+
dependencies {
6+
classpath 'net.sf.saxon:Saxon-HE:10.6'
7+
}
8+
}
9+
110
plugins {
211
id 'io.github.jyjeanne.dita-ot-gradle' version '2.3.2'
3-
id 'com.github.eerohele.saxon-gradle' version '0.9.0-beta4'
12+
// Removed: 'com.github.eerohele.saxon-gradle' - not Configuration Cache compatible
13+
// Replaced with: inline XsltTransformTask class below
414
}
515

6-
// Specify Saxon version per https://github.com/eerohele/saxon-gradle/blob/master/README.md
7-
816
repositories {
917
mavenCentral()
1018
}
1119

12-
configurations {
13-
saxon
14-
}
20+
import org.gradle.api.DefaultTask
21+
import org.gradle.api.file.RegularFileProperty
22+
import org.gradle.api.provider.MapProperty
23+
import org.gradle.api.tasks.*
24+
import net.sf.saxon.s9api.Processor
25+
import net.sf.saxon.s9api.QName
26+
import net.sf.saxon.s9api.XdmAtomicValue
27+
import javax.xml.transform.stream.StreamSource
28+
29+
/**
30+
* Gradle 9 compatible XSLT transformation task using Saxon-HE.
31+
* Replaces eerohele/saxon-gradle which is not Configuration Cache compatible.
32+
*/
33+
@CacheableTask
34+
abstract class XsltTransformTask extends DefaultTask {
35+
36+
@InputFile
37+
@PathSensitive(PathSensitivity.RELATIVE)
38+
abstract RegularFileProperty getInputFile()
39+
40+
@InputFile
41+
@PathSensitive(PathSensitivity.RELATIVE)
42+
abstract RegularFileProperty getStylesheetFile()
43+
44+
@OutputFile
45+
abstract RegularFileProperty getOutputFile()
46+
47+
@Input
48+
@Optional
49+
abstract MapProperty<String, String> getParameters()
50+
51+
@TaskAction
52+
void transform() {
53+
def inputPath = inputFile.get().asFile
54+
def stylesheetPath = stylesheetFile.get().asFile
55+
def outputPath = outputFile.get().asFile
56+
57+
try {
58+
outputPath.parentFile?.mkdirs()
59+
60+
def processor = new Processor(false)
61+
def compiler = processor.newXsltCompiler()
62+
def executable = compiler.compile(new StreamSource(stylesheetPath))
63+
def transformer = executable.load30()
64+
65+
def params = parameters.getOrElse([:])
66+
if (!params.isEmpty()) {
67+
params.each { name, value ->
68+
transformer.setStylesheetParameters(
69+
Collections.singletonMap(new QName(name), new XdmAtomicValue(value))
70+
)
71+
}
72+
}
73+
74+
transformer.transform(new StreamSource(inputPath), processor.newSerializer(outputPath))
75+
logger.lifecycle("Generated: ${outputPath.name}")
76+
} catch (Exception e) {
77+
throw new GradleException("XSLT transformation failed: ${inputPath.name} -> ${outputPath.name}\n" +
78+
"Stylesheet: ${stylesheetPath.name}\n" +
79+
"Cause: ${e.message}", e)
80+
}
81+
}
82+
83+
// DSL methods for backward compatibility with saxon-gradle syntax
84+
// Using layout API for Configuration Cache compatibility
85+
void input(Object path) {
86+
inputFile.set(project.layout.projectDirectory.file(path.toString()))
87+
}
88+
89+
void output(Object path) {
90+
outputFile.set(project.layout.projectDirectory.file(path.toString()))
91+
}
92+
93+
void stylesheet(Object path) {
94+
stylesheetFile.set(project.layout.projectDirectory.file(path.toString()))
95+
}
1596

16-
dependencies {
17-
// Use Saxon-HE 10.6 like DITA-OT, instead of the version that comes with `saxon-gradle`
18-
saxon 'net.sf.saxon:Saxon-HE:10.6'
97+
void parameters(Map<String, String> params) {
98+
parameters.putAll(params)
99+
}
19100
}
20101

21102
import com.github.jyjeanne.DitaOtTask
22-
import com.github.eerohele.SaxonXsltTask
23-
import org.gradle.process.ExecOperations
24103

25104
def getPropertyOrDefault(String name, def defaultValue) {
26105
providers.gradleProperty(name).getOrElse(defaultValue)
@@ -33,29 +112,40 @@ String ditaHome = getPropertyOrDefault('ditaHome', layout.projectDirectory.asFil
33112
String ditaHomeSrc = getPropertyOrDefault('ditaHomeSrc', ditaHome)
34113
String configDir = "${ditaHomeSrc}/config"
35114
String ditavalFile = "${projectDirPath}/platform.ditaval"
36-
Boolean toolkitBuild = file("${projectDirPath}/../lib/dost.jar").exists()
115+
116+
// Defer file existence check for Configuration Cache compatibility
117+
Boolean toolkitBuild = providers.provider {
118+
file("${projectDirPath}/../lib/dost.jar").exists()
119+
}.get()
120+
37121
String samplesDir = toolkitBuild ? "${ditaHome}/docsrc/samples" : "${projectDirPath}/samples"
38122
String outputDir = getPropertyOrDefault('outputDir', toolkitBuild ? "${ditaHome}/doc" : "${projectDirPath}/out")
39123

40124
String toURI(String path) {
41125
file(path).toURI().toString()
42126
}
43127

44-
task messages(type: SaxonXsltTask) {
128+
task messages(type: XsltTransformTask) {
129+
group = 'generation'
130+
description = 'Generate error messages documentation from DITA-OT config.'
45131
input "${configDir}/messages.xml"
46132
output "${projectDirPath}/topics/error-messages.xml"
47133
stylesheet "${projectDirPath}/resources/messages.xsl"
48134
}
49135

50-
task params(type: SaxonXsltTask) {
136+
task params(type: XsltTransformTask) {
137+
group = 'generation'
138+
description = 'Generate parameters documentation from DITA-OT plugins config.'
51139
input "${configDir}/plugins.xml"
52140
output "${projectDirPath}/parameters/all-parameters.dita"
53141
stylesheet "${projectDirPath}/resources/params.xsl"
54142
parameters('output-dir.url': toURI('parameters'))
55143
outputs.dir "${projectDirPath}/parameters"
56144
}
57145

58-
task extensionPoints(type: SaxonXsltTask) {
146+
task extensionPoints(type: XsltTransformTask) {
147+
group = 'generation'
148+
description = 'Generate extension points documentation from DITA-OT plugins config.'
59149
input "${configDir}/plugins.xml"
60150
output "${projectDirPath}/extension-points/all-extension-points.dita"
61151
stylesheet "${projectDirPath}/resources/extension-points.xsl"
@@ -64,17 +154,16 @@ task extensionPoints(type: SaxonXsltTask) {
64154
}
65155

66156
task generatePlatformFilter {
157+
group = 'generation'
158+
description = 'Generate platform-specific DITAVAL filter file.'
67159
def outputFile = layout.projectDirectory.file(ditavalFile)
68160
outputs.file(outputFile)
69161

70162
doLast {
71-
// Use Gradle's built-in OS detection instead of Ant
72-
def platformName = 'unix' // default
73-
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
74-
platformName = 'windows'
75-
} else if (org.gradle.internal.os.OperatingSystem.current().isMacOsX()) {
76-
platformName = 'mac'
77-
}
163+
// Use System properties for OS detection (public API)
164+
def osName = System.getProperty('os.name').toLowerCase()
165+
def platformName = osName.contains('win') ? 'windows' :
166+
osName.contains('mac') ? 'mac' : 'unix'
78167

79168
// Generate the ditaval file using modern Gradle file operations
80169
outputFile.asFile.text = """<?xml version="1.0" encoding="UTF-8"?>
@@ -86,69 +175,75 @@ task generatePlatformFilter {
86175
}
87176
}
88177

89-
task generatePropertiesTemplate(type: SaxonXsltTask) {
178+
task generatePropertiesTemplate(type: XsltTransformTask) {
179+
group = 'generation'
180+
description = 'Generate properties template file from DITA-OT plugins config.'
90181
input "${configDir}/plugins.xml"
91182
output "${samplesDir}/properties/template.properties"
92183
stylesheet "${projectDirPath}/resources/properties-file.xsl"
93184
}
94185

95186
task autoGenerate(dependsOn: [messages, params, extensionPoints, generatePlatformFilter, generatePropertiesTemplate]) {
187+
group = 'generation'
96188
description = 'Run tasks that generate content from resource files and the build environment.'
97189
}
98190

99191
task pdf(type: DitaOtTask, dependsOn: autoGenerate) {
192+
group = 'documentation'
193+
description = 'Build PDF documentation.'
100194
// Set DITA-OT directory: pass as parameter -PditaHome or fall back to parent when run in core repo.
101195
ditaOt file(findProperty('ditaHome') ?: ditaHome)
102196
input "${projectDirPath}/userguide-book.ditamap"
103197
output outputDir
104198
transtype 'pdf'
105199
filter "${projectDirPath}/resources/pdf.ditaval"
106200

107-
properties {
108-
property(name: 'args.chapter.layout', value: 'BASIC')
109-
property(name: 'args.gen.task.lbl', value: 'YES')
110-
property(name: 'include.rellinks', value: '#default external')
111-
property(name: 'outputFile.base', value: 'userguide')
112-
property(name: 'theme', value: "${projectDirPath}/samples/themes/dita-ot-docs-theme.yaml")
113-
}
201+
// Use ditaProperties MapProperty directly for v2.3.0 compatibility
202+
ditaProperties.put('args.chapter.layout', 'BASIC')
203+
ditaProperties.put('args.gen.task.lbl', 'YES')
204+
ditaProperties.put('include.rellinks', '#default external')
205+
ditaProperties.put('outputFile.base', 'userguide')
206+
ditaProperties.put('theme', "${projectDirPath}/samples/themes/dita-ot-docs-theme.yaml")
114207
}
115208

116209
task html(type: DitaOtTask, dependsOn: autoGenerate) {
210+
group = 'documentation'
211+
description = 'Build HTML5 documentation.'
117212
// Set DITA-OT directory: pass as parameter -PditaHome or fall back to parent when run in core repo.
118213
ditaOt file(findProperty('ditaHome') ?: ditaHome)
119214
input "${projectDirPath}/userguide.ditamap"
120215
output outputDir
121216
transtype 'html5'
122217
filter "${projectDirPath}/resources/html.ditaval"
123218

124-
properties {
125-
property(name: 'args.copycss', value: 'yes')
126-
property(name: 'args.css', value: 'dita-ot-doc.css')
127-
property(name: 'args.csspath', value: 'css')
128-
property(name: 'args.cssroot', value: "${projectDirPath}/resources/")
129-
property(name: 'args.gen.task.lbl', value: 'YES')
130-
property(name: 'args.hdr', value: "${projectDirPath}/resources/header.xml")
131-
property(name: 'args.rellinks', value: 'noparent')
132-
property(name: 'html5.toc.generate', value: 'no')
133-
property(name: 'nav-toc', value: 'partial')
134-
}
219+
// Use ditaProperties MapProperty directly for v2.3.0 compatibility
220+
ditaProperties.put('args.copycss', 'yes')
221+
ditaProperties.put('args.css', 'dita-ot-doc.css')
222+
ditaProperties.put('args.csspath', 'css')
223+
ditaProperties.put('args.cssroot', "${projectDirPath}/resources/")
224+
ditaProperties.put('args.gen.task.lbl', 'YES')
225+
ditaProperties.put('args.hdr', "${projectDirPath}/resources/header.xml")
226+
ditaProperties.put('args.rellinks', 'noparent')
227+
ditaProperties.put('html5.toc.generate', 'no')
228+
ditaProperties.put('nav-toc', 'partial')
135229
}
136230

137231
task htmlhelp(type: DitaOtTask, dependsOn: autoGenerate) {
232+
group = 'documentation'
233+
description = 'Build HTML Help (.chm) documentation.'
138234
// Set DITA-OT directory: pass as parameter -PditaHome or fall back to parent when run in core repo.
139235
ditaOt file(findProperty('ditaHome') ?: ditaHome)
140236
input "${projectDirPath}/userguide.ditamap"
141237
output outputDir
142238
transtype 'htmlhelp'
143239
filter ditavalFile
144240

145-
properties {
146-
property(name: 'args.copycss', value: 'yes')
147-
property(name: 'args.css', value: 'dita-ot-doc.css')
148-
property(name: 'args.csspath', value: 'css')
149-
property(name: 'args.cssroot', value: "${projectDirPath}/resources/")
150-
property(name: 'args.gen.task.lbl', value: 'YES')
151-
}
241+
// Use ditaProperties MapProperty directly for v2.3.0 compatibility
242+
ditaProperties.put('args.copycss', 'yes')
243+
ditaProperties.put('args.css', 'dita-ot-doc.css')
244+
ditaProperties.put('args.csspath', 'css')
245+
ditaProperties.put('args.cssroot', "${projectDirPath}/resources/")
246+
ditaProperties.put('args.gen.task.lbl', 'YES')
152247

153248
doLast {
154249
// Move .chm files using modern Gradle file operations
@@ -165,67 +260,66 @@ task htmlhelp(type: DitaOtTask, dependsOn: autoGenerate) {
165260
}
166261
}
167262

168-
task cleanUp {
263+
task cleanOutput {
264+
group = 'build'
265+
description = 'Delete the output directory.'
169266
doLast {
170267
delete outputDir
171268
}
172269
}
173270

174-
// Get git commit hash at configuration time for tasks that need it
175-
def getGitCommitHash() {
176-
try {
177-
def result = new ByteArrayOutputStream()
178-
exec {
179-
workingDir = layout.projectDirectory.asFile
180-
commandLine 'git', 'rev-parse', 'HEAD'
181-
standardOutput = result
182-
ignoreExitValue = true
183-
}
184-
return result.toString().trim()
185-
} catch (Exception e) {
186-
logger.warn("Could not get git commit hash: ${e.message}")
187-
return 'unknown'
188-
}
189-
}
190-
191-
// Store git commit for use by tasks
192-
def gitCommitHash = getGitCommitHash()
271+
// Get git commit hash using Gradle 9 compatible Provider API
272+
// Uses providers.exec() instead of deprecated project.exec()
273+
def gitCommitHash = providers.exec {
274+
commandLine 'git', 'rev-parse', 'HEAD'
275+
ignoreExitValue = true
276+
}.standardOutput.asText.map { it.trim() }.getOrElse('unknown')
193277

194278
task gitMetadata {
279+
group = 'build'
280+
description = 'Log git commit metadata.'
195281
// This task just logs the git commit for reference
196282
doLast {
197-
logger.info("Git commit: ${gitCommitHash}")
283+
logger.lifecycle("Git commit: ${gitCommitHash}")
198284
}
199285

200286
// Mark outputs to help with up-to-date checking
201287
outputs.upToDateWhen { false } // Always run since git commit changes frequently
202288
}
203289

204290
task site(type: DitaOtTask) {
291+
group = 'documentation'
292+
description = 'Build website documentation.'
205293
dependsOn 'messages', 'params', 'extensionPoints', 'gitMetadata'
206294

207295
// Set DITA-OT directory: pass as parameter -PditaHome or fall back to parent when run in core repo.
208296
ditaOt file(findProperty('ditaHome') ?: ditaHome)
209297
input file("${projectDirPath}/site.ditamap")
210-
output getPropertyOrDefault('outputDir', "${buildDir}/site")
298+
output getPropertyOrDefault('outputDir', layout.buildDirectory.dir("site").get().asFile.path)
211299
filter "${projectDirPath}/resources/site.ditaval"
212300

213301
transtype 'org.dita-ot.html'
214302

215303
// Evaluate the noCommitMeta flag at configuration time
216304
def includeCommitMeta = !providers.gradleProperty('noCommitMeta').map { Boolean.parseBoolean(it) }.getOrElse(false)
217305

218-
properties {
219-
property(name: 'args.gen.task.lbl', value: 'YES')
220-
property(name: 'args.rellinks', value: 'noparent')
221-
if (includeCommitMeta) {
222-
// Use the git commit hash obtained at configuration time
223-
property(name: 'commit', value: gitCommitHash)
224-
}
306+
// Use ditaProperties MapProperty directly for v2.3.0 compatibility
307+
ditaProperties.put('args.gen.task.lbl', 'YES')
308+
ditaProperties.put('args.rellinks', 'noparent')
309+
if (includeCommitMeta) {
310+
// Use the git commit hash obtained at configuration time
311+
ditaProperties.put('commit', gitCommitHash)
225312
}
226313
}
227314

228-
task all(dependsOn: [pdf, html, htmlhelp])
229-
task dist(dependsOn: [pdf, html])
315+
task all(dependsOn: [pdf, html, htmlhelp]) {
316+
group = 'documentation'
317+
description = 'Build all documentation formats (PDF, HTML, HTMLHelp).'
318+
}
319+
320+
task dist(dependsOn: [pdf, html]) {
321+
group = 'documentation'
322+
description = 'Build distribution documentation (PDF and HTML).'
323+
}
230324

231325
defaultTasks 'dist'

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)