Skip to content

Commit be82aa6

Browse files
committed
Support executing Jupyter Notebooks on Windows
1 parent e95efb5 commit be82aa6

13 files changed

+152
-79
lines changed

COMMANDS.md

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,11 @@
22

33
## Start an analysis
44

5-
1. Create a directory for all analysis projects
6-
7-
```shell
8-
mkdir temp
9-
cd temp
10-
```
11-
12-
1. Create a working directory for your specific analysis
13-
14-
```shell
15-
mkdir MyFirstAnalysis
16-
cd MyFirstAnalysis
17-
```
18-
19-
1. Choose an initial password for Neo4j
20-
21-
```shell
22-
export NEO4J_INITIAL_PASSWORD=theinitialpasswordthatihavechosenforneo4j
23-
```
24-
25-
1. Create the `artifacts` directory for the code to be analyzed (without `cd` afterwards)
26-
27-
```shell
28-
mkdir artifacts
29-
```
30-
31-
1. Move the artifacts you want to analyze into the `artifacts` directory
32-
33-
1. Optionally run a predefined script to download artifacts
34-
35-
```shell
36-
./../../scripts/downloader/downloadAxonFramework.sh <version>
37-
```
38-
39-
1. Optionally use a script to download artifacts from Maven ([details](#download-maven-artifacts-to-analyze))
40-
41-
1. Start the analysis
42-
43-
```shell
44-
./../../scripts/analysis/analyze.sh
45-
```
5+
An analysis is started with the script [analyze.sh](./scripts/analysis/analyze.sh).
6+
To run all analysis steps simple execute the following command:
7+
```shell
8+
./../../scripts/analysis/analyze.sh
9+
```
4610

4711
👉 See [scripts/examples/analyzeAxonFramework.sh](./scripts/examples/analyzeAxonFramework.sh) as an example script that combines all the above steps.
4812
👉 See [Code Structure Analysis Pipeline](./.github/workflows/code-structure-analysis.yml) on how to do this within a GitHub Actions Workflow.

GETTING_STARTED.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Code Graph Analysis Pipeline - Getting started guide
2+
3+
This document describes the steps to get started as quickly as possible.
4+
For more details on what you can do with this pipeline see [README](./README.md).
5+
For more details on how the commands work in detail see [COMMANDS](./COMMANDS.md).
6+
7+
## 🛠 Prerequisites
8+
9+
Please read through the [Prerequisites](./README.md#🛠-prerequisites) in the [README](./README.md) file for what is required to run the scripts.
10+
11+
## Start an analysis
12+
13+
1. Create a directory for all analysis projects
14+
15+
```shell
16+
mkdir temp
17+
cd temp
18+
```
19+
20+
1. Create a working directory for your specific analysis
21+
22+
```shell
23+
mkdir MyFirstAnalysis
24+
cd MyFirstAnalysis
25+
```
26+
27+
1. Choose an initial password for Neo4j
28+
29+
```shell
30+
export NEO4J_INITIAL_PASSWORD=theinitialpasswordthatihavechosenforneo4j
31+
```
32+
33+
1. Create the `artifacts` directory for the code to be analyzed (without `cd` afterwards)
34+
35+
```shell
36+
mkdir artifacts
37+
```
38+
39+
1. Move the artifacts you want to analyze into the `artifacts` directory
40+
41+
1. Optionally run a predefined script to download artifacts
42+
43+
```shell
44+
./../../scripts/downloader/downloadAxonFramework.sh <version>
45+
```
46+
47+
1. Optionally use a script to download artifacts from Maven ([details](#download-maven-artifacts-to-analyze))
48+
49+
1. Start the analysis
50+
51+
- Without any additional dependencies:
52+
```shell
53+
./../../scripts/analysis/analyze.sh --report Csv
54+
```
55+
- Jupyter notebook reports when Python and Conda are installed:
56+
```shell
57+
./../../scripts/analysis/analyze.sh --report Jupyter
58+
```
59+
- Graph visualizations when Node.js and npm are installed:
60+
```shell
61+
./../../scripts/analysis/analyze.sh --report Jupyter
62+
```
63+
- All reports with Python, Conda, Node.js and npm installed:
64+
```shell
65+
./../../scripts/analysis/analyze.sh
66+
```
67+
- To explore the database yourself without any automatically generated reports and no additional requirements:
68+
```shell
69+
./../../scripts/analysis/analyze.sh
70+
```
71+
72+
👉 See [scripts/examples/analyzeAxonFramework.sh](./scripts/examples/analyzeAxonFramework.sh) as an example script that combines all the above steps.
73+
👉 See [Code Structure Analysis Pipeline](./.github/workflows/code-structure-analysis.yml) on how to do this within a GitHub Actions Workflow.

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Contained within this repository is a comprehensive and automated code graph ana
66

77
---
88

9-
## 🚀 Features
9+
## Features
1010

1111
- Analyze static code structure as a graph
1212
- Fully automated [pipeline](./.github/workflows/code-structure-analysis.yml) from tool installation to report generation
@@ -37,14 +37,29 @@ Here are some reports that utilize Neo4j's [Graph Data Science Library](https://
3737

3838
## 🛠 Prerequisites
3939

40-
- Java 17 is [required for Neo4j](https://neo4j.com/docs/operations-manual/current/installation/requirements/#deployment-requirements-software) (5.x requirement)
40+
- Java 17 is [required for Neo4j](https://neo4j.com/docs/operations-manual/current/installation/requirements/#deployment-requirements-software) (Neo4j 5.x requirement).
41+
- On Windows it is recommended to use the git bash provided by [git for windows](https://gitforwindows.org).
4142
- [jq](https://github.com/jqlang/jq) the "lightweight and flexible command-line JSON processor" needs to be installed. Latest releases: https://github.com/jqlang/jq/releases/latest. Check using `jq --version`.
42-
- Python and a conda package manager are required for Jupyter Notebook reports
43-
- Chromium will automatically be downloaded if needed for Jupyter Notebook reports in PDF format
43+
- Set environment variable `NEO4J_INITIAL_PASSWORD` to a password of your choice. For example:
44+
```shell
45+
export NEO4J_INITIAL_PASSWORD=neo4j_password_of_my_choice
46+
```
47+
To run Jupyter notebooks, create an `.env` file in the folder from where you open the notebook containing for example: `NEO4J_INITIAL_PASSWORD=neo4j_password_of_my_choice`
48+
49+
### Further Prerequisites for Python Jupyter Notebooks
50+
51+
- Python is required for Jupyter Notebook reports.
52+
- 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.
53+
- Chromium will automatically be downloaded if needed for Jupyter Notebook PDF reports generation.
54+
55+
### Hints for Windows
56+
57+
- Add this line to your `~/.bashrc` file if you are using Anaconda3: `/c/ProgramData/Anaconda3/etc/profile.d/conda.sh`. Try to find a similar script for other conda package managers or versions.
58+
- Run `conda init` in the git bash opened as administrator. Running it in normal mode usually leads to an error message.
4459

45-
## Getting Started
60+
## 🚀 Getting Started
4661

47-
See [Start an analysis](./COMMANDS.md#start-an-analysis) in the [Commands Reference](./COMMANDS.md) on how to start an analysis on your local machine.
62+
See [GETTING_STARTED.md](./GETTING_STARTED.md) on how to get started on your local machine.
4863

4964
## 🏗 Pipeline and Tools
5065

scripts/executeJupyterNotebook.sh

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@
1919
# It it isn't activated, it will save the currently activated environment, change to codegraph, and restore the original one at the end again.
2020
# In cases of an error it might be, that the original conda environment isn't set back. Typically this shouldn't be the case though.
2121

22-
# Requires juypter nbconvert
22+
# Requires juypter nbconvert,,operatingSystemFunctions.sh
2323

2424
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
2525
set -eo pipefail
2626

2727
ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION=${ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION:-""} # Enable PDF generation for Jupyter Notebooks if set to any non empty value e.g. "true"
2828

29+
## Get this "scripts" directory if not already set
30+
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
31+
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
32+
# This way non-standard tools like readlink aren't needed.
33+
SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
34+
echo "startNeo4j: SCRIPTS_DIR=$SCRIPTS_DIR"
35+
2936
# Check if environment variable is set
3037
if [ -z "${NEO4J_INITIAL_PASSWORD}" ]; then
3138
echo "executeJupyterNotebook: Requires environment variable NEO4J_INITIAL_PASSWORD to be set first. Use 'export NEO4J_INITIAL_PASSWORD=<your-own-password>'."
@@ -81,36 +88,50 @@ fi
8188

8289
# Define conda environment to use for code structure analysis. Default "codegraph"
8390
CODEGRAPH_CONDA_ENVIRONMENT=${CODEGRAPH_CONDA_ENVIRONMENT:-"codegraph"} # Name of the conda environment to use for code graph analysis
84-
echo "executeJupyterNotebook: CODEGRAPH_CONDA_ENVIRONMENT=$CODEGRAPH_CONDA_ENVIRONMENT"
91+
backupCondaEnvironment=$CONDA_DEFAULT_ENV
92+
echo "executeJupyterNotebook: CODEGRAPH_CONDA_ENVIRONMENT=${CODEGRAPH_CONDA_ENVIRONMENT}"
93+
echo "executeJupyterNotebook: Current conda environment=${CONDA_DEFAULT_ENV}"
94+
95+
# Include operation system function to for example detect Windows.
96+
source "${SCRIPTS_DIR}/operatingSystemFunctions.sh"
97+
98+
scriptExtension=$(ifWindows ".bat" "")
8599

86100
# Determine the path to "conda"
87101
if [ -n "${CONDA}" ]; then
88-
pathToConda="$CONDA/bin/" # the trailing slash character is required
102+
if isWindows; then
103+
pathToConda="${CONDA}\\Scripts\\" # the trailing backslash character is required
104+
else
105+
pathToConda="${CONDA}/bin/" # the trailing slash character is required
106+
fi
89107
else
90108
pathToConda=""
91109
fi
92110
echo "executeJupyterNotebook: pathToConda=${pathToConda}"
93111

94-
# Activate conda shell hook
95-
eval "$(${pathToConda}conda shell.bash hook)"
112+
# Activate conda shell hook. Also resets CONDA_DEFAULT_ENV to base.
113+
# Thats why CONDA_DEFAULT_ENV (base) is never equal to CODEGRAPH_CONDA_ENVIRONMENT (codegraph).
114+
eval "$(${pathToConda}conda${scriptExtension} shell.bash hook)"
96115

97116
# Create (if missing) and activate Conda environment for code structure graph analysis
98-
backupCondaEnvironment=$CONDA_DEFAULT_ENV
99-
if [ ! "$backupCondaEnvironment" = "$CODEGRAPH_CONDA_ENVIRONMENT" ] ; then
100-
backupCondaEnvironment=$CONDA_DEFAULT_ENV
101-
102-
if { ${pathToConda}conda env list | grep "$CODEGRAPH_CONDA_ENVIRONMENT "; } >/dev/null 2>&1; then
103-
echo "executeJupyterNotebook: Conda environment $CODEGRAPH_CONDA_ENVIRONMENT already created"
104-
else
105-
if [ ! -f "${jupyter_notebook_file_path}/environment.yml" ] ; then
106-
echo "executeJupyterNotebook: Couldn't find environment file ${jupyter_notebook_file_path}/environment.yml."
107-
exit 2
108-
fi
109-
echo "executeJupyterNotebook: Creating Conda environment ${CODEGRAPH_CONDA_ENVIRONMENT}"
110-
${pathToConda}conda env create --file ${jupyter_notebook_file_path}/environment.yml --name "${CODEGRAPH_CONDA_ENVIRONMENT}"
117+
if { "${pathToConda}conda" env list | grep "$CODEGRAPH_CONDA_ENVIRONMENT "; } >/dev/null 2>&1; then
118+
echo "executeJupyterNotebook: Conda environment $CODEGRAPH_CONDA_ENVIRONMENT already created"
119+
else
120+
if [ ! -f "${jupyter_notebook_file_path}/environment.yml" ] ; then
121+
echo "executeJupyterNotebook: Couldn't find environment file ${jupyter_notebook_file_path}/environment.yml."
122+
exit 2
111123
fi
112-
${pathToConda}conda activate "${CODEGRAPH_CONDA_ENVIRONMENT}"
113-
echo "executeJupyterNotebook: Activated Conda environment: $CODEGRAPH_CONDA_ENVIRONMENT "
124+
echo "executeJupyterNotebook: Creating Conda environment ${CODEGRAPH_CONDA_ENVIRONMENT}"
125+
"${pathToConda}conda" env create --file "${jupyter_notebook_file_path}/environment.yml" --name "${CODEGRAPH_CONDA_ENVIRONMENT}"
126+
fi
127+
echo "executeJupyterNotebook: Activating Conda environment ${CODEGRAPH_CONDA_ENVIRONMENT}"
128+
"${pathToConda}conda" activate ${CODEGRAPH_CONDA_ENVIRONMENT}
129+
130+
if [ "${CONDA_DEFAULT_ENV}" = "${CODEGRAPH_CONDA_ENVIRONMENT}" ] ; then
131+
echo "executeJupyterNotebook: Activated Conda environment: ${CONDA_DEFAULT_ENV}"
132+
else
133+
echo "executeJupyterNotebook: Error: Failed to activate Conda environment ${CODEGRAPH_CONDA_ENVIRONMENT}. ${CONDA_DEFAULT_ENV} still active."
134+
exit 1
114135
fi
115136

116137
# Execute the Jupyter Notebook and write it to the output file name
@@ -135,7 +156,7 @@ if [ -n "${ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION}" ]; then
135156
fi
136157

137158
# Restore Conda environment
138-
if [ ! "$backupCondaEnvironment" = "$CODEGRAPH_CONDA_ENVIRONMENT" ] ; then
139-
${pathToConda}conda activate "${backupCondaEnvironment}"
140-
echo "executeJupyterNotebook: Restored Conda Environment: ${backupCondaEnvironment}"
159+
if [ ! "${backupCondaEnvironment}" = "${CODEGRAPH_CONDA_ENVIRONMENT}" ] ; then
160+
"${pathToConda}conda" activate "${backupCondaEnvironment}"
161+
echo "executeJupyterNotebook: Restored Conda Environment to ${backupCondaEnvironment}: ${CONDA_DEFAULT_ENV}"
141162
fi

scripts/reports/ArtifactDependenciesJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3636
mkdir -p "${FULL_REPORT_DIRECTORY}"
3737

3838
# Execute and convert the Jupyter Notebook "ArtifactDependencies.ipynb" within the given reports directory
39-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/ArtifactDependencies.ipynb)
39+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/ArtifactDependencies.ipynb")

scripts/reports/ExternalDependenciesJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3434
mkdir -p "${FULL_REPORT_DIRECTORY}"
3535

3636
# Execute and convert the following Jupyter Notebook within the given reports directory
37-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/ExternalDependencies.ipynb)
37+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/ExternalDependencies.ipynb")

scripts/reports/InternalDependenciesJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3333
mkdir -p "${FULL_REPORT_DIRECTORY}"
3434

3535
# Execute and convert the Jupyter Notebook "InternalDependencies.ipynb" within the given reports directory
36-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/InternalDependencies.ipynb)
36+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/InternalDependencies.ipynb")

scripts/reports/MethodMetricsJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3333
mkdir -p "${FULL_REPORT_DIRECTORY}"
3434

3535
# Execute and convert the following Jupyter Notebook within the given reports directory
36-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/MethodMetrics.ipynb)
36+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/MethodMetrics.ipynb")

scripts/reports/NodeEmbeddingsJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3434
mkdir -p "${FULL_REPORT_DIRECTORY}"
3535

3636
# Execute and convert the Jupyter Notebook "InternalDependencies.ipynb" within the given reports directory
37-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/NodeEmbeddings.ipynb)
37+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/NodeEmbeddings.ipynb")

scripts/reports/ObjectOrientedDesignMetricsJupyter.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
3333
mkdir -p "${FULL_REPORT_DIRECTORY}"
3434

3535
# Execute and convert the Jupyter Notebook "ObjectOrientedDesignMetrics.ipynb" within the given reports directory
36-
(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/ObjectOrientedDesignMetrics.ipynb)
36+
(cd "${FULL_REPORT_DIRECTORY}" && exec "${SCRIPTS_DIR}/executeJupyterNotebook.sh" "${JUPYTER_NOTEBOOK_DIRECTORY}/ObjectOrientedDesignMetrics.ipynb")

0 commit comments

Comments
 (0)