Skip to content

Commit ff7111d

Browse files
authored
Merge pull request #54 from JohT/feature/fail-fast-error-handling
Improve error handling using a fail-fast approach
2 parents 6fca29e + 8fe4165 commit ff7111d

File tree

57 files changed

+282
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+282
-96
lines changed

.github/workflows/code-structure-analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ jobs:
121121
shell: bash -el {0}
122122
env:
123123
NEO4J_INITIAL_PASSWORD: ${{ secrets.NEO4J_INITIAL_PASSWORD }}
124+
ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION: "true"
124125
run: |
125126
./../../scripts/analysis/analyze.sh
126127
@@ -136,7 +137,6 @@ jobs:
136137
name: code-analysis-logs-java-${{ matrix.java }}-python-${{ matrix.python }}-mambaforge-${{ matrix.mambaforge }}
137138
path: |
138139
./temp/**/runtime/*
139-
./results
140140
retention-days: 5
141141

142142
# Upload successful results in case they are needed for troubleshooting

COMMANDS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ If only the Jupyter reports are needed e.g. when the CSV reports had already bee
8383
./../../scripts/analysis/analyze.sh --report Jupyter
8484
```
8585
86-
#### Start an analysis without PDF generation
86+
#### Start an analysis with PDF generation
8787
88-
Generating a PDF from a Jupyter notebook using [nbconvert](https://nbconvert.readthedocs.io) might take a while or even fail due to a timeout error. Here is an example on how to skip PDF generation:
88+
Note: Generating a PDF from a Jupyter notebook using [nbconvert](https://nbconvert.readthedocs.io) takes some time and might even fail due to a timeout error.
8989
9090
```shell
91-
SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION=true ./../../scripts/analysis/analyze.sh
91+
ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION=true ./../../scripts/analysis/analyze.sh
9292
```
9393
9494
#### Setup everything to explore the graph manually

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ The [Code Structure Analysis Pipeline](./.github/workflows/code-structure-analys
124124
- How can i trigger a full rescan of all artifacts?
125125
👉 Delete the file `artifactsChangeDetectionHash.txt` in the `artifacts` directory.
126126

127-
- How can PDF generation be skipped to speed up report generation and not depend on chromium?
128-
👉 Set environment variable `SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION` to anything except an empty string. Example:
127+
- How can PDF generation for Jupyter Notebooks be enabled (depends on chromium, takes more time)?
128+
👉 Set environment variable `ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION` to anything except an empty string. Example:
129129

130130
```shell
131-
export SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION="true"
131+
export ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION="true"
132132
```
133133

134-
👉 Or prepend your command with `SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION="true"` like:
134+
👉 Alternatively prepend your command with `ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION="true"` like:
135135

136136
```shell
137-
SKIP_JUPYTER_NOTEBOOK_PDF_GENERATION=true ./../../scripts/analysis/analyze.sh
137+
ENABLE_JUPYTER_NOTEBOOK_PDF_GENERATION=true ./../../scripts/analysis/analyze.sh
138138
```

cypher/Community_Detection/Community_Detection_7d_Modularity_Members.cypher

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ CALL gds.modularity.stream(
66
,communityProperty: $dependencies_projection_write_property
77
})
88
YIELD communityId, modularity
9-
WITH communityId, modularity
9+
WITH collect({communityId: communityId, modularity: modularity}) AS modularities
1010
MATCH (member)
11-
WHERE member[$dependencies_projection_write_property] = communityId
11+
WHERE member[$dependencies_projection_write_property] IS NOT NULL
1212
AND $dependencies_projection_node IN LABELS(member)
13-
WITH communityId
14-
,modularity
13+
WITH modularities
14+
,member[$dependencies_projection_write_property] AS communityId
1515
,coalesce(member.fqn, member.fileName, member.name) AS memberName
1616
,coalesce(member.name, replace(last(split(member.fileName, '/')), '.jar', '')) AS shortMemberName
17-
RETURN communityId
18-
,modularity
17+
WITH modularities
18+
,communityId
1919
,count(DISTINCT memberName) AS memberCount
2020
,collect(DISTINCT shortMemberName) AS shortMemberNames
2121
,collect(DISTINCT memberName) AS memberNames
22+
,reduce(memberModularity = 0, modularity IN modularities |
23+
CASE modularity.communityId WHEN communityId THEN modularity.modularity
24+
ELSE memberModularity END) AS memberModularity
25+
RETURN communityId
26+
,memberModularity
27+
,memberCount
28+
,shortMemberNames
29+
,memberNames
2230
ORDER BY communityId ASCENDING
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
// Community Detection Write Modularity
1+
// Community Detection Modularity Write
22

33
CALL gds.modularity.stream(
44
$dependencies_projection + '-without-empty', {
55
relationshipWeightProperty: $dependencies_projection_weight_property
66
,communityProperty: $dependencies_projection_write_property
77
})
88
YIELD communityId, modularity
9-
WITH communityId, modularity
9+
WITH collect({communityId: communityId, modularity: modularity}) AS modularities
1010
MATCH (member)
11-
WHERE member[$dependencies_projection_write_property] = communityId
11+
WHERE member[$dependencies_projection_write_property] IS NOT NULL
1212
AND $dependencies_projection_node IN LABELS(member)
13-
CALL apoc.create.setProperty(member, $dependencies_projection_write_property + 'Modularity', modularity)
13+
WITH modularities
14+
,member
15+
,reduce(memberModularity = 0, modularity IN modularities |
16+
CASE modularity.communityId WHEN member[$dependencies_projection_write_property] THEN modularity.modularity
17+
ELSE memberModularity END) AS memberModularity
18+
CALL apoc.create.setProperty(member, $dependencies_projection_write_property + 'Modularity', memberModularity)
1419
YIELD node
15-
RETURN count(DISTINCT node) AS writtenModularityNodes;
20+
RETURN count(DISTINCT node) AS writtenModularityNodes

cypher/Community_Detection/Compare_Louvain_vs_Leiden_Results.cypher

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
MATCH (member)
44
WHERE $dependencies_projection_node IN LABELS(member)
5+
AND member.louvainCommunityId IS NOT NULL
6+
AND member.leidenCommunityId IS NOT NULL
57
WITH member.communityLouvainId AS louvainCommunityId
68
,member.communityLeidenId AS leidenCommunityId
79
,coalesce(member.fqn, member.fileName, member.signature, member.name) AS memberName
810
,coalesce(member.name, replace(last(split(member.fileName, '/')), '.jar', '')) AS shortMemberName
9-
WHERE louvainCommunityId IS NOT NULL
10-
AND leidenCommunityId IS NOT NULL
1111
WITH louvainCommunityId
1212
,leidenCommunityId
1313
,collect(DISTINCT shortMemberName) AS shortMemberNames

scripts/analysis/analyze.sh

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030

3131
# Requires setupNeo4j.sh,setupJQAssistant.sh,startNeo4j.sh,resetAndScanChanged.sh,prepareAnalysis.sh,stopNeo4j.sh,comilations/*.sh,profiles/*.sh
3232

33+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
34+
set -eo pipefail
35+
3336
# Overrideable variables with directory names
3437
REPORTS_SCRIPTS_DIRECTORY=${REPORTS_SCRIPTS_DIRECTORY:-"reports"} # Working directory containing the generated reports
3538
REPORT_COMPILATIONS_SCRIPTS_DIRECTORY=${REPORT_COMPILATIONS_SCRIPTS_DIRECTORY:-"compilations"} # Repository directory that contains scripts that execute selected report generation scripts
@@ -116,18 +119,18 @@ fi
116119

117120
# Execute the settings profile script that sets all the neccessary settings variables (overrideable by environment variables).
118121
echo "analyze: Using analysis settings profile script ${SETTINGS_PROFILE_SCRIPT}"
119-
source "${SETTINGS_PROFILE_SCRIPT}" || exit 2
122+
source "${SETTINGS_PROFILE_SCRIPT}"
120123

121124
# Setup Tools
122-
source "${SCRIPTS_DIR}/setupNeo4j.sh" || exit 3
123-
source "${SCRIPTS_DIR}/setupJQAssistant.sh" || exit 3
124-
source "${SCRIPTS_DIR}/startNeo4j.sh" || exit 3
125+
source "${SCRIPTS_DIR}/setupNeo4j.sh"
126+
source "${SCRIPTS_DIR}/setupJQAssistant.sh"
127+
source "${SCRIPTS_DIR}/startNeo4j.sh"
125128

126129
# Scan and analyze artifacts when they were changed
127-
source "${SCRIPTS_DIR}/resetAndScanChanged.sh" || exit 4
130+
source "${SCRIPTS_DIR}/resetAndScanChanged.sh"
128131

129132
# Prepare and validate graph database before analyzing and creating reports
130-
source "${SCRIPTS_DIR}/prepareAnalysis.sh" || exit 5
133+
source "${SCRIPTS_DIR}/prepareAnalysis.sh"
131134

132135
if ${exploreMode}; then
133136
echo "analyze: Explore mode activated. Report generation will be skipped. Neo4j keeps running."
@@ -138,7 +141,7 @@ fi
138141
# Create Reports
139142
#########################
140143
echo "analyze: Creating Reports with ${REPORT_COMPILATION_SCRIPT} ..."
141-
source "${REPORT_COMPILATION_SCRIPT}" || exit 6
144+
source "${REPORT_COMPILATION_SCRIPT}"
142145

143146
# Stop Neo4j at the end
144147
source "${SCRIPTS_DIR}/stopNeo4j.sh"

scripts/copyReportsIntoResults.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
# Requires generateJupyterReportReference.sh
1010

11+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
12+
set -eo pipefail
13+
1114
## Get this "scripts" directory if not already set
1215
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
1316
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.

scripts/detectChangedArtifacts.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
# The hash value is generated based on all files (their names and properties) within the artifacts directory.
55
# A change is detected when the current hash and the stored one differ.
66

7+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
8+
set -eo pipefail
9+
710
ARTIFACTS_DIRECTORY=${ARTIFACTS_DIRECTORY:-"artifacts"}
811
ARTIFACTS_CHANGE_DETECTION_HASH_FILE=${ARTIFACTS_CHANGE_DETECTION_HASH_FILE:-"artifactsChangeDetectionHash.txt"} # Name of the file that contains the hash code of the file list for change detection
912
ARTIFACTS_CHANGE_DETECTION_HASH_FILE_PATH="./${ARTIFACTS_DIRECTORY}/$ARTIFACTS_CHANGE_DETECTION_HASH_FILE"
@@ -16,7 +19,9 @@ fi
1619

1720
# Use find to list all files in the directory with their properties,
1821
# sort the output, and pipe it to md5 to create a hash
19-
CURRENT_ARTIFACTS_HASH="$( find "./$ARTIFACTS_DIRECTORY" -type f -not -name "${ARTIFACTS_CHANGE_DETECTION_HASH_FILE}" -exec stat -f "%N %p %z" {} + | sort | md5 -r )"
22+
# Use openssl md5 that is at least available on Mac and Linux.
23+
# See: https://github.com/TRON-US/go-btfs/issues/90#issuecomment-517409369
24+
CURRENT_ARTIFACTS_HASH="$( find "./$ARTIFACTS_DIRECTORY" -type f -not -name "${ARTIFACTS_CHANGE_DETECTION_HASH_FILE}" -exec openssl md5 -binary {} + | openssl md5 | awk '{print $2}' )"
2025

2126
# Assume that the files where changed if the file containing the hash of the file list does not exist yet.
2227
if [ ! -f "${ARTIFACTS_CHANGE_DETECTION_HASH_FILE_PATH}" ] ; then

scripts/documentation/appendEnvironmentVariables.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# Note: If called with "clear" instead of a filename then the generated markdown reference documentation file is deleted.
66
# This is helpful to start over with the generation of a new document.
77

8+
# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
9+
set -eo pipefail
10+
811
# Markdown file name
912
markdownFile="ENVIRONMENT_VARIABLES.md"
1013

0 commit comments

Comments
 (0)