如何使用“api”从gradle插件获取依赖关系或“实施”指令 [英] How to get dependencies from a gradle plugin using "api" or "implementation" directives

查看:201
本文介绍了如何使用“api”从gradle插件获取依赖关系或“实施”指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:运行Android Studio 3.0-beta7并尝试让一个javadoc任务为Android库工作(事实上,这不是一个现成的任务,这真的很奇怪),而且我管理根据我的需求调整一个不同问题的答案,并以此代码结束( https://stackoverflow.com/a/46810617/

 任务javadoc(类型:Javadoc){
failOnError false
source = android.sourceSets.main.java.srcDirs
//同时添加生成的R类以避免错误...
// TODO:debug是硬编码的
source + =$ buildDir / generated / source / r / debug /
// ...但从文档中排除R类
excludes + =** / R.java

// TODO:在Gradle 4.1中不赞成使用compile,
//但是implementation和api不可解析:(
classpath + = configurations.compile

评估后{
//等待评估后添加android classpath
//以避免buildToolsVersion is not specified错误
classpath + = files(android.getBootClasspath())

//进程AAR依赖关系
def aarDependencies = classpath.filter {it.name.endsWith('。aar')}
classpath - = aarDependencies
aarDependencies.each {aar - > ;
System.out.println(为aar添加类路径:+ aar.name)
//从AAR依赖项中提取classes.jar,并将其添加到javadoc类路径
def outputPath =$ buildDir / tmp / exploded-aar / $ {aar.name.replace('。aar','.jar')}
classpath + = files(outputPath)

//使用一个任务,所以实际的提取只发生在javadoc任务运行之前
dependsOn任务(名称:extract $ {aar.name})。doLast {
extractEntry(aar,'classes。 jar',outputPath)
}
}
}
}

//在压缩文件中只提取一个条目的实用方法
private def extractEntry(archive,entryPath,outputPath){
if(!archive.exists()){
throw new GradleException(archive $ archive not found)
}

def zip = new java.util.zip.ZipFile(archive)

zip.entries()。each {
if(it.name = = entryPath){
def path = new File(outputPath)

if(!path.exists()){
path.getParentFile()。mkdirs()

//当然,除了
// java.nio.Files中的一个之外,还有一个更简单的is-> os实用程序?嗯...
def buf = new byte [1024]
def is = zip.getInputStream(it)
def os = new FileOutputStream(path)
def len $ b ((len = is.read(buf))!= -1){
os.write(buf,0,len)
}
os.close
$ b ()
}
}
}
zip.close()
}

这段代码试图找到所有依赖的AAR:s,遍历它们并从中提取classes.jar,并将它们放入临时文件夹中,该文件夹在javadoc生成期间添加到类路径中。基本上试图重现真正的旧版android gradle插件用于爆炸 - 空气的做法。然而,代码依赖于使用 compile 依赖关系。使用Gradle 4.1推荐的 api 实现将不起作用,因为这些无法通过Gradle任务解析。

问题:如何使用 api 实现指令时,例如 configuration.api 呈现不可解析错误?

额外问题:是否有新的更好的方式使用Android Studio 3.0创建javadocs,不涉及100行解决方法?

您可以等待这个被合并:

https: //issues.apache.org/jira/browse/MJAVADOC-450



基本上,当前的Maven Javadoc插件忽略了诸如AAR之类的分类器。


Background: Running Android Studio 3.0-beta7 and trying to get a javadoc task to work for an Android library (the fact that this is not available as a ready-made task in the first place is really strange), and I managed to tweak an answer to a different question for my needs, ending up with this code (https://stackoverflow.com/a/46810617/1226020):

task javadoc(type: Javadoc) {
    failOnError false
    source = android.sourceSets.main.java.srcDirs
    // Also add the generated R class to avoid errors...
    // TODO: debug is hard-coded
    source += "$buildDir/generated/source/r/debug/"
    // ... but exclude the R classes from the docs
    excludes += "**/R.java"

    // TODO: "compile" is deprecated in Gradle 4.1, 
    // but "implementation" and "api" are not resolvable :(
    classpath += configurations.compile

    afterEvaluate {
        // Wait after evaluation to add the android classpath
        // to avoid "buildToolsVersion is not specified" error
        classpath += files(android.getBootClasspath())

        // Process AAR dependencies
        def aarDependencies = classpath.filter { it.name.endsWith('.aar') }
        classpath -= aarDependencies
        aarDependencies.each { aar ->
            System.out.println("Adding classpath for aar: " + aar.name)
            // Extract classes.jar from the AAR dependency, and add it to the javadoc classpath
            def outputPath = "$buildDir/tmp/exploded-aar/${aar.name.replace('.aar', '.jar')}"
            classpath += files(outputPath)

            // Use a task so the actual extraction only happens before the javadoc task is run
            dependsOn task(name: "extract ${aar.name}").doLast {
                extractEntry(aar, 'classes.jar', outputPath)
            }
        }
    }
}

// Utility method to extract only one entry in a zip file
private def extractEntry(archive, entryPath, outputPath) {
    if (!archive.exists()) {
        throw new GradleException("archive $archive not found")
    }

    def zip = new java.util.zip.ZipFile(archive)

    zip.entries().each {
        if (it.name == entryPath) {
            def path = new File(outputPath)

            if (!path.exists()) {
                path.getParentFile().mkdirs()

                // Surely there's a simpler is->os utility except
                // the one in java.nio.Files? Ah well...
                def buf = new byte[1024]
                def is = zip.getInputStream(it)
                def os = new FileOutputStream(path)
                def len

                while ((len = is.read(buf)) != -1) {
                    os.write(buf, 0, len)
                }
                os.close()
            }
        }
    }
    zip.close()
}

This code tries to find all dependency AAR:s, loops through them and extracts classes.jar from them, and puts them in a temp folder that is added to the classpath during javadoc generation. Basically trying to reproduce what the really old android gradle plugin used to do with "exploded-aar".

However, the code relies on using compile dependencies. Using api or implementation that are recommended with Gradle 4.1 will not work, since these are not resolvable from a Gradle task.

Question: how can I get a list of dependencies using the api or implementation directives when e.g. configuration.api renders a "not resolvable" error?

Bonus question: is there a new, better way to create javadocs for a library with Android Studio 3.0 that doesn't involve 100 lines of workarounds?

解决方案

You can wait for this to be merged:

https://issues.apache.org/jira/browse/MJAVADOC-450

Basically, the current Maven Javadoc plugin ignores classifiers such as AAR.

这篇关于如何使用“api”从gradle插件获取依赖关系或“实施”指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆