Skip to content

Commit 98ed65c

Browse files
committed
Add internal dependencies across artifacts reports
1 parent 1dc9274 commit 98ed65c

7 files changed

+239
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Artifacts with dependencies to other artifacts
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,round(100.0 / artifact.numberOfPackages
15+
* count(DISTINCT packageInArtifact.fqn)
16+
, 2) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,round(100.0 / artifact.numberOfTypes
20+
* count(DISTINCT typeInPackage.fqn)
21+
, 2) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN artifactName
33+
,packagesInArtifactCount
34+
,packagesCount
35+
,packageSpread
36+
,typesInArtifactCount
37+
,typesCount
38+
,typesSpread
39+
,dependencyArtifactName
40+
,dependencyTypeIsInterface
41+
,dependencyPackagesCount
42+
,dependencyTypesCount
43+
,dependencyPackages[0..2] AS someDependencyPackages
44+
,dependencyTypes[0..4] AS someDependencyTypes
45+
,packages[0..2] AS someCallingPackages
46+
,types[0..4] AS someCallingTypes
47+
ORDER BY packagesCount DESC
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Most used internal dependencies across artifacts
2+
3+
MATCH (type:Type)-[:DEPENDS_ON]->(dependencyType:Type)
4+
MATCH (artifact:Artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(type:Type)
5+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
6+
WHERE artifact.fileName <> dependencyArtifact.fileName
7+
WITH replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
8+
,COLLECT(DISTINCT dependencyPackage.fqn) AS dependencyPackageNames
9+
,COLLECT(DISTINCT dependencyType.name) AS dependencyTypeNames
10+
,COLLECT(DISTINCT replace(last(split(artifact.fileName, '/')), '.jar', '')) AS artifactNames
11+
,COUNT(DISTINCT package.fqn) AS numberOfPackages
12+
,COUNT(DISTINCT type.fqn) AS numberOfTypes
13+
,COUNT(DISTINCT dependencyType) AS numberOfDependencyTypes
14+
,REDUCE(interfaces=0, depType IN COLLECT(DISTINCT dependencyType) |
15+
CASE WHEN depType:Interface THEN interfaces + 1 ELSE interfaces END ) AS numberOfDependencyInterfaces
16+
ORDER BY numberOfPackages DESC
17+
RETURN dependencyArtifactName AS dependency
18+
,numberOfPackages AS usedByPackages
19+
,numberOfTypes AS usedByTypes
20+
,SIZE(dependencyPackageNames) AS providesPackages
21+
,SIZE(dependencyTypeNames) AS providesTypes
22+
,ROUND(100.0 / numberOfDependencyTypes * numberOfDependencyInterfaces, 2) AS interfaceRate
23+
,dependencyPackageNames[0..5] AS someProvidedPackages
24+
,dependencyTypeNames[0..5] AS someProvidedTypes
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Set number of packages and types on artifacts
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(package:Package)
4+
MATCH (package)-[:CONTAINS]->(type:Type)
5+
WITH artifact
6+
,COUNT(DISTINCT package.fqn) AS numberOfPackages
7+
,COUNT(DISTINCT type.fqn) AS numberOfTypes
8+
SET artifact.numberOfPackages = numberOfPackages
9+
,artifact.numberOfTypes = numberOfTypes
10+
RETURN artifact.fileName
11+
,numberOfPackages
12+
,numberOfTypes
13+
ORDER BY artifact.fileName
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Usage and spread of internal artifact dependencies
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,(100.0
15+
/ artifact.numberOfPackages
16+
* count(DISTINCT packageInArtifact.fqn)) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,(100.0
20+
/ artifact.numberOfTypes
21+
* count(DISTINCT typeInPackage.fqn)) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN dependencyArtifactName
33+
,dependencyTypeIsInterface
34+
,COUNT(DISTINCT artifactName) AS usedInArtifacts
35+
,SUM(packagesCount) AS usedInPackages
36+
37+
,MIN(packageSpread) AS minPackageSpread
38+
,MAX(packageSpread) AS maxPackageSpread
39+
,AVG(packageSpread) AS avgPackageSpread
40+
,stDev(packageSpread) AS stdPackageSpread
41+
,percentileDisc(packageSpread, 0.5) AS per5PackageSpread
42+
43+
,MIN(packagesCount) AS minPackageCount
44+
,MAX(packagesCount) AS maxPackageCount
45+
,AVG(packagesCount) AS avgPackageCount
46+
,stDev(packagesCount) AS stdPackageCount
47+
,percentileDisc(packagesCount, 0.5) AS per5PackageCount
48+
49+
,MIN(typesSpread) AS minTypeSpread
50+
,MAX(typesSpread) AS maxTypeSpread
51+
,AVG(typesSpread) AS avgTypeSpread
52+
,stDev(typesSpread) AS stdTypeSpread
53+
,percentileDisc(typesSpread, 0.5) AS per5TypeSpread
54+
ORDER BY toLower(dependencyArtifactName) ASC
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Usage and spread of internal artifact dependents
2+
3+
MATCH (artifact:Artifact)-[:CONTAINS]->(packageInArtifact:Package)
4+
MATCH (packageInArtifact)-[:CONTAINS]->(typeInPackage:Type)
5+
MATCH (typeInPackage)-[:DEPENDS_ON]->(dependencyType:Type)
6+
MATCH (dependencyPackage:Package)-[:CONTAINS]->(dependencyType)
7+
MATCH (dependencyArtifact:Artifact)-[:CONTAINS]->(dependencyPackage)
8+
WHERE artifact.fileName <> dependencyArtifact.fileName
9+
WITH replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
10+
,artifact.numberOfPackages AS packagesInArtifactCount
11+
,artifact.numberOfTypes AS typesInArtifactCount
12+
,collect(DISTINCT packageInArtifact.fqn) AS packages
13+
,count(DISTINCT packageInArtifact.fqn) AS packagesCount
14+
,(100.0
15+
/ artifact.numberOfPackages
16+
* count(DISTINCT packageInArtifact.fqn)) AS packageSpread
17+
,collect(DISTINCT typeInPackage.name) AS types
18+
,count(DISTINCT typeInPackage.fqn) AS typesCount
19+
,(100.0
20+
/ artifact.numberOfTypes
21+
* count(DISTINCT typeInPackage.fqn)) AS typesSpread
22+
,replace(last(split(dependencyArtifact.fileName, '/')), '.jar', '') AS dependencyArtifactName
23+
// additionally group by if the dependency is an interface or not
24+
,dependencyType:Interface AS dependencyTypeIsInterface
25+
,collect(DISTINCT dependencyPackage.fqn) AS dependencyPackages
26+
,count(DISTINCT dependencyPackage.fqn) AS dependencyPackagesCount
27+
,collect(DISTINCT dependencyType.name) AS dependencyTypes
28+
,count(DISTINCT dependencyType.fqn) AS dependencyTypesCount
29+
// Filter out empty dependency sets
30+
WHERE dependencyPackagesCount > 0
31+
AND packagesCount > 1
32+
RETURN artifactName
33+
,dependencyTypeIsInterface
34+
,COUNT(DISTINCT dependencyArtifactName) AS artifactDependencies
35+
,SUM(dependencyPackagesCount) AS artifactDependencyPackages
36+
,100.0 / SUM(packagesInArtifactCount) * SUM(packagesCount) AS dependentPackagesRate
37+
38+
,MIN(packageSpread) AS minPackageSpread
39+
,MAX(packageSpread) AS maxPackageSpread
40+
,AVG(packageSpread) AS avgPackageSpread
41+
,stDev(packageSpread) AS stdPackageSpread
42+
,percentileDisc(packageSpread, 0.5) AS per5PackageSpread
43+
44+
,MIN(packagesCount) AS minPackageCount
45+
,MAX(packagesCount) AS maxPackageCount
46+
,AVG(packagesCount) AS avgPackageCount
47+
,stDev(packagesCount) AS stdPackageCount
48+
,percentileDisc(packagesCount, 0.5) AS per5PackageCount
49+
50+
,MIN(typesSpread) AS minTypeSpread
51+
,MAX(typesSpread) AS maxTypeSpread
52+
,AVG(typesSpread) AS avgTypeSpread
53+
,stDev(typesSpread) AS stdTypeSpread
54+
,percentileDisc(typesSpread, 0.5) AS per5TypeSpread
55+
ORDER BY toLower(artifactName) ASC
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
3+
# Executes "Artifact_Dependencies" Cypher queries to get the "artifact-dependencies-csv" CSV reports.
4+
# It contains lists of dependencies across artifacts and hby ow many packages/types they are used by.
5+
6+
# Requires executeQueryFunctions.sh
7+
8+
# Overrideable Constants (defaults also defined in sub scripts)
9+
REPORTS_DIRECTORY=${REPORTS_DIRECTORY:-"reports"}
10+
11+
## Get this "scripts/reports" directory if not already set
12+
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
13+
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
14+
# This way non-standard tools like readlink aren't needed.
15+
REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )}
16+
echo "ArtifactDependenciesCsv: REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR}"
17+
18+
# Get the "scripts" directory by taking the path of this script and going one directory up.
19+
SCRIPTS_DIR=${SCRIPTS_DIR:-"${REPORTS_SCRIPT_DIR}/.."} # Repository directory containing the shell scripts
20+
echo "ArtifactDependenciesCsv SCRIPTS_DIR=${SCRIPTS_DIR}"
21+
22+
# Get the "cypher" directory by taking the path of this script and going two directory up and then to "cypher".
23+
CYPHER_DIR=${CYPHER_DIR:-"${REPORTS_SCRIPT_DIR}/../../cypher"}
24+
echo "ArtifactDependenciesCsv CYPHER_DIR=${CYPHER_DIR}"
25+
26+
# Define functions to execute cypher queries from within a given file
27+
source "${SCRIPTS_DIR}/executeQueryFunctions.sh"
28+
29+
# Create report directory
30+
REPORT_NAME="artifact-dependencies-csv"
31+
FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}"
32+
mkdir -p "${FULL_REPORT_DIRECTORY}"
33+
34+
# Local Constants
35+
ARTIFACT_DEPENDENCIES_CYPHER_DIR="${CYPHER_DIR}/Artifact_Dependencies"
36+
37+
# Preparation: Set number of packages and types per artifact
38+
execute_cypher_expect_results "${ARTIFACT_DEPENDENCIES_CYPHER_DIR}/Set_number_of_packages_and_types_on_artifacts.cypher"
39+
40+
execute_cypher "${ARTIFACT_DEPENDENCIES_CYPHER_DIR}/Most_used_internal_dependencies_acreoss_artifacts.cypher" > "${FULL_REPORT_DIRECTORY}/MostUsedDependenciesAcrossArtifacts.csv"
41+
execute_cypher "${ARTIFACT_DEPENDENCIES_CYPHER_DIR}/Artifacts_with_dependencies_to_other_artifacts.cypher" > "${FULL_REPORT_DIRECTORY}/DependenciesAcrossArtifacts.csv"
42+
43+
execute_cypher "${ARTIFACT_DEPENDENCIES_CYPHER_DIR}/Usage_and_spread_of_internal_artifact_dependencies.cypher" > "${FULL_REPORT_DIRECTORY}/InternalArtifactUsageSpreadPerDependency.csv"
44+
execute_cypher "${ARTIFACT_DEPENDENCIES_CYPHER_DIR}/Usage_and_spread_of_internal_artifact_dependents.cypher" > "${FULL_REPORT_DIRECTORY}/InternalArtifactUsageSpreadPerDependent.csv"

scripts/reports/InternalDependenciesCsv.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ INTERNAL_DEPENDENCIES_CYPHER_DIR="${CYPHER_DIR}/Internal_Dependencies"
3939
execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_as_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicDependencies.csv"
4040
execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_as_unwinded_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicDependenciesUnwinded.csv"
4141
execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicArtifactDependenciesUnwinded.csv"
42+
4243
execute_cypher "${CYPHER_DIR}/Candidates_for_Interface_Segregation.cypher" > "${FULL_REPORT_DIRECTORY}/InterfaceSegregationCandidates.csv"
44+
4345
execute_cypher "${INTERNAL_DEPENDENCIES_CYPHER_DIR}/List_types_that_are_used_by_many_different_packages.cypher" > "${FULL_REPORT_DIRECTORY}/WidelyUsedTypes.csv"
4446
execute_cypher "${INTERNAL_DEPENDENCIES_CYPHER_DIR}/How_many_packages_compared_to_all_existing_are_used_by_dependent_artifacts.cypher" > "${FULL_REPORT_DIRECTORY}/ArtifactPackageUsage.csv"
4547
execute_cypher "${INTERNAL_DEPENDENCIES_CYPHER_DIR}/How_many_classes_compared_to_all_existing_in_the_same_package_are_used_by_dependent_packages_across_different_artifacts.cypher" > "${FULL_REPORT_DIRECTORY}/ClassesPerPackageUsageAcrossArtifacts.csv"

0 commit comments

Comments
 (0)