blob: 61f6aa6604e01cde733156138e7803e73ac47139 [file] [log] [blame]
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Transform contains data transformation methods."""
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
load("//rules/flags:flags.bzl", _flags = "flags")
load(":constants.bzl", "constants")
load(":utils.bzl", "utils")
visibility(PROJECT_VISIBILITY)
def _declare_file(ctx, filename, sibling = None):
return utils.isolated_declare_file(ctx, filename, sibling = sibling)
def filter_jars(name, data):
"""Filters out files that are not compiled Jars - includes header Jars.
Args:
name: Name of the file to filter, check uses endswith on the path.
data: The list of tuples where each entry contains the originating file path
and file to apply the filter.
Returns:
A list of tuples where each entry contains the originating Jar path and the
Jar file.
"""
return [jar for jar in data if not jar.path.endswith(name)]
def dex(
ctx,
data,
deps = constants.EMPTY_LIST,
num_shards = None,
create_file = _declare_file):
"""Dex a list of Jars.
Args:
ctx: The context.
data: The list of tuples where each entry contains the originating Jar
path and the Jar to Dex.
deps: The list of dependencies for the Jar being desugared.
num_shards: The number of shards to distribute the dexed files across,
this value overrides the default provided by ctx.attr._mi_dex_shards.
create_file: In rare occasions a custom method is required to
create a unique file, override the default here. The method must
implement the following interface:
def create_file(ctx, filename, sibling = None)
Args:
ctx: The context.
filename: string. The name of the file.
sibling: File. The location of the new file.
Returns:
A File.
Returns:
A list of tuples where each entry contains the originating Jar path and
the Dex shards.
"""
if num_shards:
num_dex_shards = num_shards
elif _flags.get(ctx).use_custom_dex_shards:
num_dex_shards = _flags.get(ctx).num_dex_shards
else:
num_dex_shards = ctx.attr._mi_dex_shards
dex_files = []
for jar in data:
out_dex_shards = []
dirname = jar.basename + "_dex"
for i in range(num_shards or num_dex_shards):
out_dex_shards.append(create_file(
ctx,
dirname + "/" + str(i) + ".zip",
sibling = jar,
))
utils.dex(ctx, jar, out_dex_shards, deps)
dex_files.append(out_dex_shards)
return dex_files
def extract_jar_resources(ctx, data, create_file = _declare_file):
"""Extracts the non-class files from the list of Jars.
Args:
ctx: The context
data: The list of tuples where each entry contains the originating Jar
path and the Jar with resources to extract.
create_file: In rare occasions a custom method is required to
create a unique file, override the default here. The method must
implement the following interface:
def create_file(ctx, filename, sibling = None)
Args:
ctx: The context.
filename: string. The name of the file.
sibling: File. The location of the new file.
Returns:
A File.
Returns:
A list of extracted resource zips.
"""
resources_files = []
for jar in data:
out_resources_file = create_file(
ctx,
jar.basename + "_resources.zip",
sibling = jar,
)
utils.extract_jar_resources(ctx, jar, out_resources_file)
resources_files.append(out_resources_file)
return resources_files
def merge_dex_shards(ctx, data, sibling):
"""Merges all dex files in the transitive deps to a dex per shard.
Given a list of dex files (and resources.zips) this will create an
action per shard that runs dex_shard_merger on all dex files within that
shard.
Arguments:
ctx: The context.
data: A list of lists, where the inner list contains dex shards.
sibling: A file used to root the merged_dex shards.
Returns:
A list of merged dex shards.
"""
merged_dex_shards = []
for idx, shard_archives in enumerate(data):
# To ensure resource is added at the beginning, R.zip is named as 00.zip
# Thus data shards starts from 1 instead of 0 and ranges through 16
idx += 1
# Shards are sorted before deployment, to ensure all shards are correctly
# ordered 0 is padded to single digit shard counts
shard_name = "%s%s" % ("00"[len(str(idx)):], idx)
merged_dex_shard = utils.isolated_declare_file(
ctx,
"dex_shards/" + shard_name + ".zip",
sibling = sibling,
)
utils.merge_dex_shards(ctx, shard_archives, merged_dex_shard)
merged_dex_shards.append(merged_dex_shard)
return merged_dex_shards