Skip to content

Commit 5e76d8a

Browse files
committed
[Feat]: Add lint-requirements command
1 parent fac7ee6 commit 5e76d8a

File tree

8 files changed

+101
-0
lines changed

8 files changed

+101
-0
lines changed

.github/workflows/test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ jobs:
101101
- extra_metadata
102102
- elfdeps
103103
- prebuilt_wheel_hook
104+
- lint_requirements
104105
os:
105106
- ubuntu-latest
106107
- macos-latest

.mergify.yml

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pull_request_rules:
4848
- check-success=e2e (3.11, 1.75, prebuilt_wheels_alt_server, ubuntu-latest)
4949
- check-success=e2e (3.11, 1.75, report_missing_dependency, ubuntu-latest)
5050
- check-success=e2e (3.11, 1.75, rust_vendor, ubuntu-latest)
51+
- check-success=e2e (3.11, 1.75, lint_requirements, ubuntu-latest)
5152
- check-success=e2e (3.12, 1.75, bootstrap, macos-latest)
5253
- check-success=e2e (3.12, 1.75, bootstrap, ubuntu-latest)
5354
- check-success=e2e (3.12, 1.75, bootstrap_build_tags, macos-latest)
@@ -92,6 +93,8 @@ pull_request_rules:
9293
- check-success=e2e (3.12, 1.75, report_missing_dependency, ubuntu-latest)
9394
- check-success=e2e (3.12, 1.75, rust_vendor, macos-latest)
9495
- check-success=e2e (3.12, 1.75, rust_vendor, ubuntu-latest)
96+
- check-success=e2e (3.12, 1.75, lint_requirements, macos-latest)
97+
- check-success=e2e (3.12, 1.75, lint_requirements, ubuntu-latest)
9598
- "-draft"
9699

97100
# At least 1 reviewer

e2e/test_lint_requirements.sh

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-
3+
4+
# This script acts as an e2e test for lint_requirements command of fromager
5+
6+
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7+
source "$SCRIPTDIR/common.sh"
8+
9+
pass=true
10+
11+
# Test to demonstrate that command works as expected when input files are valid
12+
13+
if ! fromager lint-requirements "$SCRIPTDIR/validate_inputs/constraints.txt" "$SCRIPTDIR/validate_inputs/requirements.txt"; then
14+
echo "the input files should have been recognized as correctly formatted" 1>&2
15+
pass=false
16+
fi;
17+
18+
# Test to demonstrate failing of command due to missing input args
19+
20+
if fromager lint-requirements; then
21+
echo "missing input files should have been recognized by the command" 1>&2
22+
pass=false
23+
fi;
24+
25+
# Test to demonstrate that command reports error for invalid / bad input files
26+
27+
if fromager lint-requirements "$SCRIPTDIR/validate_inputs/constraints.txt" "$SCRIPTDIR/validate_inputs/invalid-requirements.txt"; then
28+
echo "invalid input files should have been recognized by the command" 1>&2
29+
pass=false
30+
fi;
31+
32+
$pass

e2e/validate_inputs/constraints.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This requirements.txt is used for testing lint_requirements
2+
# command of fromager and contains examples of packages
3+
4+
gast==0.5.5
5+
torch==2.3.1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This requirements file is invalid on purpose to test the lint-requirements
2+
# command of fromager. Do not attempt to fix this file
3+
4+
foo==
5+
bar<=

e2e/validate_inputs/requirements.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# This requirements.txt is used for testing lint_requirements
2+
# command of fromager and contains examples of packages
3+
stevedore==5.2.0
4+
kfp==2.11.0
5+

src/fromager/commands/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
download_sequence,
77
graph,
88
lint,
9+
lint_requirements,
910
list_overrides,
1011
migrate_config,
1112
server,
@@ -26,4 +27,5 @@
2627
download_sequence.download_sequence,
2728
server.wheel_server,
2829
migrate_config.migrate_config,
30+
lint_requirements.lint_requirements,
2931
]
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import glob
2+
import itertools
3+
import logging
4+
import sys
5+
6+
import click
7+
from packaging.requirements import InvalidRequirement, Requirement
8+
9+
from fromager import requirements_file
10+
11+
logger = logging.getLogger(__name__)
12+
13+
14+
@click.command()
15+
@click.argument("input_files_path", nargs=-1, type=click.Path(exists=False))
16+
def lint_requirements(input_files_path: str) -> None:
17+
"""
18+
Command to lint the constraints.txt and requirements.txt files
19+
This command takes a single wildcard path string for constraints.txt and requirements.txt.
20+
It checks the formatting of these files and reports issues if found.
21+
"""
22+
# Exit if user does not provide wildcard paths
23+
if not input_files_path:
24+
logger.error("path for requirements.txt or constraints.txt is missing")
25+
sys.exit(1)
26+
27+
# Get all the files to check in a list
28+
files_to_check = list(
29+
itertools.chain.from_iterable(glob.glob(path) for path in input_files_path)
30+
)
31+
32+
if len(files_to_check) == 0:
33+
logger.error("no constraints.txt or requirements.txt found in given paths")
34+
sys.exit(1)
35+
36+
flag = True
37+
38+
for file in files_to_check:
39+
parsed_lines = requirements_file.parse_requirements_file(file)
40+
for line in parsed_lines:
41+
try:
42+
Requirement(line)
43+
except InvalidRequirement as err:
44+
logger.error(f"{file}: {line}: {err}")
45+
flag = False
46+
47+
if not flag:
48+
sys.exit(1)

0 commit comments

Comments
 (0)