Skip to content

fix for check_pip #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 6 additions & 31 deletions .github/workflows/Tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -470,32 +470,27 @@
EXTRAS-FOR-PIP:
if: ${{ !cancelled() }}
needs: [BOOTSTRAP, MATS]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
timeout-minutes: 10
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest]
python-version: ["3.10", "3.11", "3.12"]
env:
OS: ${{ matrix.os }}
OS: 'ubuntu-latest'
PYTHON_VERSION: ${{ matrix.python-version }}
LANG: "en_US.utf-8"
LC_CTYPE: "en_US.utf-8"
COVERAGE_RCFILE: ./.coveragerc
COV_CORE_SOURCE: ./
COV_CORE_CONFIG: ./.coveragerc
COV_CORE_DATAFILE: .coverage
CODECLIMATE_REPO_TOKEN: ${{ secrets.CODECLIMATE_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies for python ${{ matrix.python-version }} on ${{ matrix.os }}
- name: Install dependencies for python ${{ matrix.python-version }}
run: |
pip install --upgrade "pip>=22.0" "setuptools>=75.0" "wheel>=0.44" "build>=1.2.1" "pip-licenses>=5.0.0";
pip install -r ./requirements.txt ;
Expand All @@ -504,31 +499,12 @@
- name: Pre-Clean
id: clean-prep
run: make -j1 -f Makefile clean ;
- name: Pre-build for Python ${{ matrix.python-version }} on ${{ matrix.os }}
run: make -j1 -f Makefile build ;
if: ${{ success() }}
- name: Test Dependencies with py${{ matrix.python-version }} on ${{ matrix.os }}
- name: Test Dependencies with py${{ matrix.python-version }}
run: |
hash -p ./.github/tool_shlock_helper.sh shlock ; export TMPDIR=./ ;
./tests/check_pip 2>&1 >> $GITHUB_STEP_SUMMARY || echo "::warning file=tests/check_pip,line=1,endLine=1,title=SKIPPED::SKIP Requirements Tests." ;
./tests/check_pip ;
shell: bash
if: ${{ !cancelled() }}
- name: Upload Python ${{ matrix.python-version }} Legacy Setup.py coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./test-reports/coverage_setup.xml
directory: .
flags: multicast,${{ matrix.os }},${{ matrix.python-version }}
name: multicast-github-${{ matrix.os }}-${{ matrix.python-version }}
verbose: true
fail_ci_if_error: false
- name: Upload Extra Python ${{ matrix.python-version }} Artifact
uses: actions/upload-artifact@v4
with:
name: Legacy_Setup-Test-Report-${{ matrix.os }}-${{ matrix.python-version }}
path: ./test-reports/
if-no-files-found: ignore
- name: Post-purge
id: post-uninstall
run: make -j1 -f Makefile purge || true ;
Expand Down Expand Up @@ -568,7 +544,6 @@
pip install --upgrade "pip>=22.0" "setuptools>=75.0" "wheel>=0.44" "build>=1.2.1";
pip install -r ./requirements.txt ;
pip install -r ./tests/requirements.txt || true ;
pip install --upgrade -r ./docs/requirements.txt || true ;
- name: Pre-Clean
id: clean-prep
run: make -j1 -f Makefile clean ;
Expand Down
7 changes: 4 additions & 3 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ instead of `None` to indicate exit code `1` by returning a `boolean` success val
> [CEP-8](https://gist.github.com/reactive-firewall/b7ee98df9e636a51806e62ef9c4ab161)'s
> POSIX-based guidelines.


### How do I build the documentation?

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

### Building Documentation with a Custom Git Reference

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:
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:

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

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.
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.

***

Expand Down
2 changes: 1 addition & 1 deletion multicast/recv.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,5 +607,5 @@ def doStep(self, *args, **kwargs):
print(str(response))
print(multicast._BLANK) # skipcq: PYL-W0212 - module ok
_result = (len(response) > 0) is True
return tuple((_result, None if not _result else response)) # skipcq: PTC-W0020 - intended
return (_result, None if not _result else response) # skipcq: PTC-W0020 - intended

2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ setuptools>=75.0
# pip - MIT license
pip>=22.0
# build - MIT license
build>=1.1.1
build>=1.1.1, !=1.2.2.post1
# multicast - MIT license
#-e git+https://github.com/reactive-firewall/multicast.git#egg=multicast
# wheel - MIT license
Expand Down
115 changes: 91 additions & 24 deletions tests/check_pip
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export -f check_command
check_command grep ;
check_command python3 ;
check_command git ;
check_command sed ;
check_command tee ;
check_command pip ;
# check_command pip-audit ; # optional
Expand Down Expand Up @@ -166,13 +167,23 @@ handle_signals

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

# set the script-file to check_pip
SCRIPT_FILE="tests/check_pip"
# Set pip-audit options
AUDIT_OPTIONS="--progress-spinner off --desc on --requirement"
# List of Allowed Licenses delimited by semicolon ;
ALLOW_LICENSES="Public Domain;Apache Software License;MIT License;BSD License;Python Software Foundation License"
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);"
# Set pip-licenses options
LICENSE_OPTIONS="--from=mixed"

# Set pip options
PIP_COMMON_FLAGS="--require-virtualenv --use-pep517 --exists-action s --upgrade --upgrade-strategy only-if-needed --quiet"
# Set Env and OS specific pip options
if [[ $( \uname -s ) == "*arwin" ]] ; then
PIP_ENV_FLAGS="--break-system-packages"
LICENSE_OPTIONS="--python python3 ${LICENSE_OPTIONS} --ignore-packages certifi"
else
PIP_ENV_FLAGS=""
fi ;
# Enable auto-fix if '--fix' argument is provided
if [[ "$1" == "--fix" ]]; then
AUDIT_OPTIONS="--fix --strict ${AUDIT_OPTIONS}"
Expand All @@ -182,62 +193,117 @@ fi
# lazy defined functions should be defined now that this is the only script instance.

function report_summary() {
printf "::group::%s\n" "Results" ;
# Improved reporting based on EXIT_CODE
case "${EXIT_CODE}" in
0) printf "%s\n" "OK: Found no detected requirements errors." ;;
1) printf "%s\n" "FAIL: General failure during script execution." >&2 ;;
3) printf "%s\n" "FAIL: Gathering repostory's requirements failed." >&2 ;; # git ls-tree command failed
4) printf "%s\n" "FAIL: pip-audit detected security vulnerabilities." >&2 ;;
5) printf "%s\n" "FAIL: pip-licenses detected license issues." >&2 ;;
6) printf "%s\n" "FAIL: pip install failed." >&2 ;;
126) printf "%s\n" "SKIP: Unable to continue script execution." >&2 ;;
*) printf "%s\n" "FAIL: Detected requirements errors." >&2 ;;
0) printf "::notice title=OK::%s\n" "OK: Found no detected requirements errors." ;;
1) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=CHECK-PIP::%s\n" "FAIL: General failure during script execution." >&2 ;;
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
4) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=SECURITY::%s\n" "FAIL: pip-audit detected security vulnerabilities." >&2 ;;
5) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=LICENSE::%s\n" "FAIL: pip-licenses detected license issues." >&2 ;;
6) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=INSTALL::%s\n" "FAIL: pip install failed." >&2 ;;
126) printf "::warning file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=SKIPPED::%s\n" "SKIP: Unable to continue script execution." >&2 ;;
*) printf "::error file=${SCRIPT_FILE},line=${BASH_LINENO:-0},title=FAILED::%s\n" "FAIL: Detected requirements errors." >&2 ;;
esac
printf "::endgroup::\n" ;
}

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

function check_license_when_given_req() {
local SUB_CODE=${EXIT_CODE-0}
umask 007
printf "::debug::%s\n" "need venv ..." ;
# Create a temporary directory for the virtual environment
temp_dir=$(mktemp -d)

# Enter the temporary directory
cd "$temp_dir"

# Create a virtual environment using venv
python3 -m venv venv

# Activate the virtual environment
source venv/bin/activate

umask 037
# 2>&1 >/dev/null
python3 -m pip install $PIP_COMMON_FLAGS $PIP_ENV_FLAGS "pip-licenses>=5.0" || SUB_CODE=6 ;
wait ;
printf "::debug::%s\n" "venv setup ... (${SUB_CODE})" ;
# Install the given Python modules using pip
for module in $@ ; do
printf "::debug::%s\n" "Checking license from package '$module' ..." ;
REQ_SPEC=$(grep -F "$module" <(cat <"${_TEST_ROOT_DIR}"/$req_file | sed -E -e '/^[[:space:]]*$/d' | sed -E -e '/^[#]+.*$/d') | grep -m1 -F "$module" )
ERR_MSG="pip install '$module' failed for $req_file." ;
if [[ ("${SUB_CODE}" -eq 0) ]] && python3 -m pip install $PIP_COMMON_FLAGS $PIP_ENV_FLAGS "${REQ_SPEC};" 2>/dev/null ;
then
printf "::debug::%s\n" "Fetched license from package '$module' ..." ;
else
[[ ("${SUB_CODE}" -eq 0) ]] && SUB_CODE=6 && \
printf "::warning file=${req_file},line=1,col=1,title=PIP::%s\n" "${ERR_MSG}" >&2
fi
unset ERR_MSG 2>/dev/null || : ;
done

# Use pip-licenses to list the licenses of the installed packages
{ pip-licenses $LICENSE_OPTIONS --allow-only="${ALLOW_LICENSES}" || SUB_CODE=5 ;} ; wait ;

# Deactivate the virtual environment
deactivate

# return to starting dir
cd "${OLDPWD}" ;

# Remove the temporary directory and all of its contents
rm -rf "${temp_dir}" || : ;
umask 137 ;
wait ;
return $SUB_CODE
}

# THIS IS THE ACTUAL TEST DIR USED (update _TEST_ROOT_DIR as needed)
_TEST_ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) ;
navigate_dirs_by_git

printf "::debug::%s\n" "Reading from repository ${_TEST_ROOT_DIR} ..." ;
# Get a list of files to check using git ls-tree with filtering (and careful shell globing)
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)
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)

# THIS IS THE ACTUAL TEST
printf "::debug::%s\n" "Starting checks ..." ;
# Iterate over files and run checks
for req_file in $FILES_TO_CHECK; do
printf "\t%s\n" "Checking ${req_file}" ;
printf "::group::%s\n" "Checking ${req_file}" ;
if [[ ( -x $(command -v pip-audit) ) ]] && [[ ("${EXIT_CODE}" -eq 0) ]] ; then
printf "\t\t%s\n" "Auditing ${req_file} for security vulnerabilities..."
printf "::debug::%s\n" "Auditing ${req_file} for security vulnerabilities ..."
{ pip-audit $AUDIT_OPTIONS "${req_file}" || EXIT_CODE=4 ;} ; wait ;
fi ;
if [[ ("${EXIT_CODE}" -eq 0) ]] ; then
printf "\t\t%s\n" "Checking licenses in $req_file..." ;
if [[ ( $(pip install -r "$req_file" --quiet 2>&1 >/dev/null || false) ) ]] ; then
{ pip-licenses $LICENSE_OPTIONS --allow-only="${ALLOW_LICENSES}" || EXIT_CODE=5 ;} ; wait ;
else
[[ ("${EXIT_CODE}" -eq 0) ]] && EXIT_CODE=6
printf "\t%s\n" "FAIL: pip install failed for $req_file." >&2
fi
printf "::debug::%s\n" "Checking licenses in $req_file ..." ;
# filter for only pkg from requirements file
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 );
check_license_when_given_req ${PKG_TO_CHECK} ; EXIT_CODE=$?
else
printf "\t%s\n" "FAIL: Found requirements errors." >&2 ;
printf "::error file=${req_file},line=${BASH_LINENO:-1},title=REQUIREMENTS::%s\n" "FAIL: Found requirements errors." >&2 ;
fi
printf "::endgroup::\n" ;
done

# summary reporting
printf "::debug::%s\n" "Summary reporting ..." ;
report_summary

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

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

wait ;
printf "::debug::%s\n" "Check-pip done." ;
# Exit with the appropriate code
exit ${EXIT_CODE:-255} ;
2 changes: 1 addition & 1 deletion tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ wheel>=0.44
# pip - MIT license
pip>=22.0
# build - MIT license
build>=1.2.1
build>=1.2.1, !=1.2.2.post1
4 changes: 3 additions & 1 deletion tests/test_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ def test_requirements_format(self):
pattern = re.compile(
r'^\s*'
r'[a-zA-Z0-9_\-\.]+'
r'(?:,?\s?(?:==|!=|>=|<=|>|<)\s?[0-9\.]+)+'
r'(?:,?\s?(?:==|!=|>=|<=|>|<)\s?[0-9]+'
r'(?:\.[0-9]+)*(?:[a-zA-Z]+[0-9]*)?'
r'(?:\.[a-zA-Z]+[0-9]*)*)+'
r'(?:\s*(?:#.*)?)$'
)
with open('tests/requirements.txt', 'r') as req_file:
Expand Down
12 changes: 6 additions & 6 deletions tests/test_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_aborts_WHEN_calling_multicast_GIVEN_invalid_tools(self):
self.assertIsNone(test_fixture)
self.assertTupleEqual(
tst_dispatch.useTool(tst_in),
tuple((False, None)), # skipcq: PTC-W0020 - This is test-code.
(False, None), # skipcq: PTC-W0020 - This is test-code.
fail_fixture
)
theResult = True
Expand Down Expand Up @@ -246,7 +246,7 @@ def test_hear_is_stable_WHEN_calling_multicast_GIVEN_invalid_tool(self):
try:
self.assertTupleEqual(
multicast.__main__.main(["HEAR", "--hex"]),
tuple((0, (True, (False, None)))) # skipcq: PTC-W0020 - This is test-code.
(0, (True, (False, None))) # skipcq: PTC-W0020 - This is test-code.
)
theResult = True
except Exception as err:
Expand All @@ -261,10 +261,10 @@ def test_noop_stable_WHEN_calling_multicast_GIVEN_noop_args(self):
fail_fixture = str("""multicast.__main__.main(NOOP) == Error""")
try:
self.assertIsNotNone(multicast.__main__.main(["NOOP"]), fail_fixture)
self.assertIsNotNone(tuple(multicast.__main__.main(["NOOP"]))[0]) # skipcq: PTC-W0020
self.assertIsNotNone(multicast.__main__.main(["NOOP"])[0]) # skipcq: PTC-W0020
self.assertTupleEqual(
multicast.__main__.main(["NOOP"]),
tuple((0, tuple((True, None)))), # skipcq: PTC-W0020 - This is test-code.
(0, (True, None)), # skipcq: PTC-W0020 - This is test-code.
)
theResult = True
except Exception as err:
Expand All @@ -281,7 +281,7 @@ def test_help_works_WHEN_calling_multicast_GIVEN_help_tool(self):
self.assertIsNotNone(multicast.__main__.McastDispatch().doStep("HELP", []))
self.assertTupleEqual(
multicast.__main__.McastDispatch().doStep(["HELP"], []),
tuple((int(2), "NoOp")), # skipcq: PTC-W0020 - This is test-code.
(int(2), "NoOp"), # skipcq: PTC-W0020 - This is test-code.
)
theResult = True
except Exception as err:
Expand Down Expand Up @@ -399,7 +399,7 @@ def test_recv_Errors_WHEN_say_not_used(self):
test_cls = multicast.__main__.McastDispatch()
self.assertTupleEqual(
test_cls.doStep("NOOP", []),
tuple((int(2), "NoOp")), # skipcq: PTC-W0020 - This is test-code.
(int(2), "NoOp"), # skipcq: PTC-W0020 - This is test-code.
sub_fail_fixture
)
except Exception as _cause:
Expand Down
Loading