Skip to content

Commit 66eabc1

Browse files
committed
fix(version-scanner): address reviewer feedback regarding encoding, float versions, and argument validation
1 parent d835491 commit 66eabc1

2 files changed

Lines changed: 41 additions & 11 deletions

File tree

scripts/version_scanner/tests/unit/test_version_scanner.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def sample_match():
5959
(PermissionError(), False, False, False, "Warning: Permission denied reading test_desc", None), # Optional PermissionError
6060
(IOError("disk full"), True, False, True, "Error reading test_desc", None), # Required IOError
6161
(IOError("disk full"), False, False, False, "Warning: Error reading test_desc", None), # Optional IOError
62+
(ValueError("invalid bytes"), True, False, True, "Error reading test_desc", None), # Required ValueError
63+
(ValueError("invalid bytes"), False, False, False, "Warning: Error reading test_desc", None), # Optional ValueError
6264
]
6365
)
6466
def test_safe_read_file_scenarios(
@@ -801,6 +803,8 @@ def test_parse_matrix_file(tmp_path):
801803
("invalid: {", True), # Invalid YAML
802804
("- not_a_mapping", True), # Invalid structure (list instead of map)
803805
("python:\n - null", True), # Invalid version type (null/None value)
806+
("python:\n - 3.10", True), # Invalid version type (float instead of string in list)
807+
("python: 3.10", True), # Invalid version type (float instead of string)
804808
]
805809
)
806810
def test_parse_matrix_file_failures(tmp_path, file_content, file_exists):
@@ -868,3 +872,26 @@ def test_scan_repository_multi_targets(tmp_path):
868872
assert protobuf_match[0]["version"] == "4.25.8"
869873
assert protobuf_match[0]["rule_name"] == "protobuf_check"
870874

875+
876+
@pytest.mark.parametrize(
877+
"args, expected_error_msg",
878+
[
879+
# Mixing -m/--matrix-file with -d or -v
880+
(['version_scanner.py', '-m', 'matrix.yaml', '-d', 'python'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"),
881+
(['version_scanner.py', '-m', 'matrix.yaml', '-v', '3.7'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"),
882+
(['version_scanner.py', '-m', 'matrix.yaml', '-d', 'python', '-v', '3.7'], "Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file"),
883+
# Missing either -d or -v when not using -m
884+
(['version_scanner.py', '-d', 'python'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"),
885+
(['version_scanner.py', '-v', '3.7'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"),
886+
(['version_scanner.py'], "Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file"),
887+
]
888+
)
889+
def test_main_cli_validation(capsys, args, expected_error_msg):
890+
from version_scanner import main
891+
with mock.patch('sys.argv', args):
892+
with pytest.raises(SystemExit) as excinfo:
893+
main()
894+
assert excinfo.value.code == 2
895+
captured = capsys.readouterr()
896+
assert expected_error_msg in captured.err
897+

scripts/version_scanner/version_scanner.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def _safe_read_file(
6565
else:
6666
print(f"Warning: Permission denied reading {description}: {file_path}", file=sys.stderr)
6767
return None
68-
except IOError as e:
68+
except (IOError, ValueError) as e:
6969
if required:
7070
print(f"Error reading {description} {file_path}: {e}", file=sys.stderr)
7171
sys.exit(1)
@@ -646,11 +646,14 @@ def parse_matrix_file(file_path: str) -> List[Tuple[str, str]]:
646646
if v is None or isinstance(v, (dict, list)):
647647
print(f"Error: Invalid version '{v}' for dependency '{dep}'", file=sys.stderr)
648648
sys.exit(1)
649-
targets.append((str(dep), str(v)))
650-
elif versions is not None and not isinstance(versions, dict):
651-
targets.append((str(dep), str(versions)))
649+
if not isinstance(v, str):
650+
print(f"Error: Version '{v}' for dependency '{dep}' must be specified as a quoted string to prevent YAML parsing issues (e.g., 3.10 parsed as 3.1).", file=sys.stderr)
651+
sys.exit(1)
652+
targets.append((str(dep), v))
653+
elif isinstance(versions, str):
654+
targets.append((str(dep), versions))
652655
else:
653-
print(f"Error: Invalid version '{versions}' for dependency '{dep}'", file=sys.stderr)
656+
print(f"Error: Invalid version '{versions}' for dependency '{dep}'. Versions must be specified as quoted strings.", file=sys.stderr)
654657
sys.exit(1)
655658

656659
return targets
@@ -743,13 +746,13 @@ def main():
743746
args = parser.parse_args()
744747

745748
# Validation of required inputs
746-
has_single_target = bool(args.dependency and args.version)
747749
has_matrix_file = bool(args.matrix_file)
748-
749-
if not (has_single_target or has_matrix_file):
750-
parser.error("Must specify either (-d/--dependency AND -v/--version) OR (-m/--matrix-file)")
751-
if has_single_target and has_matrix_file:
752-
parser.error("Cannot specify both single target (-d/-v) and matrix file (-m/--matrix-file)")
750+
if has_matrix_file:
751+
if args.dependency or args.version:
752+
parser.error("Cannot specify -d/--dependency or -v/--version when using -m/--matrix-file")
753+
else:
754+
if not (args.dependency and args.version):
755+
parser.error("Must specify both -d/--dependency and -v/--version when not using -m/--matrix-file")
753756

754757
targets = []
755758
if has_matrix_file:

0 commit comments

Comments
 (0)