[Git][java-team/gradle-debian-helper][master] 7 commits: Don't fail on a project applying the java plugin without building a jar or a javadoc
Emmanuel Bourg (@ebourg)
gitlab at salsa.debian.org
Wed Sep 30 14:12:07 BST 2026
Emmanuel Bourg pushed to branch master at Debian Java Maintainers / gradle-debian-helper
Commits:
eebdba93 by Emmanuel Bourg at 2026-09-30T14:44:47+02:00
Don't fail on a project applying the java plugin without building a jar or a javadoc
- - - - -
8c8eae4c by Emmanuel Bourg at 2026-09-30T14:44:57+02:00
dh_auto_build now detects the build.gradle.kts and settings.gradle[.kts] scripts
- - - - -
31f0f870 by Emmanuel Bourg at 2026-09-30T15:02:45+02:00
New parser for the debian/gradle.ignoreRules file
- - - - -
59c3c4e7 by Emmanuel Bourg at 2026-09-30T15:02:45+02:00
Ignore the configuration blocks listed in debian/gradle.ignoreRules
- - - - -
25e00d2b by Emmanuel Bourg at 2026-09-30T15:02:45+02:00
New example of an ignored configuration block in the test project
- - - - -
8aa87bad by Emmanuel Bourg at 2026-09-30T15:02:45+02:00
Require the Gradle and Kotlin DSL versions implementing the ignore rules
- - - - -
7695dd78 by Emmanuel Bourg at 2026-09-30T15:06:56+02:00
Upload to unstable
- - - - -
14 changed files:
- README.txt
- debian/changelog
- debian/control
- + debian/maven.rules
- gradle-helper-hook/pom.xml
- + gradle-helper-hook/src/main/java/org/debian/gradle/plugin/IgnoreRules.java
- + gradle-helper-hook/src/test/java/org/debian/gradle/plugin/IgnoreRulesTest.java
- gradle-helper-plugin/pom.xml
- gradle-helper-plugin/src/main/java/org/debian/gradle/DebianHelperPlugin.java
- + gradle-helper-plugin/src/main/java/org/debian/gradle/IgnoredExtension.java
- gradle-helper-plugin/src/main/perl/gradle.pm
- test-project/build.gradle
- + test-project/debian/gradle.ignoreRules
- test-project/init.gradle
Changes:
=====================================
README.txt
=====================================
@@ -8,6 +8,7 @@ It consists in:
(/usr/share/maven-repo). The resolver uses the same Maven rule files that
maven-debian-helper and maven-repo-helper employ (debian/maven.rules,
debian/maven.ignoreRules).
+ * Ignore the plugins and blocks declared in debian/gradle.ignoreRules
* Generate Maven POMs for being read by maven-repo-helper
* Let javadoc link to the local Javadoc of default-jdk
* a build listener displaying a message periodically to prevent the builders from killing Gradle on slow architectures.
@@ -26,13 +27,15 @@ Usage
3. Create debian/maven.rules and/or debian.maven.ignoreRules with the dependency rules
-4. For building only some subprojects and ignoring the others,
+4. Create debian/gradle.ignoreRules and declare the ignored plugins
+
+5. For building only some subprojects and ignoring the others,
pass Gradle parameters to dh_auto_build:
override_dh_auto_build:
dh_auto_build -- :project1:jar :project2:jar
-5. For running tests, override dh_auto_test and call dh_auto_build:
+6. For running tests, override dh_auto_test and call dh_auto_build:
override_dh_auto_test:
dh_auto_build -- check
=====================================
debian/changelog
=====================================
@@ -1,3 +1,14 @@
+gradle-debian-helper (3.0) unstable; urgency=medium
+
+ * Ignore the configuration blocks listed in debian/gradle.ignoreRules
+ * Require the Gradle and Kotlin DSL versions implementing the ignore rules
+ * Don't fail on a project applying the java plugin without building a jar
+ or a javadoc
+ * dh_auto_build now detects the build.gradle.kts and settings.gradle[.kts]
+ scripts
+
+ -- Emmanuel Bourg <ebourg at apache.org> Wed, 30 Sep 2026 15:02:54 +0200
+
gradle-debian-helper (2.5) unstable; urgency=medium
* New dependency on libgradle-kotlin-dsl-java to build Kotlin DSL projects
=====================================
debian/control
=====================================
@@ -8,6 +8,7 @@ Build-Depends:
debhelper-compat (= 13),
default-jdk-headless | default-jdk,
gradle (>= 4.5),
+ junit4,
maven-debian-helper
Standards-Version: 4.7.4
Vcs-Git: https://salsa.debian.org/java-team/gradle-debian-helper.git
@@ -17,8 +18,8 @@ Package: gradle-debian-helper
Architecture: all
Depends:
default-jre-headless | java7-runtime-headless,
- gradle (>= 4.5),
- libgradle-kotlin-dsl-java (>= 0.14.2-2~),
+ gradle (>= 4.6-2~),
+ libgradle-kotlin-dsl-java (>= 0.15.6-2~),
maven-repo-helper,
${misc:Depends}
Description: Helper tools for building Debian packages with Gradle
=====================================
debian/maven.rules
=====================================
@@ -0,0 +1,2 @@
+
+junit junit jar s/.*/4.x/
=====================================
gradle-helper-hook/pom.xml
=====================================
@@ -15,6 +15,12 @@
<artifactId>maven-repo-helper</artifactId>
<version>1.8.10</version>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.13.2</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
=====================================
gradle-helper-hook/src/main/java/org/debian/gradle/plugin/IgnoreRules.java
=====================================
@@ -0,0 +1,278 @@
+/**
+ * Copyright 2026 Emmanuel Bourg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.debian.gradle.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * What the build ignores, as declared in <tt>debian/gradle.ignoreRules</tt>.
+ *
+ * <p>The file has a two-column layout. The first column is one of:</p>
+ * <ul>
+ * <li>a plugin identifier, as the build script writes it</li>
+ * <li>the name of a plugin class, when the script applies it that way</li>
+ * <li>the path of a script plugin, the one applied with
+ * <tt>apply from:</tt>, recognized by its <tt>.gradle</tt> or
+ * <tt>.gradle.kts</tt> extension</li>
+ * <li>the path of a project, recognized by its leading colon, which the
+ * settings file then doesn't include</li>
+ * <li>a dash, for the blocks no plugin of the script declares</li>
+ * </ul>
+ *
+ * <p>The second column is optional and lists the names ignored with the plugin,
+ * separated by commas or whitespace: its configuration blocks and the class
+ * name of its tasks.</p>
+ *
+ * <pre>
+ * me.champeau.gradle.jmh jmh
+ * com.gradle.build-scan buildScan
+ * com.gradle.plugin-publish pluginBundle,gradlePlugin
+ * org.gradle.kotlin.ktlint-convention
+ * com.example.gradle.SomePlugin
+ * gradle/jmh.gradle jmh
+ * com.github.spotbugs spotbugs, com.github.spotbugs.SpotBugsTask
+ * :osgi-test
+ * - jmh
+ * </pre>
+ */
+public class IgnoreRules {
+
+ /** The location of the rules */
+ public static final String FILE = "debian/gradle.ignoreRules";
+
+ private final List<Rule> rules = new ArrayList<Rule>();
+
+ /**
+ * An ignored plugin and the configuration blocks it injects.
+ */
+ public static class Rule {
+
+ private final String plugin;
+ private final List<String> extensions;
+
+ Rule(String plugin, List<String> extensions) {
+ this.plugin = plugin;
+ this.extensions = extensions;
+ }
+
+ /** The plugin, the script or the project of the entry, null if it has none */
+ public String getPlugin() {
+ return plugin;
+ }
+
+ /** The names of the configuration blocks injected by the plugin */
+ public List<String> getExtensions() {
+ List<String> blocks = new ArrayList<String>();
+ for (String extension : extensions) {
+ if (!isClassName(extension)) {
+ blocks.add(extension);
+ }
+ }
+ return Collections.unmodifiableList(blocks);
+ }
+
+ /** The names of the classes brought by the plugin and named by the build script */
+ public List<String> getClasses() {
+ List<String> classes = new ArrayList<String>();
+ for (String extension : extensions) {
+ if (isClassName(extension)) {
+ classes.add(extension);
+ }
+ }
+ return Collections.unmodifiableList(classes);
+ }
+
+ /** Tells a class from a configuration block: only a class name is qualified */
+ private static boolean isClassName(String name) {
+ return name.indexOf('.') >= 0;
+ }
+
+ /** Tells if the entry designates a project of the build rather than a plugin */
+ public boolean isProject() {
+ return plugin != null && plugin.startsWith(":");
+ }
+
+ /** Tells if the entry designates a script plugin, applied with <tt>apply from:</tt> */
+ public boolean isScript() {
+ return plugin != null && (plugin.endsWith(".gradle") || plugin.endsWith(".gradle.kts"));
+ }
+ }
+
+ /**
+ * Reads the rules of the package from {@link #FILE}.
+ */
+ public static IgnoreRules read() {
+ return new IgnoreRules(new File(FILE));
+ }
+
+ /**
+ * Reads the rules from the specified file.
+ *
+ * @throws IllegalArgumentException if the file cannot be read or holds a malformed entry
+ */
+ public IgnoreRules(File file) {
+ if (!file.exists()) {
+ return;
+ }
+
+ List<String> lines;
+ try {
+ lines = Files.readAllLines(file.toPath(), Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ throw new IllegalArgumentException(file + " could not be read: " + e.getMessage(), e);
+ }
+
+ for (int i = 0; i < lines.size(); i++) {
+ Rule rule = parse(lines.get(i), file + ":" + (i + 1));
+ if (rule != null) {
+ rules.add(rule);
+ }
+ }
+ }
+
+ /**
+ * Parses one line of the file, and returns null if it holds no entry.
+ *
+ * @param location the file and the line number, for the error messages
+ */
+ private Rule parse(String line, String location) {
+ int comment = line.indexOf('#');
+ if (comment >= 0) {
+ line = line.substring(0, comment);
+ }
+ line = line.trim();
+ if (line.isEmpty()) {
+ return null;
+ }
+
+ String[] fields = line.split("\\s+", 2);
+
+ String plugin = "-".equals(fields[0]) ? null : fields[0];
+
+ List<String> extensions = new ArrayList<String>();
+ if (fields.length == 2) {
+ for (String extension : fields[1].split("[,\\s]+")) {
+ extension = extension.trim();
+ if (!extension.isEmpty()) {
+ extensions.add(extension);
+ }
+ }
+ }
+
+ if (plugin == null && extensions.isEmpty()) {
+ throw new IllegalArgumentException(location + ": an entry with no plugin must name the blocks to ignore");
+ }
+
+ return new Rule(plugin, extensions);
+ }
+
+ /**
+ * Tells if the plugin with the specified identifier is ignored.
+ *
+ * @param id the identifier used in the build script, such as com.gradle.build-scan
+ */
+ public boolean isPluginIgnored(String id) {
+ for (Rule rule : rules) {
+ if (!rule.isScript() && !rule.isProject()
+ && rule.getPlugin() != null && rule.getPlugin().equals(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tells if the class with the specified name is ignored.
+ *
+ * @param name the fully qualified name of the class
+ */
+ public boolean isClassIgnored(String name) {
+ if (isPluginIgnored(name)) {
+ return true;
+ }
+ for (Rule rule : rules) {
+ if (rule.getClasses().contains(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tells if the script at the specified path is ignored. The rules hold a
+ * path relative to the root of the package, the scripts are applied with an
+ * absolute one, so the end of the path is compared.
+ *
+ * @param path the path of the script plugin applied with <tt>apply from:</tt>
+ */
+ public boolean isScriptIgnored(String path) {
+ for (Rule rule : rules) {
+ if (rule.isScript() && (path.equals(rule.getPlugin()) || path.endsWith("/" + rule.getPlugin()))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tells if the project at the specified path is ignored.
+ *
+ * @param path the path of the project, as passed to include()
+ */
+ public boolean isProjectIgnored(String path) {
+ String normalized = path.startsWith(":") ? path : ":" + path;
+ for (Rule rule : rules) {
+ if (rule.isProject() && rule.getPlugin().equals(normalized)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the names of the configuration blocks to ignore.
+ */
+ public Set<String> getIgnoredExtensions() {
+ Set<String> extensions = new LinkedHashSet<String>();
+ for (Rule rule : rules) {
+ extensions.addAll(rule.getExtensions());
+ }
+ return extensions;
+ }
+
+ /**
+ * Returns the entries read from the file.
+ */
+ public List<Rule> getRules() {
+ return Collections.unmodifiableList(rules);
+ }
+
+ /**
+ * Tells if no rule was declared, and the mechanism therefore does nothing.
+ */
+ public boolean isEmpty() {
+ return rules.isEmpty();
+ }
+}
=====================================
gradle-helper-hook/src/test/java/org/debian/gradle/plugin/IgnoreRulesTest.java
=====================================
@@ -0,0 +1,225 @@
+/**
+ * Copyright 2026 Emmanuel Bourg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.debian.gradle.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static org.junit.Assert.*;
+
+public class IgnoreRulesTest {
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ private IgnoreRules rules2(String... lines) throws IOException {
+ return rules("rules2", lines);
+ }
+
+ private IgnoreRules rules3(String... lines) throws IOException {
+ return rules("rules3", lines);
+ }
+
+ private IgnoreRules rules(String... lines) throws IOException {
+ return rules("rules", lines);
+ }
+
+ private IgnoreRules rules(String name, String[] lines) throws IOException {
+ File file = folder.newFile(name);
+ PrintWriter writer = new PrintWriter(file, "UTF-8");
+ for (String line : lines) {
+ writer.println(line);
+ }
+ writer.close();
+
+ return new IgnoreRules(file);
+ }
+
+ @Test
+ public void testMissingFile() {
+ IgnoreRules rules = new IgnoreRules(new File("does/not/exist"));
+
+ assertTrue("rules", rules.isEmpty());
+ assertTrue("extensions", rules.getIgnoredExtensions().isEmpty());
+ assertFalse("plugin ignored", rules.isPluginIgnored("com.gradle.build-scan"));
+ }
+
+ @Test
+ public void testEmptyFile() throws Exception {
+ IgnoreRules rules = rules("# nothing but a comment", "", " ");
+
+ assertTrue("rules", rules.isEmpty());
+ }
+
+ @Test
+ public void testPluginWithOneExtension() throws Exception {
+ IgnoreRules rules = rules("me.champeau.gradle.jmh jmh");
+
+ assertEquals("rules", 1, rules.getRules().size());
+ assertTrue("plugin ignored", rules.isPluginIgnored("me.champeau.gradle.jmh"));
+ assertFalse("other plugin ignored", rules.isPluginIgnored("me.champeau.gradle.other"));
+ assertEquals("extensions", Arrays.asList("jmh"), rules.getRules().get(0).getExtensions());
+ }
+
+ @Test
+ public void testPluginWithoutExtension() throws Exception {
+ IgnoreRules rules = rules("org.gradle.kotlin.ktlint-convention");
+
+ assertTrue("plugin ignored", rules.isPluginIgnored("org.gradle.kotlin.ktlint-convention"));
+ assertTrue("extensions", rules.getIgnoredExtensions().isEmpty());
+ }
+
+ @Test
+ public void testSeveralExtensions() throws Exception {
+ IgnoreRules rules = rules("com.gradle.plugin-publish pluginBundle,gradlePlugin");
+
+ assertEquals("extensions", Arrays.asList("pluginBundle", "gradlePlugin"),
+ Arrays.asList(rules.getIgnoredExtensions().toArray()));
+ }
+
+ @Test
+ public void testClassOfAnIgnoredPlugin() throws Exception {
+ IgnoreRules rules = rules("com.github.spotbugs spotbugs, com.github.spotbugs.SpotBugsTask");
+
+ assertEquals("extensions", Arrays.asList("spotbugs"), rules.getRules().get(0).getExtensions());
+ assertEquals("classes", Arrays.asList("com.github.spotbugs.SpotBugsTask"), rules.getRules().get(0).getClasses());
+ assertTrue("class ignored", rules.isClassIgnored("com.github.spotbugs.SpotBugsTask"));
+ assertFalse("other class ignored", rules.isClassIgnored("com.github.spotbugs.OtherTask"));
+ assertFalse("block registered as a class", rules.isClassIgnored("spotbugs"));
+ }
+
+ @Test
+ public void testPluginAppliedByItsClass() throws Exception {
+ IgnoreRules rules = rules("com.example.gradle.SomePlugin");
+
+ assertTrue("class ignored", rules.isClassIgnored("com.example.gradle.SomePlugin"));
+ assertTrue("extensions", rules.getIgnoredExtensions().isEmpty());
+ }
+
+ @Test
+ public void testExtensionWithoutPlugin() throws Exception {
+ IgnoreRules rules = rules("- jmh");
+
+ assertNull("plugin", rules.getRules().get(0).getPlugin());
+ assertFalse("plugin ignored", rules.isPluginIgnored("-"));
+ assertEquals("extensions", Arrays.asList("jmh"), rules.getRules().get(0).getExtensions());
+ }
+
+ @Test
+ public void testScript() throws Exception {
+ IgnoreRules rules = rules("gradle/binaryCompatibility.gradle");
+
+ assertTrue("script", rules.getRules().get(0).isScript());
+ assertTrue("absolute path", rules.isScriptIgnored("/build/pkg-1.0/gradle/binaryCompatibility.gradle"));
+ assertTrue("relative path", rules.isScriptIgnored("gradle/binaryCompatibility.gradle"));
+ assertFalse("other script", rules.isScriptIgnored("/build/pkg-1.0/gradle/jmh.gradle"));
+ assertFalse("ignored as a plugin id", rules.isPluginIgnored("gradle/binaryCompatibility.gradle"));
+ }
+
+ @Test
+ public void testKotlinScript() throws Exception {
+ IgnoreRules rules = rules("gradle/jmh.gradle.kts jmh");
+
+ assertTrue("script", rules.getRules().get(0).isScript());
+ assertTrue("path", rules.isScriptIgnored("/build/pkg/gradle/jmh.gradle.kts"));
+ assertEquals("extensions", Arrays.asList("jmh"), rules.getRules().get(0).getExtensions());
+ }
+
+ @Test
+ public void testPluginIsNotAScript() throws Exception {
+ IgnoreRules rules = rules("me.champeau.gradle.jmh jmh");
+
+ assertFalse("script", rules.getRules().get(0).isScript());
+ assertFalse("ignored as a script", rules.isScriptIgnored("/build/pkg/me.champeau.gradle.jmh"));
+ }
+
+ @Test
+ public void testProject() throws Exception {
+ IgnoreRules rules = rules(":osgi-test", ":android");
+
+ assertTrue("project", rules.getRules().get(0).isProject());
+ assertTrue("with the colon", rules.isProjectIgnored(":osgi-test"));
+ assertTrue("without the colon", rules.isProjectIgnored("osgi-test"));
+ assertTrue("second entry", rules.isProjectIgnored("android"));
+ assertFalse("other module", rules.isProjectIgnored(":inline"));
+ assertFalse("ignored as a plugin id", rules.isPluginIgnored(":osgi-test"));
+ }
+
+ @Test
+ public void testComments() throws Exception {
+ IgnoreRules rules = rules("# the plugins ignored by this package",
+ "",
+ "com.gradle.build-scan buildScan # applied by --scan",
+ "#me.champeau.gradle.jmh jmh");
+
+ assertEquals("rules", 1, rules.getRules().size());
+ assertTrue("plugin ignored", rules.isPluginIgnored("com.gradle.build-scan"));
+ assertFalse("commented out plugin ignored", rules.isPluginIgnored("me.champeau.gradle.jmh"));
+ }
+
+ @Test
+ public void testDuplicatedExtension() throws Exception {
+ IgnoreRules rules = rules("me.champeau.gradle.jmh jmh", "- jmh");
+
+ assertEquals("rules", 2, rules.getRules().size());
+ assertEquals("extensions", 1, rules.getIgnoredExtensions().size());
+ }
+
+ @Test
+ public void testRulesAreNotCached() throws Exception {
+ File file = folder.newFile("gradle.ignoreRules");
+
+ PrintWriter writer = new PrintWriter(file, "UTF-8");
+ writer.println("me.champeau.gradle.jmh jmh");
+ writer.close();
+ assertTrue("first read", new IgnoreRules(file).isPluginIgnored("me.champeau.gradle.jmh"));
+
+ writer = new PrintWriter(file, "UTF-8");
+ writer.println("com.gradle.build-scan buildScan");
+ writer.close();
+ assertFalse("second read", new IgnoreRules(file).isPluginIgnored("me.champeau.gradle.jmh"));
+ assertTrue("second read", new IgnoreRules(file).isPluginIgnored("com.gradle.build-scan"));
+ }
+
+ @Test
+ public void testExtensionSeparators() throws Exception {
+ IgnoreRules commas = rules("com.example.plugin blockA,blockB");
+ IgnoreRules spaced = rules2("com.example.plugin blockA, blockB");
+ IgnoreRules spaces = rules3("com.example.plugin blockA blockB");
+
+ for (IgnoreRules rules : Arrays.asList(commas, spaced, spaces)) {
+ assertEquals("extensions", Arrays.asList("blockA", "blockB"),
+ Arrays.asList(rules.getIgnoredExtensions().toArray()));
+ }
+ }
+
+ @Test
+ public void testExtensionWithoutPluginNorBlock() throws Exception {
+ try {
+ rules("# the line below names nothing", "-");
+ fail("no exception thrown");
+ } catch (IllegalArgumentException e) {
+ assertTrue("message: " + e.getMessage(), e.getMessage().contains(":2: "));
+ }
+ }
+}
=====================================
gradle-helper-plugin/pom.xml
=====================================
@@ -15,6 +15,12 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>org.debian.gradle</groupId>
+ <artifactId>gradle-helper-hook</artifactId>
+ <version>1.5</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@@ -90,6 +96,13 @@
<scope>system</scope>
<systemPath>${gradle.libs}/gradle-plugins.jar</systemPath>
</dependency>
+ <dependency>
+ <groupId>org.gradle</groupId>
+ <artifactId>gradle-model-core</artifactId>
+ <version>${gradle.version}</version>
+ <scope>system</scope>
+ <systemPath>${gradle.libs}/gradle-model-core.jar</systemPath>
+ </dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-logging</artifactId>
=====================================
gradle-helper-plugin/src/main/java/org/debian/gradle/DebianHelperPlugin.java
=====================================
@@ -18,7 +18,9 @@ package org.debian.gradle;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
+import org.debian.gradle.plugin.IgnoreRules;
import org.debian.gradle.tasks.MavenPom;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
@@ -56,6 +58,33 @@ public class DebianHelperPlugin implements Plugin<Gradle> {
}
});
+ // ignore the configuration blocks listed in debian/gradle.ignoreRules
+ final Set<String> ignoredExtensions = IgnoreRules.read().getIgnoredExtensions();
+ gradle.allprojects(new Action<Project>() {
+ @Override
+ public void execute(final Project project) {
+ for (String name : ignoredExtensions) {
+ if (project.getExtensions().findByName(name) == null) {
+ log.info("\tIgnoring the '" + name + "' block of project '" + project.getName() + "'");
+ project.getExtensions().add(name, new IgnoredExtension());
+ }
+ }
+
+ // create the stub tasks after the evaluation, before it they
+ // would take the name of a task a plugin is about to create
+ project.afterEvaluate(new Action<Project>() {
+ @Override
+ public void execute(Project project) {
+ for (String name : ignoredExtensions) {
+ if (project.getTasks().findByName(name) == null) {
+ project.getTasks().create(name);
+ }
+ }
+ }
+ });
+ }
+ });
+
// generate the Maven pom after building a project
gradle.allprojects(new Action<Project>() {
@Override
@@ -63,13 +92,16 @@ public class DebianHelperPlugin implements Plugin<Gradle> {
project.afterEvaluate(new Action<Project>() {
@Override
public void execute(Project project) {
- if (project.getPluginManager().hasPlugin("java")) {
+ // a project applying the java plugin doesn't necessarily
+ // build a jar, and there is no pom to generate without one
+ Task jar = project.getTasks().findByName("jar");
+ if (project.getPluginManager().hasPlugin("java") && jar != null) {
log.info("\tAdding Maven pom generation to project '" + project.getName() + "'");
project.getPluginManager().apply("maven");
Map<String, Class> debianMavenPomTaskOptions = new HashMap<String, Class>();
debianMavenPomTaskOptions.put("type", MavenPom.class);
project.task(debianMavenPomTaskOptions, "debianMavenPom");
- ((Task) project.getTasksByName("jar", false).toArray()[0]).dependsOn("debianMavenPom");
+ jar.dependsOn("debianMavenPom");
}
}
});
@@ -83,8 +115,8 @@ public class DebianHelperPlugin implements Plugin<Gradle> {
project.afterEvaluate(new Action<Project>() {
@Override
public void execute(Project project) {
- if (project.getPluginManager().hasPlugin("java")) {
- Javadoc javadocTask = ((Javadoc) (project.getTasksByName("javadoc", false).toArray()[0]));
+ Javadoc javadocTask = (Javadoc) project.getTasks().findByName("javadoc");
+ if (project.getPluginManager().hasPlugin("java") && javadocTask != null) {
if (javadocTask.getOptions() instanceof StandardJavadocDocletOptions) {
log.info("\tLinking the generated javadoc to the system JDK API documentation");
((StandardJavadocDocletOptions) javadocTask.getOptions()).getLinks().add(0, "file:///usr/share/doc/default-jdk/api");
=====================================
gradle-helper-plugin/src/main/java/org/debian/gradle/IgnoredExtension.java
=====================================
@@ -0,0 +1,95 @@
+/**
+ * Copyright 2026 Emmanuel Bourg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.debian.gradle;
+
+import groovy.lang.Closure;
+import groovy.lang.GroovyObjectSupport;
+
+/**
+ * A stub standing for the configuration block of an ignored plugin. It is
+ * registered under the name of the block and swallows whatever the build script
+ * puts in it.
+ *
+ * <p>This works in a Groovy script, where Gradle accepts any registered name as
+ * a configuration block, without checking the type of the extension, and
+ * delegates the closure to it. The assignments of the block therefore reach
+ * {@link #setProperty}, its method calls {@link #invokeMethod}, and the nested
+ * blocks are swallowed whole since the closure they carry is never called.</p>
+ *
+ * <p>A Kotlin script is compiled before it runs, and no stub can absorb a
+ * member the compiler doesn't know; there the ignored blocks are removed from
+ * the source of the script by libgradle-kotlin-dsl-java.</p>
+ */
+public class IgnoredExtension extends Closure<Object> {
+
+ /**
+ * The owner of the closure. Groovy hands it the methods it doesn't find on
+ * the closure itself, so it has to swallow them as well, and it has to
+ * exist: with a null owner any unknown method call ends in a
+ * NullPointerException before {@link #invokeMethod} is reached.
+ */
+ private static class StubOwner extends GroovyObjectSupport {
+
+ @Override
+ public Object invokeMethod(String name, Object args) {
+ return this;
+ }
+
+ @Override
+ public Object getProperty(String property) {
+ return this;
+ }
+
+ @Override
+ public void setProperty(String property, Object value) {
+ }
+
+ @Override
+ public String toString() {
+ return "ignored";
+ }
+ }
+
+ public IgnoredExtension() {
+ super(new StubOwner());
+ }
+
+ /** Swallows the calls of the blocks the plugin declares as methods, jsign(file: 'x') */
+ @Override
+ public Object call(Object... args) {
+ return this;
+ }
+
+ @Override
+ public Object invokeMethod(String name, Object args) {
+ return this;
+ }
+
+ @Override
+ public Object getProperty(String property) {
+ return this;
+ }
+
+ @Override
+ public void setProperty(String property, Object value) {
+ }
+
+ @Override
+ public String toString() {
+ return "ignored";
+ }
+}
=====================================
gradle-helper-plugin/src/main/perl/gradle.pm
=====================================
@@ -11,12 +11,15 @@ use Dpkg::Control;
use base 'Debian::Debhelper::Buildsystem';
sub DESCRIPTION {
- "Gradle (build.gradle)"
+ "Gradle (build.gradle[.kts])"
}
sub check_auto_buildable {
my $this=shift;
- return (-e $this->get_sourcepath("build.gradle")) ? 1 : 0;
+ foreach my $script ("build.gradle", "build.gradle.kts", "settings.gradle", "settings.gradle.kts") {
+ return 1 if -e $this->get_sourcepath($script);
+ }
+ return 0;
}
sub new {
=====================================
test-project/build.gradle
=====================================
@@ -2,6 +2,14 @@ allprojects {
apply plugin: 'java'
}
+jmh {
+ fork = 1
+ resultFormat = 'CSV'
+ profiles {
+ gc = true
+ }
+}
+
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: 'debian'
compile group: 'commons-lang', name: 'commons-lang', version: '2.6'
=====================================
test-project/debian/gradle.ignoreRules
=====================================
@@ -0,0 +1,2 @@
+# The jmh plugin is ignored, with the configuration block it injects.
+me.champeau.gradle.jmh jmh
=====================================
test-project/init.gradle
=====================================
@@ -2,6 +2,7 @@ initscript {
def home = System.properties['user.home']
dependencies {
classpath fileTree(dir: '../../../gradle-helper-plugin/target/', include: '*.jar')
+ classpath fileTree(dir: '../../../gradle-helper-hook/target/', include: '*.jar')
classpath fileTree(dir: home + '/.m2/repository/org/debian/maven/maven-repo-helper/1.8.10/', include: '*.jar')
}
}
View it on GitLab: https://salsa.debian.org/java-team/gradle-debian-helper/-/compare/bb9480757e908117bcb782b6a6308036feb6869b...7695dd78520b8c5e52b0cd8605ec2f762c8cd784
--
View it on GitLab: https://salsa.debian.org/java-team/gradle-debian-helper/-/compare/bb9480757e908117bcb782b6a6308036feb6869b...7695dd78520b8c5e52b0cd8605ec2f762c8cd784
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20260930/b6710157/attachment.htm>
More information about the pkg-java-commits
mailing list