diff --git a/COMMANDS.md b/COMMANDS.md index db5a18ab9..c9f4d4043 100644 --- a/COMMANDS.md +++ b/COMMANDS.md @@ -76,10 +76,12 @@ The [analyze.sh](./scripts/analysis/analyze.sh) command comes with these command - `--profile Neo4jv5` uses the older long term support (march 2025) version v5.26.x of Neo4j and suitable compatible versions of plugins and JQAssistant. Without specifying a profile, the newest versions will be used. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). -- `--profile Neo4j-latest-continue-on-scan-errors` is based on the default profile (`Neo4j-latest`) but uses the jQAssistant configuration template [template-neo4j-remote-jqassistant-continue-on-error.yaml](./scripts/configuration/template-neo4j-remote-jqassistant-continue-on-error.yaml) to continue on scan error instead of failing fast. This is temporarily useful when there is a known error that needs to be ignored. It is still recommended to use the default profile and fail fast if there is something wrong. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). +- `--profile Neo4j-latest-continue-on-scan-errors` is based on the default profile (`Neo4j-latest`) but uses the jQAssistant configuration template [template-neo4jv5-jqassistant-continue-on-error.yaml](./scripts/configuration/template-neo4jv5-jqassistant-continue-on-error.yaml) to continue on scan error instead of failing fast. This is temporarily useful when there is a known error that needs to be ignored. It is still recommended to use the default profile and fail fast if there is something wrong. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). - `--profile Neo4j-latest-low-memory` is based on the default profile (`Neo4j-latest`) but uses only half of the memory (RAM) as configured in [template-neo4j-low-memory.conf](./scripts/configuration/template-neo4j-low-memory.conf). This is useful for the analysis of smaller codebases with less resources. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). +- `--profile Neo4j-latest-low-memory-continue-on-scan-errors` is based on the default profile (`Neo4j-latest`) but uses only half of the memory (RAM) as configured in [template-neo4j-low-memory.conf](./scripts/configuration/template-neo4j-low-memory.conf) and the jQAssistant configuration template [template-neo4jv5-jqassistant-continue-on-error.yaml](./scripts/configuration/template-neo4jv5-jqassistant-continue-on-error.yaml) to continue on scan error instead of failing fast. This is temporarily useful when there is a known error that needs to be ignored. It is still recommended to use the default profile and fail fast if there is something wrong. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). + - `--profile Neo4j-latest-high-memory` is based on the default profile (`Neo4j-latest`) but uses more memory (RAM) as configured in [template-neo4j-high-memory.conf](./scripts/configuration/template-neo4j-high-memory.conf). This is useful for the analysis of larger codebases with more resources. Other profiles can be found in the directory [scripts/profiles](./scripts/profiles/). - `--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. diff --git a/cypher/Internal_Dependencies/NPM_Package_build_levels_for_graphviz.cypher b/cypher/Internal_Dependencies/NPM_Package_build_levels_for_graphviz.cypher index 887c2fff1..e549044c3 100644 --- a/cypher/Internal_Dependencies/NPM_Package_build_levels_for_graphviz.cypher +++ b/cypher/Internal_Dependencies/NPM_Package_build_levels_for_graphviz.cypher @@ -16,8 +16,10 @@ WITH *, round((normalizedWeight * 5) + 1, 2) AS penWidth WITH *, "\\n(level " + coalesce(source.maxDistanceFromSource + "/" + maxLevel, "?") + ")" AS sourceLevelInfo WITH *, "\\n(level " + coalesce(target.maxDistanceFromSource + "/" + maxLevel, "?") + ")" AS targetLevelInfo - WITH *, source.name + sourceLevelInfo AS fullSourceName - WITH *, target.name + targetLevelInfo AS fullTargetName + WITH *, CASE WHEN source:NpmDevPackage THEN "\\n[dev]" ELSE "" END AS sourceDevDependencyInfo + WITH *, CASE WHEN target:NpmDevPackage THEN "\\n[dev]" ELSE "" END AS targetDevDependencyInfo + WITH *, source.name + sourceLevelInfo + sourceDevDependencyInfo AS fullSourceName + WITH *, target.name + targetLevelInfo + targetDevDependencyInfo AS fullTargetName WITH *, "\" -> \"" + fullTargetName + "\" [label = " + dependency.weightByDependencyType + ";" + " penwidth = " + penWidth + ";" diff --git a/cypher/Path_Finding/Set_Parameters_NPM.cypher b/cypher/Path_Finding/Set_Parameters_NonDevNpmPackage.cypher similarity index 63% rename from cypher/Path_Finding/Set_Parameters_NPM.cypher rename to cypher/Path_Finding/Set_Parameters_NonDevNpmPackage.cypher index 8ca29d24a..e032d5534 100644 --- a/cypher/Path_Finding/Set_Parameters_NPM.cypher +++ b/cypher/Path_Finding/Set_Parameters_NonDevNpmPackage.cypher @@ -2,7 +2,7 @@ :params { "dependencies_projection_language":"NPM", - "dependencies_projection": "npm-package-path-finding", - "dependencies_projection_node": "Package", + "dependencies_projection": "npm-non-dev-package-path-finding", + "dependencies_projection_node": "NpmNonDevPackage", "dependencies_projection_weight_property": "weightByDependencyType", } \ No newline at end of file diff --git a/cypher/Typescript_Enrichment/Label_npm_packages_by_dep_type.cypher b/cypher/Typescript_Enrichment/Label_npm_packages_by_dep_type.cypher new file mode 100644 index 000000000..29ab70b4a --- /dev/null +++ b/cypher/Typescript_Enrichment/Label_npm_packages_by_dep_type.cypher @@ -0,0 +1,26 @@ +// Label NPM packages as NpmDevPackage or NpmNonDevPackage based on incoming DEPENDS_ON. Requires Link_npm_packages_with_depends_on_relationships.cypher +// For each package node, calculate the maximum `weightByDependencyType` across incoming +// `DEPENDS_ON` relationships. If the max is 1 -> label `NpmDevPackage`; if > 1 -> label +// `NpmNonDevPackage`. If the property is missing or < 1 then no label is added. +// weightByDependencyType= 1 is a dev dependency, 2 is a regular dependency, and 3 is a peer dependency. + +MATCH (packageNode:NPM:Package) +OPTIONAL MATCH (packageNode)<-[dependsOnRel:DEPENDS_ON]-() +WITH packageNode, max(dependsOnRel.weightByDependencyType) AS maxWeight + +CALL { + WITH packageNode, maxWeight + FOREACH (_ IN CASE WHEN maxWeight = 1 THEN [1] ELSE [] END | + SET packageNode:NpmDevPackage + ) + + FOREACH (_ IN CASE WHEN maxWeight > 1 THEN [1] ELSE [] END | + SET packageNode:NpmNonDevPackage + ) +} IN TRANSACTIONS OF 1000 ROWS + +RETURN count(packageNode) AS evaluatedPackages, + sum(CASE WHEN maxWeight = 1 THEN 1 ELSE 0 END) AS numberOfNpmDevPackages, + sum(CASE WHEN maxWeight > 1 THEN 1 ELSE 0 END) AS numberOfNpmNonDevPackages, + sum(CASE WHEN maxWeight IS NULL THEN 1 ELSE 0 END) AS numberOfPackagesWithMissingWeight, + sum(CASE WHEN maxWeight < 1 AND maxWeight IS NOT NULL THEN 1 ELSE 0 END) AS numberOfPackagesWithWeightBelowOne \ No newline at end of file diff --git a/cypher/Typescript_Enrichment/Remove_npm_dependency_type_labels.cypher b/cypher/Typescript_Enrichment/Remove_npm_dependency_type_labels.cypher new file mode 100644 index 000000000..4dba6d4a6 --- /dev/null +++ b/cypher/Typescript_Enrichment/Remove_npm_dependency_type_labels.cypher @@ -0,0 +1,5 @@ +// Remove NPM package type labels (idempotent). + + MATCH (packageNode:NPM:Package) +REMOVE packageNode:NpmDevPackage +REMOVE packageNode:NpmNonDevPackage diff --git a/scripts/findPathsToScan.sh b/scripts/findPathsToScan.sh index 76c5e43a3..f72f16bfb 100755 --- a/scripts/findPathsToScan.sh +++ b/scripts/findPathsToScan.sh @@ -54,7 +54,18 @@ else fi if [ -d "./${SOURCE_DIRECTORY}" ] ; then + # Scan package.json files for npm (nodes package manager) in the source directory + # Since the following issue had been resolved, the scan can be done here again: + # https://github.com/jqassistant-plugin/jqassistant-npm-plugin/issues/5 + npmPackageJsonFiles="$(findPackageJsonFiles "./${SOURCE_DIRECTORY}")" + if [ -n "${npmPackageJsonFiles}" ]; then + directoriesAndFilesToScan="$(appendNonEmpty "${directoriesAndFilesToScan}")${npmPackageJsonFiles}" + fi + # Scan Typescript analysis json data files in the source directory + # Since Typescript scan might produce duplicate fileName properties on File nodes, + # it is done after the npm package.json scan, that breaks the scan on duplicate fileName properties. + # This order fixes "XOException: Expected exactly one result, but got CompositeRowObject". typescriptAnalysisFiles="$(find -L "./${SOURCE_DIRECTORY}" \ -type d -name "node_modules" -prune -o \ -type d -name "dist" -prune -o \ @@ -69,14 +80,6 @@ if [ -d "./${SOURCE_DIRECTORY}" ] ; then directoriesAndFilesToScan="$(appendNonEmpty "${directoriesAndFilesToScan}")${typescriptAnalysisFiles}" fi - # Scan package.json files for npm (nodes package manager) in the source directory - # Since the following issue had been resolved, the scan be done here again: - # https://github.com/jqassistant-plugin/jqassistant-npm-plugin/issues/5 - npmPackageJsonFiles="$(findPackageJsonFiles "./${SOURCE_DIRECTORY}")" - if [ -n "${npmPackageJsonFiles}" ]; then - directoriesAndFilesToScan="$(appendNonEmpty "${directoriesAndFilesToScan}")${npmPackageJsonFiles}" - fi - # Scan git repositories in the artifacts directory if [ "${IMPORT_GIT_LOG_DATA_IF_SOURCE_IS_PRESENT}" = "" ] || [ "${IMPORT_GIT_LOG_DATA_IF_SOURCE_IS_PRESENT}" = "plugin" ] ; then gitDirectories="$(find -L "./${SOURCE_DIRECTORY}" \ diff --git a/scripts/prepareAnalysis.sh b/scripts/prepareAnalysis.sh index 62485b9b9..206e978d9 100644 --- a/scripts/prepareAnalysis.sh +++ b/scripts/prepareAnalysis.sh @@ -79,6 +79,8 @@ execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Remove_duplicate_CONTAINS_relations_bet execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Link_npm_dependencies_to_npm_packages.cypher" execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Link_npm_packages_with_depends_on_relationships.cypher" execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Enrich_npm_packages_with_dependency_counts.cypher" +execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Remove_npm_dependency_type_labels.cypher" +execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Label_npm_packages_by_dep_type.cypher" execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Link_projects_to_npm_packages.cypher" dataVerificationResult=$( execute_cypher "${TYPESCRIPT_CYPHER_DIR}/Verify_projects_linked_to_npm_packages.cypher" "${@}") if is_csv_column_greater_zero "${dataVerificationResult}" "unresolvedProjectsCount"; then diff --git a/scripts/profiles/Neo4j-latest-low-memory-continue-on-scan-errors.sh b/scripts/profiles/Neo4j-latest-low-memory-continue-on-scan-errors.sh new file mode 100755 index 000000000..f39da2236 --- /dev/null +++ b/scripts/profiles/Neo4j-latest-low-memory-continue-on-scan-errors.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Sets all settings variables for a low memory, continue-on-error analysis with the latest version of Neo4j. +# The chosen settings are tested to be compatible and working. + +NEO4J_VERSION=${NEO4J_VERSION:-"2026.01.4"} # Neo4j Graph Database Version. Current versions: >= 2025.03.0. Version 4.4.42 and 5.26.5 are the previous LTS (long term support) versions as of April 2025. +NEO4J_HTTP_TRANSACTION_ENDPOINT=${NEO4J_HTTP_TRANSACTION_ENDPOINT:-"db/neo4j/tx/commit"} +NEO4J_CONFIG_TEMPLATE=${NEO4J_CONFIG_TEMPLATE:-"template-neo4j-low-memory.conf"} + +# Awesome Procedures (APOC) Plugin for Neo4j +NEO4J_APOC_PLUGIN_VERSION=${NEO4J_APOC_PLUGIN_VERSION:-"2026.01.4"} +NEO4J_APOC_PLUGIN_EDITION=${NEO4J_APOC_PLUGIN_EDITION:-"core"} +NEO4J_APOC_PLUGIN_GITHUB=${NEO4J_APOC_PLUGIN_GITHUB:-"neo4j/apoc"} + +NEO4J_GDS_PLUGIN_VERSION=${NEO4J_GDS_PLUGIN_VERSION:-"2.26.0"} +NEO4J_OPEN_GDS_PLUGIN_VERSION=${NEO4J_OPEN_GDS_PLUGIN_VERSION:-"2.26.0"} +NEO4J_GDS_PLUGIN_EDITION=${NEO4J_GDS_PLUGIN_EDITION:-"open"} + +JQASSISTANT_CLI_VERSION=${JQASSISTANT_CLI_VERSION:-"2.9.0"} +JQASSISTANT_CLI_ARTIFACT=${JQASSISTANT_CLI_ARTIFACT:-"jqassistant-commandline-neo4jv5"} +JQASSISTANT_CONFIG_TEMPLATE=${JQASSISTANT_CONFIG_TEMPLATE:-"template-neo4jv5-jqassistant-continue-on-error.yaml"} \ No newline at end of file diff --git a/scripts/reports/CentralityCsv.sh b/scripts/reports/CentralityCsv.sh index 6113ce049..87295b167 100755 --- a/scripts/reports/CentralityCsv.sh +++ b/scripts/reports/CentralityCsv.sh @@ -439,12 +439,12 @@ if createUndirectedDependencyProjection "${MODULE_LANGUAGE}" "${MODULE_PROJECTIO runUndirectedCentralityAlgorithms "${MODULE_PROJECTION_UNDIRECTED}" "${MODULE_NODE}" fi -# -- NPM Package Centrality --------------------------------------- +# -- Non Dev NPM Package Centrality --------------------------------------- NPM_LANGUAGE="dependencies_projection_language=NPM" -NPM_PROJECTION="dependencies_projection=npm-package-centrality" -NPM_PROJECTION_UNDIRECTED="dependencies_projection=npm-package-centrality-undirected" -NPM_NODE="dependencies_projection_node=Package" +NPM_PROJECTION="dependencies_projection=npm-non-dev-package-centrality" +NPM_PROJECTION_UNDIRECTED="dependencies_projection=npm-non-dev-package-centrality-undirected" +NPM_NODE="dependencies_projection_node=NpmNonDevPackage" NPM_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}"; then diff --git a/scripts/reports/PathFindingCsv.sh b/scripts/reports/PathFindingCsv.sh index 3359641b6..d6b663fde 100755 --- a/scripts/reports/PathFindingCsv.sh +++ b/scripts/reports/PathFindingCsv.sh @@ -140,16 +140,28 @@ if createDirectedDependencyProjection "${MODULE_LANGUAGE}" "${MODULE_PROJECTION} runPathFindingAlgorithms "${MODULE_PROJECTION}" "${MODULE_NODE}" "${MODULE_WEIGHT}" fi -# -- NPM Package Path Finding ------------------------------- +# -- Non Dev NPM Package Path Finding ------------------------------- NPM_LANGUAGE="dependencies_projection_language=NPM" -NPM_PROJECTION="dependencies_projection=npm-package-path-finding" -NPM_NODE="dependencies_projection_node=Package" +NPM_PROJECTION="dependencies_projection=npm-non-dev-package-path-finding" +NPM_NODE="dependencies_projection_node=NpmNonDevPackage" NPM_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}"; then runPathFindingAlgorithms "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}" fi + +# -- Dev NPM Package Path Finding ------------------------------- + +NPM_DEV_LANGUAGE="dependencies_projection_language=NPM" +NPM_DEV_PROJECTION="dependencies_projection=npm-dev-package-path-finding" +NPM_DEV_NODE="dependencies_projection_node=NpmDevPackage" +NPM_DEV_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" + +if createDirectedDependencyProjection "${NPM_DEV_LANGUAGE}" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}"; then + runPathFindingAlgorithms "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}" +fi + # --------------------------------------------------------------- # Clean-up after report generation. Empty reports will be deleted. diff --git a/scripts/reports/PathFindingVisualization.sh b/scripts/reports/PathFindingVisualization.sh index dd0ff8afb..22deb903c 100755 --- a/scripts/reports/PathFindingVisualization.sh +++ b/scripts/reports/PathFindingVisualization.sh @@ -90,10 +90,10 @@ if createDirectedDependencyProjection "${MODULE_LANGUAGE}" "${MODULE_PROJECTION} source "${VISUALIZATION_SCRIPTS_DIR}/visualizeQueryResults.sh" "${FULL_REPORT_DIRECTORY}/${reportName}.csv" fi -# NPM Packages: Longest Paths Visualization +# Non Dev NPM Packages: Longest Paths Visualization NPM_LANGUAGE="dependencies_projection_language=NPM" -NPM_PROJECTION="dependencies_projection=npm-package-path-finding" -NPM_NODE="dependencies_projection_node=Package" +NPM_PROJECTION="dependencies_projection=npm-non-dev-package-path-finding" +NPM_NODE="dependencies_projection_node=NpmNonDevPackage" NPM_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}"; then @@ -101,16 +101,39 @@ if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_PROJECTION}" "${N execute_cypher_queries_until_results "${TOPOLOGICAL_SORT_CYPHER_DIR}/Topological_Sort_Exists.cypher" \ "${TOPOLOGICAL_SORT_CYPHER_DIR}/Topological_Sort_Write.cypher" "${NPM_PROJECTION}" "${NPM_NODE}" - reportName="NpmPackageLongestPathsIsolated" + reportName="NpmNonDevPackageLongestPathsIsolated" echo "${SCRIPT_NAME}: Creating visualization ${reportName}..." execute_cypher "${PATH_FINDINGS_CYPHER_DIR}/Path_Finding_6_Longest_paths_for_graphviz.cypher" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}" > "${FULL_REPORT_DIRECTORY}/${reportName}.csv" source "${VISUALIZATION_SCRIPTS_DIR}/visualizeQueryResults.sh" "${FULL_REPORT_DIRECTORY}/${reportName}.csv" - reportName="NpmPackageLongestPaths" + reportName="NpmNonDevPackageLongestPaths" echo "${SCRIPT_NAME}: Creating visualization ${reportName}..." execute_cypher "${PATH_FINDINGS_CYPHER_DIR}/Path_Finding_6_Longest_paths_contributors_for_graphviz.cypher" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}" > "${FULL_REPORT_DIRECTORY}/${reportName}.csv" source "${VISUALIZATION_SCRIPTS_DIR}/visualizeQueryResults.sh" "${FULL_REPORT_DIRECTORY}/${reportName}.csv" fi +# Dev NPM Packages: Longest Paths Visualization + +NPM_DEV_LANGUAGE="dependencies_projection_language=NPM" +NPM_DEV_PROJECTION="dependencies_projection=npm-dev-package-path-finding" +NPM_DEV_NODE="dependencies_projection_node=NpmDevPackage" +NPM_DEV_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" + +if createDirectedDependencyProjection "${NPM_DEV_LANGUAGE}" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}"; then + # Determines topological sort max distance from source if not already done for level info in visualization. + execute_cypher_queries_until_results "${TOPOLOGICAL_SORT_CYPHER_DIR}/Topological_Sort_Exists.cypher" \ + "${TOPOLOGICAL_SORT_CYPHER_DIR}/Topological_Sort_Write.cypher" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" + + reportName="NpmDevPackageLongestPathsIsolated" + echo "${SCRIPT_NAME}: Creating visualization ${reportName}..." + execute_cypher "${PATH_FINDINGS_CYPHER_DIR}/Path_Finding_6_Longest_paths_for_graphviz.cypher" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}" > "${FULL_REPORT_DIRECTORY}/${reportName}.csv" + source "${VISUALIZATION_SCRIPTS_DIR}/visualizeQueryResults.sh" "${FULL_REPORT_DIRECTORY}/${reportName}.csv" + + reportName="NpmDevPackageLongestPaths" + echo "${SCRIPT_NAME}: Creating visualization ${reportName}..." + execute_cypher "${PATH_FINDINGS_CYPHER_DIR}/Path_Finding_6_Longest_paths_contributors_for_graphviz.cypher" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}" > "${FULL_REPORT_DIRECTORY}/${reportName}.csv" + source "${VISUALIZATION_SCRIPTS_DIR}/visualizeQueryResults.sh" "${FULL_REPORT_DIRECTORY}/${reportName}.csv" +fi + # Clean-up after report generation. Empty reports will be deleted. source "${SCRIPTS_DIR}/cleanupAfterReportGeneration.sh" "${FULL_REPORT_DIRECTORY}" \ No newline at end of file diff --git a/scripts/reports/TopologicalSortCsv.sh b/scripts/reports/TopologicalSortCsv.sh index be67cc528..400b0b1f0 100755 --- a/scripts/reports/TopologicalSortCsv.sh +++ b/scripts/reports/TopologicalSortCsv.sh @@ -103,17 +103,28 @@ if createDirectedDependencyProjection "${MODULE_LANGUAGE}" "${MODULE_PROJECTION} time topologicalSort "${MODULE_PROJECTION}" "${MODULE_NODE}" "${MODULE_WEIGHT}" fi -# -- NPM Package Topology --------------------------------------- +# -- Non Dev NPM Package Topology --------------------------------------- NPM_LANGUAGE="dependencies_projection_language=NPM" -NPM_PROJECTION="dependencies_projection=npm-package-topology" -NPM_NODE="dependencies_projection_node=Package" +NPM_PROJECTION="dependencies_projection=npm-non-dev-package-topology" +NPM_NODE="dependencies_projection_node=NpmNonDevPackage" NPM_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}"; then time topologicalSort "${NPM_PROJECTION}" "${NPM_NODE}" "${NPM_WEIGHT}" fi +# -- Dev NPM Package Topology -------------------------------------------- + +NPM_DEV_PROJECTION="dependencies_projection=npm-dev-package-topology" +NPM_DEV_NODE="dependencies_projection_node=NpmDevPackage" +NPM_DEV_WEIGHT="dependencies_projection_weight_property=weightByDependencyType" + +if createDirectedDependencyProjection "${NPM_LANGUAGE}" "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}"; then + time topologicalSort "${NPM_DEV_PROJECTION}" "${NPM_DEV_NODE}" "${NPM_DEV_WEIGHT}" +fi +# ---------------------------------------------------------------------- + # Clean-up after report generation. Empty reports will be deleted. source "${SCRIPTS_DIR}/cleanupAfterReportGeneration.sh" "${FULL_REPORT_DIRECTORY}"