Skip to main content

Compare Directional Graphs

Project description

This library compares two directional graphs and outputs the diff result as a dot file. Primary intended use is to compare changes in software dependencies, for example in gradle projects though it is designed to not be limited to gradle.

Github action

This repo contains an action that can be used to generate diagrams of local project dependency changes on pull requests, please see example_workflow/test_action.yml

"Deps" Input Format

The input for one graph is just multiple lines in the format:

a -> b

This line denotes that a depends on b.

You can also chain nodes:

a -> b -> c

This line denotes that a depends on b, and that b depends on c. And is the same as two entries:

a -> b
b -> c

Files of this format have the .deps suffix. See the examples folder.

The set of dependencies in a file is then loaded in to a graph format, this is a NetworkX DiGraph under the hood.

With two DiGraphs loaded (or otherwise created) you can compare them to create a diff.

Orphaned nodes can be denoted a single line with just their name on it, e.g.

a

The Diff

The diff of two DiGraphs A and B is another DiGraph that includes:

  • All removed connections (present in A but not B)
  • All added connections (present in B but not A)
  • All removed nodes
  • All added nodes
  • All nodes at either end of an included connection
  • All unchanging connections between all included nodes
  • All transitive connections between all included nodes

Elements have metadata to describe which rule they are included under, such as "added"/"removed"/"transitive".

Output

The output is a dot file, properties in the DiGraph describing the added/removed/transitive state of elements are converted to color coding/line formats.

Gradle Input

This library contains code to parse a gradle dependency output into the deps format.

An example of generating this input is:

cd sample
./gradlew -q :app:dependencies --configuration runtimeClasspath > ../examples/dependencies.txt

For your own project you may need to edit the command for your main app name (:app) and configuration name (runtimeClasspath) to match your project. Also see git_gradle_diff section below for an end-to-end example.

Setup

Install uv.

Install dot if not present, this is used to create the images from the .dot file.

On mac you can do:

brew install graphviz

For other environments see https://graphviz.org/download/

Running

Pass a single file into the diff.

uv run main.py diff examples/revision1.deps --dark-mode --caption "Revision 1" -o docs/revision1.png

And it will create a png output for the one file:

Revision 1

Running again for revision2:

uv run main.py diff examples/revision2.deps --dark-mode --caption "Revision 2" -o docs/revision2.png

Revision 1

If you look carefully, you will be able to make out the changes, but if we pass the two deps files, it will output the diff them:

uv run main.py diff examples/revision1.deps examples/revision2.deps --dark-mode --caption "Diff of Revision 1 & 2" -o docs/compare_two_dep_files.png

Now we can clearly see just the changes:

Compare two dep files

  • :lib-b was removed altogether and the link from :app was therefore also removed (in red).
  • A new link from :lib-e to :lib-f was created (in green).
  • Transitive links are shown between :app and :lib-e because they are still connected by another part of the full graph, :lib-d which is not shown as it has not changed.

You can also pass in the output of the gradle dependencies query:

uv run main.py diff examples/dependencies.txt examples/dependencies2.txt --dark-mode --caption "Diff of dependency files" -o docs/compare_two_gradle_outputs.png 

Compare two gradle outputs

git_gradle_diff

The following command given a copy of the Signal git repository, will diff two commits on signal and produce a png. It works by creating its own worktree and won't affect the repository otherwise. Note that it leaves this worktree behind afterward.

This is not yet working on windows.

uv run main.py git_gradle_diff ~/workspace/Signal-Android 1fc119e027d 4bbed2601cf -a :Signal-Android -c playProdReleaseRuntimeClasspath --dark-mode --caption "Signal {old} vs {new}" -o docs/signal_diff.png

Signal Diff

This is just one example integration, you can create your own scripts to generate intermediary gradle outputs or .deps files and just call the diff command with those.

Testing

The library has its own test runner which discovers and runs test files under the test/ path.

You can run them like so:

uv run main.py tests

The dot file output is committed to this repo as the expected result. If the output changes expectedly, you can run python main.py tests -u to update the output.

Requirements

This project uses the following libraries for these purposes:

  • NetworkX for graph analysis
  • Rich for CLI formatting
  • Click for CLI command line argument parsing

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

diff_dot-2025.2.16.2.tar.gz (134.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

diff_dot-2025.2.16.2-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file diff_dot-2025.2.16.2.tar.gz.

File metadata

  • Download URL: diff_dot-2025.2.16.2.tar.gz
  • Upload date:
  • Size: 134.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for diff_dot-2025.2.16.2.tar.gz
Algorithm Hash digest
SHA256 a2db6f37fdd79f8d70eb1da1d6d09b652e152c1802b839f85ffe3f0f79c11a79
MD5 f2ca5ded6e786b77b45cb1f227e6da58
BLAKE2b-256 62d83fe284c876319d9f908c6556b49f8bc63a37a4607c53f616f24f51675dd7

See more details on using hashes here.

Provenance

The following attestation bundles were made for diff_dot-2025.2.16.2.tar.gz:

Publisher: publish-to-test-pypi.yml on westonal/graph-diff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file diff_dot-2025.2.16.2-py3-none-any.whl.

File metadata

  • Download URL: diff_dot-2025.2.16.2-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for diff_dot-2025.2.16.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cc64ad50f41fad5672e24c058b5b3f1fc9e1bd5bcbd813c6cd4e1e6f71876c3a
MD5 3fe5ce2fe8c5cfafee3fdef255fe2c5a
BLAKE2b-256 4d33502a373f5fa02d03fb365b07383634a2be1c2ca5e2deb3e2e36e2d0af1af

See more details on using hashes here.

Provenance

The following attestation bundles were made for diff_dot-2025.2.16.2-py3-none-any.whl:

Publisher: publish-to-test-pypi.yml on westonal/graph-diff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page