Skip to content

Commit 35c2016

Browse files
authored
Merge pull request #13 from JohT/feature/independent-artifact-download
Separate artifacts and their download from the analysis
2 parents 1c15385 + 53d6045 commit 35c2016

File tree

14 files changed

+158
-107
lines changed

14 files changed

+158
-107
lines changed

.github/workflows/code-reports.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,22 @@ jobs:
9797
key:
9898
${{ runner.os }}-${{ hashFiles('**/*.sh') }}
9999

100-
- name: Analyze AxonFramework
100+
- name: Download AxonFramework artifacts
101101
working-directory: temp
102+
run: |
103+
mkdir -p AxonFramework-${{ env.AXON_FRAMEWORK_VERSION }}
104+
cd AxonFramework-${{ env.AXON_FRAMEWORK_VERSION }}
105+
echo "Working directory: $( pwd -P )"
106+
./../../scripts/downloader/downloadAxonFramework.sh ${{ env.AXON_FRAMEWORK_VERSION }}
107+
108+
- name: Analyze AxonFramework
109+
working-directory: temp/AxonFramework-${{ env.AXON_FRAMEWORK_VERSION }}
102110
# Shell type can be skipped if jupyter notebook reports (and therefore conda) aren't needed
103111
shell: bash -el {0}
104-
run: ./../scripts/analysis/analyze.sh --name AxonFramework --version ${{ env.AXON_FRAMEWORK_VERSION }} --report All --profile Neo4jv5
105112
env:
106113
NEO4J_INITIAL_PASSWORD: ${{ secrets.NEO4J_INITIAL_PASSWORD }}
114+
run: |
115+
./../../scripts/analysis/analyze.sh --report All --profile Neo4jv5
107116
108117
- name: Move reports from the temp to the results directory preserving their surrounding directory
109118
working-directory: temp

COMMANDS.md

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,67 @@
22

33
## Start an analysis
44

5-
Use the following commands in the root directory of this repository to start an analysis manually e.g. for [AxonFramework](./scripts/artifacts/downloadAxonFramework.sh).
5+
1. Create a directory for all analysis projects
66

7-
```shell
8-
export NEO4J_INITIAL_PASSWORD=theinitialpasswordthatihavechosenforneo4j
9-
mkdir -p ./temp
10-
cd temp
11-
./../scripts/analysis/analyze.sh --name AxonFramework --version 4.8.0
12-
```
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
1334

14-
Add the command line argument `--report Csv` to only run the CSV reports when you don't have Python set up
15-
or want to skip Jupyter Notebooks.
35+
```shell
36+
./../../scripts/downloader/downloadAxonFramework.sh <version>
37+
```
1638

17-
Add the command line argument `--profile Neo4jv4` if you want to use the older long term support (june 2023)
18-
version v4.4.x of Neo4j and compatible versions of plugins and JQAssistant.
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+
```
46+
47+
👉 See [scripts/examples/analyzeAxonFramework.sh](./scripts/examples/analyzeAxonFramework.sh) as an example script that combines all the above steps.
48+
👉 See [code-reports Pipeline](./.github/workflows/code-reports.yml) on how to do this within a GitHub Actions Workflow.
49+
50+
### Command Line Options
51+
52+
The [analyze.sh](./scripts/analysis/analyze.sh) command comes with these command line options:
53+
54+
- `--report Csv` only generates CSV reports. This speeds up the report generation and doesn't depend on Python, Jupyter Notebook or any other related dependencies. The default value os `All` to generate all reports. `Jupiter` will only generate Jupyter Notebook reports.
55+
56+
- `--profile Neo4jv4` uses the older long term support (june 2023) version v4.4.x of Neo4j and suitable compatible versions of plugins and JQAssistant. `Neo4jv5` will explicitly select the newest (june 2023) version 5.x of Neo4j. Without setting
57+
a profile, the newest versions will be used. Profiles are scripts that can be found in the directory [scripts/profiles](./scripts/profiles/).
58+
59+
- `--explore` activates the "explore" mode where no reports are generated. Furthermore, Neo4j won't be stopped at the end of the script and will therefore continue running. This makes it easy to just set everything up but then use the running Neo4j server to explore the data manually.
1960

2061
### Notes
2162

22-
- Be sure to use Java 11 (Mai 2023 Neo4j v4 requirement) or Java 17 (June 2023 Neo4j v5 and jQAssistant CLI v2)
63+
- Be sure to use Java 17 for Neo4j v5 and Java 11 for Neo4j v4
2364
- Use your own initial Neo4j password
2465
- For more details have a look at the script [analyze.sh](./scripts/analysis/analyze.sh)
25-
- The script file names (without the prefix "download" and without the file extension) in the directory [scripts/artifacts](./scripts/artifacts) provide all analysis names that are available.
26-
27-
28-
Have a look at [code-reports.yml](./.github/workflows/code-reports.yml) for all details about setup steps and full automation.
2966

3067
## Generate Markdown References
3168

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ The [Code Reports Pipeline](./.github/workflows/code-reports.yml) utilizes [GitH
5858
- [Checkout GIT Repository](https://github.com/actions/checkout)
5959
- [Setup Java](https://github.com/actions/setup-java)
6060
- [Setup Python with Conda](https://github.com/conda-incubator/setup-miniconda) package manager [Mambaforge](https://github.com/conda-forge/miniforge#mambaforge)
61+
- Download artifacts that contain the code to be analyzed [scripts/artifacts](./scripts/downloader/)
6162
- Setup [Neo4j](https://neo4j.com) Graph Database ([analysis.sh](./scripts/analysis/analyze.sh))
6263
- Setup [jQAssistant](https://jqassistant.org/get-started) for Java Analysis ([analysis.sh](./scripts/analysis/analyze.sh))
6364
- Start [Neo4j](https://neo4j.com) Graph Database ([analysis.sh](./scripts/analysis/analyze.sh))
64-
- Trigger Artifacts download that contain the code to be analyzed [scripts/artifacts](./scripts/artifacts/)
6565
- Generate CSV Reports [scripts/reports](./scripts/reports) using the command line JSON parser [jq](https://jqlang.github.io/jq)
6666
- Generate [Jupyter Notebook](https://jupyter.org) reports using these libraries specified in the [environment.yml](./jupyter/environment.yml):
6767
- [Python](https://www.python.org)
@@ -97,7 +97,7 @@ The [Code Reports Pipeline](./.github/workflows/code-reports.yml) utilizes [GitH
9797
## 🤔 Questions & Answers
9898

9999
- How can i run an analysis locally?
100-
👉 See [start-an-analysis](./COMMANDS.md#start-an-analysis) in the [Commands Reference](./COMMANDS.md).
100+
👉 See [Start an analysis](./COMMANDS.md#start-an-analysis) in the [Commands Reference](./COMMANDS.md).
101101

102102
- How can i add an CSV report to the pipeline?
103103
👉 Put your new cypher query into the [cypher](./cypher) directory or a suitable (new) sub directory.
@@ -109,12 +109,12 @@ The [Code Reports Pipeline](./.github/workflows/code-reports.yml) utilizes [GitH
109109
👉 Create a new Jupyter report script in the [scripts/reports](./scripts/reports/) directory. Take [OverviewJupyter.sh](./scripts/reports/OverviewJupyter.sh) as a reference for example.
110110
👉 The script will automatically be included because of the directory and its name ending with "Jupyter.sh".
111111

112-
- How can i add another code base to analyze?
113-
👉 Create an new artifacts download script in the [scripts/artifacts](./scripts/artifacts) directory. Take [downloadAxonFramework.](./scripts/artifacts/downloadAxonFramework.sh) as a reference for example.
114-
👉 The script will be triggered when the [analyze](./scripts/analysis/analyze.sh) command
112+
- How can i add another code basis to be analyzed automatically?
113+
👉 Create a new artifacts download script in the [scripts/artifacts](./scripts/artifacts) directory. Take for example [downloadAxonFramework.sh](./scripts/downloader/downloadAxonFramework.sh) as a reference.
114+
👉 Run the script separately before executing [analyze.sh](./scripts/analysis/analyze.sh) also in the [pipeline](./.github/workflows/code-reports.yml).
115115

116116
- How can i trigger a full rescan of all artifacts?
117-
👉 Delete the file `artifactsChangeDetectionHash.txt` in the temporary `artifacts` directory.
117+
👉 Delete the file `artifactsChangeDetectionHash.txt` in the `artifacts` directory.
118118

119119
- How can PDF generation be skipped to speed up report generation and not depend on chromium?
120120
👉 Set environment variable `SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION` to anything except an empty string. Example:

scripts/SCRIPTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ It provides a table listing each script file and its corresponding description f
66
Script | Directory | Description
77
-------|-----------|------------
88
| [analyze.sh](./analysis/analyze.sh) | analysis | Coordinates the end-to-end analysis process, encompassing tool installation, graph generation, and report generation. |
9-
| [downloadAxonFramework.sh](./artifacts/downloadAxonFramework.sh) | artifacts | Downloads AxonFramework (https://developer.axoniq.io/axon-framework) artifacts from Maven Central. |
109
| [copyReportsIntoResults.sh](./copyReportsIntoResults.sh) | | Copies the results from the temp directory to the results directory grouped by the analysis name. |
1110
| [detectChangedArtifacts.sh](./detectChangedArtifacts.sh) | | Detect changed files in the artifacts directory with a text file containing the last hash code of the contents. |
1211
| [downloadMavenArtifact.sh](./downloadMavenArtifact.sh) | | Downloads an artifact from Maven Central (https://mvnrepository.com/repos/central) |
12+
| [downloadAxonFramework.sh](./downloader/downloadAxonFramework.sh) | downloader | Downloads AxonFramework (https://developer.axoniq.io/axon-framework) artifacts from Maven Central. |
1313
| [executeJupyterNotebook.sh](./executeJupyterNotebook.sh) | | Executes all steps in the given Jupyter Notebook (ipynb), stores it and converts it to Markdown (md) and PDF. |
1414
| [executeQuery.sh](./executeQuery.sh) | | Utilizes Neo4j's HTTP API to execute a Cypher query from an input file and provides the results in CSV format. |
1515
| [executeQueryFunctions.sh](./executeQueryFunctions.sh) | | Provides functions to execute Cypher queries using either "executeQuery.sh" or Neo4j's "cypher-shell". |

scripts/analysis/analyze.sh

Lines changed: 40 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,14 @@
22

33
# Coordinates the end-to-end analysis process, encompassing tool installation, graph generation, and report generation.
44
# - Download and setup Neo4j and JQAssistant
5-
# - Trigger artifacts download
6-
# - Scan and analyze the artifacts to create the graph
5+
# - Scan and analyze the contents of the artifacts directory to create the graph
76
# - Trigger all requested reports
87

9-
# Note: Everything is done in the current directory.
10-
# It is recommended to create an empty directory (preferrable "temp")
8+
# Note: Everything is done in the current (=working) directory and one directory above (shared downloads).
9+
# It is recommended to create an empty directory (preferrable "temp") and
10+
# within that another one for the analysis (e.g. "MyCodebaseName-Version")
1111
# and change into it prior to starting this script.
1212

13-
# Note: The argument "--name" is requried. It is used to create the working directory
14-
# as well as to find the script "scripts/artifacts/download<name>.sh" to download the artifacts.
15-
16-
# Note: The argument "--version" is also required.
17-
# It is appended to the working directory to further distinguish the results.
18-
# The version is passed to the artifacts download script as an argument.
19-
2013
# Note: The argument "--report" is optional. The default value is "All".
2114
# It selects the report compilation, a named group of reports. Besides the default "All" there are e.g. "Csv" and "Jupyter".
2215
# This makes it possible to run only a subset of the reports. For example "Csv" won't need python to be set up and runs therefore much faster.
@@ -27,38 +20,35 @@
2720
# This makes it possible to run an analysis with e.g. Neo4j v4 instead of v5. Further profiles might come in future.
2821
# Implemented is this as a script in "scripts/profiles" that starts with the settings profile name followed by ".sh".
2922

23+
# Note: The argument "--explore" is optional. It is a switch that is deactivated by default.
24+
# It activates "explore" mode where no reports are executed and Neo4j keeps running (skip stop step).
25+
# This makes it easy to just set everything up but then use the running Neo4j server to explore the data manually.
26+
3027
# Note: The script and its sub scripts are designed to be as efficient as possible
3128
# when it comes to subsequent executions.
32-
# Existing downloads, installations, artifacts, scans and processes will be detected.
29+
# Existing downloads, installations, scans and processes will be detected.
3330

3431
# Overrideable variables with directory names
35-
ARTIFACT_SCRIPTS_DIRECTORY=${ARTIFACT_SCRIPTS_DIRECTORY:-"artifacts"}
3632
REPORTS_SCRIPTS_DIRECTORY=${REPORTS_SCRIPTS_DIRECTORY:-"reports"}
3733
REPORT_COMPILATIONS_SCRIPTS_DIRECTORY=${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY:-"compilations"}
3834
SETTINGS_PROFILE_SCRIPTS_DIRECTORY=${SETTINGS_PROFILE_SCRIPTS_DIRECTORY:-"profiles"}
35+
ARTIFACTS_DIRECTORY=${ARTIFACTS_DIRECTORY:-"artifacts"}
3936

4037
# Function to display script usage
4138
usage() {
42-
echo "Usage: $0 --name <name> --version <version> [--report <All (default), Csv, Jupyter,...>] [--profile <Default, Neo4jv5, Neo4jv4,...>]"
39+
echo "Usage: $0 [--report <All (default), Csv, Jupyter,...>] [--profile <Default, Neo4jv5, Neo4jv4,...>] [--explore]"
4340
exit 1
4441
}
4542

4643
# Default values
4744
analysisReportCompilation="All"
4845
settingsProfile="Default"
46+
exploreMode=false
4947

5048
# Parse command line arguments
5149
while [[ $# -gt 0 ]]; do
5250
key="$1"
5351
case $key in
54-
--name)
55-
analysisName="${2}"
56-
shift
57-
;;
58-
--version)
59-
analysisVersion="$2"
60-
shift
61-
;;
6252
--report)
6353
analysisReportCompilation="$2"
6454
shift
@@ -67,6 +57,10 @@ while [[ $# -gt 0 ]]; do
6757
settingsProfile="$2"
6858
shift
6959
;;
60+
--explore)
61+
exploreMode=true
62+
shift
63+
;;
7064
*)
7165
echo "analyze: Error: Unknown option: ${key}"
7266
usage
@@ -75,101 +69,74 @@ while [[ $# -gt 0 ]]; do
7569
shift
7670
done
7771

78-
# Check if the name is provided
79-
if [[ -z ${analysisName} ]]; then
80-
echo "analyze ${analysisName}: Error: Name is required."
81-
usage
82-
fi
83-
84-
# Check if the version is provided
85-
if [[ -z ${analysisVersion} ]]; then
86-
echo "analyze ${analysisName}: Error: Version is required."
87-
usage
88-
fi
89-
90-
# Assure that the analysis name only consists of letters and numbers
91-
if ! [[ ${analysisName} =~ ^[[:alnum:]]+$ ]]; then
92-
echo "analyze ${analysisName}: Error: Name can only contain letters and numbers."
93-
exit 1
94-
fi
95-
9672
# Assure that the analysis report compilation only consists of letters and numbers
9773
if ! [[ ${analysisReportCompilation} =~ ^[[:alnum:]]+$ ]]; then
98-
echo "analyze ${analysisName}: Report can only contain letters and numbers."
74+
echo "analyze: Report can only contain letters and numbers."
9975
exit 1
10076
fi
10177

10278
# Assure that the settings profile only consists of letters and numbers
10379
if ! [[ ${settingsProfile} =~ ^[[:alnum:]]+$ ]]; then
104-
echo "analyze ${analysisName}: Error: Settings profile can only contain letters and numbers."
80+
echo "analyze: Error: Settings profile can only contain letters and numbers."
10581
exit 1
10682
fi
10783

84+
# Check if Neo4j is installed
85+
if [ ! -d "${ARTIFACTS_DIRECTORY}" ] ; then
86+
echo "analyze: The ${ARTIFACTS_DIRECTORY} directory doesn't exist. Please download artifacts first."
87+
exit 1
88+
fi
89+
10890
## Get this "scripts/analysis" directory if not already set
10991
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
11092
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
11193
# This way non-standard tools like readlink aren't needed.
11294
ANALYSIS_SCRIPT_DIR=${ANALYSIS_SCRIPT_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )}
113-
echo "analyze ${analysisName}: ANALYSIS_SCRIPT_DIR=${ANALYSIS_SCRIPT_DIR}"
95+
echo "analyze: ANALYSIS_SCRIPT_DIR=${ANALYSIS_SCRIPT_DIR}"
11496

11597
# Get the "scripts" directory by taking the path of this script and going one directory up.
11698
SCRIPTS_DIR=${SCRIPTS_DIR:-$(dirname -- "${ANALYSIS_SCRIPT_DIR}")}
117-
echo "analyze ${analysisName}: SCRIPTS_DIR=${SCRIPTS_DIR}"
118-
119-
# Assure that there is a download script for the given analysis name argument.
120-
DOWNLOAD_SCRIPT="${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY}/download${analysisName}.sh"
121-
if [ ! -f "${DOWNLOAD_SCRIPT}" ] ; then
122-
echo "analyze ${analysisName}: Error: No download${analysisName}.sh script in the directory ${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY} for analysis name ${analysisName}."
123-
exit 1
124-
fi
99+
echo "analyze: SCRIPTS_DIR=${SCRIPTS_DIR}"
125100

126101
# Assure that there is a report compilation script for the given report argument.
127102
REPORT_COMPILATION_SCRIPT="${SCRIPTS_DIR}/${REPORTS_SCRIPTS_DIRECTORY}/${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY}/${analysisReportCompilation}Reports.sh"
128103
if [ ! -f "${REPORT_COMPILATION_SCRIPT}" ] ; then
129-
echo "analyze ${analysisName}: Error: No ${analysisReportCompilation}Reports.sh script in the directory ${SCRIPTS_DIR}/${REPORTS_SCRIPTS_DIRECTORY}/${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY} for report name ${analysisReportCompilation}."
104+
echo "analyze: Error: No ${analysisReportCompilation}Reports.sh script in the directory ${SCRIPTS_DIR}/${REPORTS_SCRIPTS_DIRECTORY}/${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY} for report name ${analysisReportCompilation}."
130105
exit 1
131106
fi
132107

133108
# Assure that there is a script file for the given settings profile name.
134109
SETTINGS_PROFILE_SCRIPT="${SCRIPTS_DIR}/${SETTINGS_PROFILE_SCRIPTS_DIRECTORY}/${settingsProfile}.sh"
135110
if [ ! -f "${SETTINGS_PROFILE_SCRIPT}" ] ; then
136-
echo "analyze ${analysisName}: Error: No ${settingsProfile}.sh script in the directory ${SCRIPTS_DIR}/${SETTINGS_PROFILE_SCRIPTS_DIRECTORY} for settings profile ${settingsProfile}."
111+
echo "analyze: Error: No ${settingsProfile}.sh script in the directory ${SCRIPTS_DIR}/${SETTINGS_PROFILE_SCRIPTS_DIRECTORY} for settings profile ${settingsProfile}."
137112
exit 1
138113
fi
139114

140115
# Execute the settings profile script that sets all the neccessary settings variables (overrideable by environment variables).
141-
echo "analyze ${analysisName}: Using analysis settings profile script ${SETTINGS_PROFILE_SCRIPT}"
142-
source "${SETTINGS_PROFILE_SCRIPT}" || exit 1
143-
144-
# Create working directory if it hadn't been created yet
145-
workingDirectory="${analysisName}-${analysisVersion}"
146-
mkdir -p "${workingDirectory}" || exit 2 # Create the working directory only if it doesn't exist
147-
pushd "${workingDirectory}" || exit 2 # Change into the working directory and remember the previous directory
148-
echo "analyze ${analysisName}: Working Directory: $( pwd -P )"
116+
echo "analyze: Using analysis settings profile script ${SETTINGS_PROFILE_SCRIPT}"
117+
source "${SETTINGS_PROFILE_SCRIPT}" || exit 2
149118

150119
# Setup Tools
151120
source "${SCRIPTS_DIR}/setupNeo4j.sh" || exit 3
152121
source "${SCRIPTS_DIR}/setupJQAssistant.sh" || exit 3
153122
source "${SCRIPTS_DIR}/startNeo4j.sh" || exit 3
154123

155-
# Execute the script "scripts/artifacts/download<analysisName" to download the artifacts that should be analyzed
156-
echo "Downloading artifacts with ${DOWNLOAD_SCRIPT} ..."
157-
source "${DOWNLOAD_SCRIPT}" "${analysisVersion}" || exit 4
158-
159124
# Scan and analyze artifacts when they were changed
160-
source "${SCRIPTS_DIR}/resetAndScanChanged.sh" || exit 5
125+
source "${SCRIPTS_DIR}/resetAndScanChanged.sh" || exit 4
161126

162127
# Prepare and validate graph database before analyzing and creating reports
163-
source "${SCRIPTS_DIR}/prepareAnalysis.sh" || exit 6
128+
source "${SCRIPTS_DIR}/prepareAnalysis.sh" || exit 5
129+
130+
if ${exploreMode}; then
131+
echo "analyze: Explore mode activated. Report generation will be skipped. Neo4j keeps running."
132+
exit 0
133+
fi
164134

165135
#########################
166136
# Create Reports
167137
#########################
168-
echo "Creating Reports with ${REPORT_COMPILATION_SCRIPT} ..."
169-
source "${REPORT_COMPILATION_SCRIPT}" || exit 7
138+
echo "analyze: Creating Reports with ${REPORT_COMPILATION_SCRIPT} ..."
139+
source "${REPORT_COMPILATION_SCRIPT}" || exit 6
170140

171141
# Stop Neo4j at the end
172-
source "${SCRIPTS_DIR}/stopNeo4j.sh"
173-
174-
# Change back to the previous directory where the script was started
175-
popd || exit 8
142+
source "${SCRIPTS_DIR}/stopNeo4j.sh"

0 commit comments

Comments
 (0)