2022-03-04 00:40:32 +00:00
""" Rule and corresponding provider that joins a label pointing to a TreeArtifact
with a path nested within that directory
"""
load ( " //lib:utils.bzl " , _to_label = " to_label " )
DirectoryPathInfo = provider (
doc = " Joins a label pointing to a TreeArtifact with a path nested within that directory. " ,
fields = {
" directory " : " a TreeArtifact (ctx.actions.declare_directory) " ,
" path " : " path relative to the directory " ,
} ,
)
def _directory_path ( ctx ) :
if not ctx . file . directory . is_directory :
2022-07-22 16:37:27 +00:00
msg = " Expected directory to be a TreeArtifact (ctx.actions.declare_directory) but {} is either a source file or does not exist. " . format ( ctx . file . directory )
2022-06-13 17:10:34 +00:00
fail ( msg )
2022-03-04 00:40:32 +00:00
return [ DirectoryPathInfo ( path = ctx . attr . path , directory = ctx . file . directory ) ]
directory_path = rule (
doc = """ Provide DirectoryPathInfo to reference some path within a directory.
Otherwise there is no way to give a Bazel label for it . """ ,
implementation = _directory_path ,
attrs = {
" directory " : attr . label (
doc = " a TreeArtifact (ctx.actions.declare_directory) " ,
mandatory = True ,
allow_single_file = True ,
) ,
" path " : attr . string (
doc = " path relative to the directory " ,
mandatory = True ,
) ,
} ,
2022-03-15 00:33:52 +00:00
provides = [ DirectoryPathInfo ] ,
2022-03-04 00:40:32 +00:00
)
2022-03-16 00:36:22 +00:00
def make_directory_path ( name , directory , path , * * kwargs ) :
2022-03-15 00:33:52 +00:00
""" Helper function to generate a directory_path target and return its label.
2022-03-04 00:40:32 +00:00
Args :
2022-03-16 00:36:22 +00:00
name : unique name for the generated ` directory_path ` target
directory : ` directory ` attribute passed to generated ` directory_path ` target
path : ` path ` attribute passed to generated ` directory_path ` target
* * kwargs : parameters to pass to generated ` output_files ` target
2022-03-04 00:40:32 +00:00
Returns :
The label ` name `
"""
directory_path (
name = name ,
directory = directory ,
path = path ,
2022-03-16 00:36:22 +00:00
* * kwargs
2022-03-04 00:40:32 +00:00
)
return _to_label ( name )
2022-03-16 00:36:22 +00:00
def make_directory_paths ( name , dict , * * kwargs ) :
2022-03-04 00:40:32 +00:00
""" Helper function to convert a dict of directory to path mappings to directory_path targets and labels.
For example ,
` ` `
make_directory_paths ( " my_name " , {
" //directory/artifact:target_1 " : " file/path " ,
" //directory/artifact:target_2 " : [ " file/path1 " , " file/path2 " ] ,
} )
` ` `
generates the targets ,
` ` `
directory_path (
name = " my_name_0 " ,
directory = " //directory/artifact:target_1 " ,
path = " file/path "
)
directory_path (
name = " my_name_1 " ,
directory = " //directory/artifact:target_2 " ,
path = " file/path1 "
)
directory_path (
name = " my_name_2 " ,
directory = " //directory/artifact:target_2 " ,
path = " file/path2 "
)
` ` `
and the list of targets is returned ,
` ` `
[
" my_name_0 " ,
" my_name_1 " ,
" my_name_2 " ,
]
` ` `
Args :
name : The target name to use for the generated targets & labels .
The names are generated as zero - indexed ` name + " _ " + i `
dict : The dictionary of directory keys to path or path list values .
2022-03-16 00:36:22 +00:00
* * kwargs : additional parameters to pass to each generated target
2022-03-04 00:40:32 +00:00
Returns :
The label of the generated ` directory_path ` targets named ` name + " _ " + i `
"""
labels = [ ]
pairs = [ ]
for directory , val in dict . items ( ) :
if type ( val ) == " list " :
for path in val :
pairs . append ( ( directory , path ) )
elif type ( val ) == " string " :
pairs . append ( ( directory , val ) )
else :
fail ( " Value must be a list or string " )
for i , pair in enumerate ( pairs ) :
directory , path = pair
labels . append ( make_directory_path (
" %s _ %d " % ( name , i ) ,
directory ,
path ,
2022-03-16 00:36:22 +00:00
* * kwargs
2022-03-04 00:40:32 +00:00
) )
return labels