Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document describes the steps to get started as quickly as possible.

## 🛠 Prerequisites

Please read through the [Prerequisites](./README.md#hammer_and_wrench-prerequisites) in the [README](./README.md) file for what is required to run the scripts.
Please read through the [Prerequisites](./README.md#hammer_and_wrench-prerequisites) in the [README](./README.md) file for what is required to run the scripts or simply run the [checkCompatibility.sh](./scripts/checkCompatibility.sh) script to verify that your environment is set up correctly.

## The easiest way to get started

Expand Down Expand Up @@ -40,8 +40,6 @@ Use these optional command line options as needed:

### 1. Setup

- Have a look at the [prerequisites](./README.md#hammer_and_wrench-prerequisites).

- Choose an initial password for Neo4j if not already done.

```shell
Expand Down Expand Up @@ -96,12 +94,18 @@ Use these optional command line options as needed:
./../../scripts/analysis/analyze.sh --report Python
```

- Graph visualizations when Node.js and npm are installed:
- Graph visualizations with GraphViz installed or npx to run it indirectly:

```shell
./../../scripts/analysis/analyze.sh --report Visualization
```

- Markdown reports:

```shell
./../../scripts/analysis/analyze.sh --report Markdown
```

- All reports with Python, Conda (or venv), Node.js and npm installed:

```shell
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ Here are some fully automated graph visualizations utilizing [GraphViz](https://

## :hammer_and_wrench: Prerequisites

Run [scripts/checkCompatibility.sh](./scripts/checkCompatibility.sh) to check if all required dependencies are installed and available in your environment.

- Java 21 is [required since Neo4j 2025.01](https://neo4j.com/docs/operations-manual/current/installation/requirements/#deployment-requirements-java). See also [Changes from Neo4j 5 to 2025.x](https://neo4j.com/docs/upgrade-migration-guide/current/version-2025/upgrade).
- Java 17 is [required for Neo4j 5](https://neo4j.com/docs/operations-manual/current/installation/requirements/#deployment-requirements-java).
- On Windows it is recommended to use the git bash provided by [git for windows](https://github.com/git-guides/install-git#install-git-on-windows).
Expand Down
57 changes: 44 additions & 13 deletions init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,51 @@

# Note: This script needs to be executed in the root of this directory (= same directory as this file)

# Requires analyze.sh, startNeo4j.sh, stopNeo4j.sh, checkCompatibility.sh

# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
set -o errexit -o pipefail

# Overrideable Defaults
ARTIFACTS_DIRECTORY=${ARTIFACTS_DIRECTORY:-"artifacts"}
SOURCE_DIRECTORY=${SOURCE_DIRECTORY:-"source"}

# Read the first (and only) parameter containing the name of the analysis.
## Get this "scripts" directory if not already set
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
# This way non-standard tools like readlink aren't needed.
SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts

# Local constants
SCRIPT_NAME=$(basename "${0}")
ERROR_COLOR='\033[0;31m'
NO_COLOR='\033[0m'

fail() {
echo -e "${ERROR_COLOR}${SCRIPT_NAME}: ${1}${NO_COLOR}" >&2
if [ -n "${2}" ]; then
echo -e "${ERROR_COLOR}${SCRIPT_NAME}: ${2}${NO_COLOR}" >&2
fi
exit 1
}

# Validate the first (and only) parameter containing the name of the analysis.
analysisName="${1}"
if [ -z "${analysisName}" ]; then
echo "init: Error: Missing parameter <analysisName>." >&2
echo "init: Usage example: ${0} <analysisName>" >&2
exit 1
fail "Please specify the name of the project you want to analyze." "Example: ${0} my-project"
fi
if [ -d "./temp/${analysisName}" ]; then
fail "Analysis project '${analysisName}' already exists in './temp/${analysisName}' directory." "Choose another name or delete it using 'rm -rf ./temp/${analysisName}' first and re-run the script."
fi

nameOfThisScript=$(basename "${0}")
if [ ! -f "./${nameOfThisScript}" ]; then
echo "init: Error: Please execute the script in the root directory of the code-graph-analysis-pipeline repository." >&2
echo "init: Change to the directory of this ${nameOfThisScript} script and execute it from there." >&2
exit 1
# Validate the execution directory
if [ ! -f "./${SCRIPT_NAME}" ]; then
fail "Please re-execute the script in the root directory of the repository." "Use 'cd <path-to-repo>' and re-run the script."
fi

# Check if initial password environment variable is set
# Assure that the environment variable containing the Neo4j password is set
if [ -z "${NEO4J_INITIAL_PASSWORD}" ]; then
echo "init: Error: Environment variable NEO4J_INITIAL_PASSWORD is recommended to be set first. Use 'export NEO4J_INITIAL_PASSWORD=<your-own-password>'."
exit 1
fail "Please set NEO4J_INITIAL_PASSWORD before running this script to avoid Neo4j startup issues later." "Use 'export NEO4J_INITIAL_PASSWORD=<your-own-password>' and re-run the script."
fi

createForwardingScript() {
Expand Down Expand Up @@ -60,4 +80,15 @@ createForwardingScript "./../../scripts/analysis/analyze.sh"
createForwardingScript "./../../scripts/startNeo4j.sh"
createForwardingScript "./../../scripts/stopNeo4j.sh"

echo "init: Successfully initialized analysis project ${analysisName}" >&2
source "${SCRIPTS_DIR}/scripts/checkCompatibility.sh"

echo ""
echo "${SCRIPT_NAME}: Successfully initialized analysis project ${analysisName}"
echo ""
echo "${SCRIPT_NAME}: Next steps:"
echo "${SCRIPT_NAME}: 1) Place your artifacts (e.g., Java jar/ear files) into this directory:"
echo "${SCRIPT_NAME}: $(pwd)/${ARTIFACTS_DIRECTORY}"
echo "${SCRIPT_NAME}: 2) (Optional) Place your source code projects/repositories into this directory:"
echo "${SCRIPT_NAME}: $(pwd)/${SOURCE_DIRECTORY}"
echo "${SCRIPT_NAME}: 3) Run './analyze.sh' inside 'temp/${analysisName}' to start the analysis."
echo ""
2 changes: 1 addition & 1 deletion scripts/activatePythonEnvironment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ VENV_DIRECTORY=".venv"
if [ ! -d "${ROOT_DIRECTORY}/${VENV_DIRECTORY}" ]; then
deactivate_conda_if_necessary
echo "activatePythonEnvironment: Creating ${VENV_DIRECTORY} environment..."
python3 -m venv "${ROOT_DIRECTORY}/${VENV_DIRECTORY}"
python -m venv "${ROOT_DIRECTORY}/${VENV_DIRECTORY}"
else
echo "activatePythonEnvironment: Already created ${VENV_DIRECTORY} environment."
fi
Expand Down
172 changes: 172 additions & 0 deletions scripts/checkCompatibility.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#!/usr/bin/env bash

# Check environment dependencies and tool availability.

# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
set -o errexit -o pipefail

# Overrideable Defaults

## Get this "scripts" directory if not already set
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
# This way non-standard tools like readlink aren't needed.
SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
#echo "checkCompatibility: SCRIPTS_DIR=${SCRIPTS_DIR}"

checkCommand() {
local cmd="$1"
local description="$2"
local missing_icon="$3"
local present_icon="${4:-✅}"

if command -v "${cmd}" &> /dev/null; then
echo " ${present_icon} ${cmd} - ${description}"
else
echo " ${missing_icon} ${cmd} - ${description}"
fi
}

checkRequiredCommand() {
checkCommand "$1" "$2" "❌" ""
}

checkOptionalCommand() {
checkCommand "$1" "$2" "⚠️ " "✅"
}

checkRequiredJavaVersion() {
required_java_version="$1"

if [ -z "${required_java_version}" ]; then
echo "Usage: check_java_version <major-version>" 1>&2
return 2
fi

if ! command -v "java" &> /dev/null; then
echo " ❌ java - Java Development Kit (https://adoptium.net/) for running Java applications is not installed."
return 0
fi
# Capture the first line of `java -version` (macOS & Linux both print to stderr)
java_version_output=$(java -version 2>&1 | head -n 1)

# Extract the version inside the first quotes
# Examples:
# openjdk version "17.0.2"
# java version "1.8.0_312"
# Use shell parameter expansion instead of external sed for portability and performance
full_java_version="${java_version_output#*\"}"
java_version="${full_java_version%%\"*}"

# Extract major version number supporting both Java 8 and older (1.x) and Java 9+ formats
case "${java_version}" in
1.*)
# Java 8 and older -> "1.8.0_xxx" → major = 8
java_version="${java_version#1.}"
java_version="${java_version%%.*}"
;;
*)
# Java 9+ -> "17.0.2" → major = 17
java_version="${java_version%%.*}"
;;
esac

# Compare numeric versions
if [ "${java_version}" -ge "${required_java_version}" ]; then
echo " ✅ java - Java version ${java_version} meets required version ${required_java_version}"
else
echo " ❌ java - Java version ${required_java_version} or higher is required, but found version ${java_version}"
fi
}

oneOf() {
for option in "$@"; do
if command -v "$option" &> /dev/null; then
echo "✅"
return 0
fi
done
echo "❌"
}

allOf() {
for option in "$@"; do
if ! command -v "$option" &> /dev/null; then
echo "❌"
return 0
fi
done
echo "✅"
}

isFailed() {
if [ "$1" = "❌" ]; then
return 0
else
return 1
fi
}

echo ""
echo "Checking environment dependencies and tool availability..."
echo ""
echo "--------------------------------"

# Check required main dependencies
icon=$(allOf "bash" "awk" "wc" "sed" "grep" "curl" "jq" "git" "java")
echo "${icon} Minimum required dependencies:"
checkRequiredCommand "bash" "Bourne Again SHell (https://www.gnu.org/software/bash/) for running the shell scripts"
checkRequiredCommand "awk" "Text processing tool (https://www.gnu.org/software/gawk/) for processing text files"
checkRequiredCommand "wc" "Word, line, character, byte count tool (https://www.gnu.org/software/coreutils/wc/) for counting lines in files"
checkRequiredCommand "sed" "Stream editor (https://www.gnu.org/software/sed/) for parsing and transforming text"
checkRequiredCommand "grep" "Text search tool (https://www.gnu.org/software/grep/) for text searching with regular expressions"
checkRequiredCommand "curl" "Command line tool for transferring data with URLs (https://curl.se/) for HTTP requests to Neo4j"
checkRequiredCommand "jq" "Command-line JSON processor (https://stedolan.github.io/jq/) for parsing JSON results from Neo4j"
checkRequiredCommand "git" "Version control system (https://git-scm.com/) for managing source code repositories"
checkRequiredJavaVersion "21"

if isFailed "${icon}"; then
echo ""
echo "${icon} One or more minimum required dependencies are missing. Please install them and re-run this script."
echo "--------------------------------"
echo ""
exit 1
fi

# Check dependencies for Typescript project analysis:
icon=$(allOf "npx" "npm")
echo ""
echo "${icon} Typescript project analysis dependencies:"
checkRequiredCommand "npx" "Tool to run npm packages without installing them globally (https://docs.npmjs.com/cli/v9/commands/npx)"
checkRequiredCommand "npm" "Node.js package manager (https://docs.npmjs.com/) for managing JavaScript packages"

# Check dependencies for Python environments
icon=$(oneOf "conda" "venv")
echo ""
echo "${icon} Python environment dependencies (for ./analyze.sh --report Python/Jupyter):"
checkOptionalCommand "conda" "Conda package and environment manager (https://docs.conda.io/en/latest/)"
checkOptionalCommand "virtualenv" "Python virtual environment module (https://docs.python.org/3/library/venv.html)"

# Check dependencies for Python reports
icon=$(allOf "python" "pip")
echo ""
echo "${icon} Python reports dependencies (for ./analyze.sh --report Python/Jupyter):"
checkRequiredCommand "python" "Python interpreter (https://www.python.org/) for running Python scripts"
checkRequiredCommand "pip" "Python package installer (https://pip.pypa.io/en/stable/) for installing Python packages"

# Check dependencies for Jupyter Notebook reports
icon=$(allOf "python" "pip" "jupyter")
echo ""
echo "${icon} Python reports dependencies (for ./analyze.sh --report Jupyter):"
checkRequiredCommand "jupyter" "Jupyter Notebook (https://jupyter.org/) for interactive data analysis and visualization"

# Check dependencies for visualization reports
icon=$(oneOf "npx" "dot")
echo ""
echo "${icon} Visualization report dependencies (for ./analyze.sh --report Visualization):"
checkOptionalCommand "npx" "Tool to run npm packages without installing them globally (https://docs.npmjs.com/cli/v9/commands/npx)"
checkOptionalCommand "npm" "Node.js package manager (https://docs.npmjs.com/) for managing JavaScript packages"
checkOptionalCommand "dot" "Graph visualization tool from GraphViz (https://graphviz.org/) for visualizing query results as graphs"

echo "--------------------------------"
echo ""
36 changes: 17 additions & 19 deletions scripts/examples/analyzeAntDesign.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,52 @@
# Note: This script is meant to be started in the root directory of this repository.
# Note: This script requires "cURL" ( https://curl.se ) to be installed.

# Requires: init.sh, downloadAntDesign.sh, analyze.sh

# Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
set -o errexit -o pipefail

# Local constants
SCRIPT_NAME=$(basename "${0}")

# Overrideable Defaults
SOURCE_DIRECTORY=${SOURCE_DIRECTORY:-"source"}
echo "analyzerAntDesign: SOURCE_DIRECTORY=${SOURCE_DIRECTORY}"
#echo "${SCRIPT_NAME}: SOURCE_DIRECTORY=${SOURCE_DIRECTORY}"

## Get this "scripts" directory if not already set
# Even if $BASH_SOURCE is made for Bourne-like shells it is also supported by others and therefore here the preferred solution.
# CDPATH reduces the scope of the cd command to potentially prevent unintended directory changes.
# This way non-standard tools like readlink aren't needed.
SCRIPTS_DIR=${SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
echo "analyzerAntDesign: SCRIPTS_DIR=$SCRIPTS_DIR"
EXAMPLE_SCRIPTS_DIR=${EXAMPLE_SCRIPTS_DIR:-$( CDPATH=. cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P )} # Repository directory containing the shell scripts
#echo "${SCRIPT_NAME}: EXAMPLE_SCRIPTS_DIR=${EXAMPLE_SCRIPTS_DIR}"

# Read the first unnamed input argument containing the version of the project
projectVersion=""
case "${1}" in
"--"*) ;; # Skipping named command line options to forward them later to the "analyze" command
*)
projectVersion="${1}"
echo "analyzerAntDesign: Project version set to ${projectVersion}"
echo "${SCRIPT_NAME}: Project version set to ${projectVersion}"
shift || true
;;
esac

if [ -z "${projectVersion}" ]; then
echo "analyzerAntDesign: Optional parameter <version> is not specified. Detecting latest version..." >&2
echo "analyzerAntDesign: Usage example: $0 <version> <optional analysis parameter>" >&2
projectVersion=$( "${SCRIPTS_DIR}/detectLatestGitTag.sh" --url "https://github.com/ant-design/ant-design.git" )
echo "analyzerAntDesign: Using latest version: ${projectVersion}" >&2
echo "${SCRIPT_NAME}: Optional parameter <version> is not specified. Detecting latest version..." >&2
echo "${SCRIPT_NAME}: Usage example: $0 <version> <optional analysis parameter>" >&2
projectVersion=$( "${EXAMPLE_SCRIPTS_DIR}/detectLatestGitTag.sh" --url "https://github.com/ant-design/ant-design.git" )
echo "${SCRIPT_NAME}: Using latest version: ${projectVersion}" >&2
fi

# Check if environment variable is set
if [ -z "${NEO4J_INITIAL_PASSWORD}" ]; then
echo "analyzerAntDesign: Error: Requires environment variable NEO4J_INITIAL_PASSWORD to be set first. Use 'export NEO4J_INITIAL_PASSWORD=<your-own-password>'."
echo "${SCRIPT_NAME}: Error: Requires environment variable NEO4J_INITIAL_PASSWORD to be set first. Use 'export NEO4J_INITIAL_PASSWORD=<your-own-password>'."
exit 1
fi

# Create the temporary directory for all analysis projects.
mkdir -p ./temp
cd ./temp

# Create the working directory for this specific analysis.
mkdir -p "./ant-design-${projectVersion}"
cd "./ant-design-${projectVersion}"

# Create the artifacts directory that will contain the code to be analyzed.
mkdir -p ./artifacts
# Initialize the analysis project
./init.sh "ant-design-${projectVersion}"
cd "temp/ant-design-${projectVersion}"

# Download ant-design source code
./../../scripts/downloader/downloadAntDesign.sh "${projectVersion}"
Expand Down
Loading
Loading