Skip to content

Commit

Permalink
Add DefaultOutputPathInfo provider and update write_source_files to a…
Browse files Browse the repository at this point in the history
…ccept it (#48)

Also update write_source_files to accept DirectoryPathInfo
  • Loading branch information
gregmagolan authored Mar 15, 2022
1 parent 7f2641c commit 3b93ee0
Show file tree
Hide file tree
Showing 28 changed files with 622 additions and 319 deletions.
6 changes: 3 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
docs/*.md
lib/tests/jq/*.json
lib/tests/write_source_files/a2.js
lib/tests/write_source_files/b2.js
lib/tests/write_source_files/e_dir/e.js
lib/lib/tests/write_source_files/*.js
lib/lib/tests/write_source_files/subdir/*.js
lib/lib/tests/write_source_files/subdir/subsubdir/*.js
7 changes: 5 additions & 2 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ stardoc_with_diff_test(
bzl_library_target = "//lib:directory_path",
)

update_docs(
name = "update",
stardoc_with_diff_test(
name = "default_info_files",
bzl_library_target = "//lib:default_info_files",
)

update_docs()
49 changes: 49 additions & 0 deletions docs/default_info_files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->

A rule that provides file(s) from a given target's DefaultInfo


<a id="#default_info_files"></a>

## default_info_files

<pre>
default_info_files(<a href="#default_info_files-name">name</a>, <a href="#default_info_files-paths">paths</a>, <a href="#default_info_files-target">target</a>)
</pre>

A rule that provides file(s) from a given target's DefaultInfo

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="default_info_files-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="default_info_files-paths"></a>paths | the paths of the files to provide in the DefaultInfo of the target relative to its root | List of strings | required | |
| <a id="default_info_files-target"></a>target | the target to look in for requested paths in its' DefaultInfo | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |


<a id="#make_default_info_files"></a>

## make_default_info_files

<pre>
make_default_info_files(<a href="#make_default_info_files-name">name</a>, <a href="#make_default_info_files-target">target</a>, <a href="#make_default_info_files-paths">paths</a>)
</pre>

Helper function to generate a default_info_files target and return its label.

**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="make_default_info_files-name"></a>name | unique name for the generated <code>default_info_files</code> target. | none |
| <a id="make_default_info_files-target"></a>target | the target to look in for requested paths in its' DefaultInfo | none |
| <a id="make_default_info_files-paths"></a>paths | the paths of the files to provide in the DefaultInfo of the target relative to its root | none |

**RETURNS**

The label `name`


2 changes: 1 addition & 1 deletion docs/directory_path.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Joins a label pointing to a TreeArtifact with a path nested within that director
make_directory_path(<a href="#make_directory_path-name">name</a>, <a href="#make_directory_path-directory">directory</a>, <a href="#make_directory_path-path">path</a>)
</pre>

Helper function to convert generate a directory_path target and return its label.
Helper function to generate a directory_path target and return its label.

**PARAMETERS**

Expand Down
4 changes: 2 additions & 2 deletions docs/write_source_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ If you have many sources that you want to update as a group, we recommend wrappi
| :------------- | :------------- | :------------- |
| <a id="write_source_files-name"></a>name | Name of the executable target that creates or updates the source file | none |
| <a id="write_source_files-files"></a>files | A dict where the keys are source files or folders to write to and the values are labels pointing to the desired content. Sources must be within the same bazel package as the target. | <code>{}</code> |
| <a id="write_source_files-additional_update_targets"></a>additional_update_targets | (Optional) List of other write_source_files targets to update in the same run | <code>[]</code> |
| <a id="write_source_files-suggested_update_target"></a>suggested_update_target | (Optional) Label of the write_source_files target to suggest running when files are out of date | <code>None</code> |
| <a id="write_source_files-additional_update_targets"></a>additional_update_targets | (Optional) List of other write_source_file or other executable updater targets to call in the same run | <code>[]</code> |
| <a id="write_source_files-suggested_update_target"></a>suggested_update_target | (Optional) Label of the write_source_file target to suggest running when files are out of date | <code>None</code> |
| <a id="write_source_files-kwargs"></a>kwargs | Other common named parameters such as <code>tags</code> or <code>visibility</code> | none |


18 changes: 16 additions & 2 deletions lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ bzl_library(
deps = ["//lib/private:directory_path"],
)

bzl_library(
name = "default_info_files",
srcs = ["default_info_files.bzl"],
visibility = ["//visibility:public"],
deps = ["//lib/private:default_info_files"],
)

bzl_library(
name = "copy_to_directory",
srcs = ["copy_to_directory.bzl"],
Expand All @@ -80,9 +87,16 @@ bzl_library(
srcs = ["write_source_files.bzl"],
visibility = ["//visibility:public"],
deps = [
":diff_test",
":utils",
"//lib/private:fail_with_message_test",
"//lib/private:write_source_files",
"@bazel_skylib//rules:diff_test",
"//lib/private:write_source_file",
],
)

bzl_library(
name = "diff_test",
srcs = ["diff_test.bzl"],
visibility = ["//visibility:public"],
deps = ["//lib/private:diff_test"],
)
11 changes: 11 additions & 0 deletions lib/default_info_files.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""A rule that provides file(s) from a given target's DefaultInfo
"""

load(
"//lib/private:default_info_files.bzl",
_default_info_files = "default_info_files",
_make_default_info_files = "make_default_info_files",
)

default_info_files = _default_info_files
make_default_info_files = _make_default_info_files
14 changes: 0 additions & 14 deletions lib/directory_path.bzl
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
# Copyright 2019 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.

"""Rule and corresponding provider that joins a label pointing to a TreeArtifact
with a path nested within that directory
"""
Expand Down
24 changes: 21 additions & 3 deletions lib/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ bzl_library(
srcs = ["copy_to_directory.bzl"],
visibility = ["//lib:__subpackages__"],
deps = [
":default_info_files",
":directory_path",
":paths",
"@bazel_skylib//lib:paths",
Expand Down Expand Up @@ -61,10 +62,14 @@ bzl_library(
)

bzl_library(
name = "write_source_files",
srcs = ["write_source_files.bzl"],
name = "write_source_file",
srcs = ["write_source_file.bzl"],
visibility = ["//lib:__subpackages__"],
deps = ["//lib:utils"],
deps = [
":default_info_files",
":directory_path",
"//lib:utils",
],
)

bzl_library(
Expand All @@ -79,3 +84,16 @@ bzl_library(
visibility = ["//lib:__subpackages__"],
deps = ["//lib:utils"],
)

bzl_library(
name = "default_info_files",
srcs = ["default_info_files.bzl"],
visibility = ["//lib:__subpackages__"],
deps = ["//lib:utils"],
)

bzl_library(
name = "diff_test",
srcs = ["diff_test.bzl"],
visibility = ["//lib:__subpackages__"],
)
2 changes: 1 addition & 1 deletion lib/private/copy_file.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def _copy_file_impl(ctx):
src_path = "/".join([src_file.path, ctx.attr.src[DirectoryPathInfo].path])
else:
if len(ctx.files.src) != 1:
fail("src must be a single file or a target with a DirectoryPathInfo provider")
fail("src must be a single file or a target that provides a DirectoryPathInfo")
src_file = ctx.files.src[0]
src_path = src_file.path
if ctx.attr.is_windows:
Expand Down
70 changes: 70 additions & 0 deletions lib/private/default_info_files.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""default_info_files implementation
"""

load("//lib:utils.bzl", _to_label = "to_label")

def _default_info_files(ctx):
files = []
for path in ctx.attr.paths:
file = find_short_path_in_default_info(
ctx.attr.target,
path,
)
if not file:
fail("%s file not found within the DefaultInfo of %s" % (ctx.attr.path, ctx.attr.target))
files.append(file)
return [DefaultInfo(
files = depset(direct = files),
runfiles = ctx.runfiles(files = files),
)]

default_info_files = rule(
doc = "A rule that provides file(s) from a given target's DefaultInfo",
implementation = _default_info_files,
attrs = {
"target": attr.label(
doc = "the target to look in for requested paths in its' DefaultInfo",
mandatory = True,
),
"paths": attr.string_list(
doc = "the paths of the files to provide in the DefaultInfo of the target relative to its root",
mandatory = True,
allow_empty = False,
),
},
provides = [DefaultInfo],
)

def make_default_info_files(name, target, paths):
"""Helper function to generate a default_info_files target and return its label.
Args:
name: unique name for the generated `default_info_files` target.
target: the target to look in for requested paths in its' DefaultInfo
paths: the paths of the files to provide in the DefaultInfo of the target relative to its root
Returns:
The label `name`
"""
default_info_files(
name = name,
target = target,
paths = paths,
)
return _to_label(name)

def find_short_path_in_default_info(default_info, short_path):
"""Helper function find a file in a DefaultInfo by short path
Args:
default_info: a DefaultInfo
short_path: the short path (path relative to root) to search for
Returns:
The File if found else None
"""
if default_info.files:
for file in default_info.files.to_list():
if file.short_path == short_path:
return file
return None
34 changes: 27 additions & 7 deletions lib/private/diff_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,33 @@ The rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).
"""

load(":directory_path.bzl", "DirectoryPathInfo")

def _runfiles_path(f):
if f.root.path:
return f.path[len(f.root.path) + 1:] # generated file
else:
return f.path # source file

def _diff_test_impl(ctx):
if DirectoryPathInfo in ctx.attr.file1:
file1 = ctx.attr.file1[DirectoryPathInfo].directory
file1_path = "/".join([_runfiles_path(file1), ctx.attr.file1[DirectoryPathInfo].path])
else:
if len(ctx.files.file1) != 1:
fail("file1 must be a single file or a target that provides a DirectoryPathInfo")
file1 = ctx.files.file1[0]
file1_path = _runfiles_path(file1)

if DirectoryPathInfo in ctx.attr.file2:
file2 = ctx.attr.file2[DirectoryPathInfo].directory
file2_path = "/".join([_runfiles_path(file2), ctx.attr.file2[DirectoryPathInfo].path])
else:
if len(ctx.files.file2) != 1:
fail("file2 must be a single file or a target that provides a DirectoryPathInfo")
file2 = ctx.files.file2[0]
file2_path = _runfiles_path(file2)

if ctx.attr.is_windows:
test_bin = ctx.actions.declare_file(ctx.label.name + "-test.bat")
ctx.actions.write(
Expand Down Expand Up @@ -138,8 +158,8 @@ exit /b 0
exit /b 1
""".format(
fail_msg = ctx.attr.failure_message,
file1 = _runfiles_path(ctx.file.file1),
file2 = _runfiles_path(ctx.file.file2),
file1 = file1_path,
file2 = file2_path,
),
is_executable = True,
)
Expand Down Expand Up @@ -191,26 +211,26 @@ else
fi
""".format(
fail_msg = ctx.attr.failure_message,
file1 = _runfiles_path(ctx.file.file1),
file2 = _runfiles_path(ctx.file.file2),
file1 = file1_path,
file2 = file2_path,
),
is_executable = True,
)
return DefaultInfo(
executable = test_bin,
files = depset(direct = [test_bin]),
runfiles = ctx.runfiles(files = [test_bin, ctx.file.file1, ctx.file.file2]),
runfiles = ctx.runfiles(files = [test_bin, file1, file2]),
)

_diff_test = rule(
attrs = {
"failure_message": attr.string(),
"file1": attr.label(
allow_single_file = True,
allow_files = True,
mandatory = True,
),
"file2": attr.label(
allow_single_file = True,
allow_files = True,
mandatory = True,
),
"is_windows": attr.bool(mandatory = True),
Expand Down
3 changes: 2 additions & 1 deletion lib/private/directory_path.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ Otherwise there is no way to give a Bazel label for it.""",
mandatory = True,
),
},
provides = [DirectoryPathInfo],
)

def make_directory_path(name, directory, path):
"""Helper function to convert generate a directory_path target and return its label.
"""Helper function to generate a directory_path target and return its label.
Args:
name: Unique name for the generated `directory_path` target.
Expand Down
Loading

0 comments on commit 3b93ee0

Please sign in to comment.