Skip to content

Commit e492b84

Browse files
chore: extract glob for pyupgrade to separate script for cross-platform compatibility (#950)
Currently pyupgrade cannot be run on Windows due to 'sh' in tox.ini not working in PowerShell. Adding a separate script for this might be controversial. \ I could not find another solution that is platform independent, except from inline python in tox.ini which got "complicated" due to `{posargs}`. However, if anyone has a better idea, this could be reworked. ### AI Tool Disclosure - [X] My contribution includes AI-generated content, as disclosed below: - The contents of the new script is based on suggestions from Claude Sonnet 4.6 ### Affirmation - [X] My code follows the [CONTRIBUTING.md](https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CONTRIBUTING.md) guidelines --------- Signed-off-by: Peter Schuster <p.schuster@pilz.de> Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com> Co-authored-by: Jan Kowalleck <jan.kowalleck@gmail.com>
1 parent 3ccfa4f commit e492b84

2 files changed

Lines changed: 56 additions & 4 deletions

File tree

tools/run_pyupgrade.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
# This file is part of CycloneDX Python Library
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
# Copyright (c) OWASP Foundation. All Rights Reserved.
19+
20+
import subprocess # nosec - subprocess is used to run pyupgrade and not part of published library
21+
import sys
22+
from pathlib import Path
23+
24+
HELP = f"""
25+
Wrapper around pyupgrade to perform a lookup of all *.py/*.pyi files in passed directories
26+
and pass them to pyupgrade in a single invocation.
27+
28+
Usage: {sys.argv[0]} [pyupgrade-args ...] -- <dir ...>
29+
"""
30+
31+
if '--' not in sys.argv:
32+
print(HELP, file=sys.stderr)
33+
sys.exit(1)
34+
35+
sep = sys.argv.index('--')
36+
pyupgrade_args = sys.argv[1:sep]
37+
directories = sys.argv[sep + 1:]
38+
39+
if not directories:
40+
print('Error: at least one directory must be specified after --', '\n', HELP, file=sys.stderr)
41+
sys.exit(2)
42+
43+
files = sorted({
44+
str(file)
45+
for directory in directories
46+
for pattern in ['*.py', '*.pyi']
47+
for file in Path(directory).rglob(pattern)
48+
})
49+
50+
result = subprocess.run( # nosec - shell=False is used to prevent injection, all arg passed as a list
51+
[sys.executable, '-m', 'pyupgrade', *pyupgrade_args, *files],
52+
shell=False # w/o shell all args are passed directly to the process without the need for quotes or escaping
53+
)
54+
sys.exit(result.returncode)

tox.ini

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ commands =
5252
poetry run deptry -v .
5353

5454
[testenv:pyupgrade]
55-
allowlist_externals = poetry, sh
56-
commands = sh -c "\
57-
find cyclonedx typings tests tools examples -type f \( -name '*.py' -or -name '*.pyi' \) -print0 \
58-
| xargs -0 poetry run pyupgrade --py39-plus {posargs} "
55+
# first -- stops command parsing by poetry run, the second -- splits pyupgrade args from args for glob patterns
56+
commands = poetry run -- python tools/run_pyupgrade.py --py39-plus {posargs} -- cyclonedx typings tests tools examples
5957

6058
[testenv:isort]
6159
commands = poetry run isort .

0 commit comments

Comments
 (0)