Skip to content

fix: Improvements to DOT dependency graph generation#377

Merged
arodage merged 9 commits intomainfrom
fix/deduplicate-dot-edges
Feb 4, 2026
Merged

fix: Improvements to DOT dependency graph generation#377
arodage merged 9 commits intomainfrom
fix/deduplicate-dot-edges

Conversation

@arodage
Copy link
Copy Markdown
Contributor

@arodage arodage commented Feb 3, 2026

Merge Checklist

  • The changes in the PR have been built and tested
  • Ready to merge

Description

This PR fixes issues with DOT file dependency graph generation for RPM and DEB packages.

Issue 1: Duplicate Dependency Edges

The DOT file generation was creating multiple identical edges for the same package dependency. For example, libstdc++ -> glibc appeared 5 times in the azl3-minimal-deps.dot file when a package had multiple Requires entries that resolved to the same dependency.

Solution:

  • Added edge deduplication using a map to track written edges in both rpmutils.GenerateDot() and debutils.GenerateDot()
  • Each unique edge (package -> dependency) is now written only once
  • Added test cases to verify deduplication works correctly

Issue 2: Color Coding removed due to Complexity

The DOT file color coding system was confusing and prone to errors:

  • Color assignment based on package source (Essential/System/Kernel/Bootloader) created complexity
  • Priority system for overlapping package classifications was not intuitive
  • Color coding didn't work correctly for RPM packages due to package name format mismatches
  • The visual distinction added cognitive overhead without clear benefit for dependency analysis

Solution:

  • Removed all color coding and legend generation from DOT files
  • Simplified node representation to clean, uniform format
  • Focuses visualization on dependency relationships rather than package categorization
  • Updated all tests to match simplified output format
  • Results in cleaner, more maintainable DOT files that work consistently across both RPM and DEB packages

Issue 3: dep-analyzer Script Enhancement

Added support for rendering the complete dependency graph without requiring a root package for slicing. Previously, the --root parameter was mandatory, forcing users to specify a package even when they wanted to visualize the entire dependency tree.

Solution:

  • Made --root optional - only required when slicing the graph
  • When --root is omitted, the script now renders or copies the full graph
  • Updated usage documentation with full graph rendering examples
  • Clarified which options require --root (reverse, highlight-root)

Usage:

./dep-analyzer.sh -i deps.dot -t svg    # Render full graph to SVG
./dep-analyzer.sh -i deps.dot -r vim    # Slice to vim's dependencies

This enhancement makes the tool more flexible and intuitive for users who want to visualize complete dependency graphs.

Documantation update:

  • ADR architecture document (design principle and color table)
  • CLI specification
  • Main documentation index

Any Newly Introduced Dependencies

None

How Has This Been Tested?

  • Ran earthly +test-quick - all tests pass
  • New test cases verify each unique edge appears exactly once in generated DOT files
  • Tested with packages that have duplicate dependencies (e.g., libstdc++ with multiple glibc requirements)
  • Verified deduplication: old azl3-minimal-deps.dot had 5 duplicate edges, new has 1
  • Verified simplified DOT format works for both RPM and DEB packages
  • Verified existing DOT generation functionality remains intact

Test results:

  • Old behavior: libstdc++ -> glibc appeared 5 times
  • New behavior: libstdc++ -> glibc appears 1 time ✅

Example visualization:

./scripts/dep-analyzer.sh -i azl3_raw.dot -r cloud-init-24.3.1-2.azl3.noarch.rpm -d 1 -t svg

azl3_raw_cloud-init-24 3 1-2 azl3 noarch rpm_d1

- Add edge deduplication in rpmutils and debutils GenerateDot functions
- Track written edges using map to prevent duplicate dependency links
- Add test cases to verify each unique edge appears exactly once
- Fixes issue where packages with multiple identical Requires entries
  created duplicate edges in DOT files (e.g., libstdc++ -> glibc appearing 5 times)

Resolves duplicate dependency visualization in RPM and DEB package graphs.

chore: remove accidentally committed binary and log file
@arodage arodage requested review from Copilot and magerstam February 3, 2026 06:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes duplicate dependency edges in DOT graph generation for RPM and DEB package dependency visualizations. The issue occurred when packages had multiple Requires entries that resolved to the same dependency, resulting in redundant edges like libstdc++ -> glibc appearing multiple times in the output file.

Changes:

  • Added edge deduplication logic using a map[string]bool to track written edges in both rpmutils.GenerateDot() and debutils.GenerateDot()
  • Added comprehensive test cases to verify each unique edge appears exactly once in generated DOT files

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

File Description
internal/ospackage/rpmutils/resolver.go Implemented edge deduplication in RPM DOT generation using edgesWritten map
internal/ospackage/rpmutils/resolver_test.go Added test case with duplicate dependencies and verification logic for deduplication
internal/ospackage/debutils/resolver.go Implemented edge deduplication in DEB DOT generation using edgesWritten map
internal/ospackage/debutils/resolver_test.go Added test case with duplicate dependencies and verification logic for deduplication

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/ospackage/rpmutils/resolver.go Outdated
Comment thread internal/ospackage/debutils/resolver.go Outdated
github-actions Bot and others added 5 commits February 3, 2026 06:38
- Change priority order: Essential (30) > Kernel/Bootloader (20) > System (10)
- Previously System had highest priority (30) causing incorrect colors:
  * Packages in both SystemConfig.Packages and EssentialPkgList showed green
  * Essential packages should display yellow, not green
- Essential and specific packages (kernel, bootloader) now correctly
  override generic system package classification
- Reorder setSources calls to process from general to specific
- Update test to reflect new priority where essential overrides system

This ensures DOT graphs show correct semantic colors matching package roles.

Note: Color coding for RPM packages still requires base name extraction fix
(RPM filenames include version/arch, but pkgSources uses base names only)
Simplifies DOT file generation by removing package source color coding:
- Removed color/fillcolor attributes from nodes
- Removed legend generation (packageSourceStyles, legendOrder, writeLegend)
- Simplified node output to basic format: "packagename";
- Updated tests to match simplified DOT format

Rationale:
- Color coding was complex and confusing
- RPM color coding didn't work due to package name format mismatch
- Priority system added unnecessary complexity
- Simplified DOT files are easier to understand and maintain

All tests pass (earthly +test-quick)
Remove all references to color coding system (Yellow/Green/Blue/Orange for
Essential/System/Kernel/Bootloader packages) from documentation to match
the simplified DOT graph implementation.

Changes:
- Remove 'Color Preservation' design principle from ADR
- Remove 'Semantic Color Preservation' section with color table from ADR
- Remove color-coded description from --dotfile flag in CLI specification
- Remove color legend from --dotfile flag in main documentation

This documentation update ensures consistency with the code changes that
removed color coding complexity from dependency graph generation.
…ormat

Fix false warning 'Root node not found' by updating the grep pattern to
match both node declarations and edge statements. Since color attributes
were removed, nodes now only appear in edge statements (node -> dep) rather
than standalone declarations (node [attrs];).

Also remove outdated color preservation notes from script header comments.

Changes:
- Update node detection pattern to match edge statements
- Remove color scheme documentation from usage help
- Remove 'Preserves existing semantic colors' comment
@arodage arodage changed the title fix(ospackage): deduplicate dependency edges in DOT graph generation fix(ospackage): deduplicate dependency edges and removal of color coding in DOT graph generation Feb 3, 2026
Allow dep-analyzer.sh to render the complete dependency graph when --root
is not provided. Previously, --root was always required, forcing users to
slice the graph even when they wanted to visualize the entire dependency
tree.

Usage:
  ./dep-analyzer.sh -i deps.dot -t svg    # Render full graph
  ./dep-analyzer.sh -i deps.dot -r vim    # Slice to vim's dependencies

Changes:
- Make --root optional (only required for slicing mode)
- Add full graph rendering when --root is omitted
- Update usage documentation with full graph example
- Clarify which options require --root
@arodage arodage changed the title fix(ospackage): deduplicate dependency edges and removal of color coding in DOT graph generation fix(ospackage): dependencies in DOT graph generation Feb 3, 2026
Replace fmt.Sprintf() with simple string concatenation for edge keys
in DOT generation. The previous format included spaces and arrows which
were only needed for display, not for deduplication logic.

Changes:
- debutils: edgeKey = pkg.Name + "|" + depName
- rpmutils: edgeKey = pkg.Name + "|" + dep

This reduces string formatting overhead in the hot path of edge
deduplication without changing functionality.

Addresses Copilot PR review suggestions.
@arodage arodage changed the title fix(ospackage): dependencies in DOT graph generation fix: Improvements to DOT dependency graph generation Feb 4, 2026
Copy link
Copy Markdown
Contributor

@magerstam magerstam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@arodage arodage merged commit 5ac46c9 into main Feb 4, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants