Code Diff since Baseline from within Visual Studio


This document explains how to use the NDepend build comparison features, in the context of Visual Studio and VisualNDepend.exe.

The document Reporting Code Diff explains how to use the NDepend build comparison features, in the context of reporting.




Focusing on code changes since a baseline from Visual Studio (4 minutes)





Introduction

Code evolution and code maintenance are some of the most prominent characteristics of software engineering. Nowadays Visual Studio relies mostly on Git to to explore code changes. But there is an impedance mismatch : Git and others Source Control Manager deals with textual changes while Visual Studio deals with code: Source Control Managers don't distinguish between comments change, formatting change, code in method refactored, type added, method visibility change or field removed.

NDepend comes with some advanced code evolution and code diff features that can distinguish between code change (like method behavior changed) and text change (like comment changed). These features are not meant to compete with or replace the Source Control Manager. Instead these NDepend features can be used as a complementary handy tool to track changes with a focus on code quality related changes.

Some properties of NDepend diff are:

  • The NDepend code diff feature is based on the concept of baseline: the current analysis result is compared against an older analysis result, which constitutes the baseline. Details on the baseline configuration are explained at the end of this document.
  • Since NDepend v2019.3 NDepend zips source files parsed. This way source diff can be performed against the baseline out-of-the-box, no upfront configuration is needed.
  • Diff can be queried. This way some rules can be enforced for code diff like the rules in the group API Breaking Changes and Code Smells Regression. More on querying diff here.
  • The tool used to diff sources is by default Visual Studio, but any other source diff tool like WinMerge can be plugged from NDepend > Options > Source File Compare Tool.

Let‘s expose various code diff scenarios.



▲▲ Go to Top ▲▲


Code Change Review through Global Code Diff

In the main NDepend menu, 3 menus are related to baseline:

  • New Issues since Baseline (that is self explaining)
  • Source Diff since Baseline
  • Code Diff since Baseline



The menu Source Diff since Baseline edits a code query that matches all code elements. Doing is interesting because the result is especially formatted to ease code review:

  • Code elements are grouped per directories and source files.
  • Directories and source files that contain changes have a font underline.
  • Directories and source files that are new since baseline have a font bold.
  • Directories that contain changes are expanded.
  • Source files are not expanded per default, but expanding them shows code element changes with the same font-based convention.
  • Double clicking a source file changed automatically provokes source comparison.

The menu Code Diff since Baseline opens the NDepend Search panel with the option Search Change. The Search Change Panel is actually a CQLinq code query generator related to Code change. For example, in the screenshot below, we can see that asking for Method + Change + Code was Changed or was Added generates this code query:

from m in Application.Methods 
where m.CodeWasChanged() 
let newLoc = m.NbLinesOfCode
let oldLoc = m.OlderVersion().NbLinesOfCode
select new { m, 
             
newLoc, 
             
oldLoc,
             
delta = newLoc >= oldLoc ? newLoc - oldLoc : -(oldLoc - newLoc)
           
}

The result shown can help performing Code Diff Review: not only all code changes are nicely organized at a glance, but for each methods refactored, the developer is just one click away to observe diff in source files. Moreover formatting and comment changes are not taken account here.

The Search Change Panel’s options offers various possibilities to explore diff, including searching for code elements where code and only code (not comment) was changed or where comment and only comment was changed, where visibility was changed, where methods or classes were added or removed etc….

An extra option is to search diff in third-party code, like asking for which library types is not used anymore for example. There is often something interesting to learn by reviewing API usage diff.

Typically, developers write tests for testing automatically refactored and new code. Another useful option is to search for diff coupled with code coverage by tests ratio, like asking for methods where code was changed (i.e refactored methods) and where it is not actually properly covered by tests. Reviewing how diff are covered by tests is made easy thanks to the search facility: Search by Coverage of Changes

Visual Studio Search Coverage Changes

▲▲ Go to Top ▲▲


Code Diff from within Code Source

In the Visual Studio Code Editor Window, NDepend offers the Diff since Baseline right click menu. This menu is enabled only if the source has been changed since baseline:

Also, since NDepend recognizes the code element currently edited and right-clicked in source, the user can, for example, right click a namespace or a class and generate a query to list what was changed:

▲▲ Go to Top ▲▲


Code Diff from within Solution Explorer

Clicking most of items in the Visual Studio Solution Explorer let's explore diff since baseline. Items supported are:

  • Solution
  • Project
  • Project Reference
  • Folder
  • Source File
  • Code Element in Source File

One point to note, is that NDepend proposes an heuristic to infer namespace from Solution Explorer folders. Indeed, it is a popular good practice to organize source code in a folders hierarchy that mirrors the namespace hierarchy. So right-clicking a folder can result in asking for code changes in a namespace, a narrower scope than project.



▲▲ Go to Top ▲▲


Exploring Architecture Changes with the Dependency Matrix

The Dependency Matrix shows a red tick on a cell when the dependency represented has been changed since the baseline.

  • If the red tick contains a plus character it means that the represented dependency has been added since the baseline.
  • If the red tick contains a minus character it means that the represented dependency has been removed since the baseline.
  • If the red tick doesn't contain a character it means that the represented dependency has been removed since the baseline.

When hovering such cell with a red tick the dependency description explains how the dependency changed.

Also when right clicking such cell a menu proposes to initialize the matrix horizontal and vertical headers with code elements involved in the dependency change.



▲▲ Go to Top ▲▲


Defining the Baseline for Comparison

Earlier in the post we introduced the concept of Baseline for Comparison. This represents the previous snapshot version of the code base against which the comparison is done. Typically, the Baseline for Comparison represents the latest version of the code in production.

The Baseline for Comparison can be specified through the menu: Visual Studio > NDepend > Diff > Define the Two Snapshots to Diff > Define a Baseline for Comparison. The dialog below appears and lets us choose different options to define the baseline. The Baseline for Comparison option is then persisted in the NDepend project file.

Enjoy live code diffing in Visual Studio!

▲▲ Go to Top ▲▲