为脱机开发构建Gradle存储库 [英] Build Gradle repository for offline development

查看:131
本文介绍了为脱机开发构建Gradle存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在致力于为部分软件实施Gradle构建系统,这些软件具有在没有互联网连接的情况下开发的部件或者安装Maven / Ivy服务器(如Nexus)的能力。为了支持在这些环境中的开发,我将放置一个允许生成离线工作区的Gradle插件。



我最初通过触发项目中的每个配置(触发所有依赖项的下载),然后遍历每个配置的整个依赖关系树,并将依赖项的本地缓存副本复制到脱机工作区中。 (为每个复制操作生成一个复制任务。)然后,这些JAR将使用flatDir存储库进行引用。



该实现使用afterEvaluate块执行其作业。虽然这在Gradle 2.0中运行良好,但它会在Gradle 2.2.1中触发弃用警告,因为触发解析器在某种程度上被视为在配置已被解析后修改配置(尝试更改配置):core:运行时'之后,它已被包含在依赖关系解析中。这种行为已被弃用,并计划在Gradle 3.0中删除)。总之,这种方法感觉相当不好,因为它还需要我修改build.gradle文件来显式列出所有传递依赖项,因为没有POM文件可用于正确指定依赖项。



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



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

解决方案

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

  buildscript {
repositories {
if('allow'== System.properties ['build.network_access']){
mavenCentral()
} else {
maven {
url'依赖关系'
}
}
}
依赖关系{
classpath'com.android.tools.build:gradle: 1.2.0-beta2'
}
}

要以离线模式运行键入:

  gradle --offline 

以在线模式运行:

  gradle -Dbuild.network_access =允许

为了收集所有的依赖关系,使用这个脚本在联机模式下运行gradle,获取依赖关系缓存在 $ {project_dir} /。gradle_home a在依赖关系文件夹中拷贝工件到本地maven仓库。


$ b

 #!/ usr / bin / python 

导入sys
导入os
导入子过程
导入glob
导入shutil

#把它放在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 )
如果不是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 i n glob.glob(cache_files):
用于os.listdir(cache_dir)中的cache_group_id:
cache_group_dir = os.path.join(cache_dir,cache_group_id)
repo_group_dir = os.path.join( repo_dir,cache_group_id.replace(, '/' ''))
为cache_artifact_id在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)
为cache_version_id在os.listdir(cache_artifact_dir):
cache_version_dir = os.path.join(cache_artifact_dir,cache_version_id)
repo_version_dir = os.path中。加入(repo_artifact_dir,cache_version_id)
如果不os.path.isdir(repo_version_dir):
os.makedirs(repo_version_dir)
cache_items = os.path.join(cache_version_dir,* / * )
用于cache_item在glob.glob(cache_items):
cache_item_name = os.path.basename(cache_item)
repo_item_path = os.path.join(repo_version_dir,cache_item_name)
打印%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)
返回0

if __name__ ==__main__:
sys.exit(main(sys.argv))

因此,每次依赖关系更改后,只需运行此脚本并在依赖关系文件夹中提交更改。然后你可以使用 gradle --offline 或者只是 gradle 来离线构建。


I am working on implementing a Gradle build system for a piece of software that has parts that are developed in area without Internet connectivity or the ability to install a Maven/Ivy server (like Nexus). To support development in these environments, I am putting together a Gradle plugin that allows the generation of an "Offline Workspace".

I originally implemented this functionality by triggering the resolution of each configuration in the project (triggering the download of all dependencies), then traversing the entire dependency tree of each configuration and copying the local cached copy of the dependency into the Offline Workspace. (A Copy task was generated for each copy operation.) These JARs would then be referenced using a flatDir repository.

This implementation performed its job using an afterEvaluate block. While this worked fine in Gradle 2.0, it triggers a deprecation warning in Gradle 2.2.1 because triggering the resolution is somehow seen as modifying a configuration after it has already been resolved (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). In all, this approach feels rather hacky since it also requires me to modify the build.gradle files to explicitly list all transitive dependencies since there are no POM files available to properly specify dependencies.

A more elegant approach seems like it would build a local Maven repository of all dependencies (including POM files, source JARs, javadoc JARs, etc) and then just use the mavenLocal() repository type. Unfortunately, I'm not sure how to do this properly where I don't need to trigger artifact resolution in order to perform this operation.

Is there some better way that I can achieve the full artifact download into an easy-to-package way than just zipping up my entire $USER_HOME/.gradle directory?

解决方案

To have an offline build you need somehow to provide all required dependencies. One of the options here is just to commit those jars into version control. The hard part is to collect all those dependencies. For that it's possible to have a build.gradle file that can operate in two modes (online and offline):

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'
    }
}

To run in offline mode type:

gradle --offline

And to run in online mode:

gradle -Dbuild.network_access=allow

And to collect all dependencies use this script that will run gradle in online mode, fetch dependencies to cache inside ${project_dir}/.gradle_home and copy artifacts to local maven repository in dependencies folder.

#!/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))

So, after each dependency change just run this script and commit changes in dependencies folder. Then you can build offline with gradle --offline or just gradle.

这篇关于为脱机开发构建Gradle存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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