Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stamp attribute to pkg_tar (in the style of cc_binary(stamp=-1,0,1) #288

Merged
merged 19 commits into from
May 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions examples/time_stamping/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2021 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.
# -*- coding: utf-8 -*-

licenses(["notice"])
aiuto marked this conversation as resolved.
Show resolved Hide resolved

load("@rules_pkg//:pkg.bzl", "pkg_tar")

pkg_tar(
name = "never_stamped",
srcs = [
":BUILD",
],
)

pkg_tar(
name = "always_stamped",
srcs = [
":BUILD",
],
stamp = 1,
)

pkg_tar(
name = "controlled_by_stamp_option",
srcs = [
":BUILD",
],
stamp = -1,
)
26 changes: 26 additions & 0 deletions examples/time_stamping/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2021 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.

workspace(name = "rules_pkg_examples")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

local_repository(
name = "rules_pkg",
path = "../../pkg",
)

load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")

rules_pkg_dependencies()
52 changes: 52 additions & 0 deletions examples/time_stamping/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Examples of how time stamping works.
aiuto marked this conversation as resolved.
Show resolved Hide resolved

## How it works

Target declarations may use the `stamp` attribute to control
the time stamping of files in an archive. The behavior follows
the pattern of the cc_binary rule:

https://docs.bazel.build/versions/main/be/c-cpp.html#cc_binary

Read the BUILD file for more details.

## Try this

```
bazel build :*
for tarball in bazel-bin/*.tar ; do
echo ==== $tarball
tar tvf $tarball
done

bazel build :* --stamp=1
for tarball in bazel-bin/*.tar ; do
echo ==== $tarball
tar tvf $tarball
done
aiuto marked this conversation as resolved.
Show resolved Hide resolved
```

You should see something like:
```
INFO: Build completed successfully, 3 total actions
==== bazel-bin/always_stamped.tar
drwxr-xr-x 0 0 0 0 May 3 17:34 ./
-r-xr-xr-x 0 0 0 968 May 3 17:34 ./BUILD
==== bazel-bin/controlled_by_stamp_option.tar
drwxr-xr-x 0 0 0 0 Dec 31 1999 ./
-r-xr-xr-x 0 0 0 968 Dec 31 1999 ./BUILD
==== bazel-bin/never_stamped.tar
drwxr-xr-x 0 0 0 0 Dec 31 1999 ./
-r-xr-xr-x 0 0 0 968 Dec 31 1999 ./BUILD
INFO: Build option --stamp has changed, discarding analysis cache.
INFO: Build completed successfully, 3 total actions
==== bazel-bin/always_stamped.tar
drwxr-xr-x 0 0 0 0 May 3 17:34 ./
-r-xr-xr-x 0 0 0 968 May 3 17:34 ./BUILD
==== bazel-bin/controlled_by_stamp_option.tar
drwxr-xr-x 0 0 0 0 May 6 17:42 ./
-r-xr-xr-x 0 0 0 968 May 6 17:42 ./BUILD
==== bazel-bin/never_stamped.tar
drwxr-xr-x 0 0 0 0 Dec 31 1999 ./
-r-xr-xr-x 0 0 0 968 Dec 31 1999 ./BUILD
```
4 changes: 2 additions & 2 deletions pkg/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ licenses(["notice"])
exports_files(
glob([
"*.bzl",
"private/**",
]),
visibility = ["//visibility:public"],
)
Expand Down Expand Up @@ -88,6 +87,7 @@ py_binary(
deps = [
":archive",
":helpers",
"//private:build_info",
],
)

Expand Down Expand Up @@ -148,6 +148,6 @@ py_library(
py_binary(
name = "filter_directory",
srcs = ["filter_directory.py"],
visibility = ["//visibility:public"],
python_version = "PY3",
visibility = ["//visibility:public"],
)
9 changes: 8 additions & 1 deletion pkg/build_tar.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import archive
import helpers
from private import build_info


class TarFile(object):
Expand Down Expand Up @@ -264,6 +265,8 @@ def main():
'path/to/file=root.root.')
parser.add_argument('--root_directory', default='./',
help='Default root directory is named "."')
parser.add_argument('--stamp_from', default='',
help='File to find BUILD_STAMP in')
options = parser.parse_args()

# Parse modes arguments
Expand Down Expand Up @@ -303,11 +306,15 @@ def main():
f = f[1:]
ids_map[f] = (int(user), int(group))

default_mtime = options.mtime
if options.stamp_from:
default_mtime = build_info.get_timestamp(options.stamp_from)

# Add objects to the tar file
with TarFile(
options.output, helpers.GetFlagValue(options.directory),
options.compression, options.compressor, options.root_directory,
options.mtime) as output:
default_mtime=default_mtime) as output:

def file_attributes(filename):
if filename.startswith('/'):
Expand Down
3 changes: 2 additions & 1 deletion pkg/distro/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pkg_tar(
srcs = [
":small_workspace",
"//:standard_package",
"//private:standard_package",
"//releasing:standard_package",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bah, this is missing //rpm:standard_package. I'll fix this myself shortly.

"//toolchains:standard_package",
],
Expand Down Expand Up @@ -97,7 +98,7 @@ genrule(
bzl_library(
name = "rules_pkg_lib",
srcs = [
"//:private/util.bzl",
"//private:util.bzl",
"//:package_variables.bzl",
"//:path.bzl",
"//:pkg.bzl",
Expand Down
16 changes: 15 additions & 1 deletion pkg/pkg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

load(":path.bzl", "compute_data_path", "dest_path")
load(":providers.bzl", "PackageArtifactInfo", "PackageVariablesInfo")
load("private/util.bzl", "setup_output_files", "substitute_package_variables")
load("//private:util.bzl", "setup_output_files", "substitute_package_variables")

# TODO(aiuto): Figure out how to get this from the python toolchain.
# See check for lzma in archive.py for a hint at a method.
Expand All @@ -30,6 +30,7 @@ SUPPORTED_TAR_COMPRESSIONS = (
)
deb_filetype = [".deb", ".udeb"]
_DEFAULT_MTIME = -1
_stamp_condition = str(Label("//private:private_stamp_detect"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does stringifying the Label do that simply including the string wouldn't?

Also, should this be _STAMP_CONDITION? Seems to be inconsistent casing for these internal constants.


def _remap(remap_paths, path):
"""If path starts with a key in remap_paths, rewrite it."""
Expand Down Expand Up @@ -151,6 +152,10 @@ def _pkg_tar_impl(ctx):
"--link=%s:%s" % (_quote(k, protect = ":"), ctx.attr.symlinks[k])
for k in ctx.attr.symlinks
]
if ctx.attr.stamp == 1 or (ctx.attr.stamp == -1 and
ctx.attr.private_stamp_detect):
args.append("--stamp_from=%s" % ctx.version_file.path)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any plans on having ctx.version_file documented in bazel's own documentation?

files.append(ctx.version_file)
arg_file = ctx.actions.declare_file(ctx.label.name + ".args")
files.append(arg_file)
ctx.actions.write(arg_file, "\n".join(args))
Expand Down Expand Up @@ -337,6 +342,7 @@ def _pkg_deb_impl(ctx):
),
]


# A rule for creating a tar file, see README.md
pkg_tar_impl = rule(
implementation = _pkg_tar_impl,
Expand Down Expand Up @@ -372,6 +378,10 @@ pkg_tar_impl = rule(
doc = "See Common Attributes",
providers = [PackageVariablesInfo],
),
"stamp": attr.int(default = 0),
# Is --stamp set on the command line?
# TODO(https://github.com/bazelbuild/rules_pkg/issues/340): Remove this.
"private_stamp_detect": attr.bool(default = False),

# Implicit dependencies.
"build_tar": attr.label(
Expand Down Expand Up @@ -413,6 +423,10 @@ def pkg_tar(name, **kwargs):
pkg_tar_impl(
name = name,
out = kwargs.pop("out", None) or (name + "." + extension),
private_stamp_detect = select({
_stamp_condition: True,
"//conditions:default": False,
}),
aiuto marked this conversation as resolved.
Show resolved Hide resolved
**kwargs
)

Expand Down
55 changes: 55 additions & 0 deletions pkg/private/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2021 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.
"""rules_pkg internal code.

This is subject to change at any time.
"""

load("@rules_python//python:defs.bzl", "py_library")

licenses(["notice"])

filegroup(
name = "standard_package",
srcs = glob([
"BUILD",
"*.bzl",
"*.py",
]),
visibility = ["//distro:__pkg__"],
)

exports_files(
glob([
"*.bzl",
]),
visibility = ["//distro:__pkg__"],
)

config_setting(
name = "private_stamp_detect",
values = {"stamp": "1"},
)

py_library(
name = "build_info",
srcs = [
"build_info.py",
],
srcs_version = "PY3",
visibility = [
"//:__pkg__",
"//tests:__pkg__",
],
)
37 changes: 37 additions & 0 deletions pkg/private/build_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2021 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.
"""Get BUILD_TIMESTAMP."""


def get_timestamp(volatile_status_file):
"""Get BUILD_TIMESTAMP as an integer.

Reads a file of "name<space>value" pairs and returns the value
of the BUILD_TIMESTAMP. The file should be in the workspace status
format: https://docs.bazel.build/versions/master/user-manual.html#workspace_status

Args:
volatile_status_file: path to input file. Typically ctx.version_file.path.
Returns:
int: value of BUILD_TIMESTAMP
Exceptions:
Exception: Raised if there is no BUILD_TIMESTAMP or if it is not a number.
"""
with open(volatile_status_file, 'r') as status_f:
for line in status_f:
parts = line.strip().split(' ')
if len(parts) > 1 and parts[0] == 'BUILD_TIMESTAMP':
return int(parts[1])
raise Exception(
"Invalid status file <%s>. Expected to find BUILD_TIMESTAMP" % volatile_status_file)
2 changes: 1 addition & 1 deletion pkg/private/util.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.
"""Internal utilities for rules_pkg."""

load(":providers.bzl", "PackageVariablesInfo")
load("//:providers.bzl", "PackageVariablesInfo")

def setup_output_files(ctx, package_file_name = None, default_output_file = None):
"""Provide output file metadata for common packaging rules
Expand Down
2 changes: 1 addition & 1 deletion pkg/rpm_pfg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ find_system_rpmbuild(name="rules_pkg_rpmbuild")
```
"""

load("//:private/util.bzl", "setup_output_files")
load("//private:util.bzl", "setup_output_files")
load("//:providers.bzl", "PackageArtifactInfo", "PackageFilegroupInfo", "PackageVariablesInfo")

rpm_filetype = [".rpm"]
Expand Down
19 changes: 19 additions & 0 deletions pkg/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,22 @@ py_test(
"@bazel_tools//tools/python/runfiles",
],
)

pkg_tar(
name = "stamped_tar",
srcs = ["BUILD"],
stamp = 1,
)

py_test(
name = "stamp_test",
srcs = [
"stamp_test.py",
],
data = [
"stamped_tar.tar",
],
deps = [
"@bazel_tools//tools/python/runfiles",
],
)
aiuto marked this conversation as resolved.
Show resolved Hide resolved
Loading