no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / mobile / android / gradle.configure
blobd13290c1d9a082627e7c9d59cbac5660b526acde
1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
2 # vim: set filetype=python:
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 # If --with-gradle is specified, build mobile/android with Gradle.  If no
8 # Gradle binary is specified use the in tree Gradle wrapper.  The wrapper
9 # downloads and installs Gradle, which is good for local developers but not
10 # good in automation.
11 option(
12     "--without-gradle",
13     nargs="?",
14     help="Disable building mobile/android with Gradle "
15     "(argument: location of binary or wrapper (gradle/gradlew))",
19 @depends("--with-gradle")
20 def with_gradle(value):
21     if not value:
22         die(
23             "Building --without-gradle is no longer supported: "
24             "see https://bugzilla.mozilla.org/show_bug.cgi?id=1414415."
25         )
27     if value:
28         return True
31 @depends(host, "--with-gradle", build_environment)
32 @imports(_from="os.path", _import="isfile")
33 def gradle(host, value, build_env):
34     if len(value):
35         gradle = value[0]
36     else:
37         gradle = os.path.join(build_env.topsrcdir, "gradlew")
38         if host.os == "WINNT":
39             gradle = gradle + ".bat"
41     # TODO: verify that $GRADLE is executable.
42     if not isfile(gradle):
43         die("GRADLE must be executable: %s", gradle)
45     return gradle
48 set_config("GRADLE", gradle)
51 @dependable
52 @imports(_from="itertools", _import="chain")
53 def gradle_android_build_config():
54     def capitalize(s):
55         # str.capitalize lower cases trailing letters.
56         if s:
57             return s[0].upper() + s[1:]
58         else:
59             return s
61     def variant(productFlavors, buildType):
62         return namespace(
63             productFlavors=productFlavors,
64             buildType=buildType,
65             # Like 'WithoutGeckoBinariesDebug'
66             name="".join(capitalize(t) for t in chain(productFlavors, (buildType,))),
67         )
69     return namespace(
70         geckoview=namespace(
71             variant=variant(("withGeckoBinaries",), "debug"),
72         ),
73         geckoview_example=namespace(
74             variant=variant(("withGeckoBinaries",), "debug"),
75         ),
76     )
79 @depends(gradle_android_build_config)
80 def gradle_android_intermediates_folder(build_config):
81     """Path to intermediates classes folder."""
83     def uncapitalize(s):
84         if s:
85             return s[0].lower() + s[1:]
86         else:
87             return s
89     def capitalize(s):
90         # str.capitalize lower cases trailing letters.
91         if s:
92             return s[0].upper() + s[1:]
93         else:
94             return s
96     productFlavor = uncapitalize(
97         "".join(capitalize(f) for f in build_config.geckoview.variant.productFlavors)
98     )
99     buildType = uncapitalize(build_config.geckoview.variant.buildType)
101     return (
102         "gradle/build/mobile/android/geckoview/intermediates/javac/{}{}/classes".format(
103             productFlavor,
104             capitalize(buildType),
105         )
106     )
109 set_config(
110     "GRADLE_ANDROID_GECKOVIEW_APILINT_FOLDER", gradle_android_intermediates_folder
114 @depends(gradle_android_build_config)
115 def gradle_android_geckoview_test_runner_bundle(build_config):
116     """Path to intermediates classes folder."""
118     def uncapitalize(s):
119         if s:
120             return s[0].lower() + s[1:]
121         else:
122             return s
124     def capitalize(s):
125         # str.capitalize lower cases trailing letters.
126         if s:
127             return s[0].upper() + s[1:]
128         else:
129             return s
131     productFlavor = uncapitalize(
132         "".join(capitalize(f) for f in build_config.geckoview.variant.productFlavors)
133     )
134     buildType = uncapitalize(build_config.geckoview.variant.buildType)
135     variant = uncapitalize(build_config.geckoview.variant.name)
137     return "gradle/build/mobile/android/test_runner/outputs/bundle/{}/test_runner-{}-{}.aab".format(
138         variant,
139         productFlavor,
140         buildType,
141     )
144 set_config(
145     "GRADLE_ANDROID_GECKOVIEW_TEST_RUNNER_BUNDLE",
146     gradle_android_geckoview_test_runner_bundle,
150 @depends(gradle_android_build_config)
151 def gradle_android_geckoview_example_bundle(build_config):
152     """Path to intermediates classes folder."""
154     def uncapitalize(s):
155         if s:
156             return s[0].lower() + s[1:]
157         else:
158             return s
160     def capitalize(s):
161         # str.capitalize lower cases trailing letters.
162         if s:
163             return s[0].upper() + s[1:]
164         else:
165             return s
167     productFlavor = uncapitalize(
168         "".join(capitalize(f) for f in build_config.geckoview.variant.productFlavors)
169     )
170     buildType = uncapitalize(build_config.geckoview.variant.buildType)
171     variant = uncapitalize(build_config.geckoview.variant.name)
173     return "gradle/build/mobile/android/geckoview_example/outputs/bundle/{}/geckoview_example-{}-{}.aab".format(
174         variant,
175         productFlavor,
176         buildType,
177     )
180 set_config(
181     "GRADLE_ANDROID_GECKOVIEW_EXAMPLE_BUNDLE", gradle_android_geckoview_example_bundle
185 @depends(gradle_android_build_config)
186 def gradle_android_variant_name(build_config):
187     """Like "withoutGeckoBinariesDebug"."""
189     def uncapitalize(s):
190         if s:
191             return s[0].lower() + s[1:]
192         else:
193             return s
195     return namespace(
196         geckoview=uncapitalize(build_config.geckoview.variant.name),
197     )
200 set_config(
201     "GRADLE_ANDROID_GECKOVIEW_VARIANT_NAME", gradle_android_variant_name.geckoview
205 @depends(gradle_android_build_config)
206 def gradle_android_app_tasks(build_config):
207     """Gradle tasks run by |mach android assemble-app|."""
208     return [
209         "geckoview:generateJNIWrappersForGenerated{geckoview.variant.name}".format(
210             geckoview=build_config.geckoview
211         ),
212     ]
215 set_config("GRADLE_ANDROID_APP_TASKS", gradle_android_app_tasks)
218 @dependable
219 def gradle_android_generate_sdk_bindings_tasks():
220     """Gradle tasks run by |mach android generate-sdk-bindings|."""
221     return [
222         "geckoview:generateSDKBindings",
223     ]
226 set_config(
227     "GRADLE_ANDROID_GENERATE_SDK_BINDINGS_TASKS",
228     gradle_android_generate_sdk_bindings_tasks,
232 @depends(gradle_android_build_config)
233 def gradle_android_generate_generated_jni_wrappers_tasks(build_config):
234     """Gradle tasks run by |mach android generate-generated-jni-wrappers|."""
235     return [
236         "geckoview:generateJNIWrappersForGenerated{geckoview.variant.name}".format(
237             geckoview=build_config.geckoview
238         ),
239     ]
242 set_config(
243     "GRADLE_ANDROID_GENERATE_GENERATED_JNI_WRAPPERS_TASKS",
244     gradle_android_generate_generated_jni_wrappers_tasks,
248 @depends(gradle_android_build_config)
249 def gradle_android_test_tasks(build_config):
250     """Gradle tasks run by |mach android test|."""
251     return [
252         "geckoview:test{geckoview.variant.name}UnitTest".format(
253             geckoview=build_config.geckoview
254         ),
255     ]
258 set_config("GRADLE_ANDROID_TEST_TASKS", gradle_android_test_tasks)
261 @depends(gradle_android_build_config)
262 def gradle_android_lint_tasks(build_config):
263     """Gradle tasks run by |mach android lint|."""
264     return [
265         "geckoview:lint{geckoview.variant.name}".format(
266             geckoview=build_config.geckoview
267         ),
268     ]
271 set_config("GRADLE_ANDROID_LINT_TASKS", gradle_android_lint_tasks)
274 @depends(gradle_android_build_config)
275 def gradle_android_api_lint_tasks(build_config):
276     """Gradle tasks run by |mach android api-lint|."""
277     return [
278         "geckoview:apiLint{geckoview.variant.name}".format(
279             geckoview=build_config.geckoview
280         ),
281     ]
284 set_config("GRADLE_ANDROID_API_LINT_TASKS", gradle_android_api_lint_tasks)
287 set_config(
288     "GRADLE_ANDROID_FORMAT_LINT_FIX_TASKS", ["spotlessJavaApply", "spotlessKotlinApply"]
292 @dependable
293 def gradle_android_format_lint_check_tasks():
294     return ["spotlessJavaCheck", "spotlessKotlinCheck"]
297 set_config(
298     "GRADLE_ANDROID_FORMAT_LINT_CHECK_TASKS", gradle_android_format_lint_check_tasks
301 set_config(
302     "GRADLE_ANDROID_FORMAT_LINT_FOLDERS",
303     [
304         "mobile/android/annotations",
305         "mobile/android/geckoview",
306         "mobile/android/geckoview_example",
307         "mobile/android/test_runner",
308         "mobile/android/examples/messaging_example",
309         "mobile/android/examples/port_messaging_example",
310     ],
314 @depends(gradle_android_build_config)
315 def gradle_android_checkstyle_tasks(build_config):
316     """Gradle tasks run by |mach android checkstyle|."""
317     return [
318         "geckoview:checkstyle{geckoview.variant.name}".format(
319             geckoview=build_config.geckoview
320         ),
321     ]
324 set_config("GRADLE_ANDROID_CHECKSTYLE_TASKS", gradle_android_checkstyle_tasks)
327 @depends(gradle_android_build_config)
328 def gradle_android_checkstyle_output_files(build_config):
329     def uncapitalize(s):
330         if s:
331             return s[0].lower() + s[1:]
332         else:
333             return s
335     variant = uncapitalize(build_config.geckoview.variant.name)
337     """Output folder for checkstyle"""
338     return [
339         "gradle/build/mobile/android/geckoview/reports/checkstyle/{}.xml".format(
340             variant
341         ),
342     ]
345 set_config(
346     "GRADLE_ANDROID_CHECKSTYLE_OUTPUT_FILES", gradle_android_checkstyle_output_files
350 option(
351     "--disable-android-bundle",
352     help="{Enable|Disable} AAB build.",
355 imply_option("--disable-android-bundle", False, when="--enable-address-sanitizer")
358 @depends(gradle_android_build_config, "--disable-android-bundle")
359 def gradle_android_archive_geckoview_tasks(build_config, aab_enabled):
360     """Gradle tasks run by |mach android archive-geckoview|."""
361     tasks = [
362         "geckoview:assemble{geckoview.variant.name}".format(
363             geckoview=build_config.geckoview
364         ),
365         "geckoview:assemble{geckoview.variant.name}AndroidTest".format(
366             geckoview=build_config.geckoview
367         ),
368         "test_runner:assemble{geckoview_example.variant.name}".format(
369             geckoview_example=build_config.geckoview_example
370         ),
371         "geckoview_example:assemble{geckoview_example.variant.name}".format(
372             geckoview_example=build_config.geckoview_example
373         ),
374         "messaging_example:assemble{geckoview_example.variant.name}".format(
375             geckoview_example=build_config.geckoview_example
376         ),
377         "port_messaging_example:assemble{geckoview_example.variant.name}".format(
378             geckoview_example=build_config.geckoview_example
379         ),
380         "geckoview:publish{geckoview.variant.name}PublicationToMavenRepository".format(
381             geckoview=build_config.geckoview
382         ),
383         "exoplayer2:publishDebugPublicationToMavenRepository",
384     ]
386     if aab_enabled:
387         tasks += [
388             "test_runner:bundle{geckoview_example.variant.name}".format(
389                 geckoview_example=build_config.geckoview_example
390             ),
391             "geckoview_example:bundle{geckoview_example.variant.name}".format(
392                 geckoview_example=build_config.geckoview_example
393             ),
394         ]
395     return tasks
398 set_config(
399     "GRADLE_ANDROID_ARCHIVE_GECKOVIEW_TASKS", gradle_android_archive_geckoview_tasks
403 @depends(gradle_android_build_config)
404 def gradle_android_geckoview_docs_tasks(build_config):
405     """Gradle tasks run by |mach android geckoview-docs|."""
406     return [
407         "geckoview:javadoc{geckoview.variant.name}".format(
408             geckoview=build_config.geckoview
409         ),
410     ]
413 set_config("GRADLE_ANDROID_GECKOVIEW_DOCS_TASKS", gradle_android_geckoview_docs_tasks)
416 @depends(gradle_android_build_config)
417 def gradle_android_geckoview_docs_archive_tasks(build_config):
418     """Gradle tasks run by |mach android geckoview-docs --archive| or |... --upload."""
419     return [
420         "geckoview:javadocCopyJar{geckoview.variant.name}".format(
421             geckoview=build_config.geckoview
422         ),
423     ]
426 set_config(
427     "GRADLE_ANDROID_GECKOVIEW_DOCS_ARCHIVE_TASKS",
428     gradle_android_geckoview_docs_archive_tasks,
432 @depends(gradle_android_build_config)
433 def gradle_android_geckoview_docs_output_files(build_config):
434     """Output files for GeckoView javadoc."""
436     def uncapitalize(s):
437         if s:
438             return s[0].lower() + s[1:]
439         else:
440             return s
442     variant = uncapitalize(build_config.geckoview.variant.name)
444     return [
445         "gradle/build/mobile/android/geckoview/reports/javadoc-results-{}.json".format(
446             variant
447         ),
448     ]
451 set_config(
452     "GRADLE_ANDROID_GECKOVIEW_DOCS_OUTPUT_FILES",
453     gradle_android_geckoview_docs_output_files,
457 @depends(gradle_android_build_config)
458 def gradle_android_archive_coverage_artifacts_tasks(build_config):
459     """Gradle tasks run by |mach android archive-coverage-artifacts|."""
460     return [
461         "geckoview:archiveClassfiles{geckoview.variant.name}".format(
462             geckoview=build_config.geckoview
463         ),
464         "geckoview:copyCoverageDependencies",
465     ]
468 set_config(
469     "GRADLE_ANDROID_ARCHIVE_COVERAGE_ARTIFACTS_TASKS",
470     gradle_android_archive_coverage_artifacts_tasks,
474 @depends(gradle_android_build_config)
475 def gradle_android_build_geckoview_example_tasks(build_config):
476     """Gradle tasks run by |mach android build-geckoview_example|."""
477     return [
478         "geckoview_example:assemble{geckoview_example.variant.name}".format(
479             geckoview_example=build_config.geckoview_example
480         ),
481         "geckoview_example:bundle{geckoview_example.variant.name}".format(
482             geckoview_example=build_config.geckoview_example
483         ),
484         "geckoview:assemble{geckoview.variant.name}AndroidTest".format(
485             geckoview=build_config.geckoview
486         ),
487         "test_runner:assemble{geckoview.variant.name}".format(
488             geckoview=build_config.geckoview
489         ),
490         "test_runner:bundle{geckoview.variant.name}".format(
491             geckoview=build_config.geckoview
492         ),
493     ]
496 set_config(
497     "GRADLE_ANDROID_BUILD_GECKOVIEW_EXAMPLE_TASKS",
498     gradle_android_build_geckoview_example_tasks,
502 @depends(gradle_android_build_config)
503 def gradle_android_compile_all_tasks(build_config):
504     """Gradle tasks run by |mach android compile-all|."""
506     def capitalize(s):
507         # str.capitalize lower cases trailing letters.
508         if s:
509             return s[0].upper() + s[1:]
510         else:
511             return s
513     buildType = capitalize(build_config.geckoview.variant.buildType)
515     tasks = [
516         f"compileJava",
517         f"compileTestJava",
518         f"compile{buildType}Sources",
519         f"compile{buildType}UnitTestSources",
520         f"geckoview:compile{build_config.geckoview.variant.name}Sources",
521         f"geckoview:compile{build_config.geckoview.variant.name}UnitTestSources",
522         f"test_runner:compile{build_config.geckoview.variant.name}Sources",
523         f"test_runner:compile{build_config.geckoview.variant.name}UnitTestSources",
524         f"messaging_example:compile{build_config.geckoview.variant.name}Sources",
525         f"messaging_example:compile{build_config.geckoview.variant.name}UnitTestSources",
526         f"port_messaging_example:compile{build_config.geckoview.variant.name}Sources",
527         f"port_messaging_example:compile{build_config.geckoview.variant.name}UnitTestSources",
528         f"geckoview_example:compile{build_config.geckoview_example.variant.name}Sources",
529         f"geckoview_example:compile{build_config.geckoview_example.variant.name}UnitTestSources",
530     ]
532     if buildType == "Debug":
533         tasks += [
534             f"compile{buildType}AndroidTestSources",
535             f"geckoview:compile{build_config.geckoview.variant.name}AndroidTestSources",
536             f"test_runner:compile{build_config.geckoview.variant.name}AndroidTestSources",
537             f"messaging_example:compile{build_config.geckoview.variant.name}AndroidTestSources",
538             f"port_messaging_example:compile{build_config.geckoview.variant.name}AndroidTestSources",
539             f"geckoview_example:compile{build_config.geckoview_example.variant.name}AndroidTestSources",
540         ]
542     return tasks
545 set_config(
546     "GRADLE_ANDROID_COMPILE_ALL_TASKS",
547     gradle_android_compile_all_tasks,
551 @depends(gradle_android_build_config)
552 def gradle_android_install_geckoview_test_runner_tasks(build_config):
553     """Gradle tasks run by |mach android install-geckoview-test_runner|."""
554     return [
555         "test_runner:install{geckoview.variant.name}".format(
556             geckoview=build_config.geckoview
557         ),
558     ]
561 set_config(
562     "GRADLE_ANDROID_INSTALL_GECKOVIEW_TEST_RUNNER_TASKS",
563     gradle_android_install_geckoview_test_runner_tasks,
567 @depends(gradle_android_build_config)
568 def gradle_android_install_geckoview_test_tasks(build_config):
569     """Gradle tasks run by |mach android install-geckoview-test|."""
570     return [
571         "geckoview:install{geckoview.variant.name}AndroidTest".format(
572             geckoview=build_config.geckoview
573         ),
574     ]
577 set_config(
578     "GRADLE_ANDROID_INSTALL_GECKOVIEW_TEST_TASKS",
579     gradle_android_install_geckoview_test_tasks,
583 @depends(gradle_android_build_config)
584 def gradle_android_install_geckoview_example_tasks(build_config):
585     """Gradle tasks run by |mach android install-geckoview_example|."""
586     return [
587         "geckoview_example:install{geckoview_example.variant.name}".format(
588             geckoview_example=build_config.geckoview_example
589         ),
590     ]
593 set_config(
594     "GRADLE_ANDROID_INSTALL_GECKOVIEW_EXAMPLE_TASKS",
595     gradle_android_install_geckoview_example_tasks,
599 @depends(
600     gradle_android_api_lint_tasks,
601     gradle_android_format_lint_check_tasks,
602     gradle_android_checkstyle_tasks,
604 @imports(_from="itertools", _import="chain")
605 def gradle_android_dependencies_tasks(*tasks):
606     """Gradle tasks run by |mach android dependencies|."""
608     # The union, plus a bit more, of all of the Gradle tasks
609     # invoked by the android-* automation jobs.
610     def withoutGeckoBinaries(task):
611         return task.replace("withGeckoBinaries", "withoutGeckoBinaries")
613     return list(withoutGeckoBinaries(t) for t in chain(*tasks))
616 set_config("GRADLE_ANDROID_DEPENDENCIES_TASKS", gradle_android_dependencies_tasks)
619 # Automation uses this to change log levels, not use the daemon, and use
620 # offline mode.
621 option(env="GRADLE_FLAGS", default="", help="Flags to pass to Gradle.")
624 @depends("GRADLE_FLAGS")
625 def gradle_flags(value):
626     return value[0] if value else ""
629 set_config("GRADLE_FLAGS", gradle_flags)
631 # Automation will set this to (file:///path/to/local, ...) via the mozconfig.
632 # Local developer default is (maven.google.com).
633 option(
634     env="GRADLE_MAVEN_REPOSITORIES",
635     nargs="+",
636     default=(
637         "https://maven.mozilla.org/maven2/",
638         "https://maven.google.com/",
639         "https://repo.maven.apache.org/maven2/",
640         "https://plugins.gradle.org/m2/",
641     ),
642     help="Comma-separated URLs of Maven repositories containing Gradle dependencies.",
645 option(
646     "--allow-insecure-gradle-repositories",
647     help="Gradle is allowed to connect to insecure Maven repositories.",
650 set_config(
651     "ALLOW_INSECURE_GRADLE_REPOSITORIES",
652     True,
653     when="--allow-insecure-gradle-repositories",
656 option(
657     "--download-all-gradle-dependencies",
658     help="Download all dependencies, even those that are conditionally used.",
661 set_config(
662     "DOWNLOAD_ALL_GRADLE_DEPENDENCIES",
663     True,
664     when="--download-all-gradle-dependencies",
668 @depends("GRADLE_MAVEN_REPOSITORIES")
669 @imports(_from="os.path", _import="isdir")
670 def gradle_maven_repositories(values):
671     if not values:
672         die("GRADLE_MAVEN_REPOSITORIES must not be empty")
673     if not all(values):
674         die("GRADLE_MAVEN_REPOSITORIES entries must not be empty")
675     return values
678 set_config("GRADLE_MAVEN_REPOSITORIES", gradle_maven_repositories)