[gradle] Implement bootstrap mode

Mikolaj Izdebski mizdebsk at fedoraproject.org
Fri Jan 23 10:20:28 UTC 2015


commit e5885f768c037974da0fddfb936c1ac93cfb263b
Author: Mikolaj Izdebski <mizdebsk at redhat.com>
Date:   Fri Jan 23 08:38:48 2015 +0100

    Implement bootstrap mode

 gradle-bootstrap-default-imports.txt   |  146 +++++++++++++++++++++
 gradle-bootstrap-gererate-resources.py |  122 ++++++++++++++++++
 gradle-bootstrap-module-dependencies   |   48 +++++++
 gradle-bootstrap-module-list           |   48 +++++++
 gradle-bootstrap-plugin.properties     |    3 +
 gradle-bootstrap.sh                    |  221 ++++++++++++++++++++++++++++++++
 gradle.spec                            |   62 +++++++++-
 7 files changed, 647 insertions(+), 3 deletions(-)
---
diff --git a/gradle-bootstrap-default-imports.txt b/gradle-bootstrap-default-imports.txt
new file mode 100644
index 0000000..2aed6bc
--- /dev/null
+++ b/gradle-bootstrap-default-imports.txt
@@ -0,0 +1,146 @@
+import org.gradle.*
+import org.gradle.api.*
+import org.gradle.api.artifacts.*
+import org.gradle.api.artifacts.cache.*
+import org.gradle.api.artifacts.component.*
+import org.gradle.api.artifacts.dsl.*
+import org.gradle.api.artifacts.ivy.*
+import org.gradle.api.artifacts.maven.*
+import org.gradle.api.artifacts.query.*
+import org.gradle.api.artifacts.repositories.*
+import org.gradle.api.artifacts.result.*
+import org.gradle.api.component.*
+import org.gradle.api.distribution.*
+import org.gradle.api.distribution.plugins.*
+import org.gradle.api.dsl.*
+import org.gradle.api.execution.*
+import org.gradle.api.file.*
+import org.gradle.api.initialization.*
+import org.gradle.api.initialization.dsl.*
+import org.gradle.api.invocation.*
+import org.gradle.api.java.archives.*
+import org.gradle.api.logging.*
+import org.gradle.api.plugins.*
+import org.gradle.api.plugins.announce.*
+import org.gradle.api.plugins.antlr.*
+import org.gradle.api.plugins.buildcomparison.gradle.*
+import org.gradle.api.plugins.jetty.*
+import org.gradle.api.plugins.osgi.*
+import org.gradle.api.plugins.quality.*
+import org.gradle.api.plugins.scala.*
+import org.gradle.api.plugins.sonar.*
+import org.gradle.api.plugins.sonar.model.*
+import org.gradle.api.publish.*
+import org.gradle.api.publish.ivy.*
+import org.gradle.api.publish.ivy.plugins.*
+import org.gradle.api.publish.ivy.tasks.*
+import org.gradle.api.publish.maven.*
+import org.gradle.api.publish.maven.plugins.*
+import org.gradle.api.publish.maven.tasks.*
+import org.gradle.api.publish.plugins.*
+import org.gradle.api.reporting.*
+import org.gradle.api.reporting.components.*
+import org.gradle.api.reporting.dependencies.*
+import org.gradle.api.reporting.plugins.*
+import org.gradle.api.resources.*
+import org.gradle.api.specs.*
+import org.gradle.api.tasks.*
+import org.gradle.api.tasks.ant.*
+import org.gradle.api.tasks.application.*
+import org.gradle.api.tasks.bundling.*
+import org.gradle.api.tasks.compile.*
+import org.gradle.api.tasks.diagnostics.*
+import org.gradle.api.tasks.incremental.*
+import org.gradle.api.tasks.javadoc.*
+import org.gradle.api.tasks.scala.*
+import org.gradle.api.tasks.testing.*
+import org.gradle.api.tasks.testing.junit.*
+import org.gradle.api.tasks.testing.testng.*
+import org.gradle.api.tasks.util.*
+import org.gradle.api.tasks.wrapper.*
+import org.gradle.buildinit.plugins.*
+import org.gradle.buildinit.tasks.*
+import org.gradle.external.javadoc.*
+import org.gradle.ide.cdt.*
+import org.gradle.ide.cdt.tasks.*
+import org.gradle.ide.visualstudio.*
+import org.gradle.ide.visualstudio.plugins.*
+import org.gradle.ide.visualstudio.tasks.*
+import org.gradle.jvm.*
+import org.gradle.jvm.platform.*
+import org.gradle.jvm.plugins.*
+import org.gradle.jvm.toolchain.*
+import org.gradle.language.*
+import org.gradle.language.assembler.*
+import org.gradle.language.assembler.plugins.*
+import org.gradle.language.assembler.tasks.*
+import org.gradle.language.base.*
+import org.gradle.language.base.artifact.*
+import org.gradle.language.base.plugins.*
+import org.gradle.language.c.*
+import org.gradle.language.c.plugins.*
+import org.gradle.language.c.tasks.*
+import org.gradle.language.cpp.*
+import org.gradle.language.cpp.plugins.*
+import org.gradle.language.cpp.tasks.*
+import org.gradle.language.java.*
+import org.gradle.language.java.artifact.*
+import org.gradle.language.java.plugins.*
+import org.gradle.language.java.tasks.*
+import org.gradle.language.jvm.*
+import org.gradle.language.jvm.plugins.*
+import org.gradle.language.jvm.tasks.*
+import org.gradle.language.nativeplatform.*
+import org.gradle.language.nativeplatform.tasks.*
+import org.gradle.language.objectivec.*
+import org.gradle.language.objectivec.plugins.*
+import org.gradle.language.objectivec.tasks.*
+import org.gradle.language.objectivecpp.*
+import org.gradle.language.objectivecpp.plugins.*
+import org.gradle.language.objectivecpp.tasks.*
+import org.gradle.language.rc.*
+import org.gradle.language.rc.plugins.*
+import org.gradle.language.rc.tasks.*
+import org.gradle.nativeplatform.*
+import org.gradle.nativeplatform.platform.*
+import org.gradle.nativeplatform.plugins.*
+import org.gradle.nativeplatform.tasks.*
+import org.gradle.nativeplatform.test.*
+import org.gradle.nativeplatform.test.cunit.*
+import org.gradle.nativeplatform.test.cunit.plugins.*
+import org.gradle.nativeplatform.test.cunit.tasks.*
+import org.gradle.nativeplatform.test.plugins.*
+import org.gradle.nativeplatform.test.tasks.*
+import org.gradle.nativeplatform.toolchain.*
+import org.gradle.nativeplatform.toolchain.plugins.*
+import org.gradle.platform.base.*
+import org.gradle.platform.base.binary.*
+import org.gradle.platform.base.component.*
+import org.gradle.platform.base.test.*
+import org.gradle.plugin.use.*
+import org.gradle.plugins.ear.*
+import org.gradle.plugins.ear.descriptor.*
+import org.gradle.plugins.ide.api.*
+import org.gradle.plugins.ide.eclipse.*
+import org.gradle.plugins.ide.idea.*
+import org.gradle.plugins.javascript.base.*
+import org.gradle.plugins.javascript.coffeescript.*
+import org.gradle.plugins.javascript.envjs.*
+import org.gradle.plugins.javascript.envjs.browser.*
+import org.gradle.plugins.javascript.envjs.http.*
+import org.gradle.plugins.javascript.envjs.http.simple.*
+import org.gradle.plugins.javascript.jshint.*
+import org.gradle.plugins.javascript.rhino.*
+import org.gradle.plugins.javascript.rhino.worker.*
+import org.gradle.plugins.signing.*
+import org.gradle.plugins.signing.signatory.*
+import org.gradle.plugins.signing.signatory.pgp.*
+import org.gradle.plugins.signing.type.*
+import org.gradle.plugins.signing.type.pgp.*
+import org.gradle.process.*
+import org.gradle.sonar.runner.*
+import org.gradle.sonar.runner.plugins.*
+import org.gradle.sonar.runner.tasks.*
+import org.gradle.testing.jacoco.plugins.*
+import org.gradle.testing.jacoco.tasks.*
+import org.gradle.util.*
diff --git a/gradle-bootstrap-gererate-resources.py b/gradle-bootstrap-gererate-resources.py
new file mode 100755
index 0000000..b839c30
--- /dev/null
+++ b/gradle-bootstrap-gererate-resources.py
@@ -0,0 +1,122 @@
+#!/usr/bin/python
+#
+# Parse Gradle module structure and generate resource files which are
+# used to bootstrap Gradle.
+#
+# First file, gradle-bootstrap-module-list, contains list of Gradle
+# modules sorted by dependencies.  First module doesn't depend on any
+# other module.  All subsequent modules can depend only on modules
+# listed above them.  This is the order in which modules should be
+# compiled.
+#
+# A second file, gradle-bootstrap-module-dependencies, contains list
+# of dependecies for each module.
+#
+# Author: Mikolaj Izdebski <mizdebsk at redhat.com>
+
+import sys
+from glob import glob
+from zipfile import ZipFile
+
+
+class GradleModule(object):
+    def __init__(self, path):
+        self.name = path[path.rindex("/") + 1 : path.rindex("-")]
+        self.path = path
+        self.dependencies = []
+
+    def read_dependencies(self):
+        with ZipFile(self.path) as jar:
+            props_name = self.name + "-classpath.properties"
+            with jar.open(props_name, "rU") as props:
+                for line in [line.rstrip() for line in props.readlines()]:
+                    if line.startswith("projects=") and line[9:]:
+                        self.dependencies = line[9:].split(",")
+
+    def __eq__(self, other):
+        return self.name == other.name
+
+    def __hash__(self):
+        return hash(self.name)
+
+
+# Read all Gradle modules from given Gradle home directory
+def read_gradle_modules(gradle_home):
+    paths = []
+    for pattern in ["/lib/gradle-*.jar", "/lib/plugins/gradle-*.jar"]:
+        paths.extend(glob(gradle_home + pattern))
+
+    return [GradleModule(path) for path in paths]
+
+
+# Resolve module dependencies to concrete modules
+def resolve_dependencies(modules, mapping):
+    for module in modules:
+        module.read_dependencies()
+        resolved_deps = []
+        for dep in module.dependencies:
+            resolved_dep = mapping.get(dep, None)
+            if not resolved_dep:
+                raise RuntimeError("Unresolved dependency from %s to %s" % (module.name, dep))
+            resolved_deps.append(resolved_dep)
+        module.dependencies = resolved_deps
+
+
+# Sort modules in-situ, placing them in dependency order
+def topological_sort(modules):
+    not_visited = set(modules)
+    visiting = set()
+    del modules[:]
+
+    def visit(module):
+        visiting.add(module)
+        for dependency in module.dependencies:
+            if dependency in visiting:
+                raise RuntimeError("module dependency cycle detected")
+            if dependency in not_visited:
+                visit(dependency)
+        modules.append(module)
+        not_visited.remove(module)
+        visiting.remove(module)
+
+    while not_visited:
+        visit(next(iter(not_visited)))
+
+    return modules
+
+
+# Extract a single resource from given module
+def extract_resource(module, resource, target_file):
+    with ZipFile(module.path) as jar:
+        with open(target_file, "w") as f:
+            f.write(jar.read(resource))
+
+
+if len(sys.argv) != 2:
+    sys.exit("Missing argument, usage: %s <path-to-unpacked-gradle-binary-distribution>" % sys.argv[0])
+gradle_home = sys.argv[1]
+
+modules = read_gradle_modules(gradle_home)
+if not modules:
+    sys.exit("Unable to find any Gradle modules in specifed location")
+
+module_mapping = dict((module.name, module) for module in modules)
+
+resolve_dependencies(modules, module_mapping)
+
+topological_sort(modules)
+
+
+# Generate file with sorted module list
+with open("gradle-bootstrap-module-list", "w") as f:
+    for module in modules:
+        f.write("%s\n" % module.name)
+
+# Generate file with module dependencies
+with open("gradle-bootstrap-module-dependencies", "w") as f:
+    for module in modules:
+        f.write("%s=%s\n" % (module.name, ",".join(dep.name for dep in module.dependencies)))
+
+# Extract some other resoures from Gradle JARs
+extract_resource(module_mapping["gradle-docs"], "default-imports.txt", "gradle-bootstrap-default-imports.txt")
+extract_resource(module_mapping["gradle-core"], "gradle-plugins.properties", "gradle-bootstrap-plugin.properties")
diff --git a/gradle-bootstrap-module-dependencies b/gradle-bootstrap-module-dependencies
new file mode 100644
index 0000000..0b02d10
--- /dev/null
+++ b/gradle-bootstrap-module-dependencies
@@ -0,0 +1,48 @@
+gradle-docs=
+gradle-base-services=
+gradle-model-core=gradle-base-services
+gradle-base-services-groovy=gradle-base-services
+gradle-model-groovy=gradle-base-services-groovy,gradle-model-core
+gradle-cli=
+gradle-native=gradle-base-services
+gradle-messaging=gradle-base-services
+gradle-resources=gradle-base-services,gradle-messaging
+gradle-core=gradle-docs,gradle-model-core,gradle-model-groovy,gradle-cli,gradle-native,gradle-base-services,gradle-base-services-groovy,gradle-messaging,gradle-resources
+gradle-platform-base=gradle-core
+gradle-platform-jvm=gradle-platform-base,gradle-core
+gradle-language-jvm=gradle-platform-jvm,gradle-platform-base
+gradle-resources-http=gradle-resources,gradle-base-services
+gradle-dependency-management=gradle-core,gradle-resources-http
+gradle-reporting=gradle-core
+gradle-language-java=gradle-core,gradle-platform-jvm,gradle-language-jvm
+gradle-language-groovy=gradle-platform-jvm,gradle-language-java
+gradle-plugins=gradle-core,gradle-dependency-management,gradle-reporting,gradle-platform-jvm,gradle-language-jvm,gradle-language-java,gradle-language-groovy
+gradle-scala=gradle-core,gradle-language-jvm,gradle-plugins
+gradle-open-api=
+gradle-ui=gradle-core,gradle-open-api
+gradle-wrapper=gradle-cli
+gradle-tooling-api=gradle-core,gradle-messaging,gradle-wrapper,gradle-base-services
+gradle-launcher=gradle-base-services,gradle-core,gradle-cli,gradle-ui,gradle-tooling-api,gradle-native
+gradle-ear=gradle-core,gradle-plugins
+gradle-ide=gradle-scala,gradle-core,gradle-launcher,gradle-plugins,gradle-ear,gradle-tooling-api
+gradle-code-quality=gradle-core,gradle-plugins,gradle-reporting
+gradle-osgi=gradle-core,gradle-plugins
+gradle-build-init=gradle-core,gradle-plugins,gradle-wrapper
+gradle-jetty=gradle-core,gradle-plugins
+gradle-platform-native=gradle-core,gradle-platform-base
+gradle-language-native=gradle-core,gradle-platform-native
+gradle-ide-native=gradle-core,gradle-ide,gradle-platform-native,gradle-language-native
+gradle-plugin-use=gradle-core,gradle-dependency-management,gradle-resources-http
+gradle-javascript=gradle-core,gradle-plugins,gradle-dependency-management
+gradle-jacoco=gradle-core,gradle-plugins,gradle-reporting
+gradle-sonar=gradle-core,gradle-plugins,gradle-jacoco
+gradle-announce=gradle-core
+gradle-build-comparison=gradle-resources,gradle-core,gradle-tooling-api,gradle-reporting,gradle-plugins,gradle-ear
+gradle-publish=gradle-core,gradle-dependency-management
+gradle-maven=gradle-core,gradle-dependency-management,gradle-plugins,gradle-publish
+gradle-signing=gradle-core,gradle-plugins,gradle-maven
+gradle-plugin-development=gradle-core,gradle-plugins
+gradle-antlr=gradle-core,gradle-plugins
+gradle-ivy=gradle-core,gradle-publish,gradle-plugins,gradle-dependency-management
+gradle-diagnostics=gradle-core,gradle-reporting,gradle-plugins,gradle-platform-native,gradle-language-native,gradle-dependency-management
+gradle-cunit=gradle-core,gradle-platform-native,gradle-language-native
diff --git a/gradle-bootstrap-module-list b/gradle-bootstrap-module-list
new file mode 100644
index 0000000..75d4166
--- /dev/null
+++ b/gradle-bootstrap-module-list
@@ -0,0 +1,48 @@
+gradle-docs
+gradle-base-services
+gradle-model-core
+gradle-base-services-groovy
+gradle-model-groovy
+gradle-cli
+gradle-native
+gradle-messaging
+gradle-resources
+gradle-core
+gradle-platform-base
+gradle-platform-jvm
+gradle-language-jvm
+gradle-resources-http
+gradle-dependency-management
+gradle-reporting
+gradle-language-java
+gradle-language-groovy
+gradle-plugins
+gradle-scala
+gradle-open-api
+gradle-ui
+gradle-wrapper
+gradle-tooling-api
+gradle-launcher
+gradle-ear
+gradle-ide
+gradle-code-quality
+gradle-osgi
+gradle-build-init
+gradle-jetty
+gradle-platform-native
+gradle-language-native
+gradle-ide-native
+gradle-plugin-use
+gradle-javascript
+gradle-jacoco
+gradle-sonar
+gradle-announce
+gradle-build-comparison
+gradle-publish
+gradle-maven
+gradle-signing
+gradle-plugin-development
+gradle-antlr
+gradle-ivy
+gradle-diagnostics
+gradle-cunit
diff --git a/gradle-bootstrap-plugin.properties b/gradle-bootstrap-plugin.properties
new file mode 100644
index 0000000..d8b5eb1
--- /dev/null
+++ b/gradle-bootstrap-plugin.properties
@@ -0,0 +1,3 @@
+#plugin definitions
+#Mon Nov 24 10:47:09 CET 2014
+plugins=gradle-plugins,gradle-code-quality,gradle-jetty,gradle-antlr,gradle-wrapper,gradle-osgi,gradle-maven,gradle-ide,gradle-announce,gradle-scala,gradle-sonar,gradle-signing,gradle-ear,gradle-javascript,gradle-build-comparison,gradle-diagnostics,gradle-reporting,gradle-publish,gradle-ivy,gradle-jacoco,gradle-build-init,gradle-platform-base,gradle-platform-jvm,gradle-language-jvm,gradle-language-java,gradle-language-groovy,gradle-platform-native,gradle-language-native,gradle-ide-native,gradle-cunit,gradle-plugin-development,gradle-plugin-use
diff --git a/gradle-bootstrap.sh b/gradle-bootstrap.sh
new file mode 100755
index 0000000..a8c4f40
--- /dev/null
+++ b/gradle-bootstrap.sh
@@ -0,0 +1,221 @@
+#!/bin/sh
+# Build Gradle with plain groovyc
+#
+# Usage: $0 <path-to-module-list> <path-to-module-dependencies>
+#
+# Author: Mikolaj Izdebski <mizdebsk at redhat.com>
+
+set -e
+test $# -eq 2
+
+LANG=en_US.utf8
+
+# External dependencies needed by Gradle.
+external_deps="
+aether-ant-tasks/aether-ant-tasks
+aether/aether-api
+aether/aether-connector-basic
+aether/aether-impl
+aether/aether-spi
+aether/aether-transport-classpath
+aether/aether-transport-file
+aether/aether-transport-http
+aether/aether-transport-wagon
+aether/aether-util
+ant/ant
+ant/ant-antlr
+ant/ant-junit
+ant/ant-launcher
+antlr
+apache-commons-collections
+apache-commons-configuration
+apache-commons-lang
+apache-ivy/ivy
+aqute-bndlib
+atinject
+base64coder
+bcpg
+bcprov
+bea-stax
+bea-stax-api
+beust-jcommander
+bsf
+bsh
+cglib
+commons-cli
+commons-codec
+commons-io
+commons-logging
+dom4j
+ecj
+extra166y
+felix/org.osgi.core
+findbugs
+geronimo-annotation
+geronimo-jms
+glassfish-servlet-api
+google-gson/gson
+gpars/gpars
+groovy/groovy-all
+guava
+guava-jdk5
+hamcrest/core
+hawtjni/hawtjni-runtime
+httpcomponents/httpclient
+httpcomponents/httpcore
+isorelax
+jansi-native/jansi-native
+jansi/jansi
+jarjar/jarjar
+jatl
+javamail/javax.mail
+jaxen
+jcifs
+jcip-annotations
+jcsp
+jdom
+jdom2/jdom2
+jettison/jettison
+jetty/jetty-annotations
+jetty/jetty-jsp
+jetty/jetty-plus
+jetty/jetty-security
+jetty/jetty-server
+jetty/jetty-servlet
+jetty/jetty-util
+jetty/jetty-webapp
+jetty/jetty-xml
+jline/jline
+jna
+joda-convert
+joda-time
+js
+jsch
+junit
+jzlib
+kryo
+kxml
+kxml-min
+log4j-1.2.17
+logback/logback-classic
+logback/logback-core
+maven-wagon/http
+maven-wagon/http-shared
+maven-wagon/provider-api
+maven/maven-aether-provider
+maven/maven-artifact
+maven/maven-compat
+maven/maven-core
+maven/maven-model
+maven/maven-model-builder
+maven/maven-plugin-api
+maven/maven-repository-metadata
+maven/maven-settings
+maven/maven-settings-builder
+minlog
+msv-core
+multiverse/multiverse-core
+native-platform
+nekohtml
+netty3-3.6.6
+objectweb-asm/asm-all
+objenesis/objenesis
+org.eclipse.sisu.plexus
+plexus-classworlds
+plexus-containers/plexus-component-annotations
+plexus-containers/plexus-container-default
+plexus/interpolation
+plexus/plexus-cipher
+plexus/plexus-sec-dispatcher
+plexus/utils
+qdox
+reflectasm
+relaxngDatatype/relaxngDatatype
+simple
+slf4j/jcl-over-slf4j
+slf4j/jul-to-slf4j
+slf4j/log4j-over-slf4j
+slf4j/slf4j-api
+snakeyaml
+sonar/sonar-batch
+sonar/sonar-batch-bootstrapper
+sonar/sonar-core
+sonar/sonar-deprecated
+sonar/sonar-java-api
+sonar/sonar-plugin-api
+sonar/sonar-squid
+stax2-api
+tesla-polyglot/tesla-polyglot-common
+tesla-polyglot/tesla-polyglot-groovy
+testng
+woodstox-core
+xalan-j2
+xalan-j2-serializer
+xbean/xbean-reflect
+xerces-j2
+xml-commons-apis
+xml-commons-resolver
+xom
+xsdlib
+xstream/xstream
+"
+
+# Generate some dummy build properties - they don't need to be 100 % correct.
+cat <<EOF >subprojects/core/src/main/resources/org/gradle/build-receipt.properties
+buildNumber=none
+buildTimestamp=20150101000000+0000
+commitId=foo
+hostname=localhost
+isSnapshot=false
+javaVersion=1.8.0
+osName=Linux
+osVersion=3.1.0
+project=gradle
+rcNumber=
+username=mock
+versionBase=2.0
+versionNumber=2.0
+EOF
+
+rm -rf bootstrap-home
+mkdir -p bootstrap-home/lib/plugins
+
+echo "******************************"
+echo "*** GRADLE BOOTSTRAP BUILD ***"
+echo "******************************"
+
+echo "== finding external dependencies..."
+build-jar-repository -s -p bootstrap-home/lib/plugins $external_deps
+for old in bootstrap-home/lib/plugins/*; do
+    new=${old/.jar/}-00.jar
+    new=${new///*_//lib/plugins/}
+    mv $old $new
+done
+classpath=$(build-classpath $external_deps)
+
+dep_runtime=$(ls bootstrap-home/lib/plugins | xargs | sed s/\ /,/g)
+
+rm -rf bootstrap-classes
+mkdir bootstrap-classes
+
+for mod in $(cat "$1"); do
+    classes_dir=bootstrap-classes/$mod
+    mkdir -p $classes_dir
+    srcdirs=""
+    for lang in groovy java; do
+	dir=subprojects/${mod/gradle-/}/src/main/$lang
+	[[ -d $dir ]] && srcdirs="$srcdirs $dir"
+    done
+    if [[ -n "$srcdirs" ]]; then
+	echo "== groovyc $mod..."
+	groovyc -cp $classpath -j -d $classes_dir $(find $srcdirs -name *.java -o -name *.groovy)
+    fi
+    jar=$PWD/bootstrap-home/lib/$mod-00.jar
+    (cd ./$classes_dir && jar cf $jar .)
+    resources_dir=subprojects/${mod/gradle-/}/src/main/resources
+    mkdir -p $resources_dir
+    sed -n "/^$mod=/{s//projects=/;p}" "$2" >$resources_dir/$mod-classpath.properties
+    echo "runtime=$dep_runtime" >>$resources_dir/$mod-classpath.properties
+    (cd ./subprojects/${mod/gradle-/}/src/main/resources && jar uf $jar .)
+    classpath=$classpath:$jar
+done
diff --git a/gradle.spec b/gradle.spec
index 0aa551b..fcf79a2 100644
--- a/gradle.spec
+++ b/gradle.spec
@@ -1,3 +1,16 @@
+# Gradle depends on itself for building.  This can be problematic, for
+# example when some library it uses changes API, Gradle may stop
+# working and it may be impossible to rebuild it in normal way.
+#
+# For cases like that bootstrap mode can be used.  In this mode a
+# minimal working version of Gradle is built with plain groovyc.  The
+# only purpose of bootstrapped Gradle is to rebuild itself.  Gradle
+# built using bootstrap mode doesn't have all features, for example it
+# doesn't provide Maven metadata, and it may have some functionality
+# missing.  For this reason a normal non-bootstrap build should be
+# done immediately after Gradle is bootstrapped.
+%bcond_with bootstrap
+
 Name:           gradle
 Version:        2.2.1
 Release:        1%{?dist}
@@ -16,6 +29,19 @@ Source4:        gradle-launcher.sh
 Source5:        gradle.desktop
 Source6:        GradleResolver.java
 
+# Sources 99xx are used only for bootstrapping.
+# Main script used to build gradle with plain groovyc
+Source9900:     gradle-bootstrap.sh
+# Script used to generate Source991x from upstream binaries
+Source9901:     gradle-bootstrap-gererate-resources.py
+# Files containing information about Gradle module structure
+Source9910:     gradle-bootstrap-module-list
+Source9911:     gradle-bootstrap-module-dependencies
+# List of default imorts, extracted from gradle-docs.jar
+Source9920:     gradle-bootstrap-default-imports.txt
+# List of Gradle plugins, extracted from gradle-core.jar
+Source9921:     gradle-bootstrap-plugin.properties
+
 Patch0:         0001-Gradle-local-mode.patch
 Patch1:         0002-Use-Maven-Wagon-2.8.patch
 Patch2:         0003-Use-bndlib-1.50.0.patch
@@ -30,8 +56,15 @@ Patch8:         0009-Use-hostname-command-as-fallback-way-of-getting-buil.patch
 Patch9:         0010-Compatibility-with-Guava-18.0.patch
 Patch10:        0011-Add-build-dependency-on-ASM-5.0.3.patch
 
-# Generic build dependencies
+# Dependencies on build system used.  In bootstrap mode we use plain
+# groovyc to compile Gradle, otherwise Gradle is built with itself.
+%if %{with bootstrap}
+BuildRequires:  groovy >= 2.3
+%else
 BuildRequires:  gradle-local >= 2.2
+%endif
+
+# Generic build dependencies
 BuildRequires:  desktop-file-utils
 BuildRequires:  hostname
 
@@ -421,17 +454,39 @@ rm -rf buildSrc/src/test
 sed -i 's/"-Werror" <<//' gradle/strictCompile.gradle
 
 %build
+%if %{with bootstrap}
+mkdir -p subprojects/docs/src/main/resources && cp %{SOURCE9920} subprojects/docs/src/main/resources/default-imports.txt
+cp %{SOURCE9921} subprojects/core/src/main/resources/gradle-plugins.properties
+%{SOURCE9900} %{SOURCE9910} %{SOURCE9911}
+%else
 gradle -x docs:distDocs --offline -s install -Pgradle_installPath=$PWD/inst \
     -PfinalRelease -Dbuild.number="%{?fedora:Fedora }%{?rhel:Red Hat }%{version}-%{release}"
+%endif
 
 # Build and assemble XMvn connector for Gradle
 mkdir -p local/org/fedoraproject/xmvn/connector/gradle
 cd ./local
 cp %{SOURCE6} org/fedoraproject/xmvn/connector/gradle/
-javac -cp $(echo ../subprojects/core/build/libs/gradle-core-%{version}*.jar):$(echo ../subprojects/dependency-management/build/libs/gradle-dependency-management-%{version}*.jar):$(echo ../subprojects/resources/build/libs/gradle-resources-%{version}*.jar):$(echo ../subprojects/base-services/build/libs/gradle-base-services-%{version}*.jar):$(build-classpath xmvn/xmvn-api xmvn/xmvn-launcher slf4j/api ivy) $(find -name *.java)
+%if %{with bootstrap}
+gradle_classpath=../bootstrap-home/lib/gradle-core-00.jar:../bootstrap-home/lib/gradle-dependency-management-00.jar:../bootstrap-home/lib/gradle-resources-00.jar:../bootstrap-home/lib/gradle-base-services-00.jar
+%else
+gradle_classpath="$(echo ../subprojects/core/build/libs/gradle-core-%{version}*.jar):$(echo ../subprojects/dependency-management/build/libs/gradle-dependency-management-%{version}*.jar):$(echo ../subprojects/resources/build/libs/gradle-resources-%{version}*.jar):$(echo ../subprojects/base-services/build/libs/gradle-base-services-%{version}*.jar)"
+%endif
+javac -cp $gradle_classpath:$(build-classpath xmvn/xmvn-api xmvn/xmvn-launcher slf4j/api ivy) $(find -name *.java)
 jar cf xmvn-connector-gradle.jar org
 
 %install
+install -d -m 755 %{buildroot}%{_javadir}/%{name}/
+
+%if %{with bootstrap}
+cp -r bootstrap-home %{buildroot}%{_datadir}/%{name}
+for mod in launcher core base-services; do
+    ln -s %{_datadir}/%{name}/lib/gradle-$mod-00.jar %{buildroot}%{_javadir}/%{name}/gradle-$mod.jar
+done
+cp subprojects/distributions/src/toplevel/{changelog.txt,LICENSE,NOTICE} .
+echo > .mfiles
+%else
+
 repo=$HOME/.m2/repository
 
 install -d -m 755 %{buildroot}%{_datadir}/%{name}/
@@ -446,7 +501,6 @@ ln -sf %{_javadir}/jarjar/jarjar.jar %{buildroot}%{_datadir}/%{name}/lib/jarjar-
 # Symlink most of dependency JARs
 xmvn-subst %{buildroot}%{_datadir}/%{name}/lib/
 
-install -d -m 755 %{buildroot}%{_javadir}/%{name}/
 
 for f in gradle-base-services gradle-base-services-groovy gradle-cli gradle-core gradle-docs \
          gradle-launcher gradle-messaging gradle-model-core gradle-model-groovy gradle-native \
@@ -476,6 +530,8 @@ do
     ln -sf %{_javadir}/%{name}/$mod.jar %{buildroot}%{_datadir}/%{name}/lib/$f-%{version}*.jar
 done
 
+%endif
+
 # Install XMvn connector for Gradle. This should eventually be moved to XMvn.
 %mvn_artifact org.fedoraproject.xmvn:xmvn-connector-gradle:2.1.0-SNAPSHOT local/xmvn-connector-gradle.jar
 %mvn_package ":xmvn*" local


More information about the scm-commits mailing list