1515"""Rules to aid testing"""
1616
1717load ("//pkg/private:pkg_files.bzl" , "add_label_list" , "write_manifest" )
18+ load ("//pkg:providers.bzl" , "PackageFilegroupInfo" , "PackageSymlinkInfo" )
1819load ("@bazel_skylib//lib:unittest.bzl" , "analysistest" , "asserts" )
1920load ("@rules_python//python:defs.bzl" , "py_binary" )
2021
@@ -24,10 +25,15 @@ def _directory_impl(ctx):
2425 args = ctx .actions .args ()
2526 args .add (out_dir_file .path )
2627
28+ # This helper is horrible. We should pass all the args in files.
2729 for fn in ctx .attr .filenames :
2830 args .add (fn )
2931 args .add (ctx .attr .contents )
3032
33+ for link , target in ctx .attr .links .items ():
34+ args .add (link )
35+ args .add ('@@' + target )
36+
3137 ctx .actions .run (
3238 outputs = [out_dir_file ],
3339 inputs = [],
@@ -48,6 +54,11 @@ creation capabilities are "unsound".
4854 doc = """Paths to create in the directory.
4955
5056Paths containing directories will also have the intermediate directories created too.""" ,
57+ ),
58+ "links" : attr .string_dict (
59+ doc = """Set of (virtual) links to create.
60+
61+ The keys of links are paths to create. The values are the target of the links.""" ,
5162 ),
5263 "contents" : attr .string (),
5364 "outdir" : attr .string (),
@@ -101,6 +112,37 @@ cc_binary in complexity, but does not depend on a large toolchain.""",
101112 },
102113)
103114
115+ def _link_tree_impl (ctx ):
116+ links = []
117+ prefix = ctx .attr .package_dir or ""
118+ if prefix and not prefix .endswith ('/' ):
119+ prefix = prefix + "/"
120+ for link , target in ctx .attr .links .items ():
121+ print (' %s -> %s ' % (link , target ))
122+ links .append (
123+ (PackageSymlinkInfo (destination = prefix + link , target = target ),
124+ ctx .label ))
125+ return [PackageFilegroupInfo (pkg_symlinks = links )]
126+
127+ link_tree = rule (
128+ doc = """Helper rule to create a lot of fake symlinks.
129+
130+ The inspiration is to create test data for the kinds of layouts needed by
131+ nodejs. See. https://pnpm.io/symlinked-node-modules-structure
132+ """ ,
133+ implementation = _link_tree_impl ,
134+ attrs = {
135+ "links" : attr .string_dict (
136+ doc = """Set of (virtual) links to create.
137+
138+ The keys of links are paths to create. The values are the target of the links.""" ,
139+ mandatory = True ,
140+ ),
141+ "package_dir" : attr .string (doc = """Prefix to apply to all link paths.""" ),
142+ },
143+ provides = [PackageFilegroupInfo ],
144+ )
145+
104146def _write_content_manifest_impl (ctx ):
105147 content_map = {} # content handled in the manifest
106148 file_deps = [] # inputs we depend on
0 commit comments