Skip to content

Commit 835b0d6

Browse files
authored
Merge pull request #6 from JohT/feature/support-neo4j-v5
Support Neo4j v5 and jQAssistant CLI 2.0
2 parents 5a542b6 + 717e480 commit 835b0d6

29 files changed

+1037
-192
lines changed

.github/workflows/code-reports.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
matrix:
4343
include:
4444
- os: ubuntu-latest
45-
java: 11
45+
java: 17
4646
python: 3.11
4747
mambaforge: 23.1.0-1
4848

COMMANDS.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,27 @@
44

55
Use the following commands in the root directory of this repository to start an analysis manually e.g. for [AxonFramework](./scripts/artifacts/downloadAxonFramework.sh).
66

7-
### Notes
8-
9-
- Be sure to use Java 11 (June 2023 Neo4j 4.x requirement)
10-
- Use your own initial Neo4j password
11-
- It uses the script [analyze.sh](./scripts/analysis/analyze.sh)
12-
- The script file names (without the prefix "download" and without the file extension) in the directory [scripts/artifacts](./scripts/artifacts) provide the possible analysis names.
13-
14-
157
```shell
168
export NEO4J_INITIAL_PASSWORD=theinitialpasswordthatihavechosenforneo4j
179
mkdir -p ./temp
18-
./../scripts/analysis/analyze.sh --name AxonFramework --version 4.7.5 --report All
10+
cd temp
11+
./../scripts/analysis/analyze.sh --name AxonFramework --version 4.8.0
1912
```
2013

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.
16+
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.
19+
20+
### Notes
21+
22+
- Be sure to use Java 11 (Mai 2023 Neo4j v4 requirement) or Java 17 (June 2023 Neo4j v5 and jQAssistant CLI v2)
23+
- Use your own initial Neo4j password
24+
- 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+
2128
Have a look at [code-reports.yml](./.github/workflows/code-reports.yml) for all details about setup steps and full automation.
2229

2330
## Generate Markdown References

JQAssistantGraphDatabaseCompatibilityIssues.md

Lines changed: 161 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ The [Code Reports Pipeline](./.github/workflows/code-reports.yml) utilizes [GitH
9797

9898
## 🤔 Questions & Answers
9999

100+
- How can i run an analysis locally?
101+
👉 See [start-an-analysis](./COMMANDS.md#start-an-analysis) in the [Commands Reference](./COMMANDS.md).
102+
100103
- How can i add an CSV report to the pipeline?
101104
👉 Put your new cypher query into the [cypher](./cypher) directory or a suitable (new) sub directory.
102105
👉 Create a new CSV report script in the [scripts/reports](./scripts/reports/) directory. Take for example [OverviewCsv.sh](./scripts/reports/OverviewCsv.sh) as a reference.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Count nodes and relationships
2+
3+
MATCH (n)-[r]-(m)
4+
RETURN COUNT(DISTINCT n) AS nodeCount
5+
,COUNT(DISTINCT r) AS relationshipCount
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Create a DEPENDS_ON relationship for every DEPENDS_ON_ARTIFACT
2+
3+
MATCH (a:Artifact)-[existing:DEPENDS_ON_ARTIFACT]->(b:Artifact)
4+
MERGE (a)-[created:DEPENDS_ON]->(b)
5+
WITH count(existing) as numberOfExistingRelations
6+
,count(created) as numberOfCreatedRelations
7+
RETURN numberOfExistingRelations, numberOfCreatedRelations
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Create a DEPENDS_ON relationship for every DEPENDS_ON_PACKAGE
2+
3+
MATCH (a:Package)-[existing:DEPENDS_ON_PACKAGE]->(b:Package)
4+
MERGE (a)-[created:DEPENDS_ON]->(b)
5+
WITH count(existing) as numberOfExistingRelations
6+
,count(created) as numberOfCreatedRelations
7+
RETURN numberOfExistingRelations, numberOfCreatedRelations

scripts/SCRIPTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ Script | Directory | Description
1616
| [generateCypherReference.sh](./generateCypherReference.sh) | | Generates "CYPHER.md" containing a reference to all Cypher files in this directory and its subdirectories. |
1717
| [generateMarkdownReference.sh](./generateMarkdownReference.sh) | | Generates "REPORTS.md" containing a reference to all scripts in this directory and its subdirectories. |
1818
| [generateScriptReference.sh](./generateScriptReference.sh) | | Generates "SCRIPTS.md" containing a reference to all scripts in this directory and its subdirectories. |
19+
| [prepareAnalysis.sh](./prepareAnalysis.sh) | | Prepares and validates the graph database before analysis |
20+
| [Default.sh](./profiles/Default.sh) | profiles | Sets (if any) settings variables for a default analysis. |
21+
| [Neo4jv4.sh](./profiles/Neo4jv4.sh) | profiles | Sets all settings variables for an analysis with Neo4j v4.4.x (long term support (LTS) version as of may 2023). |
22+
| [Neo4jv5.sh](./profiles/Neo4jv5.sh) | profiles | Sets all settings variables for an analysis with Neo4j v5.x (newest version as of june 2023). |
1923
| [CentralityCsv.sh](./reports/CentralityCsv.sh) | reports | Looks for centrality using the Graph Data Science Library of Neo4j and creates CSV reports. |
2024
| [CommunityCsv.sh](./reports/CommunityCsv.sh) | reports | Detects communities using the Graph Data Science Library of Neo4j and creates CSV reports. |
25+
| [DatabaseCsvExport.sh](./reports/DatabaseCsvExport.sh) | reports | Exports the whole graph database as a CSV file using the APOC procedure "apoc.export.csv.all" |
2126
| [ExternalDependenciesCsv.sh](./reports/ExternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. |
2227
| [ExternalDependenciesJupyter.sh](./reports/ExternalDependenciesJupyter.sh) | reports | Creates the "overview" report (ipynb, md, pdf) based on the Jupyter Notebook "Overview.ipynb". |
2328
| [ObjectOrientedDesignMetricsCsv.sh](./reports/ObjectOrientedDesignMetricsCsv.sh) | reports | Executes "Metrics" Cypher queries to get the "object-oriented-design-metrics" CSV reports. |
@@ -35,6 +40,7 @@ Script | Directory | Description
3540
| [JupyterReports.sh](./reports/compilations/JupyterReports.sh) | compilations | Runs all Jupyter Notebook report scripts. |
3641
| [resetAndScan.sh](./resetAndScan.sh) | | Deletes all data in the Neo4j graph database and rescans the downloaded artifacts to create a new graph. |
3742
| [resetAndScanChanged.sh](./resetAndScanChanged.sh) | | Executes "resetAndScan.sh" only if "detectChangedArtifacts.sh" returns detected changes. |
43+
| [resetAndScanMemgraph.sh](./resetAndScanMemgraph.sh) | | Deletes all data in the Neo4j graph database and rescans the downloaded artifacts to create a new graph. |
3844
| [setupJQAssistant.sh](./setupJQAssistant.sh) | | Installs (download and unzip) jQAssistant (https://jqassistant.org/get-started). |
3945
| [setupNeo4j.sh](./setupNeo4j.sh) | | Installs (download, unpack, get plugins, configure) a local Neo4j Graph Database (https://neo4j.com/download-center/#community). |
4046
| [setupNeo4jInitialPassword.sh](./setupNeo4jInitialPassword.sh) | | Sets the initial password for the local Neo4j Graph Database (https://neo4j.com/download-center/#community). |

scripts/analysis/analyze.sh

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,42 @@
1010
# It is recommended to create an empty directory (preferrable "temp")
1111
# and change into it prior to starting this script.
1212

13-
# Note: The first argument "--name" is requried. It is used to create the working directory
13+
# Note: The argument "--name" is requried. It is used to create the working directory
1414
# as well as to find the script "scripts/artifacts/download<name>.sh" to download the artifacts.
1515

16-
# Note: The second argument "--version" is optional.
16+
# Note: The argument "--version" is also required.
1717
# 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+
20+
# Note: The argument "--report" is optional. The default value is "All".
21+
# It selects the report compilation, a named group of reports. Besides the default "All" there are e.g. "Csv" and "Jupyter".
22+
# 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.
23+
# Implemented is this as a script in "scripts/reports/compilations" that starts with the report compilation name followed by "Reports.sh".
24+
25+
# Note: The argument "--profile" is optional. The default value is "Default".
26+
# It selects a settings profile that sets all suitable variables for the analysis.
27+
# This makes it possible to run an analysis with e.g. Neo4j v4 instead of v5. Further profiles might come in future.
28+
# Implemented is this as a script in "scripts/profiles" that starts with the settings profile name followed by ".sh".
1829

1930
# Note: The script and its sub scripts are designed to be as efficient as possible
2031
# when it comes to subsequent executions.
2132
# Existing downloads, installations, artifacts, scans and processes will be detected.
2233

23-
# Overrideable environment variables (optional, defaults also defined in sub scripts where needed)
24-
NEO4J_EDITION=${NEO4J_EDITION:-"community"} # Choose "community" or "enterprise"
25-
NEO4J_VERSION=${NEO4J_VERSION:-"4.4.20"} # Version 4.4.x is the current long term support (LTS) version (may 2023)
26-
JQASSISTANT_CLI_VERSION=${JQASSISTANT_CLI_VERSION:-"1.12.2"} # Version 1.12.2 is the current version (may 2023)
27-
28-
# Overrideable environment variables for ports (optional, defaults also defined in sub scripts where needed)
29-
# Override them if you need to run multiple neo4j database servers in parallel.
30-
NEO4J_HTTP_PORT=${NEO4J_HTTP_PORT:-"7474"}
31-
NEO4J_HTTPS_PORT=${NEO4J_HTTPS_PORT:-"7473"}
32-
NEO4J_BOLT_PORT=${NEO4J_BOLT_PORT:-"7687"}
33-
34+
# Overrideable variables with directory names
3435
ARTIFACT_SCRIPTS_DIRECTORY=${ARTIFACT_SCRIPTS_DIRECTORY:-"artifacts"}
3536
REPORTS_SCRIPTS_DIRECTORY=${REPORTS_SCRIPTS_DIRECTORY:-"reports"}
3637
REPORT_COMPILATIONS_SCRIPTS_DIRECTORY=${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY:-"compilations"}
38+
SETTINGS_PROFILE_SCRIPTS_DIRECTORY=${SETTINGS_PROFILE_SCRIPTS_DIRECTORY:-"profiles"}
3739

3840
# Function to display script usage
3941
usage() {
40-
echo "Usage: $0 --name <name> --version <version> [--report <All (default), Csv, Jupyter,...>]"
42+
echo "Usage: $0 --name <name> --version <version> [--report <All (default), Csv, Jupyter,...>] [--profile <Default, Neo4jv5, Neo4jv4,...>]"
4143
exit 1
4244
}
4345

4446
# Default values
4547
analysisReportCompilation="All"
48+
settingsProfile="Default"
4649

4750
# Parse command line arguments
4851
while [[ $# -gt 0 ]]; do
@@ -60,8 +63,12 @@ while [[ $# -gt 0 ]]; do
6063
analysisReportCompilation="$2"
6164
shift
6265
;;
66+
--profile)
67+
settingsProfile="$2"
68+
shift
69+
;;
6370
*)
64-
echo "Error (analyze): Unknown option: ${key}"
71+
echo "analyze: Error: Unknown option: ${key}"
6572
usage
6673
;;
6774
esac
@@ -70,25 +77,31 @@ done
7077

7178
# Check if the name is provided
7279
if [[ -z ${analysisName} ]]; then
73-
echo "Error (analyze): Name is required."
80+
echo "analyze ${analysisName}: Error: Name is required."
7481
usage
7582
fi
7683

7784
# Check if the version is provided
7885
if [[ -z ${analysisVersion} ]]; then
79-
echo "Error (analyze): Version is required."
86+
echo "analyze ${analysisName}: Error: Version is required."
8087
usage
8188
fi
8289

8390
# Assure that the analysis name only consists of letters and numbers
8491
if ! [[ ${analysisName} =~ ^[[:alnum:]]+$ ]]; then
85-
echo "Error (analyze): Name can only contain letters and numbers."
92+
echo "analyze ${analysisName}: Error: Name can only contain letters and numbers."
8693
exit 1
8794
fi
8895

8996
# Assure that the analysis report compilation only consists of letters and numbers
9097
if ! [[ ${analysisReportCompilation} =~ ^[[:alnum:]]+$ ]]; then
91-
echo "Error (analyze): Report can only contain letters and numbers."
98+
echo "analyze ${analysisName}: Report can only contain letters and numbers."
99+
exit 1
100+
fi
101+
102+
# Assure that the settings profile only consists of letters and numbers
103+
if ! [[ ${settingsProfile} =~ ^[[:alnum:]]+$ ]]; then
104+
echo "analyze ${analysisName}: Error: Settings profile can only contain letters and numbers."
92105
exit 1
93106
fi
94107

@@ -103,26 +116,31 @@ echo "analyze ${analysisName}: ANALYSIS_SCRIPT_DIR=${ANALYSIS_SCRIPT_DIR}"
103116
SCRIPTS_DIR=${SCRIPTS_DIR:-$(dirname -- "${ANALYSIS_SCRIPT_DIR}")}
104117
echo "analyze ${analysisName}: SCRIPTS_DIR=${SCRIPTS_DIR}"
105118

106-
# Assure that there is a download script for the given analysis name.
107-
if [ ! -f "${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY}/download${analysisName}.sh" ] ; then
108-
echo "Error (analyze): No download${analysisName}.sh script in the directory ${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY} for analysis name ${analysisName}."
109-
exit 1
110-
fi
111-
112119
# Assure that there is a download script for the given analysis name argument.
113120
DOWNLOAD_SCRIPT="${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY}/download${analysisName}.sh"
114121
if [ ! -f "${DOWNLOAD_SCRIPT}" ] ; then
115-
echo "Error (analyze): No download${analysisName}.sh script in the directory ${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY} for analysis name ${analysisName}."
122+
echo "analyze ${analysisName}: Error: No download${analysisName}.sh script in the directory ${SCRIPTS_DIR}/${ARTIFACT_SCRIPTS_DIRECTORY} for analysis name ${analysisName}."
116123
exit 1
117124
fi
118125

119126
# Assure that there is a report compilation script for the given report argument.
120127
REPORT_COMPILATION_SCRIPT="${SCRIPTS_DIR}/${REPORTS_SCRIPTS_DIRECTORY}/${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY}/${analysisReportCompilation}Reports.sh"
121128
if [ ! -f "${REPORT_COMPILATION_SCRIPT}" ] ; then
122-
echo "Error (analyze): No ${analysisReportCompilation}Reports.sh script in the directory ${SCRIPTS_DIR}/${REPORTS_SCRIPTS_DIRECTORY}/${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY} for report name ${analysisReportCompilation}."
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}."
130+
exit 1
131+
fi
132+
133+
# Assure that there is a script file for the given settings profile name.
134+
SETTINGS_PROFILE_SCRIPT="${SCRIPTS_DIR}/${SETTINGS_PROFILE_SCRIPTS_DIRECTORY}/${settingsProfile}.sh"
135+
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}."
123137
exit 1
124138
fi
125139

140+
# 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+
126144
# Create working directory if it hadn't been created yet
127145
workingDirectory="${analysisName}-${analysisVersion}"
128146
mkdir -p "${workingDirectory}" || exit 2 # Create the working directory only if it doesn't exist
@@ -141,14 +159,17 @@ source "${DOWNLOAD_SCRIPT}" "${analysisVersion}" || exit 4
141159
# Scan and analyze artifacts when they were changed
142160
source "${SCRIPTS_DIR}/resetAndScanChanged.sh" || exit 5
143161

162+
# Prepare and validate graph database before analyzing and creating reports
163+
source "${SCRIPTS_DIR}/prepareAnalysis.sh" || exit 6
164+
144165
#########################
145166
# Create Reports
146167
#########################
147168
echo "Creating Reports with ${REPORT_COMPILATION_SCRIPT} ..."
148-
source "${REPORT_COMPILATION_SCRIPT}" || exit 6
169+
source "${REPORT_COMPILATION_SCRIPT}" || exit 7
149170

150171
# Stop Neo4j at the end
151172
source "${SCRIPTS_DIR}/stopNeo4j.sh"
152173

153174
# Change back to the previous directory where the script was started
154-
popd || exit 7
175+
popd || exit 8

scripts/executeQuery.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
# Overrideable Defaults
1717
NEO4J_HTTP_PORT=${NEO4J_HTTP_PORT:-"7474"}
18+
NEO4J_HTTP_TRANSACTION_ENDPOINT=${NEO4J_HTTP_TRANSACTION_ENDPOINT:-"db/neo4j/tx/commit"} # Neo4j v5: "db/<name>/tx/commit", Neo4j v4: "db/data/transaction/commit",
1819

1920
# Check if environment variable is set
2021
if [ -z "${NEO4J_INITIAL_PASSWORD}" ]; then
@@ -85,7 +86,7 @@ cypher_query_for_api="{\"statements\":[{\"statement\":${cypher_query},\"includeS
8586
# Calls the Neo4j HTTP API using cURL ( https://curl.se )
8687
cyper_query_result=$(curl --silent -S --fail-with-body -H Accept:application/json -H Content-Type:application/json \
8788
-u neo4j:"${NEO4J_INITIAL_PASSWORD}" \
88-
"http://localhost:${NEO4J_HTTP_PORT}/db/data/transaction/commit" \
89+
"http://localhost:${NEO4J_HTTP_PORT}/${NEO4J_HTTP_TRANSACTION_ENDPOINT}" \
8990
-d "${cypher_query_for_api}")
9091
#echo "Cypher Query Result: $cyper_query_result"
9192

0 commit comments

Comments
 (0)