diff options
author | Klaus Aehlig <aehlig@google.com> | 2018-06-15 06:01:26 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-15 06:02:53 -0700 |
commit | b42734f4213e505d9582def4cd25bd510f0909a9 (patch) | |
tree | e829f7c821ada256bd5fcab6b8d24132acadd61c /tools | |
parent | f5be981a28fa50ba83391d4cd42a6e8bce07cca0 (diff) |
git_repository: return actual commit
Using that repository rules now may return a non-None value,
make git_repository return the arguments that make the rule
reproducible; in particular, return the actual commit (instead
of a tag) and the date of the commit, so support shallow clones.
The added test also demonstrates how the `bazel sync` command
together with `--experimental_repository_resolved_file` can be
used to replay an earlier state of external dependencies.
Change-Id: Ifa1cfdfdb5eb299a15b9d0ec7d285dc84c0bcdc0
PiperOrigin-RevId: 200705705
Diffstat (limited to 'tools')
-rw-r--r-- | tools/build_defs/repo/git.bzl | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/tools/build_defs/repo/git.bzl b/tools/build_defs/repo/git.bzl index a46330542c..3663dc804f 100644 --- a/tools/build_defs/repo/git.bzl +++ b/tools/build_defs/repo/git.bzl @@ -80,17 +80,37 @@ set -ex if st.return_code: fail("error updating submodules %s:\n%s" % (ctx.name, st.stderr)) -def _new_git_repository_implementation(ctx): - if ((not ctx.attr.build_file and not ctx.attr.build_file_content) or - (ctx.attr.build_file and ctx.attr.build_file_content)): - fail("Exactly one of build_file and build_file_content must be provided.") - _clone_or_update(ctx) - workspace_and_buildfile(ctx) - patch(ctx) - -def _git_repository_implementation(ctx): - _clone_or_update(ctx) - patch(ctx) + # After the fact, determine the actual commit and its date + actual_commit = ctx.execute([ + bash_exe, + "-c", + "(cd '{directory}' && git log -n 1 --pretty='format:%H')".format( + directory = ctx.path("."), + ), + ]).stdout + shallow_date = ctx.execute([ + bash_exe, + "-c", + "(cd '{directory}' && git log -n 1 --pretty='format:%cd' --date='format:%Y-%d-%m')".format( + directory = ctx.path("."), + ), + ]).stdout + return {"commit": actual_commit, "shallow_since": shallow_date} + +def _update_commit(orig, keys, override): + # Merge the override information into the dict, resulting by taking the + # given keys, as well as the name, form orig (if present there). + result = {} + for key in keys: + if getattr(orig, key) != None: + result[key] = getattr(orig, key) + result["name"] = orig.name + result.update(override) + + # remove tag if we found the actual commit + if "commit" in result: + result.pop("tag", None) + return result _common_attrs = { "remote": attr.string(mandatory = True), @@ -106,19 +126,38 @@ _common_attrs = { "patch_cmds": attr.string_list(default = []), } +_new_git_repository_attrs = dict(_common_attrs.items() + { + "build_file": attr.label(allow_single_file = True), + "build_file_content": attr.string(), + "workspace_file": attr.label(), + "workspace_file_content": attr.string(), +}.items()) + +def _new_git_repository_implementation(ctx): + if ((not ctx.attr.build_file and not ctx.attr.build_file_content) or + (ctx.attr.build_file and ctx.attr.build_file_content)): + fail("Exactly one of build_file and build_file_content must be provided.") + update = _clone_or_update(ctx) + workspace_and_buildfile(ctx) + patch(ctx) + return _update_commit(ctx.attr, _new_git_repository_attrs.keys(), update) + +def _git_repository_implementation(ctx): + update = _clone_or_update(ctx) + patch(ctx) + return _update_commit(ctx.attr, _common_attrs.keys(), update) + new_git_repository = repository_rule( implementation = _new_git_repository_implementation, - attrs = dict(_common_attrs.items() + { - "build_file": attr.label(allow_single_file = True), - "build_file_content": attr.string(), - "workspace_file": attr.label(), - "workspace_file_content": attr.string(), - }.items()), + attrs = _new_git_repository_attrs, ) """Clone an external git repository. Clones a Git repository, checks out the specified tag, or commit, and -makes its targets available for binding. +makes its targets available for binding. Also determine the id of the +commit actually checkted out and its date, and return a dict with paramters +that provide a reproducible version of this rule (which a tag not necessarily +is). Args: name: A unique name for this rule. @@ -173,7 +212,11 @@ git_repository = repository_rule( """Clone an external git repository. Clones a Git repository, checks out the specified tag, or commit, and -makes its targets available for binding. +makes its targets available for binding. Also determine the id of the +commit actually checkted out and its date, and return a dict with paramters +that provide a reproducible version of this rule (which a tag not necessarily +is). + Args: name: A unique name for this rule. |