Vendor dependencies
Let's see how I like this workflow.
This commit is contained in:
parent
34d1830413
commit
9c435dc440
7500 changed files with 1665121 additions and 99 deletions
74
vendor/cxx/tools/buck/prelude/js/js.bzl
vendored
Normal file
74
vendor/cxx/tools/buck/prelude/js/js.bzl
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
load("@prelude//android:android.bzl", "android_toolchain")
|
||||
load("@prelude//js:js_bundle.bzl", "js_bundle_impl")
|
||||
load("@prelude//js:js_bundle_genrule.bzl", "js_bundle_genrule_impl")
|
||||
load("@prelude//js:js_library.bzl", "js_library_impl")
|
||||
load("@prelude//genrule.bzl", "genrule_attributes")
|
||||
|
||||
def _select_platform():
|
||||
# FIXME: prelude// should be standalone (not refer to ovr_config//)
|
||||
return select({
|
||||
"DEFAULT": "android",
|
||||
"ovr_config//os/constraints:iphoneos": "ios",
|
||||
})
|
||||
|
||||
def _is_release():
|
||||
# FIXME: prelude// should be standalone (not refer to ovr_config//)
|
||||
return select({
|
||||
"DEFAULT": False,
|
||||
"ovr_config//build_mode/constraints:release": True,
|
||||
})
|
||||
|
||||
def _is_build_only_native_code():
|
||||
return select(
|
||||
{
|
||||
"DEFAULT": False,
|
||||
"fbsource//xplat/buck2/platform/android:build_only_native_code": True,
|
||||
},
|
||||
)
|
||||
|
||||
implemented_rules = {
|
||||
"js_bundle": js_bundle_impl,
|
||||
"js_bundle_genrule": js_bundle_genrule_impl,
|
||||
"js_library": js_library_impl,
|
||||
}
|
||||
|
||||
extra_attributes = {
|
||||
"js_bundle": {
|
||||
"worker": attrs.exec_dep(),
|
||||
"_android_toolchain": android_toolchain(),
|
||||
"_is_release": attrs.bool(
|
||||
default = _is_release(),
|
||||
),
|
||||
"_platform": attrs.string(
|
||||
default = _select_platform(),
|
||||
),
|
||||
},
|
||||
"js_bundle_genrule": genrule_attributes() | {
|
||||
"type": attrs.string(
|
||||
default = "js_bundle_genrule",
|
||||
),
|
||||
"_is_release": attrs.bool(
|
||||
default = _is_release(),
|
||||
),
|
||||
"_platform": attrs.string(
|
||||
default = _select_platform(),
|
||||
),
|
||||
},
|
||||
"js_library": {
|
||||
"worker": attrs.exec_dep(),
|
||||
"_build_only_native_code": attrs.bool(default = _is_build_only_native_code()),
|
||||
"_is_release": attrs.bool(
|
||||
default = _is_release(),
|
||||
),
|
||||
"_platform": attrs.string(
|
||||
default = _select_platform(),
|
||||
),
|
||||
},
|
||||
}
|
||||
217
vendor/cxx/tools/buck/prelude/js/js_bundle.bzl
vendored
Normal file
217
vendor/cxx/tools/buck/prelude/js/js_bundle.bzl
vendored
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
load("@prelude//android:android_providers.bzl", "AndroidResourceInfo", "merge_android_packageable_info")
|
||||
load("@prelude//android:android_resource.bzl", "JAVA_PACKAGE_FILENAME", "aapt2_compile", "get_text_symbols")
|
||||
load("@prelude//android:android_toolchain.bzl", "AndroidToolchainInfo")
|
||||
load("@prelude//js:js_providers.bzl", "JsBundleInfo", "JsLibraryInfo", "get_transitive_outputs")
|
||||
load("@prelude//js:js_utils.bzl", "RAM_BUNDLE_TYPES", "TRANSFORM_PROFILES", "get_bundle_name", "get_flavors", "run_worker_command")
|
||||
load("@prelude//utils:utils.bzl", "expect", "map_idx")
|
||||
|
||||
def _build_dependencies_file(
|
||||
ctx: "context",
|
||||
transform_profile: str.type,
|
||||
flavors: [str.type],
|
||||
transitive_js_library_outputs: "transitive_set_args_projection") -> "artifact":
|
||||
dependencies_file = ctx.actions.declare_output("{}/dependencies_file", transform_profile)
|
||||
|
||||
# ctx.attrs.extra_json can contain attrs.arg().
|
||||
#
|
||||
# As a result, we need to pass extra_data_args as hidden arguments so that the rule
|
||||
# it is referencing exists as an input.
|
||||
extra_data_args = cmd_args(
|
||||
ctx.attrs.extra_json if ctx.attrs.extra_json else "{}",
|
||||
delimiter = "",
|
||||
)
|
||||
job_args = {
|
||||
"command": "dependencies",
|
||||
"entryPoints": [ctx.attrs.entry] if type(ctx.attrs.entry) == "string" else list(ctx.attrs.entry),
|
||||
"extraData": extra_data_args,
|
||||
"flavors": flavors,
|
||||
"libraries": transitive_js_library_outputs,
|
||||
"outputFilePath": dependencies_file,
|
||||
"platform": ctx.attrs._platform,
|
||||
"release": ctx.attrs._is_release,
|
||||
}
|
||||
command_args_file = ctx.actions.write_json(
|
||||
"{}_dep_command_args".format(transform_profile),
|
||||
job_args,
|
||||
)
|
||||
|
||||
run_worker_command(
|
||||
ctx = ctx,
|
||||
worker_tool = ctx.attrs.worker,
|
||||
command_args_file = command_args_file,
|
||||
identifier = transform_profile,
|
||||
category = "dependencies",
|
||||
hidden_artifacts = cmd_args([
|
||||
dependencies_file.as_output(),
|
||||
extra_data_args,
|
||||
]).add(transitive_js_library_outputs),
|
||||
)
|
||||
return dependencies_file
|
||||
|
||||
def _build_js_bundle(
|
||||
ctx: "context",
|
||||
bundle_name: str.type,
|
||||
ram_bundle_name: str.type,
|
||||
ram_bundle_command: str.type,
|
||||
transform_profile: str.type,
|
||||
flavors: [str.type],
|
||||
transitive_js_library_outputs: "transitive_set_args_projection",
|
||||
dependencies_file: "artifact") -> JsBundleInfo.type:
|
||||
base_dir = "{}_{}".format(ram_bundle_name, transform_profile) if ram_bundle_name else transform_profile
|
||||
assets_dir = ctx.actions.declare_output("{}/assets_dir".format(base_dir))
|
||||
bundle_dir_output = ctx.actions.declare_output("{}/js".format(base_dir))
|
||||
misc_dir_path = ctx.actions.declare_output("{}/misc_dir_path".format(base_dir))
|
||||
source_map = ctx.actions.declare_output("{}/source_map".format(base_dir))
|
||||
|
||||
# ctx.attrs.extra_json can contain attrs.arg().
|
||||
#
|
||||
# As a result, we need to pass extra_data_args as hidden arguments so that the rule
|
||||
# it is referencing exists as an input.
|
||||
extra_data_args = cmd_args(
|
||||
ctx.attrs.extra_json if ctx.attrs.extra_json else "{}",
|
||||
delimiter = "",
|
||||
)
|
||||
job_args = {
|
||||
"assetsDirPath": assets_dir,
|
||||
"bundlePath": cmd_args(
|
||||
[bundle_dir_output, bundle_name],
|
||||
delimiter = "/",
|
||||
),
|
||||
"command": "bundle",
|
||||
"entryPoints": [ctx.attrs.entry] if type(ctx.attrs.entry) == "string" else list(ctx.attrs.entry),
|
||||
"extraData": extra_data_args,
|
||||
"flavors": flavors,
|
||||
"libraries": transitive_js_library_outputs,
|
||||
"miscDirPath": misc_dir_path,
|
||||
"platform": ctx.attrs._platform,
|
||||
"release": ctx.attrs._is_release,
|
||||
"sourceMapPath": source_map,
|
||||
}
|
||||
|
||||
if ram_bundle_command:
|
||||
job_args["ramBundle"] = ram_bundle_command
|
||||
|
||||
command_args_file = ctx.actions.write_json(
|
||||
"{}_bundle_command_args".format(base_dir),
|
||||
job_args,
|
||||
)
|
||||
|
||||
run_worker_command(
|
||||
ctx = ctx,
|
||||
worker_tool = ctx.attrs.worker,
|
||||
command_args_file = command_args_file,
|
||||
identifier = base_dir,
|
||||
category = job_args["command"],
|
||||
hidden_artifacts = cmd_args([
|
||||
bundle_dir_output.as_output(),
|
||||
assets_dir.as_output(),
|
||||
misc_dir_path.as_output(),
|
||||
source_map.as_output(),
|
||||
extra_data_args,
|
||||
]).add(transitive_js_library_outputs),
|
||||
)
|
||||
|
||||
return JsBundleInfo(
|
||||
bundle_name = bundle_name,
|
||||
built_js = bundle_dir_output,
|
||||
source_map = source_map,
|
||||
res = assets_dir,
|
||||
misc = misc_dir_path,
|
||||
dependencies_file = dependencies_file,
|
||||
)
|
||||
|
||||
def _get_fallback_transform_profile(ctx: "context") -> str.type:
|
||||
if ctx.attrs.fallback_transform_profile in TRANSFORM_PROFILES:
|
||||
return ctx.attrs.fallback_transform_profile
|
||||
|
||||
if ctx.attrs.fallback_transform_profile == "default" or ctx.attrs.fallback_transform_profile == None:
|
||||
return "transform-profile-default"
|
||||
|
||||
fail("Invalid fallback_transform_profile attribute {}!".format(ctx.attrs.fallback_transform_profile))
|
||||
|
||||
def _get_default_providers(js_bundle_info: JsBundleInfo.type) -> ["provider"]:
|
||||
return [DefaultInfo(default_outputs = [js_bundle_info.built_js])]
|
||||
|
||||
def _get_android_resource_info(ctx: "context", js_bundle_info: JsBundleInfo.type, identifier: str.type) -> "AndroidResourceInfo":
|
||||
aapt2_compile_output = aapt2_compile(
|
||||
ctx,
|
||||
js_bundle_info.res,
|
||||
ctx.attrs._android_toolchain[AndroidToolchainInfo],
|
||||
identifier = identifier,
|
||||
)
|
||||
expect(ctx.attrs.android_package != None, "Must provide android_package for android builds!")
|
||||
r_dot_java_package = ctx.actions.write("{}_{}".format(identifier, JAVA_PACKAGE_FILENAME), ctx.attrs.android_package)
|
||||
return AndroidResourceInfo(
|
||||
aapt2_compile_output = aapt2_compile_output,
|
||||
allow_strings_as_assets_resource_filtering = True,
|
||||
assets = js_bundle_info.built_js,
|
||||
manifest_file = None,
|
||||
r_dot_java_package = r_dot_java_package,
|
||||
res = js_bundle_info.res,
|
||||
text_symbols = get_text_symbols(ctx, js_bundle_info.res, [], identifier),
|
||||
)
|
||||
|
||||
def _get_extra_providers(ctx: "context", js_bundle_info: JsBundleInfo.type, identifier: str.type) -> ["provider"]:
|
||||
providers = [js_bundle_info]
|
||||
if ctx.attrs._platform == "android":
|
||||
resource_info = _get_android_resource_info(ctx, js_bundle_info, identifier)
|
||||
providers.append(resource_info)
|
||||
providers.append(merge_android_packageable_info(ctx.label, ctx.actions, ctx.attrs.deps, resource_info = resource_info))
|
||||
|
||||
return providers
|
||||
|
||||
def js_bundle_impl(ctx: "context") -> ["provider"]:
|
||||
sub_targets = {}
|
||||
default_outputs = []
|
||||
extra_unnamed_output_providers = None
|
||||
bundle_name = get_bundle_name(ctx, "{}.js".format(ctx.attrs.name))
|
||||
flavors = get_flavors(ctx)
|
||||
for transform_profile in TRANSFORM_PROFILES:
|
||||
dep_infos = map_idx(JsLibraryInfo, [dep[DefaultInfo].sub_targets[transform_profile] for dep in ctx.attrs.deps])
|
||||
|
||||
transitive_js_library_tset = get_transitive_outputs(ctx.actions, deps = dep_infos)
|
||||
transitive_js_library_outputs = transitive_js_library_tset.project_as_args("artifacts")
|
||||
dependencies_file = _build_dependencies_file(ctx, transform_profile, flavors, transitive_js_library_outputs)
|
||||
|
||||
for ram_bundle_name, ram_bundle_command in RAM_BUNDLE_TYPES.items():
|
||||
js_bundle_info = _build_js_bundle(ctx, bundle_name, ram_bundle_name, ram_bundle_command, transform_profile, flavors, transitive_js_library_outputs, dependencies_file)
|
||||
|
||||
simple_name = transform_profile if not ram_bundle_name else "{}-{}".format(ram_bundle_name, transform_profile)
|
||||
built_js_providers = _get_default_providers(js_bundle_info)
|
||||
extra_providers = _get_extra_providers(ctx, js_bundle_info, simple_name)
|
||||
misc_providers = [DefaultInfo(default_outputs = [js_bundle_info.misc])]
|
||||
source_map_providers = [DefaultInfo(default_outputs = [js_bundle_info.source_map])]
|
||||
dependencies_providers = [DefaultInfo(default_outputs = [js_bundle_info.dependencies_file])]
|
||||
|
||||
sub_targets[simple_name] = built_js_providers + extra_providers
|
||||
sub_targets["{}-misc".format(simple_name)] = misc_providers
|
||||
sub_targets["{}-source_map".format(simple_name)] = source_map_providers
|
||||
sub_targets["{}-dependencies".format(simple_name)] = dependencies_providers
|
||||
|
||||
fallback_transform_profile = _get_fallback_transform_profile(ctx)
|
||||
if transform_profile == fallback_transform_profile:
|
||||
if not ram_bundle_name:
|
||||
default_outputs.append(js_bundle_info.built_js)
|
||||
expect(extra_unnamed_output_providers == None, "Extra unnamed output providers should only be set once!")
|
||||
extra_unnamed_output_providers = extra_providers
|
||||
sub_targets["misc"] = misc_providers
|
||||
sub_targets["source_map"] = source_map_providers
|
||||
sub_targets["dependencies"] = dependencies_providers
|
||||
else:
|
||||
sub_targets[ram_bundle_name] = built_js_providers + extra_providers
|
||||
sub_targets["{}-misc".format(ram_bundle_name)] = misc_providers
|
||||
sub_targets["{}-source_map".format(ram_bundle_name)] = source_map_providers
|
||||
sub_targets["{}-dependencies".format(ram_bundle_name)] = dependencies_providers
|
||||
|
||||
expect(len(default_outputs) == 1, "Should get exactly one default output!")
|
||||
expect(extra_unnamed_output_providers != None, "Should set extra unnamed output providers once!")
|
||||
return [
|
||||
DefaultInfo(default_outputs = default_outputs, sub_targets = sub_targets),
|
||||
] + extra_unnamed_output_providers
|
||||
129
vendor/cxx/tools/buck/prelude/js/js_bundle_genrule.bzl
vendored
Normal file
129
vendor/cxx/tools/buck/prelude/js/js_bundle_genrule.bzl
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
load("@prelude//:genrule.bzl", "process_genrule")
|
||||
load("@prelude//android:android_providers.bzl", "AndroidResourceInfo", "merge_android_packageable_info")
|
||||
load("@prelude//js:js_providers.bzl", "JsBundleInfo")
|
||||
load("@prelude//js:js_utils.bzl", "RAM_BUNDLE_TYPES", "TRANSFORM_PROFILES", "get_bundle_name")
|
||||
load("@prelude//utils:utils.bzl", "expect")
|
||||
|
||||
def _build_js_bundle(
|
||||
ctx: "context",
|
||||
bundle_name_out: str.type,
|
||||
js_bundle_info: JsBundleInfo.type,
|
||||
named_output: str.type) -> JsBundleInfo.type:
|
||||
env_vars = {
|
||||
"DEPENDENCIES": cmd_args(js_bundle_info.dependencies_file),
|
||||
"JS_BUNDLE_NAME": cmd_args(js_bundle_info.bundle_name),
|
||||
"JS_BUNDLE_NAME_OUT": cmd_args(bundle_name_out),
|
||||
"JS_DIR": cmd_args(js_bundle_info.built_js),
|
||||
"MISC_DIR": cmd_args(js_bundle_info.misc),
|
||||
"PLATFORM": cmd_args(ctx.attrs._platform),
|
||||
"RELEASE": cmd_args("1" if ctx.attrs._is_release else ""),
|
||||
"RES_DIR": cmd_args(js_bundle_info.res),
|
||||
"SOURCEMAP": cmd_args(js_bundle_info.source_map),
|
||||
}
|
||||
|
||||
if ctx.attrs.rewrite_sourcemap:
|
||||
source_map_out = ctx.actions.declare_output("{}/source_map".format(named_output))
|
||||
env_vars["SOURCEMAP_OUT"] = cmd_args(source_map_out.as_output())
|
||||
else:
|
||||
source_map_out = js_bundle_info.source_map
|
||||
|
||||
if ctx.attrs.rewrite_misc:
|
||||
misc_out = ctx.actions.declare_output("{}/misc".format(named_output))
|
||||
env_vars["MISC_OUT"] = cmd_args(misc_out.as_output())
|
||||
else:
|
||||
misc_out = js_bundle_info.misc
|
||||
|
||||
if ctx.attrs.rewrite_deps_file:
|
||||
dependencies_out = ctx.actions.declare_output("{}/dependencies".format(named_output))
|
||||
env_vars["DEPENDENCIES_OUT"] = cmd_args(dependencies_out.as_output())
|
||||
else:
|
||||
dependencies_out = js_bundle_info.dependencies_file
|
||||
|
||||
providers = process_genrule(ctx, "{}-js".format(named_output), None, env_vars, named_output)
|
||||
|
||||
expect(
|
||||
len(providers) == 1,
|
||||
"expected exactly one provider of type DefaultInfo from {} ({})"
|
||||
.format(ctx.label.name, providers),
|
||||
)
|
||||
|
||||
default_info = providers[0] # DefaultInfo type
|
||||
outputs = default_info.default_outputs
|
||||
expect(
|
||||
len(outputs) == 1,
|
||||
"expected exactly one output from {} ({})"
|
||||
.format(ctx.label.name, outputs),
|
||||
)
|
||||
built_js = outputs[0]
|
||||
|
||||
return JsBundleInfo(
|
||||
bundle_name = bundle_name_out,
|
||||
built_js = built_js,
|
||||
source_map = source_map_out,
|
||||
res = js_bundle_info.res,
|
||||
misc = misc_out,
|
||||
dependencies_file = dependencies_out,
|
||||
)
|
||||
|
||||
def _get_extra_providers(
|
||||
ctx: "context",
|
||||
skip_resources: bool.type,
|
||||
initial_target: ["provider_collection", "dependency"],
|
||||
js_bundle_out: JsBundleInfo.type) -> ["provider"]:
|
||||
providers = []
|
||||
android_resource_info = initial_target[AndroidResourceInfo]
|
||||
if android_resource_info:
|
||||
new_android_resource_info = AndroidResourceInfo(
|
||||
aapt2_compile_output = None if skip_resources else android_resource_info.aapt2_compile_output,
|
||||
allow_strings_as_assets_resource_filtering = True,
|
||||
assets = js_bundle_out.built_js,
|
||||
manifest_file = None,
|
||||
r_dot_java_package = None if skip_resources else android_resource_info.r_dot_java_package,
|
||||
res = None if skip_resources else android_resource_info.res,
|
||||
text_symbols = None if skip_resources else android_resource_info.text_symbols,
|
||||
)
|
||||
providers.append(new_android_resource_info)
|
||||
providers.append(merge_android_packageable_info(ctx.label, ctx.actions, deps = [], resource_info = new_android_resource_info))
|
||||
|
||||
return providers
|
||||
|
||||
def js_bundle_genrule_impl(ctx: "context") -> ["provider"]:
|
||||
sub_targets = {}
|
||||
for transform_profile in TRANSFORM_PROFILES:
|
||||
for ram_bundle_name in RAM_BUNDLE_TYPES.keys():
|
||||
simple_named_output = transform_profile if not ram_bundle_name else "{}-{}".format(ram_bundle_name, transform_profile)
|
||||
|
||||
js_bundle = ctx.attrs.js_bundle[DefaultInfo].sub_targets[simple_named_output]
|
||||
js_bundle_info = js_bundle[JsBundleInfo]
|
||||
bundle_name_out = get_bundle_name(ctx, js_bundle_info.bundle_name)
|
||||
|
||||
js_bundle_out = _build_js_bundle(ctx, bundle_name_out, js_bundle_info, simple_named_output)
|
||||
|
||||
sub_targets[simple_named_output] = [
|
||||
DefaultInfo(default_outputs = [js_bundle_out.built_js]),
|
||||
js_bundle_out,
|
||||
] + _get_extra_providers(ctx, ctx.attrs.skip_resources, js_bundle, js_bundle_out)
|
||||
sub_targets["{}-misc".format(simple_named_output)] = [DefaultInfo(default_outputs = [js_bundle_out.misc])]
|
||||
sub_targets["{}-source_map".format(simple_named_output)] = [DefaultInfo(default_outputs = [js_bundle_out.source_map])]
|
||||
sub_targets["{}-dependencies".format(simple_named_output)] = [DefaultInfo(default_outputs = [js_bundle_out.dependencies_file])]
|
||||
|
||||
js_bundle_info = ctx.attrs.js_bundle[JsBundleInfo]
|
||||
bundle_name_out = get_bundle_name(ctx, js_bundle_info.bundle_name)
|
||||
js_bundle_out = _build_js_bundle(ctx, bundle_name_out, js_bundle_info, "default")
|
||||
|
||||
sub_targets["dependencies"] = [DefaultInfo(default_outputs = [js_bundle_out.dependencies_file])]
|
||||
sub_targets["misc"] = [DefaultInfo(default_outputs = [js_bundle_out.misc])]
|
||||
sub_targets["source_map"] = [DefaultInfo(default_outputs = [js_bundle_out.source_map])]
|
||||
default_info_out = DefaultInfo(
|
||||
default_outputs = [js_bundle_out.built_js],
|
||||
sub_targets = sub_targets,
|
||||
)
|
||||
|
||||
return [default_info_out, js_bundle_out] + _get_extra_providers(ctx, ctx.attrs.skip_resources, ctx.attrs.js_bundle, js_bundle_out)
|
||||
215
vendor/cxx/tools/buck/prelude/js/js_library.bzl
vendored
Normal file
215
vendor/cxx/tools/buck/prelude/js/js_library.bzl
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
load("@prelude//:paths.bzl", "paths")
|
||||
load("@prelude//js:js_providers.bzl", "JsLibraryInfo", "get_transitive_outputs")
|
||||
load("@prelude//js:js_utils.bzl", "TRANSFORM_PROFILES", "get_canonical_src_name", "get_flavors", "run_worker_command")
|
||||
load("@prelude//utils:utils.bzl", "expect", "map_idx")
|
||||
|
||||
# A group of sources that all have the same canonical name. The main_source is arbitrary but
|
||||
# consistent (it is just the first source encountered when processing the src files).
|
||||
GroupedSource = record(
|
||||
canonical_name = str.type,
|
||||
main_source = "artifact",
|
||||
additional_sources = ["artifact"],
|
||||
)
|
||||
|
||||
def _get_grouped_srcs(ctx: "context") -> [GroupedSource.type]:
|
||||
grouped_srcs = {}
|
||||
for src in ctx.attrs.srcs:
|
||||
# TODO(ianc) also support sources with an "inner path".
|
||||
expect(
|
||||
type(src) == "artifact",
|
||||
"src {} is not an artifact, its type is: {}".format(src, type(src)),
|
||||
)
|
||||
canonical_src_name = get_canonical_src_name(src.short_path)
|
||||
if grouped_srcs.get(canonical_src_name, None) == None:
|
||||
grouped_srcs[canonical_src_name] = GroupedSource(
|
||||
canonical_name = canonical_src_name,
|
||||
main_source = src,
|
||||
additional_sources = [],
|
||||
)
|
||||
else:
|
||||
grouped_srcs[canonical_src_name].additional_sources.append(src)
|
||||
|
||||
return grouped_srcs.values()
|
||||
|
||||
def _get_virtual_path(ctx: "context", src: "artifact", base_path: [str.type, None]) -> str.type:
|
||||
package = ctx.label.package
|
||||
if base_path and base_path not in ["", "."]:
|
||||
package = paths.join(package, base_path)
|
||||
|
||||
return paths.join(package, src.short_path)
|
||||
|
||||
def _build_js_file(
|
||||
ctx: "context",
|
||||
transform_profile: str.type,
|
||||
flavors: [str.type],
|
||||
grouped_src: GroupedSource.type) -> "artifact":
|
||||
identifier = "{}/{}".format(transform_profile, grouped_src.canonical_name)
|
||||
|
||||
output_path = ctx.actions.declare_output(identifier)
|
||||
job_args = {
|
||||
"additionalSources": [{
|
||||
"sourcePath": additional_source,
|
||||
"virtualPath": _get_virtual_path(ctx, additional_source, ctx.attrs.base_path),
|
||||
} for additional_source in grouped_src.additional_sources],
|
||||
"command": "transform",
|
||||
"flavors": flavors,
|
||||
"outputFilePath": output_path,
|
||||
"release": ctx.attrs._is_release,
|
||||
"sourceJsFileName": _get_virtual_path(ctx, grouped_src.main_source, ctx.attrs.base_path),
|
||||
"sourceJsFilePath": grouped_src.main_source,
|
||||
"transformProfile": "default" if transform_profile == "transform-profile-default" else transform_profile,
|
||||
}
|
||||
if ctx.attrs.extra_json:
|
||||
job_args["extraData"] = cmd_args(ctx.attrs.extra_json, delimiter = "")
|
||||
|
||||
command_args_file = ctx.actions.write_json(
|
||||
"{}_command_args".format(identifier),
|
||||
job_args,
|
||||
)
|
||||
|
||||
run_worker_command(
|
||||
ctx = ctx,
|
||||
worker_tool = ctx.attrs.worker,
|
||||
command_args_file = command_args_file,
|
||||
identifier = identifier,
|
||||
category = "transform",
|
||||
hidden_artifacts = cmd_args([
|
||||
output_path.as_output(),
|
||||
grouped_src.main_source,
|
||||
] + grouped_src.additional_sources),
|
||||
)
|
||||
|
||||
return output_path
|
||||
|
||||
def _build_library_files(
|
||||
ctx: "context",
|
||||
transform_profile: str.type,
|
||||
flavors: [str.type],
|
||||
js_files: ["artifact"]) -> "artifact":
|
||||
output_path = ctx.actions.declare_output("{}/library_files".format(transform_profile))
|
||||
command_args_file = ctx.actions.write_json(
|
||||
"library_files_{}_command_args".format(transform_profile),
|
||||
{
|
||||
"command": "library-files",
|
||||
"flavors": flavors,
|
||||
"outputFilePath": output_path,
|
||||
"platform": ctx.attrs._platform,
|
||||
"release": ctx.attrs._is_release,
|
||||
"sourceFilePaths": js_files,
|
||||
},
|
||||
)
|
||||
|
||||
run_worker_command(
|
||||
ctx = ctx,
|
||||
worker_tool = ctx.attrs.worker,
|
||||
command_args_file = command_args_file,
|
||||
identifier = transform_profile,
|
||||
category = "library_files",
|
||||
hidden_artifacts = cmd_args([output_path.as_output()] + js_files),
|
||||
)
|
||||
return output_path
|
||||
|
||||
def _build_js_library(
|
||||
ctx: "context",
|
||||
transform_profile: str.type,
|
||||
library_files: "artifact",
|
||||
flavors: [str.type],
|
||||
js_library_deps: ["artifact"]) -> "artifact":
|
||||
output_path = ctx.actions.declare_output("{}.jslib".format(transform_profile))
|
||||
job_args = {
|
||||
"aggregatedSourceFilesFilePath": library_files,
|
||||
"command": "library-dependencies",
|
||||
"dependencyLibraryFilePaths": js_library_deps,
|
||||
"flavors": flavors,
|
||||
"outputPath": output_path,
|
||||
"platform": ctx.attrs._platform,
|
||||
"release": ctx.attrs._is_release,
|
||||
}
|
||||
|
||||
if ctx.attrs.extra_json:
|
||||
job_args["extraData"] = cmd_args(ctx.attrs.extra_json, delimiter = "")
|
||||
|
||||
command_args_file = ctx.actions.write_json(
|
||||
"library_deps_{}_args".format(transform_profile),
|
||||
job_args,
|
||||
)
|
||||
|
||||
run_worker_command(
|
||||
ctx = ctx,
|
||||
worker_tool = ctx.attrs.worker,
|
||||
command_args_file = command_args_file,
|
||||
identifier = transform_profile,
|
||||
category = "library_dependencies",
|
||||
hidden_artifacts = cmd_args([
|
||||
output_path.as_output(),
|
||||
library_files,
|
||||
] + js_library_deps),
|
||||
)
|
||||
|
||||
return output_path
|
||||
|
||||
def js_library_impl(ctx: "context") -> ["provider"]:
|
||||
if ctx.attrs._build_only_native_code:
|
||||
sub_targets = {}
|
||||
unused_output = ctx.actions.write("unused.js", [])
|
||||
|
||||
for transform_profile in TRANSFORM_PROFILES:
|
||||
sub_targets[transform_profile] = [
|
||||
DefaultInfo(default_outputs = [unused_output]),
|
||||
JsLibraryInfo(
|
||||
output = unused_output,
|
||||
transitive_outputs = None,
|
||||
),
|
||||
]
|
||||
|
||||
return [
|
||||
DefaultInfo(default_outputs = [], sub_targets = sub_targets),
|
||||
]
|
||||
|
||||
grouped_srcs = _get_grouped_srcs(ctx)
|
||||
flavors = get_flavors(ctx)
|
||||
sub_targets = {}
|
||||
|
||||
for transform_profile in TRANSFORM_PROFILES:
|
||||
built_js_files = [
|
||||
_build_js_file(ctx, transform_profile, flavors, grouped_src)
|
||||
for grouped_src in grouped_srcs
|
||||
]
|
||||
library_files = _build_library_files(ctx, transform_profile, flavors, built_js_files)
|
||||
|
||||
js_library_deps = dedupe(map_idx(
|
||||
JsLibraryInfo,
|
||||
[dep[DefaultInfo].sub_targets[transform_profile] for dep in ctx.attrs.deps],
|
||||
))
|
||||
js_library = _build_js_library(
|
||||
ctx,
|
||||
transform_profile,
|
||||
library_files,
|
||||
flavors,
|
||||
[js_library_dep.output for js_library_dep in js_library_deps],
|
||||
)
|
||||
|
||||
transitive_outputs = get_transitive_outputs(
|
||||
ctx.actions,
|
||||
value = js_library,
|
||||
deps = js_library_deps,
|
||||
)
|
||||
|
||||
sub_targets[transform_profile] = [
|
||||
DefaultInfo(default_outputs = [js_library]),
|
||||
JsLibraryInfo(
|
||||
output = js_library,
|
||||
transitive_outputs = transitive_outputs,
|
||||
),
|
||||
]
|
||||
|
||||
return [
|
||||
DefaultInfo(default_outputs = [], sub_targets = sub_targets),
|
||||
]
|
||||
47
vendor/cxx/tools/buck/prelude/js/js_providers.bzl
vendored
Normal file
47
vendor/cxx/tools/buck/prelude/js/js_providers.bzl
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
def _artifacts(value: "artifact"):
|
||||
return value
|
||||
|
||||
TransitiveOutputsTSet = transitive_set(args_projections = {"artifacts": _artifacts})
|
||||
|
||||
JsLibraryInfo = provider(
|
||||
fields = [
|
||||
"output", # "artifact"
|
||||
"transitive_outputs", # ["TransitiveOutputsTSet", None]
|
||||
],
|
||||
)
|
||||
|
||||
JsBundleInfo = provider(
|
||||
fields = [
|
||||
"bundle_name", # str.type
|
||||
# Directory containing the built JavaScript.
|
||||
"built_js", # "artifact",
|
||||
# Source map belonging to the built JavaScript.
|
||||
"source_map", # "artifact",
|
||||
# Directory containing the resources (or assets) used by the bundled JavaScript source code.
|
||||
"res", # ["artifact", None]
|
||||
# Directory containing various metadata that can be used by dependent rules but are not
|
||||
# meant to be shipped with the application.
|
||||
"misc", # "artifact"
|
||||
# Dependencies graph file associated with the built JavaScript.
|
||||
"dependencies_file", # "artifact"
|
||||
],
|
||||
)
|
||||
|
||||
def get_transitive_outputs(
|
||||
actions: "actions",
|
||||
value: ["artifact", None] = None,
|
||||
deps: [JsLibraryInfo.type] = []) -> TransitiveOutputsTSet.type:
|
||||
kwargs = {}
|
||||
if value:
|
||||
kwargs["value"] = value
|
||||
if deps:
|
||||
kwargs["children"] = filter(None, [js_library_info.transitive_outputs for js_library_info in deps])
|
||||
|
||||
return actions.tset(TransitiveOutputsTSet, **kwargs)
|
||||
129
vendor/cxx/tools/buck/prelude/js/js_utils.bzl
vendored
Normal file
129
vendor/cxx/tools/buck/prelude/js/js_utils.bzl
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under both the MIT license found in the
|
||||
# LICENSE-MIT file in the root directory of this source tree and the Apache
|
||||
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
# of this source tree.
|
||||
|
||||
load("@prelude//:paths.bzl", "paths")
|
||||
load("@prelude//:worker_tool.bzl", "WorkerToolInfo")
|
||||
load("@prelude//utils:utils.bzl", "expect")
|
||||
|
||||
RAM_BUNDLE_TYPES = {
|
||||
"": "",
|
||||
"rambundle-indexed": "--indexed-rambundle",
|
||||
}
|
||||
|
||||
TRANSFORM_PROFILES = ["transform-profile-default", "hermes-stable", "hermes-canary"]
|
||||
|
||||
# Matches the default value for resolver.assetExts in metro-config
|
||||
ASSET_EXTENSIONS = [
|
||||
# Image formats
|
||||
"bmp",
|
||||
"gif",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"psd",
|
||||
"svg",
|
||||
"webp",
|
||||
# Video formats
|
||||
"m4v",
|
||||
"mov",
|
||||
"mp4",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"webm",
|
||||
# Audio formats
|
||||
"aac",
|
||||
"aiff",
|
||||
"caf",
|
||||
"m4a",
|
||||
"mp3",
|
||||
"wav",
|
||||
# Document formats
|
||||
"html",
|
||||
"pdf",
|
||||
"yaml",
|
||||
"yml",
|
||||
# Font formats
|
||||
"otf",
|
||||
"ttf",
|
||||
# Archives (virtual files)
|
||||
"zip",
|
||||
]
|
||||
|
||||
# Matches the default value for resolver.platforms in metro-config
|
||||
ASSET_PLATFORMS = ["ios", "android", "windows", "web"]
|
||||
|
||||
def _strip_platform_from_asset_name(name: str.type) -> str.type:
|
||||
name_without_extension, extension = paths.split_extension(name)
|
||||
return name_without_extension if extension[1:] in ASSET_PLATFORMS else name
|
||||
|
||||
def _strip_scale_from_asset_name(name: str.type) -> str.type:
|
||||
scale_start = -1
|
||||
for i in range(len(name)):
|
||||
char = name[i]
|
||||
if scale_start != -1:
|
||||
if char == "x":
|
||||
return name[:scale_start] + name[i + 1:]
|
||||
if char.isdigit() or char == ".":
|
||||
continue
|
||||
fail("Invalid format for scale of asset {}!".format(name))
|
||||
if name[i] == "@":
|
||||
scale_start = i
|
||||
|
||||
expect(scale_start == -1, "Found scale_start but not its end {}!".format(name))
|
||||
|
||||
return name
|
||||
|
||||
def get_canonical_src_name(src: str.type) -> str.type:
|
||||
basename, extension = paths.split_extension(src)
|
||||
if extension[1:] not in ASSET_EXTENSIONS:
|
||||
return src
|
||||
|
||||
basename = _strip_platform_from_asset_name(basename)
|
||||
basename = _strip_scale_from_asset_name(basename)
|
||||
|
||||
return basename + extension
|
||||
|
||||
def get_flavors(ctx: "context") -> [str.type]:
|
||||
flavors = [ctx.attrs._platform]
|
||||
if ctx.attrs._is_release:
|
||||
flavors.append("release")
|
||||
|
||||
return flavors
|
||||
|
||||
def get_bundle_name(ctx: "context", default_bundle_name: str.type) -> str.type:
|
||||
bundle_name_for_flavor_map = {key: value for key, value in ctx.attrs.bundle_name_for_flavor}
|
||||
flavors = bundle_name_for_flavor_map.keys()
|
||||
for flavor in flavors:
|
||||
expect(
|
||||
flavor == "android" or flavor == "ios",
|
||||
"Currently only support picking bundle name by platform!",
|
||||
)
|
||||
|
||||
platform = ctx.attrs._platform
|
||||
if platform in flavors:
|
||||
return bundle_name_for_flavor_map[platform]
|
||||
else:
|
||||
return default_bundle_name
|
||||
|
||||
def run_worker_command(
|
||||
ctx: "context",
|
||||
worker_tool: "dependency",
|
||||
command_args_file: "artifact",
|
||||
identifier: str.type,
|
||||
category: str.type,
|
||||
hidden_artifacts = "cmd_args"):
|
||||
worker_tool_info = worker_tool[WorkerToolInfo]
|
||||
worker_command = worker_tool_info.command.copy()
|
||||
worker_command.add("--command-args-file", command_args_file)
|
||||
worker_command.hidden(hidden_artifacts)
|
||||
worker_command.add("--command-args-file-extra-data-fixup-hack=true")
|
||||
|
||||
ctx.actions.run(
|
||||
worker_command,
|
||||
category = category.replace("-", "_"),
|
||||
identifier = identifier,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue