Skip to content

Commit 4be6d45

Browse files
committed
Support Python's build-in module venv for virtual environments
1 parent a9cc1d8 commit 4be6d45

File tree

10 files changed

+319
-23
lines changed

10 files changed

+319
-23
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: (DRAFT) Java Code Structure Graph Analysis using venv
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
# Ignore changes in documentation, general configuration and reports for push events
8+
paths-ignore:
9+
- '**/*.md'
10+
- '**/*.txt'
11+
- '**/*.css'
12+
- '**/*.html'
13+
- '**/*.js'
14+
- '.gitignore'
15+
- '.gitattributes'
16+
- 'renovate.json'
17+
- 'renovate-presets/**'
18+
- 'changelogTemplate.mustache'
19+
- '**.code-workspace'
20+
- '.github/workflows/internal-typescript-code-analysis.yml'
21+
- '.github/workflows/*documentation.yml'
22+
pull_request:
23+
branches:
24+
- main
25+
# Ignore changes in documentation, general configuration and reports for pull request events
26+
paths-ignore:
27+
- '**/*.md'
28+
- '**/*.txt'
29+
- '**/*.css'
30+
- '**/*.html'
31+
- '**/*.js'
32+
- '.gitignore'
33+
- '.gitattributes'
34+
- 'renovate.json'
35+
- 'renovate-presets/**'
36+
- 'changelogTemplate.mustache'
37+
- '**.code-workspace'
38+
- '.github/workflows/internal-typescript-code-analysis.yml'
39+
- '.github/workflows/*documentation.yml'
40+
41+
# Requires the secret NEO4J_INITIAL_PASSWORD to be configured
42+
jobs:
43+
prepare-code-to-analyze:
44+
runs-on: ubuntu-latest
45+
outputs:
46+
analysis-name: ${{ steps.set-analysis-name.outputs.analysis-name }}
47+
sources-upload-name: ${{ steps.set-sources-upload-name.outputs.sources-upload-name }}
48+
artifacts-upload-name: ${{ steps.set-artifacts-upload-name.outputs.artifacts-upload-name }}
49+
50+
env:
51+
PROJECT_NAME: AxonFramework
52+
# Version variable names matches renovate.json configuration entry
53+
AXON_FRAMEWORK_VERSION: 4.11.2
54+
55+
steps:
56+
- name: Checkout GIT Repository
57+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
58+
59+
- name: Run script tests
60+
id: script-tests
61+
run: ./scripts/runTests.sh
62+
63+
- name: Set Set output variable 'analysis-name'
64+
id: set-analysis-name
65+
run: echo "analysis-name=${{ env.PROJECT_NAME }}-${{ env.AXON_FRAMEWORK_VERSION }}" >> "$GITHUB_OUTPUT"
66+
67+
- name: Setup temp directory if missing
68+
run: mkdir -p ./temp
69+
70+
- name: Download ${{ steps.set-analysis-name.outputs.analysis-name }}
71+
working-directory: temp
72+
run: |
73+
mkdir -p ${{ steps.set-analysis-name.outputs.analysis-name }}
74+
cd ${{ steps.set-analysis-name.outputs.analysis-name }}
75+
echo "Working directory: $( pwd -P )"
76+
./../../scripts/downloader/downloadAxonFramework.sh ${{ env.AXON_FRAMEWORK_VERSION }}
77+
78+
- name: Debug folder structure in temp directory
79+
if: runner.debug == '1'
80+
working-directory: temp
81+
run: |
82+
ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
83+
84+
- name: (Prepare Code to Analyze) Generate ARTIFACT_UPLOAD_ID
85+
run: echo "ARTIFACT_UPLOAD_ID=$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10)" >> $GITHUB_ENV
86+
87+
- name: (Prepare Code to Analyze) Set sources-upload-name
88+
id: set-sources-upload-name
89+
run: echo "sources-upload-name=${{ steps.set-analysis-name.outputs.analysis-name }}-analysis-sources_input-${{ env.ARTIFACT_UPLOAD_ID }}" >> "$GITHUB_OUTPUT"
90+
91+
- name: (Prepare Code to Analyze) Set output variable 'artifacts-upload-name'
92+
id: set-artifacts-upload-name
93+
run: echo "artifacts-upload-name=${{ steps.set-analysis-name.outputs.analysis-name }}-analysis-artifacts-input-${{ env.ARTIFACT_UPLOAD_ID }}" >> "$GITHUB_OUTPUT"
94+
95+
- name: (Prepare Code to Analyze) Upload sources to analyze
96+
if: success()
97+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
98+
with:
99+
name: ${{ steps.set-sources-upload-name.outputs.sources-upload-name }}
100+
path: ./temp/${{ steps.set-analysis-name.outputs.analysis-name }}/source
101+
include-hidden-files: true
102+
if-no-files-found: error
103+
retention-days: 1
104+
105+
- name: (Prepare Code to Analyze) Upload artifacts to analyze
106+
if: success()
107+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
108+
with:
109+
name: ${{ steps.set-artifacts-upload-name.outputs.artifacts-upload-name }}
110+
path: ./temp/${{ steps.set-analysis-name.outputs.analysis-name }}/artifacts
111+
if-no-files-found: error
112+
retention-days: 1
113+
114+
115+
116+
analyze-code-graph:
117+
needs: [prepare-code-to-analyze]
118+
uses: ./.github/workflows/public-analyze-code-graph.yml
119+
with:
120+
analysis-name: ${{ needs.prepare-code-to-analyze.outputs.analysis-name }}
121+
artifacts-upload-name: ${{ needs.prepare-code-to-analyze.outputs.artifacts-upload-name }}
122+
sources-upload-name: ${{ needs.prepare-code-to-analyze.outputs.sources-upload-name }}
123+
jupyter-pdf: "false"
124+
use-venv_virtual_python_environment: "true"

.github/workflows/public-analyze-code-graph.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ on:
6161
required: false
6262
type: string
6363
default: 'true'
64+
use-venv_virtual_python_environment:
65+
description: >
66+
Use venv for virtual Python environments instead of Conda ("true") or not ("false", default).
67+
required: false
68+
type: string
69+
default: 'false'
6470
outputs:
6571
uploaded-analysis-results:
6672
description: >
@@ -103,6 +109,7 @@ jobs:
103109

104110
# "Setup Python" can be skipped if jupyter notebook analysis-results aren't needed
105111
- name: (Python Setup) Use version ${{ matrix.python }} with Conda package manager Miniforge
112+
if: inputs.use-venv_virtual_python_environment == 'false'
106113
id: prepare-conda-environment
107114
uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3
108115
with:
@@ -112,7 +119,15 @@ jobs:
112119
environment-file: ./conda-environment.yml
113120
auto-activate-base: false
114121
show-channel-urls: true
122+
123+
- name: (Python Setup) Use version ${{ matrix.python }} with venv environment management module
124+
if: inputs.use-venv_virtual_python_environment == 'true'
125+
uses: actions/setup-python@v5
126+
with:
127+
python-version: ${{ matrix.python }}
128+
115129
- name: (Python Setup) Conda environment info
130+
if: inputs.use-venv_virtual_python_environment == 'false'
116131
shell: bash -el {0}
117132
run: |
118133
conda info
@@ -168,6 +183,7 @@ jobs:
168183
ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION: ${{ inputs.jupyter-pdf }}
169184
IMPORT_GIT_LOG_DATA_IF_SOURCE_IS_PRESENT: "" # Options: "none", "aggregated", "full". default = "plugin" or ""
170185
PREPARE_CONDA_ENVIRONMENT: "false" # Had already been done in step with id "prepare-conda-environment".
186+
USE_VIRTUAL_PYTHON_ENVIRONMENT_VENV: ${{ inputs.use-venv_virtual_python_environment }}
171187
run: |
172188
TYPESCRIPT_SCAN_HEAP_MEMORY=${{ inputs.typescript-scan-heap-memory }} ./../../scripts/analysis/analyze.sh ${{ inputs.analysis-arguments }}
173189

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ __pycache__/
9898

9999
# Python environments
100100
.conda
101+
.venv/
102+
*.pyc
101103

102104
# Optuna (and other) Database data
103105
*.db

GETTING_STARTED.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ Use these optional command line options as needed:
8484
./../../scripts/analysis/analyze.sh --report Csv
8585
```
8686
87-
- Jupyter notebook reports when Python and Conda are installed (and Chromium Browser for PDF generation):
87+
- Jupyter notebook reports when Python and Conda (or venv) are installed (and Chromium Browser for PDF generation):
8888
8989
```shell
9090
./../../scripts/analysis/analyze.sh --report Jupyter
9191
```
9292
93-
- Python reports when Python and Conda are installed (without Chromium Browser for PDF generation):
93+
- Python reports when Python and Conda (or venv) are installed (without Chromium Browser for PDF generation):
9494
9595
```shell
9696
./../../scripts/analysis/analyze.sh --report Python
@@ -102,7 +102,7 @@ Use these optional command line options as needed:
102102
./../../scripts/analysis/analyze.sh --report Visualization
103103
```
104104
105-
- All reports with Python, Conda, Node.js and npm installed:
105+
- All reports with Python, Conda (or venv), Node.js and npm installed:
106106
107107
```shell
108108
./../../scripts/analysis/analyze.sh

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,10 @@ Here are some fully automated graph visualizations utilizing [GraphViz](https://
8686

8787
### Additional Prerequisites for Python and Jupyter Notebooks
8888

89-
- Python is required for Jupyter Notebook reports.
90-
- A conda package manager like [Miniconda](https://docs.conda.io/projects/miniconda/en/latest) or [Anaconda](https://www.anaconda.com/download)(Recommended for Windows) is required for Jupyter Notebook reports.
89+
- Python is required for Jupyter Notebook and Python reports.
90+
- Either [Conda](https://docs.conda.io) or Python's build-in module [venv](https://docs.python.org/3/library/venv.html) a required as environment manager.
91+
- For Conda, use for example [Miniconda](https://docs.conda.io/projects/miniconda/en/latest) or [Anaconda](https://www.anaconda.com/download)(Recommended for Windows).
92+
- To use venv, no additional installation is needed. For that the environment variable `USE_VIRTUAL_PYTHON_ENVIRONMENT_VENV` needs to be set to `'true'`.
9193
- Chromium will automatically be downloaded if needed for Jupyter Notebook PDF reports generation.
9294

9395
### Additional Prerequisites for Graph Visualization
@@ -131,6 +133,7 @@ The [Code Structure Analysis Pipeline](./.github/workflows/internal-java-code-an
131133
- [Checkout GIT Repository](https://github.com/actions/checkout)
132134
- [Setup Java](https://github.com/actions/setup-java)
133135
- [Setup Python with Conda](https://github.com/conda-incubator/setup-miniconda) package manager [Mambaforge](https://github.com/conda-forge/miniforge#mambaforge)
136+
- [Setup Python with venv](https://docs.python.org/3/library/venv.html)
134137
- Download artifacts and optionally source code that contain the code to be analyzed [scripts/downloader](./scripts/downloader)
135138
- Setup [Neo4j](https://neo4j.com) Graph Database ([analysis.sh](./scripts/analysis/analyze.sh))
136139
- Setup [jQAssistant](https://jqassistant.github.io/jqassistant/current) for Java and [Typescript](https://github.com/jqassistant-plugin/jqassistant-typescript-plugin) analysis ([analysis.sh](./scripts/analysis/analyze.sh))

requirements.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# --- Core Python version ---
2+
# NOTE: Python version must be >= 3.12 for compatibility
3+
# This should be enforced by the user/environment, not pip
4+
5+
# --- Core tools ---
6+
jupyter==1.1.*
7+
matplotlib==3.10.*
8+
nbconvert[webpdf]==7.16.*
9+
numpy==1.26.*
10+
pandas==2.2.*
11+
pip==25.0.*
12+
setuptools==75.8.* # opentsne uses sklearn.base uses joblib uses distutils missing in Python >= 12 (TODO use native openTSNE?)
13+
typing-extensions==4.12.* # Needed for opentsne and Python >= 3.12
14+
15+
# --- Visualization ---
16+
wordcloud==1.9.*
17+
monotonic==1.*
18+
plotly[kaleido]==6.2.*
19+
seaborn==0.13 # To visualize clustering results
20+
21+
# --- Machine Learning / Optimization ---
22+
scikit-learn==1.6.*
23+
optuna==4.3.*
24+
umap-learn==0.5.* # Dimensionality reduction to visualize node embeddings in 2D
25+
26+
# --- Database connector ---
27+
neo4j==5.23.*
28+
29+
# --- Native/scientific packages (may require compilation) ---
30+
# These are included but may cause install errors in pip/venv
31+
opentsne==1.0.* # Dimensionality reduction to visualize node embeddings in 2D. Might get replaced by umap.
32+
shap==0.48.* # For e.g. explaining anomaly detection results

scripts/activateCondaEnvironment.sh

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
#!/usr/bin/env bash
22

3-
# Activates the Conda (Python package manager) environment "codegraph" with all packages needed to execute the Jupyter Notebooks.
3+
# Activates the Conda (Python package manager) environment "codegraph" with all packages needed to run the included Jupyter Notebooks and Python scripts.
44

55
# Note: This script uses the conda environment defined in CODEGRAPH_CONDA_ENVIRONMENT (defaults to "codegraph").
6-
# If the environment hadn't been created yet, it will use "conda-environment.yml" from the root directory
7-
# in the same directory as the given jupyter notebook ipynb file
8-
# to create the environment.
6+
# If the environment hadn't been created yet, it will use "conda-environment.yml" from the root directory to create the environment.
97

108
# Requires operatingSystemFunctions.sh
119

1210
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
1311
set -o errexit -o pipefail
1412

13+
PREPARE_CONDA_ENVIRONMENT=${PREPARE_CONDA_ENVIRONMENT:-"true"} # Wether to prepare a Python environment with Conda if needed (default, "true") or use an already prepared Conda environment ("false")
14+
15+
if [ "${PREPARE_CONDA_ENVIRONMENT}" = "false" ]; then
16+
echo "activateCondaEnvironment: Skipping activation. An already activated environment and installed dependencies are expected (PREPARE_CONDA_ENVIRONMENT=false)."
17+
# "return" needs to be used here instead of "exit".
18+
# This script is included in another script by using "source".
19+
# "exit" would end the main script, "return" just ends this sub script.
20+
return 0
21+
fi
22+
23+
if [ "${USE_VIRTUAL_PYTHON_ENVIRONMENT_VENV}" = "true" ]; then
24+
echo "activateCondaEnvironment: Skipping activation. venv will be used instead of conda (USE_VIRTUAL_PYTHON_ENVIRONMENT_VENV=true)."
25+
# "return" needs to be used here instead of "exit".
26+
# This script is included in another script by using "source".
27+
# "exit" would end the main script, "return" just ends this sub script.
28+
return 0
29+
fi
30+
1531
## Get this "scripts" directory if not already set
1632
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
1733
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
@@ -37,16 +53,6 @@ echo "activateCondaEnvironment: CONDA_PREFIX=${CONDA_PREFIX}"
3753
echo "activateCondaEnvironment: Current conda environment=${CONDA_DEFAULT_ENV}"
3854
echo "activateCondaEnvironment: Target conda environment=${CODEGRAPH_CONDA_ENVIRONMENT}"
3955

40-
PREPARE_CONDA_ENVIRONMENT=${PREPARE_CONDA_ENVIRONMENT:-"true"} # Wether to prepare a Python environment with Conda if needed (default, "true") or use an already prepared Conda environment ("false")
41-
42-
if [ "${PREPARE_CONDA_ENVIRONMENT}" = "false" ]; then
43-
echo "activateCondaEnvironment: Skipping activation. ${PREPARE_CONDA_ENVIRONMENT} is set to false."
44-
# "return" needs to be used here instead of "exit".
45-
# This script is included in another script by using "source".
46-
# "exit" would end the main script, "return" just ends this sub script.
47-
return 0
48-
fi
49-
5056
# Include operation system function to for example detect Windows.
5157
source "${SCRIPTS_DIR}/operatingSystemFunctions.sh"
5258

0 commit comments

Comments
 (0)