Skip to content

Commit 6056ff3

Browse files
[MERGER] Close #161 with fix for check_pip.
2 parents 5a7c1c1 + e6b275e commit 6056ff3

File tree

8 files changed

+113
-68
lines changed

8 files changed

+113
-68
lines changed

.github/workflows/Tests.yml

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -470,32 +470,27 @@ jobs:
470470
EXTRAS-FOR-PIP:
471471
if: ${{ !cancelled() }}
472472
needs: [BOOTSTRAP, MATS]
473-
runs-on: ${{ matrix.os }}
473+
runs-on: ubuntu-latest
474474
defaults:
475475
run:
476476
shell: bash
477477
timeout-minutes: 10
478478
strategy:
479479
matrix:
480-
os: [ubuntu-latest, macos-latest]
480+
os: [ubuntu-latest]
481481
python-version: ["3.10", "3.11", "3.12"]
482482
env:
483-
OS: ${{ matrix.os }}
483+
OS: 'ubuntu-latest'
484484
PYTHON_VERSION: ${{ matrix.python-version }}
485485
LANG: "en_US.utf-8"
486486
LC_CTYPE: "en_US.utf-8"
487-
COVERAGE_RCFILE: ./.coveragerc
488-
COV_CORE_SOURCE: ./
489-
COV_CORE_CONFIG: ./.coveragerc
490-
COV_CORE_DATAFILE: .coverage
491-
CODECLIMATE_REPO_TOKEN: ${{ secrets.CODECLIMATE_TOKEN }}
492487
steps:
493488
- uses: actions/checkout@v4
494489
- name: Set up Python ${{ matrix.python-version }}
495490
uses: actions/setup-python@v5
496491
with:
497492
python-version: ${{ matrix.python-version }}
498-
- name: Install dependencies for python ${{ matrix.python-version }} on ${{ matrix.os }}
493+
- name: Install dependencies for python ${{ matrix.python-version }}
499494
run: |
500495
pip install --upgrade "pip>=22.0" "setuptools>=75.0" "wheel>=0.44" "build>=1.2.1" "pip-licenses>=5.0.0";
501496
pip install -r ./requirements.txt ;
@@ -504,31 +499,12 @@ jobs:
504499
- name: Pre-Clean
505500
id: clean-prep
506501
run: make -j1 -f Makefile clean ;
507-
- name: Pre-build for Python ${{ matrix.python-version }} on ${{ matrix.os }}
508-
run: make -j1 -f Makefile build ;
509-
if: ${{ success() }}
510-
- name: Test Dependencies with py${{ matrix.python-version }} on ${{ matrix.os }}
502+
- name: Test Dependencies with py${{ matrix.python-version }}
511503
run: |
512504
hash -p ./.github/tool_shlock_helper.sh shlock ; export TMPDIR=./ ;
513-
./tests/check_pip 2>&1 >> $GITHUB_STEP_SUMMARY || echo "::warning file=tests/check_pip,line=1,endLine=1,title=SKIPPED::SKIP Requirements Tests." ;
505+
./tests/check_pip ;
514506
shell: bash
515507
if: ${{ !cancelled() }}
516-
- name: Upload Python ${{ matrix.python-version }} Legacy Setup.py coverage to Codecov
517-
uses: codecov/codecov-action@v4
518-
with:
519-
token: ${{ secrets.CODECOV_TOKEN }}
520-
files: ./test-reports/coverage_setup.xml
521-
directory: .
522-
flags: multicast,${{ matrix.os }},${{ matrix.python-version }}
523-
name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }}
524-
verbose: true
525-
fail_ci_if_error: false
526-
- name: Upload Extra Python ${{ matrix.python-version }} Artifact
527-
uses: actions/upload-artifact@v4
528-
with:
529-
name: Legacy_Setup-Test-Report-${{ matrix.os }}-${{ matrix.python-version }}
530-
path: ./test-reports/
531-
if-no-files-found: ignore
532508
- name: Post-purge
533509
id: post-uninstall
534510
run: make -j1 -f Makefile purge || true ;
@@ -568,7 +544,6 @@ jobs:
568544
pip install --upgrade "pip>=22.0" "setuptools>=75.0" "wheel>=0.44" "build>=1.2.1";
569545
pip install -r ./requirements.txt ;
570546
pip install -r ./tests/requirements.txt || true ;
571-
pip install --upgrade -r ./docs/requirements.txt || true ;
572547
- name: Pre-Clean
573548
id: clean-prep
574549
run: make -j1 -f Makefile clean ;

docs/FAQ.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ instead of `None` to indicate exit code `1` by returning a `boolean` success val
236236
> [CEP-8](https://gist.github.com/reactive-firewall/b7ee98df9e636a51806e62ef9c4ab161)'s
237237
> POSIX-based guidelines.
238238
239-
240239
### How do I build the documentation?
241240

242241
* Typicly the documentation will be automatically build by CI/CD and posted to the official
@@ -250,14 +249,16 @@ instead of `None` to indicate exit code `1` by returning a `boolean` success val
250249

251250
### Building Documentation with a Custom Git Reference
252251

253-
By default, the documentation links to the `stable` branch on GitHub. To override this and link to the specific commit you're working on, set the `DOCS_BUILD_REF` environment variable:
252+
By default, the documentation links to the `stable` branch on GitHub. To override this and link
253+
to the specific commit you're working on, set the `DOCS_BUILD_REF` environment variable:
254254

255255
```bash
256256
export DOCS_BUILD_REF=$(${GIT:-git} rev-parse --verify HEAD)
257257
make build-docs # or your own documentation build command
258258
```
259259

260-
This command dynamically sets `DOCS_BUILD_REF` to the current Git commit hash, ensuring that documentation links point to the exact version of your code.
260+
This command dynamically sets `DOCS_BUILD_REF` to the current Git commit hash, ensuring that
261+
documentation links point to the exact version of your code.
261262

262263
***
263264

multicast/recv.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,5 +607,5 @@ def doStep(self, *args, **kwargs):
607607
print(str(response))
608608
print(multicast._BLANK) # skipcq: PYL-W0212 - module ok
609609
_result = (len(response) > 0) is True
610-
return tuple((_result, None if not _result else response)) # skipcq: PTC-W0020 - intended
610+
return (_result, None if not _result else response) # skipcq: PTC-W0020 - intended
611611

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ setuptools>=75.0
3131
# pip - MIT license
3232
pip>=22.0
3333
# build - MIT license
34-
build>=1.1.1
34+
build>=1.1.1, !=1.2.2.post1
3535
# multicast - MIT license
3636
#-e git+https://github.com/reactive-firewall/multicast.git#egg=multicast
3737
# wheel - MIT license

tests/check_pip

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export -f check_command
124124
check_command grep ;
125125
check_command python3 ;
126126
check_command git ;
127+
check_command sed ;
127128
check_command tee ;
128129
check_command pip ;
129130
# check_command pip-audit ; # optional
@@ -166,13 +167,23 @@ handle_signals
166167

167168
# lazy defined variables should be defined now that this is the only script instance.
168169

170+
# set the script-file to check_pip
171+
SCRIPT_FILE="tests/check_pip"
169172
# Set pip-audit options
170173
AUDIT_OPTIONS="--progress-spinner off --desc on --requirement"
171174
# List of Allowed Licenses delimited by semicolon ;
172-
ALLOW_LICENSES="Public Domain;Apache Software License;MIT License;BSD License;Python Software Foundation License"
175+
ALLOW_LICENSES="Public Domain;Apache Software License;MIT License;BSD License;Python Software Foundation License;The Unlicense (Unlicense);Mozilla Public License 2.0 (MPL 2.0);"
173176
# Set pip-licenses options
174177
LICENSE_OPTIONS="--from=mixed"
175-
178+
# Set pip options
179+
PIP_COMMON_FLAGS="--require-virtualenv --use-pep517 --exists-action s --upgrade --upgrade-strategy only-if-needed --quiet"
180+
# Set Env and OS specific pip options
181+
if [[ $( \uname -s ) == "*arwin" ]] ; then
182+
PIP_ENV_FLAGS="--break-system-packages"
183+
LICENSE_OPTIONS="--python python3 ${LICENSE_OPTIONS} --ignore-packages certifi"
184+
else
185+
PIP_ENV_FLAGS=""
186+
fi ;
176187
# Enable auto-fix if '--fix' argument is provided
177188
if [[ "$1" == "--fix" ]]; then
178189
AUDIT_OPTIONS="--fix --strict ${AUDIT_OPTIONS}"
@@ -182,62 +193,117 @@ fi
182193
# lazy defined functions should be defined now that this is the only script instance.
183194

184195
function report_summary() {
196+
printf "::group::%s\n" "Results" ;
185197
# Improved reporting based on EXIT_CODE
186198
case "${EXIT_CODE}" in
187-
0) printf "%s\n" "OK: Found no detected requirements errors." ;;
188-
1) printf "%s\n" "FAIL: General failure during script execution." >&2 ;;
189-
3) printf "%s\n" "FAIL: Gathering repostory's requirements failed." >&2 ;; # git ls-tree command failed
190-
4) printf "%s\n" "FAIL: pip-audit detected security vulnerabilities." >&2 ;;
191-
5) printf "%s\n" "FAIL: pip-licenses detected license issues." >&2 ;;
192-
6) printf "%s\n" "FAIL: pip install failed." >&2 ;;
193-
126) printf "%s\n" "SKIP: Unable to continue script execution." >&2 ;;
194-
*) printf "%s\n" "FAIL: Detected requirements errors." >&2 ;;
199+
0) printf "::notice title=OK::%s\n" "OK: Found no detected requirements errors." ;;
200+
1) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=CHECK-PIP::%s\n" "FAIL: General failure during script execution." >&2 ;;
201+
3) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=CONFIGURATION::%s\n" "FAIL: Gathering repostory's requirements failed." >&2 ;; # git ls-tree command failed
202+
4) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=SECURITY::%s\n" "FAIL: pip-audit detected security vulnerabilities." >&2 ;;
203+
5) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=LICENSE::%s\n" "FAIL: pip-licenses detected license issues." >&2 ;;
204+
6) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=INSTALL::%s\n" "FAIL: pip install failed." >&2 ;;
205+
126) printf "::warning file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=SKIPPED::%s\n" "SKIP: Unable to continue script execution." >&2 ;;
206+
*) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=FAILED::%s\n" "FAIL: Detected requirements errors." >&2 ;;
195207
esac
208+
printf "::endgroup::\n" ;
196209
}
197210

198211
function navigate_dirs_by_git() {
199212
if _TEST_ROOT_DIR=$(git rev-parse --show-superproject-working-tree 2>/dev/null); then
200213
if [ -z "${_TEST_ROOT_DIR}" ]; then
201214
_TEST_ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null)
202215
fi
216+
printf "::debug::%s\n" "Found ${_TEST_ROOT_DIR} ..." ;
203217
else
204-
printf "\t%s\n" "FAIL: missing valid repository or source structure" >&2
218+
printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=${FUNCNAME:-$0}::%s\n" "FAIL: missing valid repository or source structure" >&2
205219
EXIT_CODE=40
206220
fi
207221
}
208222

223+
function check_license_when_given_req() {
224+
local SUB_CODE=${EXIT_CODE-0}
225+
umask 007
226+
printf "::debug::%s\n" "need venv ..." ;
227+
# Create a temporary directory for the virtual environment
228+
temp_dir=$(mktemp -d)
229+
230+
# Enter the temporary directory
231+
cd "$temp_dir"
232+
233+
# Create a virtual environment using venv
234+
python3 -m venv venv
235+
236+
# Activate the virtual environment
237+
source venv/bin/activate
238+
239+
umask 037
240+
# 2>&1 >/dev/null
241+
python3 -m pip install $PIP_COMMON_FLAGS $PIP_ENV_FLAGS "pip-licenses>=5.0" || SUB_CODE=6 ;
242+
wait ;
243+
printf "::debug::%s\n" "venv setup ... (${SUB_CODE})" ;
244+
# Install the given Python modules using pip
245+
for module in $@ ; do
246+
printf "::debug::%s\n" "Checking license from package '$module' ..." ;
247+
REQ_SPEC=$(grep -F "$module" <(cat <"${_TEST_ROOT_DIR}"/$req_file | sed -E -e '/^[[:space:]]*$/d' | sed -E -e '/^[#]+.*$/d') | grep -m1 -F "$module" )
248+
ERR_MSG="pip install '$module' failed for $req_file." ;
249+
if [[ ("${SUB_CODE}" -eq 0) ]] && python3 -m pip install $PIP_COMMON_FLAGS $PIP_ENV_FLAGS "${REQ_SPEC};" 2>/dev/null ;
250+
then
251+
printf "::debug::%s\n" "Fetched license from package '$module' ..." ;
252+
else
253+
[[ ("${SUB_CODE}" -eq 0) ]] && SUB_CODE=6 && \
254+
printf "::warning file=${req_file},line=1,col=1,title=PIP::%s\n" "${ERR_MSG}" >&2
255+
fi
256+
unset ERR_MSG 2>/dev/null || : ;
257+
done
258+
259+
# Use pip-licenses to list the licenses of the installed packages
260+
{ pip-licenses $LICENSE_OPTIONS --allow-only="${ALLOW_LICENSES}" || SUB_CODE=5 ;} ; wait ;
261+
262+
# Deactivate the virtual environment
263+
deactivate
264+
265+
# return to starting dir
266+
cd "${OLDPWD}" ;
267+
268+
# Remove the temporary directory and all of its contents
269+
rm -rf "${temp_dir}" || : ;
270+
umask 137 ;
271+
wait ;
272+
return $SUB_CODE
273+
}
274+
209275
# THIS IS THE ACTUAL TEST DIR USED (update _TEST_ROOT_DIR as needed)
210276
_TEST_ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) ;
211277
navigate_dirs_by_git
212278

279+
printf "::debug::%s\n" "Reading from repository ${_TEST_ROOT_DIR} ..." ;
213280
# Get a list of files to check using git ls-tree with filtering (and careful shell globing)
214-
FILES_TO_CHECK=$(git ls-tree -r --full-tree --name-only HEAD -- "${_TEST_ROOT_DIR}"/**/requirements.txt "${_TEST_ROOT_DIR}"/*-requirements.txt "${_TEST_ROOT_DIR}/requirements.txt" 2>/dev/null || EXIT_CODE=3)
281+
FILES_TO_CHECK=$(git ls-tree -r --full-tree --name-only HEAD -- "${_TEST_ROOT_DIR}"/test/requirements.txt "${_TEST_ROOT_DIR}"/*-requirements.txt "${_TEST_ROOT_DIR}/requirements.txt" 2>/dev/null || EXIT_CODE=3)
215282

216283
# THIS IS THE ACTUAL TEST
284+
printf "::debug::%s\n" "Starting checks ..." ;
217285
# Iterate over files and run checks
218286
for req_file in $FILES_TO_CHECK; do
219-
printf "\t%s\n" "Checking ${req_file}" ;
287+
printf "::group::%s\n" "Checking ${req_file}" ;
220288
if [[ ( -x $(command -v pip-audit) ) ]] && [[ ("${EXIT_CODE}" -eq 0) ]] ; then
221-
printf "\t\t%s\n" "Auditing ${req_file} for security vulnerabilities..."
289+
printf "::debug::%s\n" "Auditing ${req_file} for security vulnerabilities ..."
222290
{ pip-audit $AUDIT_OPTIONS "${req_file}" || EXIT_CODE=4 ;} ; wait ;
223291
fi ;
224292
if [[ ("${EXIT_CODE}" -eq 0) ]] ; then
225-
printf "\t\t%s\n" "Checking licenses in $req_file..." ;
226-
if [[ ( $(pip install -r "$req_file" --quiet 2>&1 >/dev/null || false) ) ]] ; then
227-
{ pip-licenses $LICENSE_OPTIONS --allow-only="${ALLOW_LICENSES}" || EXIT_CODE=5 ;} ; wait ;
228-
else
229-
[[ ("${EXIT_CODE}" -eq 0) ]] && EXIT_CODE=6
230-
printf "\t%s\n" "FAIL: pip install failed for $req_file." >&2
231-
fi
293+
printf "::debug::%s\n" "Checking licenses in $req_file ..." ;
294+
# filter for only pkg from requirements file
295+
PKG_TO_CHECK=$( { cat <"$req_file" | tr '><=' '=' | cut -d\= -f 1-1 | sed -E -e '/^[[:space:]]*$/d' | sed -E -e '/^[#]+.*$/d' | xargs -I{} grep -o -m1 -F "{}" "$req_file" | grep -ovE "^pip|setuptools|wheel|build|hypothesis|certifi$" | sort -u ; wait ;} 2>/dev/null );
296+
check_license_when_given_req ${PKG_TO_CHECK} ; EXIT_CODE=$?
232297
else
233-
printf "\t%s\n" "FAIL: Found requirements errors." >&2 ;
298+
printf "::error file=${req_file},line=${BASH_LINENO:-1},title=REQUIREMENTS::%s\n" "FAIL: Found requirements errors." >&2 ;
234299
fi
300+
printf "::endgroup::\n" ;
235301
done
236302

237-
# summary reporting
303+
printf "::debug::%s\n" "Summary reporting ..." ;
238304
report_summary
239305

240-
# cleaning up
306+
printf "::debug::%s\n" "Cleaning up ..." ;
241307
cleanup || rm -f ${LOCK_FILE} 2>/dev/null || : ;
242308

243309
# unset when done
@@ -247,5 +313,6 @@ unset ALLOW_LICENSES 2>/dev/null || : ;
247313
unset LICENSE_OPTIONS 2>/dev/null || : ;
248314

249315
wait ;
316+
printf "::debug::%s\n" "Check-pip done." ;
250317
# Exit with the appropriate code
251318
exit ${EXIT_CODE:-255} ;

tests/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ wheel>=0.44
6666
# pip - MIT license
6767
pip>=22.0
6868
# build - MIT license
69-
build>=1.2.1
69+
build>=1.2.1, !=1.2.2.post1

tests/test_deps.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ def test_requirements_format(self):
6969
pattern = re.compile(
7070
r'^\s*'
7171
r'[a-zA-Z0-9_\-\.]+'
72-
r'(?:,?\s?(?:==|!=|>=|<=|>|<)\s?[0-9\.]+)+'
72+
r'(?:,?\s?(?:==|!=|>=|<=|>|<)\s?[0-9]+'
73+
r'(?:\.[0-9]+)*(?:[a-zA-Z]+[0-9]*)?'
74+
r'(?:\.[a-zA-Z]+[0-9]*)*)+'
7375
r'(?:\s*(?:#.*)?)$'
7476
)
7577
with open('tests/requirements.txt', 'r') as req_file:

tests/test_usage.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def test_aborts_WHEN_calling_multicast_GIVEN_invalid_tools(self):
132132
self.assertIsNone(test_fixture)
133133
self.assertTupleEqual(
134134
tst_dispatch.useTool(tst_in),
135-
tuple((False, None)), # skipcq: PTC-W0020 - This is test-code.
135+
(False, None), # skipcq: PTC-W0020 - This is test-code.
136136
fail_fixture
137137
)
138138
theResult = True
@@ -246,7 +246,7 @@ def test_hear_is_stable_WHEN_calling_multicast_GIVEN_invalid_tool(self):
246246
try:
247247
self.assertTupleEqual(
248248
multicast.__main__.main(["HEAR", "--hex"]),
249-
tuple((0, (True, (False, None)))) # skipcq: PTC-W0020 - This is test-code.
249+
(0, (True, (False, None))) # skipcq: PTC-W0020 - This is test-code.
250250
)
251251
theResult = True
252252
except Exception as err:
@@ -261,10 +261,10 @@ def test_noop_stable_WHEN_calling_multicast_GIVEN_noop_args(self):
261261
fail_fixture = str("""multicast.__main__.main(NOOP) == Error""")
262262
try:
263263
self.assertIsNotNone(multicast.__main__.main(["NOOP"]), fail_fixture)
264-
self.assertIsNotNone(tuple(multicast.__main__.main(["NOOP"]))[0]) # skipcq: PTC-W0020
264+
self.assertIsNotNone(multicast.__main__.main(["NOOP"])[0]) # skipcq: PTC-W0020
265265
self.assertTupleEqual(
266266
multicast.__main__.main(["NOOP"]),
267-
tuple((0, tuple((True, None)))), # skipcq: PTC-W0020 - This is test-code.
267+
(0, (True, None)), # skipcq: PTC-W0020 - This is test-code.
268268
)
269269
theResult = True
270270
except Exception as err:
@@ -281,7 +281,7 @@ def test_help_works_WHEN_calling_multicast_GIVEN_help_tool(self):
281281
self.assertIsNotNone(multicast.__main__.McastDispatch().doStep("HELP", []))
282282
self.assertTupleEqual(
283283
multicast.__main__.McastDispatch().doStep(["HELP"], []),
284-
tuple((int(2), "NoOp")), # skipcq: PTC-W0020 - This is test-code.
284+
(int(2), "NoOp"), # skipcq: PTC-W0020 - This is test-code.
285285
)
286286
theResult = True
287287
except Exception as err:
@@ -399,7 +399,7 @@ def test_recv_Errors_WHEN_say_not_used(self):
399399
test_cls = multicast.__main__.McastDispatch()
400400
self.assertTupleEqual(
401401
test_cls.doStep("NOOP", []),
402-
tuple((int(2), "NoOp")), # skipcq: PTC-W0020 - This is test-code.
402+
(int(2), "NoOp"), # skipcq: PTC-W0020 - This is test-code.
403403
sub_fail_fixture
404404
)
405405
except Exception as _cause:

0 commit comments

Comments
 (0)