gradle offline

Construir repositorio Gradle para el desarrollo fuera de línea



offline (2)

Estoy trabajando en la implementación de un sistema de compilación Gradle para una pieza de software que tiene partes desarrolladas en un área sin conectividad a Internet o la capacidad de instalar un servidor Maven / Ivy (como Nexus). Para apoyar el desarrollo en estos entornos, estoy creando un complemento de Gradle que permite la generación de un "Área de trabajo sin conexión".

Originalmente implementé esta funcionalidad activando la resolución de cada configuración en el proyecto (activando la descarga de todas las dependencias), luego atravesando el árbol de dependencias completo de cada configuración y copiando la copia local en caché de la dependencia en el área de trabajo fuera de línea. (Se generó una tarea de Copia para cada operación de copia). Luego se haría referencia a estos JAR utilizando un repositorio de flatDir.

Esta implementación realizó su trabajo utilizando un bloque afterEvaluate. Si bien esto funcionó bien en Gradle 2.0, activa una advertencia de desaprobación en Gradle 2.2.1 porque de alguna manera se considera que la activación de la resolución modifica una configuración después de que ya se haya resuelto ( 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 ). En general, este enfoque se siente bastante intrépido ya que también me obliga a modificar los archivos build.gradle para enumerar explícitamente todas las dependencias transitivas, ya que no hay archivos POM disponibles para especificar adecuadamente las dependencias.

Un enfoque más elegante parece que construiría un repositorio local de Maven de todas las dependencias (incluidos los archivos POM, los archivos JAR de origen, los archivos JAR de javadoc, etc.) y luego solo usaría el tipo de repositorio mavenLocal (). Desafortunadamente, no estoy seguro de cómo hacer esto correctamente donde no necesito activar la resolución de artefactos para realizar esta operación.

¿Hay alguna mejor manera de lograr la descarga completa de artefactos de una manera fácil de empaquetar que simplemente comprimiendo todo mi directorio $ USER_HOME / .gradle?


En el pasado, usé una solución similar, aunque "mi" script de copia se realizó en groovy en lugar de python.

Detecté otro enfoque hace un par de semanas: existe el complemento ivypot . Ahora ya no tiene que usar ningún script "externo", el complemento puede copiar todas las dependencias en un directorio local que es un repositorio de hiedra.

Un proyecto de prueba se puede encontrar en github . Puedo proporcionar un README en inglés en caso de que haya demanda para ello.


Para tener una compilación fuera de línea, debe proporcionar de alguna manera todas las dependencias necesarias. Una de las opciones aquí es simplemente comprometer esos archivos jar en el control de versiones. La parte difícil es recoger todas esas dependencias. Para eso es posible tener un archivo build.gradle que pueda operar en dos modos (en línea y fuera de línea):

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

Para ejecutar en modo sin conexión escriba:

gradle --offline

Y para ejecutar en modo online:

gradle -Dbuild.network_access=allow

Y para recopilar todas las dependencias, use este script que ejecutará gradle en modo en línea, busque las dependencias para almacenar en caché dentro de ${project_dir}/.gradle_home y copie los artefactos en el repositorio local de Maven en dependencies carpeta de dependencies .

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

Entonces, después de cada cambio de dependencia, simplemente ejecute este script y confirme los cambios en dependencies carpeta de dependencies . Entonces puedes construir offline con gradle --offline o solo gradle .