From 04a491dd7576e254949aab294bf20988aba945a8 Mon Sep 17 00:00:00 2001 From: JohT Date: Thu, 29 Jun 2023 08:09:11 +0200 Subject: [PATCH 1/6] Rename package to internal dependencies --- README.md | 6 +++--- ...endencies.ipynb => InternalDependencies.ipynb} | 2 +- .../ArtifactPackageUsage.csv | 0 .../ClassesPerPackageUsageAcrossArtifacts.csv | 0 .../CyclicDependencies.csv | 0 .../CyclicDependenciesUnwinded.csv | 0 .../InterfaceSegregationCandidates.csv | 0 .../WidelyUsedTypes.csv | 0 .../InternalDependencies.ipynb} | 0 .../InternalDependencies.md} | 0 .../InternalDependencies.pdf} | Bin scripts/SCRIPTS.md | 5 ++--- ...endenciesCsv.sh => InternalDependenciesCsv.sh} | 10 +++++----- ...sJupyter.sh => InternalDependenciesJupyter.sh} | 14 +++++++------- scripts/reports/VisibilityMetricsJupyter.sh | 2 +- 15 files changed, 19 insertions(+), 20 deletions(-) rename jupyter/{PackageDependencies.ipynb => InternalDependencies.ipynb} (99%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/ArtifactPackageUsage.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/ClassesPerPackageUsageAcrossArtifacts.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/CyclicDependencies.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/CyclicDependenciesUnwinded.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/InterfaceSegregationCandidates.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies-csv => internal-dependencies-csv}/WidelyUsedTypes.csv (100%) rename results/AxonFramework-4.7.5/{package-dependencies/PackageDependencies.ipynb => internal-dependencies/InternalDependencies.ipynb} (100%) rename results/AxonFramework-4.7.5/{package-dependencies/PackageDependencies.md => internal-dependencies/InternalDependencies.md} (100%) rename results/AxonFramework-4.7.5/{package-dependencies/PackageDependencies.pdf => internal-dependencies/InternalDependencies.pdf} (100%) rename scripts/reports/{PackageDependenciesCsv.sh => InternalDependenciesCsv.sh} (88%) rename scripts/reports/{PackageDependenciesJupyter.sh => InternalDependenciesJupyter.sh} (69%) diff --git a/README.md b/README.md index 70ca39022..d2b561191 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Contained within this repository is a comprehensive and automated code graph ana - [External Dependencies](./jupyter/ExternalDependencies.ipynb) reports with amongst others the most and least used external packages ([Example](./results/AxonFramework-4.7.5/external-dependencies/ExternalDependencies.md)) - [Object Oriented Design Quality Metrics](./jupyter/ObjectOrientedDesignMetrics.ipynb) report based on [OO Design Quality Metrics by Robert Martin](https://www.semanticscholar.org/paper/OO-Design-Quality-Metrics-Martin-October/18acd7eb21b918c8a5f619157f7e4f6d451d18f8) ([Example](./results/AxonFramework-4.7.5/object-oriented-design-metrics/ObjectOrientedDesignMetrics.md)) - [Overview](./jupyter/Overview.ipynb) reports with the number of Java types and packages, method line count, etc. ([Example](./results/AxonFramework-4.7.5/overview/Overview.md)) -- [Package Dependencies](./jupyter/PackageDependencies.ipynb) report based on [Analyze java package metrics in a graph database](https://joht.github.io/johtizen/data/2023/04/21/java-package-metrics-analysis.html) including cyclic dependencies ([Example](./results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.md)) +- [Internal Dependencies](./jupyter/InternalDependencies.ipynb) report based on [Analyze java package metrics in a graph database](https://joht.github.io/johtizen/data/2023/04/21/java-package-metrics-analysis.html) including cyclic dependencies ([Example](./results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.md)) - [Visibility Metrics](./jupyter/VisibilityMetrics.ipynb) reports based on [Visibility Metrics and the Importance of Hiding Things](https://dzone.com/articles/visibility-metrics-and-the-importance-of-hiding-th) ([Example](./results/AxonFramework-4.7.5/visibility-metrics/VisibilityMetrics.md)) - [Wordcloud](./jupyter/Wordcloud.ipynb) with a visual representation of Java package and class names ([Example](./results/AxonFramework-4.7.5/wordcloud/Wordcloud.md)) @@ -36,8 +36,8 @@ Here are some reports that utilize Neo4j's [Graph Data Science Library](https:// - [External Dependencies (CSV)](./scripts/reports/ExternalDependenciesCsv.sh) ([Example](./results/AxonFramework-4.7.5/external-dependencies-csv/External_package_usage_overall.csv)) - [Object Oriented Design Metrics (CSV)](./scripts/reports/ObjectOrientedDesignMetricsCsv.sh) ([Example](./results/AxonFramework-4.7.5/object-oriented-design-metrics-csv/MainSequenceAbstractnessInstabilityDistance.csv)) - [Overview (CSV)](./scripts/reports/OverviewCsv.sh) ([Example](./results/AxonFramework-4.7.5/overview-csv/Cyclomatic_Method_Complexity.csv)) -- [Package Dependencies - Cyclic (CSV)](./scripts/reports/PackageDependenciesCsv.sh) ([Example](./results/AxonFramework-4.7.5/package-dependencies-csv/CyclicDependenciesUnwinded.csv)) -- [Package Dependencies - Interface Segregation (CSV)](./scripts/reports/PackageDependenciesCsv.sh) ([Example](./results/AxonFramework-4.7.5/package-dependencies-csv/InterfaceSegregationCandidates.csv)) +- [Internal Dependencies - Cyclic (CSV)](./scripts/reports/InternalDependenciesCsv.sh) ([Example](./results/AxonFramework-4.7.5/internal-dependencies-csv/CyclicDependenciesUnwinded.csv)) +- [Internal Dependencies - Interface Segregation (CSV)](./scripts/reports/InternalDependenciesCsv.sh) ([Example](./results/AxonFramework-4.7.5/internal-dependencies-csv/InterfaceSegregationCandidates.csv)) - [Visibility Metrics (CSV)](./scripts/reports/VisibilityMetricsCsv.sh) ([Example](./results/AxonFramework-4.7.5/visibility-metrics-csv/RelativeVisibilityPerArtifact.csv)) ## 🛠 Prerequisites diff --git a/jupyter/PackageDependencies.ipynb b/jupyter/InternalDependencies.ipynb similarity index 99% rename from jupyter/PackageDependencies.ipynb rename to jupyter/InternalDependencies.ipynb index 316a3a0d1..0bf1ad810 100644 --- a/jupyter/PackageDependencies.ipynb +++ b/jupyter/InternalDependencies.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# Package Dependencies for Java with Neo4j\n", + "# Internal Dependencies\n", "
\n", "\n", "### References\n", diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/ArtifactPackageUsage.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/ArtifactPackageUsage.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/ArtifactPackageUsage.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/ArtifactPackageUsage.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/ClassesPerPackageUsageAcrossArtifacts.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/ClassesPerPackageUsageAcrossArtifacts.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/ClassesPerPackageUsageAcrossArtifacts.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/ClassesPerPackageUsageAcrossArtifacts.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/CyclicDependencies.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/CyclicDependencies.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/CyclicDependencies.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/CyclicDependencies.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/CyclicDependenciesUnwinded.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/CyclicDependenciesUnwinded.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/CyclicDependenciesUnwinded.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/CyclicDependenciesUnwinded.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/InterfaceSegregationCandidates.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/InterfaceSegregationCandidates.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/InterfaceSegregationCandidates.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/InterfaceSegregationCandidates.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies-csv/WidelyUsedTypes.csv b/results/AxonFramework-4.7.5/internal-dependencies-csv/WidelyUsedTypes.csv similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies-csv/WidelyUsedTypes.csv rename to results/AxonFramework-4.7.5/internal-dependencies-csv/WidelyUsedTypes.csv diff --git a/results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.ipynb b/results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.ipynb similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.ipynb rename to results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.ipynb diff --git a/results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.md b/results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.md similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.md rename to results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.md diff --git a/results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.pdf b/results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.pdf similarity index 100% rename from results/AxonFramework-4.7.5/package-dependencies/PackageDependencies.pdf rename to results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.pdf diff --git a/scripts/SCRIPTS.md b/scripts/SCRIPTS.md index c1cf0011b..a14be9176 100644 --- a/scripts/SCRIPTS.md +++ b/scripts/SCRIPTS.md @@ -25,12 +25,12 @@ Script | Directory | Description | [DatabaseCsvExport.sh](./reports/DatabaseCsvExport.sh) | reports | Exports the whole graph database as a CSV file using the APOC procedure "apoc.export.csv.all" | | [ExternalDependenciesCsv.sh](./reports/ExternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. | | [ExternalDependenciesJupyter.sh](./reports/ExternalDependenciesJupyter.sh) | reports | Creates the "overview" report (ipynb, md, pdf) based on the Jupyter Notebook "Overview.ipynb". | +| [InternalDependenciesCsv.sh](./reports/InternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "internal-dependencies" CSV reports. | +| [InternalDependenciesJupyter.sh](./reports/InternalDependenciesJupyter.sh) | reports | Creates the "internal-dependencies" report (ipynb, md, pdf) based on the Jupyter Notebook "InternalDependencies.ipynb". | | [ObjectOrientedDesignMetricsCsv.sh](./reports/ObjectOrientedDesignMetricsCsv.sh) | reports | Executes "Metrics" Cypher queries to get the "object-oriented-design-metrics" CSV reports. | | [ObjectOrientedDesignMetricsJupyter.sh](./reports/ObjectOrientedDesignMetricsJupyter.sh) | reports | Creates the "object-oriented-design-metrics" report (ipynb, md, pdf) based on the Jupyter Notebook "ObjectOrientedDesignMetrics.ipynb". | | [OverviewCsv.sh](./reports/OverviewCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. | | [OverviewJupyter.sh](./reports/OverviewJupyter.sh) | reports | Creates the "overview" report (ipynb, md, pdf) based on the Jupyter Notebook "Overview.ipynb". | -| [PackageDependenciesCsv.sh](./reports/PackageDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. | -| [PackageDependenciesJupyter.sh](./reports/PackageDependenciesJupyter.sh) | reports | Creates the "package-dependencies" report (ipynb, md, pdf) based on the Jupyter Notebook "PackageDependencies.ipynb". | | [SimilarityCsv.sh](./reports/SimilarityCsv.sh) | reports | Looks for similarity using the Graph Data Science Library of Neo4j and creates CSV reports. | | [VisibilityMetricsCsv.sh](./reports/VisibilityMetricsCsv.sh) | reports | Executes "Visibility" Cypher queries to get the "visibility-metrics" CSV reports. | | [VisibilityMetricsJupyter.sh](./reports/VisibilityMetricsJupyter.sh) | reports | Creates the "visibility-metrics" report (ipynb, md, pdf) based on the Jupyter Notebook "VisibilityMetrics.ipynb". | @@ -40,7 +40,6 @@ Script | Directory | Description | [JupyterReports.sh](./reports/compilations/JupyterReports.sh) | compilations | Runs all Jupyter Notebook report scripts. | | [resetAndScan.sh](./resetAndScan.sh) | | Deletes all data in the Neo4j graph database and rescans the downloaded artifacts to create a new graph. | | [resetAndScanChanged.sh](./resetAndScanChanged.sh) | | Executes "resetAndScan.sh" only if "detectChangedArtifacts.sh" returns detected changes. | -| [resetAndScanMemgraph.sh](./resetAndScanMemgraph.sh) | | Deletes all data in the Neo4j graph database and rescans the downloaded artifacts to create a new graph. | | [setupJQAssistant.sh](./setupJQAssistant.sh) | | Installs (download and unzip) jQAssistant (https://jqassistant.org/get-started). | | [setupNeo4j.sh](./setupNeo4j.sh) | | Installs (download, unpack, get plugins, configure) a local Neo4j Graph Database (https://neo4j.com/download-center/#community). | | [setupNeo4jInitialPassword.sh](./setupNeo4jInitialPassword.sh) | | Sets the initial password for the local Neo4j Graph Database (https://neo4j.com/download-center/#community). | diff --git a/scripts/reports/PackageDependenciesCsv.sh b/scripts/reports/InternalDependenciesCsv.sh similarity index 88% rename from scripts/reports/PackageDependenciesCsv.sh rename to scripts/reports/InternalDependenciesCsv.sh index e7de539e6..1c3169c06 100755 --- a/scripts/reports/PackageDependenciesCsv.sh +++ b/scripts/reports/InternalDependenciesCsv.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. +# Executes "Package_Usage" Cypher queries to get the "internal-dependencies" CSV reports. # It contains lists of e.g. incoming and outgoing package dependencies, # abstractness, instability and the distance to the so called "main sequence". @@ -12,21 +12,21 @@ REPORTS_DIRECTORY=${REPORTS_DIRECTORY:-"reports"} # CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes. # This way non-standard tools like readlink aren't needed. REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} -echo "PackageDependenciesCsv: REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR}" +echo "InternalDependenciesCsv: REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR}" # Get the "scripts" directory by taking the path of this script and going one directory up. SCRIPTS_DIR=${SCRIPTS_DIR:-"${REPORTS_SCRIPT_DIR}/.."} -echo "PackageDependenciesCsv SCRIPTS_DIR=${SCRIPTS_DIR}" +echo "InternalDependenciesCsv SCRIPTS_DIR=${SCRIPTS_DIR}" # Get the "cypher" directory by taking the path of this script and going two directory up and then to "cypher". CYPHER_DIR=${CYPHER_DIR:-"${REPORTS_SCRIPT_DIR}/../../cypher"} -echo "PackageDependenciesCsv CYPHER_DIR=${CYPHER_DIR}" +echo "InternalDependenciesCsv CYPHER_DIR=${CYPHER_DIR}" # Define functions to execute cypher queries from within a given file source "${SCRIPTS_DIR}/executeQueryFunctions.sh" # Create report directory -REPORT_NAME="package-dependencies-csv" +REPORT_NAME="internal-dependencies-csv" FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}" mkdir -p "${FULL_REPORT_DIRECTORY}" diff --git a/scripts/reports/PackageDependenciesJupyter.sh b/scripts/reports/InternalDependenciesJupyter.sh similarity index 69% rename from scripts/reports/PackageDependenciesJupyter.sh rename to scripts/reports/InternalDependenciesJupyter.sh index 7b6020f04..4eae5802f 100755 --- a/scripts/reports/PackageDependenciesJupyter.sh +++ b/scripts/reports/InternalDependenciesJupyter.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Creates the "package-dependencies" report (ipynb, md, pdf) based on the Jupyter Notebook "PackageDependencies.ipynb". +# Creates the "internal-dependencies" report (ipynb, md, pdf) based on the Jupyter Notebook "InternalDependencies.ipynb". # It contains lists of e.g. cyclic dependencies, dependencies that are only used by a few packages, # classes that are used by many different packages and some more. @@ -12,20 +12,20 @@ REPORTS_DIRECTORY=${REPORTS_DIRECTORY:-"reports"} # CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes. # This way non-standard tools like readlink aren't needed. REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} -echo "PackageDependenciesJupyter: REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR}" +echo "InternalDependenciesJupyter: REPORTS_SCRIPT_DIR=${REPORTS_SCRIPT_DIR}" # Get the "scripts" directory by taking the path of this script and going one directory up. SCRIPTS_DIR=${SCRIPTS_DIR:-"${REPORTS_SCRIPT_DIR}/.."} -echo "PackageDependenciesJupyter: SCRIPTS_DIR=${SCRIPTS_DIR}" +echo "InternalDependenciesJupyter: SCRIPTS_DIR=${SCRIPTS_DIR}" # Get the "jupyter" directory by taking the path of this script and going two directory up and then to "jupyter". JUPYTER_NOTEBOOK_DIRECTORY=${JUPYTER_NOTEBOOK_DIRECTORY:-"${SCRIPTS_DIR}/../jupyter"} -echo "PackageDependenciesJupyter: JUPYTER_NOTEBOOK_DIRECTORY=$JUPYTER_NOTEBOOK_DIRECTORY" +echo "InternalDependenciesJupyter: JUPYTER_NOTEBOOK_DIRECTORY=$JUPYTER_NOTEBOOK_DIRECTORY" # Create report directory -REPORT_NAME="package-dependencies" +REPORT_NAME="internal-dependencies" FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}" mkdir -p "${FULL_REPORT_DIRECTORY}" -# Execute and convert the Jupyter Notebook "PackageDependencies.ipynb" within the given reports directory -(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/PackageDependencies.ipynb) || exit 1 \ No newline at end of file +# Execute and convert the Jupyter Notebook "InternalDependencies.ipynb" within the given reports directory +(cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/InternalDependencies.ipynb) || exit 1 \ No newline at end of file diff --git a/scripts/reports/VisibilityMetricsJupyter.sh b/scripts/reports/VisibilityMetricsJupyter.sh index 09a5676ce..809ed3e74 100755 --- a/scripts/reports/VisibilityMetricsJupyter.sh +++ b/scripts/reports/VisibilityMetricsJupyter.sh @@ -26,5 +26,5 @@ REPORT_NAME="visibility-metrics" FULL_REPORT_DIRECTORY="${REPORTS_DIRECTORY}/${REPORT_NAME}" mkdir -p "${FULL_REPORT_DIRECTORY}" -# Execute and convert the Jupyter Notebook "PackageDependencies.ipynb" within the given reports directory +# Execute and convert the Jupyter Notebook "VisibilityMetrics.ipynb" within the given reports directory (cd "${FULL_REPORT_DIRECTORY}" && exec ${SCRIPTS_DIR}/executeJupyterNotebook.sh ${JUPYTER_NOTEBOOK_DIRECTORY}/VisibilityMetrics.ipynb) || exit 1 \ No newline at end of file From 2e2e0180ea9d2b701987225eb8679f759cab6a5e Mon Sep 17 00:00:00 2001 From: JohT Date: Thu, 29 Jun 2023 08:11:13 +0200 Subject: [PATCH 2/6] Report cyclic artifacts dependencies --- ...between_Artrifacts_as_unwinded_List.cypher | 36 +++++++++++++++++++ scripts/reports/InternalDependenciesCsv.sh | 1 + 2 files changed, 37 insertions(+) create mode 100644 cypher/Cyclic_Dependencies/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher diff --git a/cypher/Cyclic_Dependencies/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher b/cypher/Cyclic_Dependencies/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher new file mode 100644 index 000000000..2da2fc856 --- /dev/null +++ b/cypher/Cyclic_Dependencies/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher @@ -0,0 +1,36 @@ +//Cyclic Dependencies between Artifacts as unwinded List + +MATCH (package:Package)-[:CONTAINS]->(forwardSource:Type)-[:DEPENDS_ON]->(forwardTarget:Type)<-[:CONTAINS]-(dependentPackage:Package) +MATCH (dependentPackage)-[:CONTAINS]->(backwardSource:Type)-[:DEPENDS_ON]->(backwardTarget:Type)<-[:CONTAINS]-(package) +MATCH (artifact:Artifact)-[:CONTAINS]->(package) +MATCH (dependentArtifact:Artifact)-[:CONTAINS]->(dependentPackage) + WITH artifact + ,dependentArtifact + ,package + ,dependentPackage + ,collect(DISTINCT forwardSource.name + '->' + forwardTarget.name) AS forwardDependencies + ,collect(DISTINCT backwardTarget.name + '<-' + backwardSource.name) AS backwardDependencies + WITH artifact + ,dependentArtifact + ,package + ,dependentPackage + ,forwardDependencies + ,backwardDependencies + ,size(forwardDependencies) AS numberOfForwardDependencies + ,size(backwardDependencies) AS numberOfBackwardDependencies + ,size(forwardDependencies) + size(backwardDependencies) AS numberOfAllCyclicDependencies +WHERE artifact <> dependentArtifact + AND package <> dependentPackage + AND (size(forwardDependencies) > size(backwardDependencies) + OR (size(forwardDependencies) = size(backwardDependencies) + AND size(package.fqn) >= size(dependentPackage.fqn))) +UNWIND (backwardDependencies + forwardDependencies) AS dependency +RETURN artifact.fileName AS artifactName + ,dependentArtifact.fileName AS dependentArtifactName + ,package.fqn AS packageName + ,dependentPackage.fqn AS dependentPackageName + ,dependency + ,toFloat(ABS(numberOfForwardDependencies - numberOfBackwardDependencies)) / numberOfAllCyclicDependencies AS forwardToBackwardBalance + ,numberOfForwardDependencies AS numberForward + ,numberOfBackwardDependencies AS numberBackward +ORDER BY forwardToBackwardBalance DESC, packageName ASC \ No newline at end of file diff --git a/scripts/reports/InternalDependenciesCsv.sh b/scripts/reports/InternalDependenciesCsv.sh index 1c3169c06..23af6afbe 100755 --- a/scripts/reports/InternalDependenciesCsv.sh +++ b/scripts/reports/InternalDependenciesCsv.sh @@ -36,6 +36,7 @@ PACKAGE_USAGE_CYPHER_DIR="${CYPHER_DIR}/Package_Usage" execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_as_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicDependencies.csv" execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_as_unwinded_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicDependenciesUnwinded.csv" +execute_cypher "${CYCLIC_DEPENDENCIES_CYPHER_DIR}/Cyclic_Dependencies_between_Artrifacts_as_unwinded_List.cypher" > "${FULL_REPORT_DIRECTORY}/CyclicArtifactDependenciesUnwinded.csv" execute_cypher "${CYPHER_DIR}/Candidates_for_Interface_Segregation.cypher" > "${FULL_REPORT_DIRECTORY}/InterfaceSegregationCandidates.csv" execute_cypher "${PACKAGE_USAGE_CYPHER_DIR}/List_types_that_are_used_by_many_different_packages.cypher" > "${FULL_REPORT_DIRECTORY}/WidelyUsedTypes.csv" execute_cypher "${PACKAGE_USAGE_CYPHER_DIR}/How_many_packages_compared_to_all_existing_are_used_by_dependent_artifacts.cypher" > "${FULL_REPORT_DIRECTORY}/ArtifactPackageUsage.csv" From ca6c111192a85126e788ebade3585b63fabd0843 Mon Sep 17 00:00:00 2001 From: JohT Date: Thu, 29 Jun 2023 08:25:50 +0200 Subject: [PATCH 3/6] Fix script descriptions --- scripts/SCRIPTS.md | 4 ++-- scripts/reports/ExternalDependenciesCsv.sh | 5 ++--- scripts/reports/OverviewCsv.sh | 5 ++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/scripts/SCRIPTS.md b/scripts/SCRIPTS.md index a14be9176..639c68f17 100644 --- a/scripts/SCRIPTS.md +++ b/scripts/SCRIPTS.md @@ -23,13 +23,13 @@ Script | Directory | Description | [CentralityCsv.sh](./reports/CentralityCsv.sh) | reports | Looks for centrality using the Graph Data Science Library of Neo4j and creates CSV reports. | | [CommunityCsv.sh](./reports/CommunityCsv.sh) | reports | Detects communities using the Graph Data Science Library of Neo4j and creates CSV reports. | | [DatabaseCsvExport.sh](./reports/DatabaseCsvExport.sh) | reports | Exports the whole graph database as a CSV file using the APOC procedure "apoc.export.csv.all" | -| [ExternalDependenciesCsv.sh](./reports/ExternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. | +| [ExternalDependenciesCsv.sh](./reports/ExternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "external-dependencies-csv" CSV reports. | | [ExternalDependenciesJupyter.sh](./reports/ExternalDependenciesJupyter.sh) | reports | Creates the "overview" report (ipynb, md, pdf) based on the Jupyter Notebook "Overview.ipynb". | | [InternalDependenciesCsv.sh](./reports/InternalDependenciesCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "internal-dependencies" CSV reports. | | [InternalDependenciesJupyter.sh](./reports/InternalDependenciesJupyter.sh) | reports | Creates the "internal-dependencies" report (ipynb, md, pdf) based on the Jupyter Notebook "InternalDependencies.ipynb". | | [ObjectOrientedDesignMetricsCsv.sh](./reports/ObjectOrientedDesignMetricsCsv.sh) | reports | Executes "Metrics" Cypher queries to get the "object-oriented-design-metrics" CSV reports. | | [ObjectOrientedDesignMetricsJupyter.sh](./reports/ObjectOrientedDesignMetricsJupyter.sh) | reports | Creates the "object-oriented-design-metrics" report (ipynb, md, pdf) based on the Jupyter Notebook "ObjectOrientedDesignMetrics.ipynb". | -| [OverviewCsv.sh](./reports/OverviewCsv.sh) | reports | Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. | +| [OverviewCsv.sh](./reports/OverviewCsv.sh) | reports | Executes "Overview" Cypher queries to get the "overview-csv" CSV reports. | | [OverviewJupyter.sh](./reports/OverviewJupyter.sh) | reports | Creates the "overview" report (ipynb, md, pdf) based on the Jupyter Notebook "Overview.ipynb". | | [SimilarityCsv.sh](./reports/SimilarityCsv.sh) | reports | Looks for similarity using the Graph Data Science Library of Neo4j and creates CSV reports. | | [VisibilityMetricsCsv.sh](./reports/VisibilityMetricsCsv.sh) | reports | Executes "Visibility" Cypher queries to get the "visibility-metrics" CSV reports. | diff --git a/scripts/reports/ExternalDependenciesCsv.sh b/scripts/reports/ExternalDependenciesCsv.sh index 0ccac5a42..a77eb1ff7 100755 --- a/scripts/reports/ExternalDependenciesCsv.sh +++ b/scripts/reports/ExternalDependenciesCsv.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash -# Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. -# It contains lists of e.g. incoming and outgoing package dependencies, -# abstractness, instability and the distance to the so called "main sequence". +# Executes "Package_Usage" Cypher queries to get the "external-dependencies-csv" CSV reports. +# They list external library package usage like how often a external package is called. # Overrideable Constants (defaults also defined in sub scripts) REPORTS_DIRECTORY=${REPORTS_DIRECTORY:-"reports"} diff --git a/scripts/reports/OverviewCsv.sh b/scripts/reports/OverviewCsv.sh index 14c67223f..855541cc8 100755 --- a/scripts/reports/OverviewCsv.sh +++ b/scripts/reports/OverviewCsv.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash -# Executes "Package_Usage" Cypher queries to get the "package-dependencies" CSV reports. -# It contains lists of e.g. incoming and outgoing package dependencies, -# abstractness, instability and the distance to the so called "main sequence". +# Executes "Overview" Cypher queries to get the "overview-csv" CSV reports. +# It contains the numbers of packages, types, methods, cyclic complexity, etc. # Overrideable Constants (defaults also defined in sub scripts) REPORTS_DIRECTORY=${REPORTS_DIRECTORY:-"reports"} From b52ca608bfd42b05a62639dbd75c7afff2693730 Mon Sep 17 00:00:00 2001 From: JohT Date: Sat, 1 Jul 2023 08:47:44 +0200 Subject: [PATCH 4/6] Simplify Jupyter Notebook report titles --- jupyter/ExternalDependencies.ipynb | 2 +- jupyter/ObjectOrientedDesignMetrics.ipynb | 2 +- jupyter/Overview.ipynb | 2 +- jupyter/VisibilityMetrics.ipynb | 2 +- jupyter/Wordcloud.ipynb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jupyter/ExternalDependencies.ipynb b/jupyter/ExternalDependencies.ipynb index 656ce828f..78d0b563e 100644 --- a/jupyter/ExternalDependencies.ipynb +++ b/jupyter/ExternalDependencies.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# External Dependencies of Java Artifacts with Neo4j\n", + "# External Dependencies\n", "
\n", "\n", "### References\n", diff --git a/jupyter/ObjectOrientedDesignMetrics.ipynb b/jupyter/ObjectOrientedDesignMetrics.ipynb index acea35db4..98c4a8870 100644 --- a/jupyter/ObjectOrientedDesignMetrics.ipynb +++ b/jupyter/ObjectOrientedDesignMetrics.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# Object Oriented Design Quality Metrics for Java with Neo4j\n", + "# Object Oriented Design Quality Metrics\n", "
\n", "\n", "### References\n", diff --git a/jupyter/Overview.ipynb b/jupyter/Overview.ipynb index 709262cd5..a21bc127f 100644 --- a/jupyter/Overview.ipynb +++ b/jupyter/Overview.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# Overview of Java Artifacts with Neo4j\n", + "# Overview\n", "
\n", "\n", "### References\n", diff --git a/jupyter/VisibilityMetrics.ipynb b/jupyter/VisibilityMetrics.ipynb index 31e8227de..4916d6ee1 100644 --- a/jupyter/VisibilityMetrics.ipynb +++ b/jupyter/VisibilityMetrics.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# Visibility Metrics for Java with Neo4j\n", + "# Visibility Metrics\n", "
\n", "\n", "### References\n", diff --git a/jupyter/Wordcloud.ipynb b/jupyter/Wordcloud.ipynb index a719b1b22..ede83c7d9 100644 --- a/jupyter/Wordcloud.ipynb +++ b/jupyter/Wordcloud.ipynb @@ -6,7 +6,7 @@ "id": "2f0eabc4", "metadata": {}, "source": [ - "# Overview of Java Artifacts with Neo4j\n", + "# Wordcloud\n", "
\n", "\n", "### References\n", From 53d886a3bd89ffc4d547be46d5cc433b5e097eb4 Mon Sep 17 00:00:00 2001 From: JohT Date: Sat, 1 Jul 2023 09:10:06 +0200 Subject: [PATCH 5/6] Refine main documentation --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d2b561191..93a22f5ee 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -Contained within this repository is a comprehensive and automated code graph analysis pipeline. While initially designed to support Java through the utilization of [jQAssistant](https://jqassistant.org/get-started), its capabilities extend beyond that particular language. The graph database [Neo4j](https://neo4j.com) serves as the foundation for storing and querying the graph, which encompasses all the structural intricacies of the analyzed code. Additionally, Neo4j's [Graph Data Science](https://neo4j.com/product/graph-data-science) integration maximizes the utilization of its features. The generated reports offer flexibility, ranging from simple query results presented as CSV files to more elaborate Jupyter Notebooks converted to Markdown or PDF formats. +Contained within this repository is a comprehensive and automated code graph analysis pipeline. While initially designed to support Java through the utilization of [jQAssistant](https://jqassistant.org/get-started), it is open to extension for further programming languages. The graph database [Neo4j](https://neo4j.com) serves as the foundation for storing and querying the graph, which encompasses all the structural intricacies of the analyzed code. Additionally, Neo4j's [Graph Data Science](https://neo4j.com/product/graph-data-science) provides additional algorithms like community detection to analyze the code structure. The generated reports offer flexibility, ranging from simple query results presented as CSV files to more elaborate Jupyter Notebooks converted to Markdown or PDF formats. --- @@ -16,12 +16,12 @@ Contained within this repository is a comprehensive and automated code graph ana ### 📖 Jupyter Notebook Reports -- [External Dependencies](./jupyter/ExternalDependencies.ipynb) reports with amongst others the most and least used external packages ([Example](./results/AxonFramework-4.7.5/external-dependencies/ExternalDependencies.md)) -- [Object Oriented Design Quality Metrics](./jupyter/ObjectOrientedDesignMetrics.ipynb) report based on [OO Design Quality Metrics by Robert Martin](https://www.semanticscholar.org/paper/OO-Design-Quality-Metrics-Martin-October/18acd7eb21b918c8a5f619157f7e4f6d451d18f8) ([Example](./results/AxonFramework-4.7.5/object-oriented-design-metrics/ObjectOrientedDesignMetrics.md)) -- [Overview](./jupyter/Overview.ipynb) reports with the number of Java types and packages, method line count, etc. ([Example](./results/AxonFramework-4.7.5/overview/Overview.md)) -- [Internal Dependencies](./jupyter/InternalDependencies.ipynb) report based on [Analyze java package metrics in a graph database](https://joht.github.io/johtizen/data/2023/04/21/java-package-metrics-analysis.html) including cyclic dependencies ([Example](./results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.md)) -- [Visibility Metrics](./jupyter/VisibilityMetrics.ipynb) reports based on [Visibility Metrics and the Importance of Hiding Things](https://dzone.com/articles/visibility-metrics-and-the-importance-of-hiding-th) ([Example](./results/AxonFramework-4.7.5/visibility-metrics/VisibilityMetrics.md)) -- [Wordcloud](./jupyter/Wordcloud.ipynb) with a visual representation of Java package and class names ([Example](./results/AxonFramework-4.7.5/wordcloud/Wordcloud.md)) +- [External Dependencies](./jupyter/ExternalDependencies.ipynb) contains the most and least used external packages, etc. ([Example](./results/AxonFramework-4.7.5/external-dependencies/ExternalDependencies.md)) +- [Object Oriented Design Quality Metrics](./jupyter/ObjectOrientedDesignMetrics.ipynb) is based on [OO Design Quality Metrics by Robert Martin](https://www.semanticscholar.org/paper/OO-Design-Quality-Metrics-Martin-October/18acd7eb21b918c8a5f619157f7e4f6d451d18f8) ([Example](./results/AxonFramework-4.7.5/object-oriented-design-metrics/ObjectOrientedDesignMetrics.md)) +- [Overview](./jupyter/Overview.ipynb) contains the number of types and packages, method line count, cyclomatic complexity, etc. ([Example](./results/AxonFramework-4.7.5/overview/Overview.md)) +- [Internal Dependencies](./jupyter/InternalDependencies.ipynb) is based on [Analyze java package metrics in a graph database](https://joht.github.io/johtizen/data/2023/04/21/java-package-metrics-analysis.html) including cyclic dependencies ([Example](./results/AxonFramework-4.7.5/internal-dependencies/InternalDependencies.md)) +- [Visibility Metrics](./jupyter/VisibilityMetrics.ipynb) is based on [Visibility Metrics and the Importance of Hiding Things](https://dzone.com/articles/visibility-metrics-and-the-importance-of-hiding-th) ([Example](./results/AxonFramework-4.7.5/visibility-metrics/VisibilityMetrics.md)) +- [Wordcloud](./jupyter/Wordcloud.ipynb) contains a visual representation of package and class names ([Example](./results/AxonFramework-4.7.5/wordcloud/Wordcloud.md)) ### 📖 Graph Data Science Reports @@ -42,14 +42,13 @@ Here are some reports that utilize Neo4j's [Graph Data Science Library](https:// ## 🛠 Prerequisites -- Java 11 is required (June 2023 Neo4j 4.x requirement) -- Python with a conda package manager is needed for Jupyter Notebook reports -- Chromium will automatically be downloaded if needed for Jupyter Notebook reports in PDF format. +- Java 17 is required (June 2023 Neo4j 5.x requirement) +- Python and a conda package manager are required for Jupyter Notebook reports +- Chromium will automatically be downloaded if needed for Jupyter Notebook reports in PDF format ## Getting Started -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. +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. ## 🏗 Pipeline and Tools From 209461a66c1b6caea68e4ea123e1f0f9a6817eab Mon Sep 17 00:00:00 2001 From: JohT Date: Sat, 1 Jul 2023 09:10:58 +0200 Subject: [PATCH 6/6] Try another main picture in documentation --- README.md | 2 +- images/DALL-E-Mini-Graph-Pipeline-Logo-2.png | Bin 0 -> 55986 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 images/DALL-E-Mini-Graph-Pipeline-Logo-2.png diff --git a/README.md b/README.md index 93a22f5ee..7e57640a8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Code Graph Analysis Pipeline - + Contained within this repository is a comprehensive and automated code graph analysis pipeline. While initially designed to support Java through the utilization of [jQAssistant](https://jqassistant.org/get-started), it is open to extension for further programming languages. The graph database [Neo4j](https://neo4j.com) serves as the foundation for storing and querying the graph, which encompasses all the structural intricacies of the analyzed code. Additionally, Neo4j's [Graph Data Science](https://neo4j.com/product/graph-data-science) provides additional algorithms like community detection to analyze the code structure. The generated reports offer flexibility, ranging from simple query results presented as CSV files to more elaborate Jupyter Notebooks converted to Markdown or PDF formats. diff --git a/images/DALL-E-Mini-Graph-Pipeline-Logo-2.png b/images/DALL-E-Mini-Graph-Pipeline-Logo-2.png new file mode 100644 index 0000000000000000000000000000000000000000..db34bfa6912b8b5befa091d212c68abb28d0522a GIT binary patch literal 55986 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

TH(HiVw}L8CuzNV>2*^3x`KfROhwrv~(yt&lF6b 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

YT_&!@7QcHxCZ;oJ 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