构建Gradle存储库以进行脱机开发

Chr*_*ieb 18 offline gradle

我正在为一块软件实现Gradle构建系统,该软件具有在没有Internet连接的情况下开发的部件或者能够安装Maven/Ivy服务器(如Nexus).为了支持这些环境中的开发,我正在整理一个允许生成"离线工作区"的Gradle插件.

我最初通过触发项目中每个配置的解析(触发所有依赖项的下载),然后遍历每个配置的整个依赖关系树并将依赖关系的本地缓存副本复制到Offline Workspace来实现此功能.(为每个复制操作生成了一个复制任务.)然后使用flatDir存储库引用这些JAR.

此实现使用afterEvaluate块执行其作业.虽然这在Gradle 2.0中运行良好,但它会在Gradle 2.2.1中触发弃用警告,因为触发分辨率在某种程度上被视为在已经解析后修改配置(Attempting to change configuration ':core:runtime' after it has been included in dependency resolution. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0).总之,这种方法感觉相当hacky,因为它还要求我修改build.gradle文件以显式列出所有传递依赖项,因为没有可用于正确指定依赖项的POM文件.

更优雅的方法似乎是构建所有依赖项的本地Maven存储库(包括POM文件,源JAR,javadoc JAR等),然后只使用mavenLocal()存储库类型.不幸的是,我不确定如何正确地执行此操作,我不需要触发工件解析来执行此操作.

有没有更好的方法可以实现完整的工件下载到一个易于打包的方式,而不仅仅是压缩我的整个$ USER_HOME/.gradle目录?

won*_*ice 13

要进行脱机构建,您需要以某种方式提供所有必需的依赖项.这里的一个选项就是将这些jar提交到版本控制中.困难的部分是收集所有这些依赖项.为此,可以有一个build.gradle文件,可以在两种模式下运行(在线和离线):

buildscript {
    repositories {
        if ('allow' == System.properties['build.network_access']) {
            mavenCentral()
        } else {
            maven {
                url 'dependencies'
            }
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.0-beta2'
    }
}
Run Code Online (Sandbox Code Playgroud)

要在离线模式下运行,请键入:

gradle --offline
Run Code Online (Sandbox Code Playgroud)

并以在线模式运行:

gradle -Dbuild.network_access=allow
Run Code Online (Sandbox Code Playgroud)

要收集所有依赖项,请使用此脚本,该脚本将在联机模式下运行gradle,获取依赖项以在内部缓存${project_dir}/.gradle_home并将工件复制到dependencies文件夹中的本地maven存储库.

#!/usr/bin/python

import sys
import os
import subprocess
import glob
import shutil

# Place this in build.gradle:
# repositories {
#     if ('allow' == System.properties['build.network_access']) {
#         mavenCentral()
#     } else {
#         maven { url 'dependencies' }
#     }
# }
def main(argv):
    project_dir = os.path.dirname(os.path.realpath(__file__))
    repo_dir = os.path.join(project_dir, "dependencies")
    temp_home = os.path.join(project_dir, ".gradle_home")
    if not os.path.isdir(temp_home):
        os.makedirs(temp_home)
    subprocess.call(["gradle", "-g", temp_home, "-Dbuild.network_access=allow"])
    cache_files = os.path.join(temp_home, "caches/modules-*/files-*")
    for cache_dir in glob.glob(cache_files):
        for cache_group_id in os.listdir(cache_dir):
            cache_group_dir = os.path.join(cache_dir, cache_group_id)
            repo_group_dir = os.path.join(repo_dir, cache_group_id.replace('.', '/'))
            for cache_artifact_id in os.listdir(cache_group_dir):
                cache_artifact_dir = os.path.join(cache_group_dir, cache_artifact_id)
                repo_artifact_dir = os.path.join(repo_group_dir, cache_artifact_id)
                for cache_version_id in os.listdir(cache_artifact_dir):
                    cache_version_dir = os.path.join(cache_artifact_dir, cache_version_id)
                    repo_version_dir = os.path.join(repo_artifact_dir, cache_version_id)
                    if not os.path.isdir(repo_version_dir):
                        os.makedirs(repo_version_dir)
                    cache_items = os.path.join(cache_version_dir, "*/*")
                    for cache_item in glob.glob(cache_items):
                        cache_item_name = os.path.basename(cache_item)
                        repo_item_path = os.path.join(repo_version_dir, cache_item_name)
                        print "%s:%s:%s (%s)" % (cache_group_id, cache_artifact_id, cache_version_id, cache_item_name)
                        shutil.copyfile(cache_item, repo_item_path)
    shutil.rmtree(temp_home)
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv))
Run Code Online (Sandbox Code Playgroud)

因此,在每次依赖项更改后,只需运行此脚本并提交dependencies文件夹中的更改.然后您可以使用gradle --offline或仅使用离线构建gradle.

  • 刚刚制作了一个开源工具,其功能与[GradleCopy](https://github.com/top-master/GradleCopy/releases)上的脚本相同(它是为Windows构建的,但源代码是跨平台的) (2认同)

小智 5

过去,我使用了类似的解决方案,尽管“我的”复制脚本是在 groovy 而不是 python 中完成的。

几周前我发现了另一种方法:有ivypot 插件。现在您不必再使用任何“外部”脚本,该插件能够将所有依赖项复制到一个本地目录中,该目录是一个 ivy 存储库。

可以在 github上找到一个测试项目。如果有需要,我可以提供英文 README。