12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
- """A simple macro to pin the requirements.
15
+ """A simple macro to lock the requirements.
16
16
"""
17
17
18
18
load ("@bazel_skylib//rules:write_file.bzl" , "write_file" )
19
19
load ("//python:py_binary.bzl" , "py_binary" )
20
+ load ("//python/config_settings:transition.bzl" , transition_py_binary = "py_binary" )
20
21
load ("//python/private:bzlmod_enabled.bzl" , "BZLMOD_ENABLED" ) # buildifier: disable=bzl-visibility
21
22
22
- _REQUIREMENTS_TARGET_COMPATIBLE_WITH = select ({
23
- "@platforms//os:linux" : [],
24
- "@platforms//os:macos" : [],
25
- "//conditions:default" : ["@platforms//:incompatible" ],
26
- }) if BZLMOD_ENABLED else ["@platforms//:incompatible" ]
23
+ visibility (["//..." ])
27
24
28
- def pin (* , name , srcs , out , upgrade = False , universal = True , python_version = None ):
25
+ _REQUIREMENTS_TARGET_COMPATIBLE_WITH = [] if BZLMOD_ENABLED else ["@platforms//:incompatible" ]
26
+
27
+ def lock (* , name , srcs , out , upgrade = False , universal = True , python_version = None ):
29
28
"""Pin the requirements based on the src files.
30
29
31
30
Args:
@@ -44,24 +43,23 @@ def pin(*, name, srcs, out, upgrade = False, universal = True, python_version =
44
43
- Supports transitions out of the box.
45
44
"""
46
45
pkg = native .package_name ()
47
- _out = "_" + out
46
+ update_target = name + ".update"
48
47
49
48
args = [
50
- "--custom-compile-command='bazel run //{}:{}'" .format (pkg , name ),
49
+ "--custom-compile-command='bazel run //{}:{}'" .format (pkg , update_target ),
51
50
"--generate-hashes" ,
52
51
"--emit-index-url" ,
53
52
"--no-strip-extras" ,
54
53
"--python=$(PYTHON3)" ,
55
54
] + [
56
55
"$(location {})" .format (src )
57
56
for src in srcs
58
- ] + [
59
- "--output-file=$(location {})" .format (_out ),
60
57
]
61
58
if upgrade :
62
59
args .append ("--upgrade" )
63
60
if universal :
64
61
args .append ("--universal" )
62
+ args .append ("--output-file=$@" )
65
63
cmd = "$(UV_BIN) pip compile " + " " .join (args )
66
64
67
65
# Check if the output file already exists, if yes, first copy it to the
@@ -72,9 +70,9 @@ def pin(*, name, srcs, out, upgrade = False, universal = True, python_version =
72
70
srcs .append (out )
73
71
74
72
native .genrule (
75
- name = name + ".uv.out" ,
73
+ name = name ,
76
74
srcs = srcs ,
77
- outs = [_out ],
75
+ outs = [out + ".new" ],
78
76
cmd_bash = cmd ,
79
77
tags = [
80
78
"local" ,
@@ -88,97 +86,36 @@ def pin(*, name, srcs, out, upgrade = False, universal = True, python_version =
88
86
],
89
87
)
90
88
if python_version :
91
- transitioned_name = "{}.uv.out.{}" .format (name , python_version )
92
- _versioned (
93
- name = transitioned_name ,
94
- src = _out ,
95
- python_version = python_version ,
96
- tags = ["manual" ],
97
- )
98
- _out = transitioned_name
89
+ py_binary_rule = lambda * args , ** kwargs : transition_py_binary (python_version = python_version , * args , ** kwargs )
90
+ else :
91
+ py_binary_rule = py_binary
99
92
100
93
# Write a script that can be used for updating the in-tree version of the
101
94
# requirements file
102
95
write_file (
103
- name = name + ".gen " ,
104
- out = name + ".gen .py" ,
96
+ name = name + ".update_gen " ,
97
+ out = update_target + ".py" ,
105
98
content = [
106
99
"from os import environ" ,
107
100
"from pathlib import Path" ,
108
101
"from sys import stderr" ,
109
102
"" ,
110
103
'src = Path(environ["REQUIREMENTS_FILE"])' ,
104
+ 'assert src.exists(), f"the {src} file does not exist"' ,
111
105
'dst = Path(environ["BUILD_WORKSPACE_DIRECTORY"]) / "{}" / "{}"' .format (pkg , out ),
112
106
'print(f"Writing requirements contents\\ n from {src.absolute()}\\ n to {dst.absolute()}", file=stderr)' ,
113
107
"dst.write_text(src.read_text())" ,
114
108
'print("Success!", file=stderr)' ,
115
109
],
116
- target_compatible_with = _REQUIREMENTS_TARGET_COMPATIBLE_WITH ,
117
110
)
118
111
119
- py_binary (
120
- name = name ,
121
- srcs = [name + ".gen .py" ],
122
- main = name + ".gen .py" ,
123
- data = [_out ],
112
+ py_binary_rule (
113
+ name = update_target ,
114
+ srcs = [update_target + ".py" ],
115
+ main = update_target + ".py" ,
116
+ data = [name ],
124
117
env = {
125
- "REQUIREMENTS_FILE" : "$(location {})" .format (_out ),
118
+ "REQUIREMENTS_FILE" : "$(rootpath {})" .format (name ),
126
119
},
127
120
tags = ["manual" ],
128
- target_compatible_with = _REQUIREMENTS_TARGET_COMPATIBLE_WITH ,
129
121
)
130
-
131
- def _transition_python_version_impl (_ , attr ):
132
- return {"//python/config_settings:python_version" : str (attr .python_version )}
133
-
134
- _transition_python_version = transition (
135
- implementation = _transition_python_version_impl ,
136
- inputs = [],
137
- outputs = ["//python/config_settings:python_version" ],
138
- )
139
-
140
- def _impl (ctx ):
141
- target = ctx .attr .src
142
-
143
- default_info = target [0 ][DefaultInfo ]
144
- files = default_info .files
145
- original_executable = default_info .files_to_run .executable
146
- runfiles = default_info .default_runfiles
147
-
148
- new_executable = ctx .actions .declare_file (ctx .attr .name )
149
-
150
- ctx .actions .symlink (
151
- output = new_executable ,
152
- target_file = original_executable ,
153
- is_executable = True ,
154
- )
155
-
156
- files = depset (direct = [new_executable ], transitive = [files ])
157
- runfiles = runfiles .merge (ctx .runfiles ([new_executable ]))
158
-
159
- return [
160
- DefaultInfo (
161
- files = files ,
162
- runfiles = runfiles ,
163
- executable = new_executable ,
164
- ),
165
- ]
166
-
167
- _versioned = rule (
168
- implementation = _impl ,
169
- attrs = {
170
- "python_version" : attr .string (
171
- mandatory = True ,
172
- ),
173
- "src" : attr .label (
174
- allow_single_file = True ,
175
- executable = False ,
176
- mandatory = True ,
177
- cfg = _transition_python_version ,
178
- ),
179
- "_allowlist_function_transition" : attr .label (
180
- default = "@bazel_tools//tools/allowlists/function_transition_allowlist" ,
181
- ),
182
- },
183
- executable = True ,
184
- )
0 commit comments