使用标签路径检查文件位置是否存在

时间:2018-05-16 10:43:31

标签: bazel

是否有一种简单的方法来获取路径对象,以便检查给定的标签路径是否存在。比如说if path.exists("@external_project_name//:filethatmightexist.txt"):。我可以看到存储库上下文有这个。但我需要一个包装存储库规则。是否可以在宏或Skylark本机调用中执行此操作?

1 个答案:

答案 0 :(得分:1)

即使有了repository_rule,由于您已经指出,我对此也遇到了很多麻烦:

如果使用不存在的路径创建标签,则会导致构建失败

但是,如果您愿意执行存储库规则,这是一个可能的解决方案...

在此示例中,如果不存在配置文件,则我的规则允许指定默认配置。可以将配置签入.gitignore并为各个开发人员覆盖,但在大多数情况下都可以直接使用。

我想我理解为什么ctx.actions现在具有同级参数,这里的想法相同。诀窍是config_file_location是一个真标签,然后config_file是一个字符串属性。我随意选择了BUILD,但是由于所有工作区都具有顶级BUILD,因此公开似乎是合法的。

WORKSPACE Definition
...
workspace(name="E02_mysql_database")
json_datasource_configuration(name="E02_datasources",
                              config_file_location="@E02_mysql_database//:BUILD",
                              config_file="database.json")

json_datasource_configuration的定义如下:

json_datasource_configuration = repository_rule(
    attrs = {
        "config_file_location": attr.label(
            doc="""
            Path relative to the repository root for a datasource config file.

            """),
        "config_file": attr.string(
            doc="""
            Config file, maybe absent
            """),
        "default_config": attr.string(
            # better way to do this?
            default="None",
            doc = """
            If no config is at the path, then this will be the default config.
            Should look something like:

            {
                "datasource_name": {
                    "host": "<host>"
                    "port": <port>
                    "password": "<password>"
                    "username": "<username>"
                    "jdbc_connection_string": "<optional>"
                }
            }

            There can be more than datasource configured... maybe, eventually.
            """,
        ),
    },
    local = True,
    implementation = _json_config_impl,
)

然后按照规则,我可以测试文件是否存在,如果不存在,请执行其他逻辑。

def _json_config_impl(ctx):
    """
    Allows you to specify a file on disk to use for data connection.

    If you pass a default
    """
    config_path = ctx.path(ctx.attr.config_file_location).dirname.get_child(ctx.attr.config_file)

    config = ""
    if config_path.exists:
        config = ctx.read(config_path)
    elif ctx.attr.default_config == "None":
        fail("Could not find config at %s, you must supply a default_config if this is intentional" % ctx.attr.config_file)
    else:
        config = ctx.attr.default_config
...

可能为时已晚,无法提供帮助,但是您的问题是我发现唯一与此目标相关的问题。如果有人知道更好的方法,我正在寻找其他选择。向其他开发人员解释该规则为何必须按其方式工作很复杂。

还请注意,如果更改配置文件,则必须进行清理以使工作区重新读取配置。我还没有办法解决这个问题。 glob()在工作空间中不起作用。