Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add manifest_values to android library rules #8808

Closed
xykivo opened this issue Jul 6, 2019 · 3 comments
Closed

Add manifest_values to android library rules #8808

xykivo opened this issue Jul 6, 2019 · 3 comments
Labels
P2 We'll consider working on this in future. (Assignee optional) stale Issues or PRs that are stale (no activity for 30 days) team-Android Issues for Android team type: feature request

Comments

@xykivo
Copy link

xykivo commented Jul 6, 2019

Description of the problem / feature request:

Currently android library rules do not have the manifest_values argument.
This makes it harder to enforce things such as minSdkVersion and targetSdkVersion for all
projects under a workspace, since each library has to have the min and target SDKs defined
separately in the manifest file.

Feature requests: what underlying problem are you trying to solve with this feature?

Use common minSdkVersion and targetSdkVersion for all android packages in a workspace.

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

NA

What operating system are you running Bazel on?

Windows & Linux

What's the output of bazel info release?

release 0.27.0

If bazel info release returns "development version" or "(@non-git)", tell us how you built Bazel.

NA

What's the output of git remote get-url origin ; git rev-parse master ; git rev-parse HEAD ?

NA.

Have you found anything relevant by searching the web?

No

Any other information, logs, or outputs that you want to share?

NA

@aiuto aiuto added team-Android Issues for Android team untriaged labels Jul 8, 2019
@ahumesky ahumesky added P2 We'll consider working on this in future. (Assignee optional) type: feature request and removed untriaged labels Jul 16, 2019
@xykivo
Copy link
Author

xykivo commented Nov 28, 2019

I found a possible workaround for this issue.
The basic idea is

  1. Use a python script to generate a manifest file with the needed values
  2. Add an Android library manifest package for each android library that uses the generated manifest in 1
  3. Add a dependency on the manifest package library

Sample code below is released under the GPL-3 license:

Copyright (C) 2019 Dror Smolarsky

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.

// #############################################################3
// File: <workspace_root>/build_tools/BUILD
// #############################################################3

py_binary(
name = "gen-android-manifest",
visibility = ["//visibility:public"],
srcs = ["generate_android_manifest.py"],
main = "generate_android_manifest.py",
python_version = "PY3",
)

// #############################################################3
// File <workspace_root>/build_tools/generate_android_manifest.py
// #############################################################3

import argparse

class InvalidArgumentError(Exception):
'''Raised on an invalid command line argument
'''

def parse_manifest_values_arg(manifest_values_arg):
'''Parse the manifest values command line argument

Validate the manifest values argument has a package value.
Return a dictionary of values, where the key is the value name.
'''
try:
    manifest_values_list = [value.split('=') for value in args.manifest_values.split(',')]
    manifest_values = {}
    manifest_values.update(manifest_values_list)
    if 'package' not in manifest_values:
        raise InvalidArgumentError('Missing package manifest value')
except ValueError as value_error:
    raise InvalidArgumentError(value_error, manifest_values_arg)
return manifest_values

def write_manifest(manifest_values):
'''Write the Android manifest file with the given manifest values
'''
android_manifest = open(args.manifest, 'w')
android_manifest.write('\n')
android_manifest.write('<manifest\n')
android_manifest.write(' xmlns:android="http://schemas.android.com/apk/res/android"\n')
android_manifest.write(' package="{0}"\n'.format(manifest_values['package']))
if 'versionName' in manifest_values:
android_manifest.write(' android:versionName="{0}"\n'.format(
manifest_values['versionName']))
if 'versionCode' in manifest_values:
android_manifest.write(' android:versionCode="{0}"\n'.format(
manifest_values['versionCode']))
android_manifest.write(' >"\n')
if ('minSdkVersion' in manifest_values) or ('targetSdkVersion' in manifest_values):
android_manifest.write(' <uses-sdk\n')
if 'minSdkVersion' in manifest_values:
android_manifest.write(' android:minSdkVersion="{0}"\n'.format(
manifest_values['minSdkVersion']))
if 'targetSdkVersion' in manifest_values:
android_manifest.write(' android:targetSdkVersion="{0}"\n'.format(
manifest_values['targetSdkVersion']))
android_manifest.write(' />"\n')
android_manifest.write('\n')
android_manifest.close()

if 'main' == name:
'''Generate Android Manifest for the given package with given version values
'''
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('manifest_values', help='The Android manifest values')
arg_parser.add_argument('manifest',
help='The path to the generated Android manifest file')
args = arg_parser.parse_args()
manifest_values = parse_manifest_values_arg(args.manifest_values)
write_manifest(manifest_values)

// #############################################################3
// File: <workspace_root>/bazel/android.bzl
// #############################################################3

load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
load("//bazel:version.bzl", "version_code") # generate version code from semantic version name

def _xkv_android_manifest_values(name, version):
"""Generate Android manifest values for a manifest library package
"""
return ",".join([
"package={0}.{1}.manifest".format(ANDROID_PACKAGE_NAME_PREFIX, name),
"versionName=" + version,
"versionCode=" + str(version_code(version)),
"minSdkVersion=" + ANDROID_MIN_SDK_VERSION,
"targetSdkVersion=" + ANDROID_TARGET_SDK_VERSION,
])

def _xkv_android_manifest_values_rule_impl(ctx):
"""Android manifest values rule implementation

Pass manifest values in a MANIFEST_VALUES variable.
"""
return platform_common.TemplateVariableInfo({"MANIFEST_VALUES": ctx.attr.var_value})

//# Rule to get Android manifest values variable
xkv_android_manifest_values = rule(
implementation = _xkv_android_manifest_values_rule_impl,
attrs = {"var_value": attr.string()},
)

def xkv_android_library(name, version, **kwargs):
"""Xykivo android Java library rule.

Common definitions and behaviors for all Xykivo Android libraries.
"""
xkv_android_manifest_values(
    name = "manifest_values",
    var_value = _xkv_android_manifest_values(name, version),
)
native.genrule(
    name = "generate_manifest",
    outs = ["AndroidManifest.xml"],
    srcs = [],
    tools = ["//build_tools:gen-android-manifest"],
    toolchains = [":manifest_values"],
    cmd = "$(execpath //build_tools:gen-android-manifest) $(MANIFEST_VALUES) $@",
)
manifest_library_name = name + "_manifest"
native.android_library(
    name = manifest_library_name,
    manifest = ":generate_manifest",
)
dependencies = kwargs.pop("deps", [])
dependencies.append(manifest_library_name)
native.android_library(
    name = name,
    deps = dependencies,
    **kwargs
)

def xkv_android_kt_library(name, version, **kwargs):
"""Xykivo android Kotlin library rule.

Common definitions and behaviors for all Xykivo Android Kotlin libraries.
"""
xkv_android_manifest_values(
    name = "manifest_values",
    var_value = _xkv_android_manifest_values(name, version),
)
native.genrule(
    name = "generate_manifest",
    outs = ["AndroidManifest.xml"],
    srcs = [],
    tools = ["//build_tools:gen-android-manifest"],
    toolchains = [":manifest_values"],
    cmd = "$(execpath //build_tools:gen-android-manifest) $(MANIFEST_VALUES) $@",
)
manifest_library_name = name + "_manifest"
native.android_library(
    name = manifest_library_name,
    manifest = ":generate_manifest",
)
dependencies = kwargs.pop("deps", [])
dependencies.append(manifest_library_name)
kt_android_library(
    name = name,
    deps = dependencies,
    **kwargs
)

// ######################################################
// File <workspace_root>/path/to/android/library/package
// ######################################################

load("@rules_jvm_external//:defs.bzl", "artifact")
load("//bazel:android.bzl", "xkv_android_kt_library")
load(":version.bzl", "VERSION")

xkv_android_kt_library(
name = "android_library_name",
srcs = glob(["*.kt"]),
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
version = VERSION,
)

@github-actions
Copy link

Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 3 years. It will be closed in the next 14 days unless any other activity occurs or one of the following labels is added: "not stale", "awaiting-bazeler". Please reach out to the triage team (@bazelbuild/triage) if you think this issue is still relevant or you are interested in getting the issue resolved.

@github-actions github-actions bot added the stale Issues or PRs that are stale (no activity for 30 days) label Feb 28, 2023
@github-actions
Copy link

This issue has been automatically closed due to inactivity. If you're still interested in pursuing this, please reach out to the triage team (@bazelbuild/triage). Thanks!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Mar 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) stale Issues or PRs that are stale (no activity for 30 days) team-Android Issues for Android team type: feature request
Projects
None yet
Development

No branches or pull requests

3 participants