diff options
author | aiuto <aiuto@google.com> | 2022-09-12 23:58:39 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-12 23:58:39 -0400 |
commit | 46eabd36cf957920406d2a8b05f178a0bd0f851a (patch) | |
tree | 6a66193d3343ec8249b8dfd1d30177f782767017 | |
parent | 60dbd92d1ce3338cbb8adcb8ae8800ea3421d7b8 (diff) | |
download | bazelbuild-rules_pkg-46eabd36cf957920406d2a8b05f178a0bd0f851a.tar.gz |
Create an example of the kind of link tree Node users must create (#603)
* Create an example of the kind of link tree Node users muse create
-rw-r--r-- | pkg/private/pkg_files.bzl | 15 | ||||
-rw-r--r-- | tests/BUILD | 9 | ||||
-rw-r--r-- | tests/mappings/BUILD | 29 | ||||
-rwxr-xr-x | tests/mappings/node_modules_manifest.golden | 9 | ||||
-rw-r--r-- | tests/tar/BUILD | 53 | ||||
l--------- | tests/testdata/outer_BUILD | 1 | ||||
-rw-r--r-- | tests/util/create_directory_with_contents.py | 10 | ||||
-rw-r--r-- | tests/util/defs.bzl | 42 |
8 files changed, 156 insertions, 12 deletions
diff --git a/pkg/private/pkg_files.bzl b/pkg/private/pkg_files.bzl index 5922b35..75e12db 100644 --- a/pkg/private/pkg_files.bzl +++ b/pkg/private/pkg_files.bzl @@ -127,12 +127,15 @@ def _process_pkg_symlink(content_map, pkg_symlink_info, origin, default_mode, de ) def _process_pkg_filegroup(content_map, pkg_filegroup_info, origin, default_mode, default_user, default_group): - for d in pkg_filegroup_info.pkg_dirs: - _process_pkg_dirs(content_map, d[0], d[1], default_mode, default_user, default_group) - for pf in pkg_filegroup_info.pkg_files: - _process_pkg_files(content_map, pf[0], pf[1], default_mode, default_user, default_group) - for psl in pkg_filegroup_info.pkg_symlinks: - _process_pkg_symlink(content_map, psl[0], psl[1], default_mode, default_user, default_group) + if hasattr(pkg_filegroup_info, "pkg_dirs"): + for d in pkg_filegroup_info.pkg_dirs: + _process_pkg_dirs(content_map, d[0], d[1], default_mode, default_user, default_group) + if hasattr(pkg_filegroup_info, "pkg_files"): + for pf in pkg_filegroup_info.pkg_files: + _process_pkg_files(content_map, pf[0], pf[1], default_mode, default_user, default_group) + if hasattr(pkg_filegroup_info, "pkg_symlinks"): + for psl in pkg_filegroup_info.pkg_symlinks: + _process_pkg_symlink(content_map, psl[0], psl[1], default_mode, default_user, default_group) def process_src(content_map, files, src, origin, default_mode, default_user, default_group): diff --git a/tests/BUILD b/tests/BUILD index d2bd1f1..c6666c6 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -40,6 +40,15 @@ filegroup( ) filegroup( + name = "file_and_link", + srcs = [ + "BUILD", + "testdata/outer_BUILD", + ], + visibility = ["//visibility:public"], +) + +filegroup( name = "glob_for_texts", srcs = glob(["**/*.txt"]), ) diff --git a/tests/mappings/BUILD b/tests/mappings/BUILD index b742ff5..6ebee0a 100644 --- a/tests/mappings/BUILD +++ b/tests/mappings/BUILD @@ -27,7 +27,7 @@ load( "pkg_mkdirs", "strip_prefix", ) -load("//tests/util:defs.bzl", "directory", "write_content_manifest") +load("//tests/util:defs.bzl", "directory", "link_tree", "write_content_manifest") load("@rules_python//python:defs.bzl", "py_test") package(default_applicable_licenses = ["//:license"]) @@ -158,3 +158,30 @@ manifest_golden_test( expected = "glob_for_texts_manifest.golden", target = "glob_for_texts_manifest", ) + +link_tree( + name = "node_modules", + links = { + "foo": ".pnpm/foo@1.0.0/node_modules/foo", + ".pnpm/bar@1.0.0/node_modules/bar": "STORE/bar", + ".pnpm/bar@1.0.0/node_modules/qar": "../../qar@2.0.0/node_modules/qar", + ".pnpm/foo@1.0.0/node_modules/foo": "STORE/foo", + ".pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", + ".pnpm/foo@1.0.0/node_modules/qar": "../../qar@2.0.0/node_modules/qar", + ".pnpm/qar@2.0.0/node_modules/qar": "STORE/qar", + }, + package_dir = "node_modules", +) + +write_content_manifest( + name = "node_modules_manifest", + srcs = [ + ":node_modules", + ], +) + +manifest_golden_test( + name = "link_tree_test", + expected = "node_modules_manifest.golden", + target = "node_modules_manifest", +) diff --git a/tests/mappings/node_modules_manifest.golden b/tests/mappings/node_modules_manifest.golden new file mode 100755 index 0000000..fb55d06 --- /dev/null +++ b/tests/mappings/node_modules_manifest.golden @@ -0,0 +1,9 @@ +[ +[1,"node_modules/.pnpm/bar@1.0.0/node_modules/bar","STORE/bar","",null,null], +[1,"node_modules/.pnpm/bar@1.0.0/node_modules/qar","../../qar@2.0.0/node_modules/qar","",null,null], +[1,"node_modules/.pnpm/foo@1.0.0/node_modules/bar","../../bar@1.0.0/node_modules/bar","",null,null], +[1,"node_modules/.pnpm/foo@1.0.0/node_modules/foo","STORE/foo","",null,null], +[1,"node_modules/.pnpm/foo@1.0.0/node_modules/qar","../../qar@2.0.0/node_modules/qar","",null,null], +[1,"node_modules/.pnpm/qar@2.0.0/node_modules/qar","STORE/qar","",null,null], +[1,"node_modules/foo",".pnpm/foo@1.0.0/node_modules/foo","",null,null] +] diff --git a/tests/tar/BUILD b/tests/tar/BUILD index 8fc1abf..34defdc 100644 --- a/tests/tar/BUILD +++ b/tests/tar/BUILD @@ -18,11 +18,14 @@ load("//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("//pkg/private/tar:tar.bzl", "SUPPORTED_TAR_COMPRESSIONS", "pkg_tar") load("//tests:my_package_name.bzl", "my_package_naming") -load("//tests/util:defs.bzl", "directory", "fake_artifact") +load("//tests/util:defs.bzl", "directory", "link_tree", "fake_artifact") load("@rules_python//python:defs.bzl", "py_test") load("@bazel_skylib//rules:copy_file.bzl", "copy_file") -package(default_applicable_licenses = ["//:license"]) +package( + default_applicable_licenses = ["//:license"], + default_visibility = ["//visibility:private"], +) py_test( name = "tar_writer_test", @@ -396,3 +399,49 @@ py_test( "@bazel_tools//tools/python/runfiles", ], ) + +link_tree( + name = "node_modules", + links = { + "foo": ".pnpm/foo@1.0.0/node_modules/foo", + ".pnpm/bar@1.0.0/node_modules/bar": "STORE/bar", + ".pnpm/foo@1.0.0/node_modules/foo": "STORE/foo", + ".pnpm/foo@1.0.0/node_modules/bar": "../../bar@1.0.0/node_modules/bar", + }, + package_dir = "node_modules", +) + +directory( + name = "tree_artifact_with_links", + contents = "hello there", + filenames = [ + "foo/hello.txt", + "foo/bar/baz", + ], + links = { + "foo/bar/hello": "../hello.txt", + "foo/bar/alt_baz": "baz", + "foo/alt_baz": "bar/baz", + }, +) + + +# This target has symlinks 3 ways. +# - mklinks rules. +# - source files that are symlinks +# - tree artifacts +pkg_tar( + name = "relative_links_tar", + srcs = [ + ":node_modules", + ":tree_artifact_with_links", + "//tests:file_and_link", + ], +) + +pkg_tar( + name = "relative_links_re_tar", + deps = [ + ":relative_links_tar", + ], +) diff --git a/tests/testdata/outer_BUILD b/tests/testdata/outer_BUILD new file mode 120000 index 0000000..c447d20 --- /dev/null +++ b/tests/testdata/outer_BUILD @@ -0,0 +1 @@ +../BUILD
\ No newline at end of file diff --git a/tests/util/create_directory_with_contents.py b/tests/util/create_directory_with_contents.py index 4e436ad..7138884 100644 --- a/tests/util/create_directory_with_contents.py +++ b/tests/util/create_directory_with_contents.py @@ -36,9 +36,13 @@ for a in rest_args_iter: os.makedirs(dirname, exist_ok=True) for fname, contents in files_contents_map.items(): + path = os.path.join(dirname, fname) os.makedirs( - os.path.join(dirname, os.path.dirname(fname)), + os.path.dirname(path), exist_ok=True, ) - with open(os.path.join(dirname, fname), 'w') as fh: - fh.write(contents) + if contents.startswith('@@'): + os.symlink(contents[2:], path) + else: + with open(path, 'w') as fh: + fh.write(contents) diff --git a/tests/util/defs.bzl b/tests/util/defs.bzl index 94076e3..eb3124c 100644 --- a/tests/util/defs.bzl +++ b/tests/util/defs.bzl @@ -15,6 +15,7 @@ """Rules to aid testing""" load("//pkg/private:pkg_files.bzl", "add_label_list", "write_manifest") +load("//pkg:providers.bzl", "PackageFilegroupInfo", "PackageSymlinkInfo") load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@rules_python//python:defs.bzl", "py_binary") @@ -24,10 +25,15 @@ def _directory_impl(ctx): args = ctx.actions.args() args.add(out_dir_file.path) + # This helper is horrible. We should pass all the args in files. for fn in ctx.attr.filenames: args.add(fn) args.add(ctx.attr.contents) + for link, target in ctx.attr.links.items(): + args.add(link) + args.add('@@' + target) + ctx.actions.run( outputs = [out_dir_file], inputs = [], @@ -49,6 +55,11 @@ creation capabilities are "unsound". Paths containing directories will also have the intermediate directories created too.""", ), + "links": attr.string_dict( + doc = """Set of (virtual) links to create. + +The keys of links are paths to create. The values are the target of the links.""", + ), "contents": attr.string(), "outdir": attr.string(), "_dir_creator": attr.label( @@ -101,6 +112,37 @@ cc_binary in complexity, but does not depend on a large toolchain.""", }, ) +def _link_tree_impl(ctx): + links = [] + prefix = ctx.attr.package_dir or "" + if prefix and not prefix.endswith('/'): + prefix = prefix + "/" + for link, target in ctx.attr.links.items(): + print(' %s -> %s ' % (link, target)) + links.append( + (PackageSymlinkInfo(destination = prefix + link, target = target), + ctx.label)) + return [PackageFilegroupInfo(pkg_symlinks = links)] + +link_tree = rule( + doc = """Helper rule to create a lot of fake symlinks. + +The inspiration is to create test data for the kinds of layouts needed by +nodejs. See. https://pnpm.io/symlinked-node-modules-structure + """, + implementation = _link_tree_impl, + attrs = { + "links": attr.string_dict( + doc = """Set of (virtual) links to create. + +The keys of links are paths to create. The values are the target of the links.""", + mandatory = True, + ), + "package_dir": attr.string(doc = """Prefix to apply to all link paths."""), + }, + provides = [PackageFilegroupInfo], +) + def _write_content_manifest_impl(ctx): content_map = {} # content handled in the manifest file_deps = [] # inputs we depend on |