Gradle 的 javadoc 目标不从 doc-files 复制文件

Gradle's javadoc goal does not copy files from doc-files

我发现 gradle 的 javadoc 任务不会从包目录的 doc-files 子目录复制文件。

这可以修复吗?

可能是的。您可以使用 <<:

javadoc 添加操作
javadoc << {
   //copy all the files here
}

或创建一个将完成 javadoc 并复制文件的任务:

task copySub(type: Copy) {
   //configuration goes here
}

javadoc.finalizedBy(copySub)

可能有点晚了,但我 运行 遇到了同样的问题并实施了修复作为 Gradle-Fury

的一部分

基本上,我在 Javadoc 和 Javadoc 的 Jar 任务之间注入了一个新任务(涵盖 android 和常规 java 项目),它从 src/main/java 或 src/variant/java 与文档文件的模式匹配。

copy {
    from f.absolutePath
    into "$project.buildDir/docs/javadoc/"
    include "**/doc-files/*"
}

<< 现已弃用,应使用 doLast。

javadoc {
     // ...
     // ...
     doLast{
           copy{
                    from "<src-package>/doc-files"
                    into "$project.buildDir/docs/javadoc/<src-package>/doc-files"
                    include "*.png"
                }
           copy{
               }
            }
     }

可以使用以上从多个文件夹复制

我首先尝试了这种方法:

javadoc {
  …
  doLast {
    copy {
      from "$projectDir/src/main/java"
      into "$project.docsDir/javadoc"
      include "**/doc-files/*"
    }
  }
}

但我发现它不适用于 Java 模块 (Jigsaw),因为对于它们来说,在 javadoc 下面有一个包含模块名称的文件夹,其中包含 *.html 文件对于 类 以及 doc-files 也需要结束的地方。

所以我来到这里:

javadoc {
  …
  doLast {
    var moduleName = Tools.obtainModuleName( project.sourceSets.main )
    var targetDir = moduleName.map( "/%s"::formatted ).orElse( "" )
    copy {
      from "$projectDir/src/main/java"
      into "$project.docsDir/javadoc$targetDir"
      include "**/doc-files/*"
    }
  }
}

Tools.obtainModuleName()是一个函数,从项目中的module-info.java文件中获取Java模块的名称:

public static final Optional<String> obtainModuleName( final SourceSet sourceSet )
{
    Optional<String> retValue = Optional.empty();

    final var directorySet = sourceSet.getAllJava();
    final var moduleDefinitionFile = directorySet.getFiles()
        .stream()
        .filter( File::exists )
        .filter( File::isFile )
        .filter( f -> f.getName().equals( MODULE_DEFINITION ) )
        .findFirst()
        .map( File::toPath );
    if( moduleDefinitionFile.isPresent() )
    {
        try( final var lines = lines( moduleDefinitionFile.get() ) )
        {
            final var contents = lines.collect( joining() );
            final var pattern = compile( ".*module\s+(\S+)\s*\{.*" );
            final var matcher = pattern.matcher( contents );
            if( matcher.matches() )
            {
                retValue = Optional.ofNullable( matcher.group( 1 ) );
            }
        }
        catch( final IOException e )
        {
            throw new Error( e );
        }
    }

    //---* Done *----------------------------------------------------------
    return retValue;
}   //  obtainModuleName()

不幸的是,这仍然不是解决方案……

潜在的问题是 Gradle 的 JavaDoc 任务与 Java SourceSet 相同编译器任务——后者只接受 *.java 文件。

只是将 doc-files 文件夹从源文件夹复制到 JavaDoc 文件夹作为 JavaDoc 任务的最后一个操作似乎只能正常工作,因为 JavaDoc 工具本身(来自 $JDK_HOME/bin/javadoc 的工具)也 处理 其他文件,而不仅仅是 *.java – 至少它对 *.html 文件做了一些事情: 您可以使用通常的 JavaDoc 标签,例如 {@code …}{@link …} 甚至自定义标签。

仅将 doc-files 文件夹及其内容添加到 sourceSet 也无济于事。在我的例子中,它会导致关于 doc-files 文件夹中文件的非法包名称的错误消息,因为文件夹名称中的某处有连字符(相同路径适用于 Java 来源......) .

我目前正在研究一种解决方案,以说服 Gradle 的 JavaDoc 任务也处理 doc-files 中的文件。敬请期待……