Validation to ensure requirements_lock is pinned. (#732)
* Light validation to ensure lockfile is pinned.
* Clean up
* .
Co-authored-by: Alex Eagle <alex@aspect.dev>
diff --git a/examples/pip_install/requirements.in b/examples/pip_install/requirements.in
index 593e5ad..2351369 100644
--- a/examples/pip_install/requirements.in
+++ b/examples/pip_install/requirements.in
@@ -1,6 +1,3 @@
-boto3==1.14.51
-s3cmd==2.1.0
-yamllint==1.26.3
-
-# Last available for Python 3.6.
-setuptools==59.6.0
+boto3~=1.14.51
+s3cmd~=2.1.0
+yamllint~=1.26.3
diff --git a/examples/pip_install/requirements.txt b/examples/pip_install/requirements.txt
index 43bfad4..26de1ad 100644
--- a/examples/pip_install/requirements.txt
+++ b/examples/pip_install/requirements.txt
@@ -98,6 +98,4 @@
setuptools==59.6.0 \
--hash=sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373 \
--hash=sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e
- # via
- # -r requirements.in
- # yamllint
+ # via yamllint
diff --git a/examples/pip_parse/BUILD b/examples/pip_parse/BUILD
index 92b59ae..653f75c 100644
--- a/examples/pip_parse/BUILD
+++ b/examples/pip_parse/BUILD
@@ -59,7 +59,7 @@
compile_pip_requirements(
name = "requirements",
extra_args = ["--allow-unsafe"],
- requirements_in = "requirements.txt",
+ requirements_in = "requirements.in",
requirements_txt = "requirements_lock.txt",
)
diff --git a/examples/pip_parse/requirements.in b/examples/pip_parse/requirements.in
new file mode 100644
index 0000000..ec2102f
--- /dev/null
+++ b/examples/pip_parse/requirements.in
@@ -0,0 +1,3 @@
+requests~=2.25.1
+s3cmd~=2.1.0
+yamllint~=1.26.3
diff --git a/examples/pip_parse/requirements.txt b/examples/pip_parse/requirements.txt
deleted file mode 100644
index e315194..0000000
--- a/examples/pip_parse/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-requests==2.25.1
-s3cmd==2.1.0
-yamllint==1.26.3
-
-# Last avialable for python3.6
-setuptools==59.6.0
diff --git a/examples/pip_parse/requirements_lock.txt b/examples/pip_parse/requirements_lock.txt
index f270699..d3cb1f5 100644
--- a/examples/pip_parse/requirements_lock.txt
+++ b/examples/pip_parse/requirements_lock.txt
@@ -66,11 +66,11 @@
requests==2.25.1 \
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
- # via -r requirements.txt
+ # via -r requirements.in
s3cmd==2.1.0 \
--hash=sha256:49cd23d516b17974b22b611a95ce4d93fe326feaa07320bd1d234fed68cbccfa \
--hash=sha256:966b0a494a916fc3b4324de38f089c86c70ee90e8e1cae6d59102103a4c0cc03
- # via -r requirements.txt
+ # via -r requirements.in
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
@@ -81,12 +81,10 @@
# via requests
yamllint==1.26.3 \
--hash=sha256:3934dcde484374596d6b52d8db412929a169f6d9e52e20f9ade5bf3523d9b96e
- # via -r requirements.txt
+ # via -r requirements.in
# The following packages are considered to be unsafe in a requirements file:
setuptools==59.6.0 \
--hash=sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373 \
--hash=sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e
- # via
- # -r requirements.txt
- # yamllint
+ # via yamllint
diff --git a/python/pip_install/parse_requirements_to_bzl/__init__.py b/python/pip_install/parse_requirements_to_bzl/__init__.py
index 9519d62..83526a7 100644
--- a/python/pip_install/parse_requirements_to_bzl/__init__.py
+++ b/python/pip_install/parse_requirements_to_bzl/__init__.py
@@ -31,16 +31,30 @@
parser = RequirementsFileParser(ps, line_parser)
install_req_and_lines: List[Tuple[InstallRequirement, str]] = []
_, content = get_file_content(requirements_lock, ps)
+ unpinned_reqs = []
for parsed_line, (_, line) in zip(
parser.parse(requirements_lock, constraint=False), preprocess(content)
):
if parsed_line.is_requirement:
+ install_req = constructors.install_req_from_line(parsed_line.requirement)
+ if not install_req.is_pinned:
+ unpinned_reqs.append(str(install_req))
install_req_and_lines.append(
- (constructors.install_req_from_line(parsed_line.requirement), line)
+ (install_req, line)
)
else:
extra_pip_args.extend(shlex.split(line))
+
+ if len(unpinned_reqs) > 0:
+ unpinned_reqs_str = "\n".join(unpinned_reqs)
+ raise RuntimeError(f"""\
+The `requirements_lock` file must be fully pinned. See `compile_pip_requirements`.
+Alternatively, use `pip-tools` or a similar mechanism to produce a pinned lockfile.
+
+The following requirements were not pinned:
+{unpinned_reqs_str}""")
+
return install_req_and_lines