Emerge (emerge-viz)

repository·dev·Indexed 22 days ago

https://github.com/glato/emerge

An interactive code analysis tool that extracts metrics and structural insights from source code to generate force-directed graph visualizations. It supports a wide range of languages including Java, C, C++, Python, Go, and Swift. Key features include SLOC, Fan-In/Fan-Out, and Louvain modularity metrics, with exports available in GraphML, D3-compatible JSON, and interactive HTML web applications.

Tokens
4.1K
Snippets
9
Records
20
Agent score
28%

What's inside emerge-viz

  1. Overview of Emerge (emerge-viz)

    dev

    Emerge (also known as emerge-viz) is an interactive code analysis tool designed to gather insights into software project structure, metrics, dependencies, and complexity. It scans source code, calculates metrics (like SLOC, Fan-In/Fan-Out, and Louvain modularity), and generates interactive web applications featuring force-directed graphs (using D3.js) to visualize filesystem hierarchies, dependency graphs, and inheritance structures.

    Supported Languages:

    • File Scan: C, C++, Groovy, Java, JavaScript, TypeScript, Kotlin, ObjC, Ruby, Swift, Python, Go.
    • Entity Scan (Classes, etc.): Groovy, Java, Kotlin, Swift.

    Key Features:

    • Metrics: SLOC, Whitespace Complexity, Number of Methods, Fan-In/Fan-Out, Louvain Modularity, and experimental git-based metrics (Change Coupling, code churn).
    • Visualizations: Interactive HTML/web apps with dark mode, semantic search (TF-IDF), heatmap support, and cluster visualization.
    • Exports: GraphML, D3-compatible JSON, tabular console/file output, and interactive HTML.
  2. Identify modularity and code smells in architecture graphs

    dev

    Emerge generates force-directed graphs to visualize software architecture. You can interpret these graphs using specific visual indicators to assess code quality:

    • Modularity: Look for coherent, colored clusters with low coupling (minimal distance between clusters). Activating cluster hulls helps identify well-defined interfaces; minimal hull overlap indicates good abstraction and modularity.
    • Code Smells (God Classes/High Coupling): High overlap between clusters or large entities (visible via SLOC metrics) can indicate 'god classes' or increased maintenance effort.
    • Big Ball of Mud: If enabling hull rendering for all clusters results in a single large cluster, the architecture is likely a 'spaghetti code jungle' lacking clear structure.
    • Irrelevant Dependencies: Large-scale graphs may be cluttered by standard libraries (e.g., java.lang, java.util) or third-party dependencies. Removing these can reveal the true underlying architecture.
  3. Install Emerge via pip

    dev

    You can install Emerge directly into your Python environment using pip.

    Prerequisites (Ubuntu 20.04+): You must install graphviz and graphviz-dev before installing the Python package:

    apt-get install graphviz graphviz-dev

    Installation: To install the package:

    pip install emerge-viz

    To update an existing installation:

    pip install -U emerge-viz
    # Install prerequisites on Ubuntu
    apt-get install graphviz graphviz-dev
    
    # Install emerge
    pip install emerge-viz
  4. Run emerge unit tests

    dev

    You can run the project's unit tests from the cloned root directory using either the standard unittest module or the provided helper script.

    Using unittest:

    python -m unittest discover -v -s ./emerge -p "test_*.py"

    Using run_tests.py:

    python run_tests.py
    python run_tests.py
  5. Install emerge from source

    dev

    To install emerge for development, clone the repository and set up a virtual environment. Follow the specific steps for your operating system.

    macOS Setup

    1. Install graphviz via Homebrew:
      brew install graphviz
      Note for Apple Silicon: If you encounter graphviz/cgraph.h not found errors, run:
      pip install --global-option=build_ext --global-option="-I$(brew --prefix graphviz)/include/" --global-option="-L$(brew --prefix graphviz)/lib/" pygraphviz
    2. Create a virtual environment:
      cd emerge
      pip3 install virtualenv
      virtualenv -p python3 venv
    3. Activate the environment:
      source venv/bin/activate
    4. Install dependencies:
      pip install -r requirements.txt

    Ubuntu Setup

    1. Install prerequisites:
      apt-get install python3-venv python3-dev graphviz graphviz-dev
    2. Create and activate a virtual environment:
      cd emerge
      python3 -m venv venv
      source venv/bin/activate
    3. Install dependencies:
      pip install wheel
      pip install -r requirements.txt
    git clone https://github.com/glato/emerge.git
  6. Create and run a project analysis

    dev

    Follow these steps to perform a full analysis of your project:

    1. Generate a configuration template: Use the -a flag with a language keyword to create a template file (e.g., java-template.yaml).
      emerge -a java
    
    2. **Configure the template:**
       Open the generated `.yaml` file and adjust the `analyses.source_directory` and `export.directory` to point to your actual project paths.
    
    3. **Start the scan:**
       Run the analysis using the `-c` flag pointing to your config file.
       ```bash
    emerge -c java-template.yaml
    1. View results: Once finished, the console will provide a file:// path to an emerge.html file. Copy this path into a modern web browser to interact with the visualization.
    # 1. Create template
    emerge -a java
    
    # 2. Run analysis
    emerge -c java-template.yaml
    
    # 3. Open the output (example path)
    # file:///Users/user1/tmp/java/html/emerge.html
  7. Explore analysis results in the web app

    dev

    After running emerge, the tool generates an interactive web app. Locate the file:// path in the terminal output (e.g., file:///path/to/export/html/emerge.html) and open it in a modern web browser.

    Interactive Keyboard Shortcuts:

    • Select/Highlight Node: ⬆️ + s (Hover over a node first)
    • Reset Selection: ⬆️ + r
    • Fade Unselected Nodes: ⬆️ + f (Highlights the current selection by dimming others)
  8. Use Emerge as a Docker container

    dev

    The easiest way to run Emerge without local installation is via Docker.

    1. Prepare your working directory with the following structure:

      • config.yml: Your configuration file.
      • export/: A folder where results will be saved.
      • source/: A folder containing your source code.
    2. Run the analysis using the following command: docker run --rm -v <YOUR_WORKING_FOLDER_PATH>:/tmp/emerge achtelik/emerge:2.0.0 /tmp/emerge/config.yml

    Important Note on Paths: When using Docker, your analyses.source_directory and export.directory inside config.yml must start with /tmp/emerge because the analysis runs inside the container's filesystem mapping.

    # Directory structure
    config.yml
    📁export
    📁source
    
    # Execution command
    docker run --rm -v <YOUR_WORKING_FOLDER_PATH>:/tmp/emerge achtelik/emerge:2.0.0 /tmp/emerge/config.yml
  9. Configure entity_scan metrics

    dev

    The entity_scan section defines metrics applied to fine-grained entities (e.g., classes or structs) extracted from files.

    Available metrics:

    • dependency_graph: Creates a dependency graph based on extracted entities.
    • inheritance_graph: Creates an inheritance graph based on extracted entities.
    • complete_graph: A union of the dependency and inheritance graphs.
    • source_lines_of_code: Calculates SLOC for every entity.
    • number_of_methods: Counts methods per entity.
    • fan_in_out: Calculates fan-in/fan-out graph metrics per entity.
    • louvain_modularity: Applies Louvain modularity metrics per entity.
    • tfidf: Extracts semantic keywords for every entity.
  10. Configure analysis settings in config.yml

    dev

    The config.yml file defines the scope and behavior of an Emerge analysis. The top-level analysis key controls how files are discovered and filtered.

    Key configuration options include:

    • source_directory: The starting point for the recursive file scan.
    • git_directory: The path to the git repo (required if using git_metrics).
    • git_commit_limit: Number of recent commits to mine (default: 150).
    • git_exclude_merge_commits: Whether to exclude merge commits (default: true).
    • only_permit_languages: Restrict scanning to specific languages (e.g., java, kotlin, objc, swift, ruby, groovy, javascript, c).
    • only_permit_file_extensions: Explicitly allow specific extensions (e.g., .java).
    • ignore_files_containing / ignore_directories_containing: Substring filters to exclude files or directories.
    • import_aliases: Map aliases to paths (e.g., "@foo": src/foo).
    • ignore_dependencies_containing / ignore_dependencies_matching: Filter dependencies by substring or regex.
    • ignore_entities_containing / ignore_entities_matching: Filter entities (like classes) by substring or regex.
  11. Configure emerge via YAML

    dev

    Emerge uses YAML files to define project-level settings and specific analyses.

    Project Level Configuration

    KeyDescription
    project_nameA name for all analyses, scans, and exports
    loglevelerror (silent), info (basic logs), or debug (verbose)
    analysesAn array of individual analysis configurations

    Analysis Configuration

    Each item in the analyses array defines how a specific part of the project is scanned. Key fields include:

    • source_directory: The path to the code being analyzed.
    • only_permit_languages: List of languages to include (e.g., [c]).
    • only_permit_file_extensions: List of extensions to include (e.g., [.c, .h]).
    • ignore_dependencies_containing: Exclude dependencies matching a string.
    • ignore_entities_containing: Exclude entities (like SwiftUI previews) matching a string.
    • file_scan: List of metrics to collect for files (e.g., number_of_methods, source_lines_of_code, dependency_graph).
    • entity_scan: List of metrics to collect for entities (e.g., dependency_graph, tfidf).
    • export: Configuration for output, including directory and formats like json, d3, graphml, or tabular_file.

    Example: Full Configuration

    project_name: java_project_example
    loglevel: info
    analyses:
    - analysis_name: check_java_files_and_classes
      source_directory: /Users/user1/emerge/project/source
      only_permit_languages:
      - java
      only_permit_file_extensions:
      - .java
      ignore_dependencies_containing:
      - java.util
      file_scan:
      - number_of_methods
      - source_lines_of_code
      - dependency_graph
      - fan_in_out
      - louvain_modularity
      - tfidf
      entity_scan:
      - dependency_graph
      - source_lines_of_code
      - number_of_methods
      - fan_in_out
      - louvain_modularity
      - tfidf
      export:
      - directory: /Users/user1/emerge/project/export
      - graphml
      - json
      - tabular_file
      - tabular_console_overall
      - d3
    python emerge.py -c configs/c-template.yaml
  12. Filter irrelevant dependencies in Emerge configuration

    dev

    To reduce complexity and reveal the core architecture, you can configure Emerge to ignore specific dependencies that clutter the graph. Use the following keys in your configuration:

    • ignore_dependencies_containing: Filters out dependencies that contain a specific string.
    • ignore_dependencies_matching: Filters out dependencies using regular expressions.