Application engineers reviewing a dependency update have two questions to answer:
- What library changes are interesting to review?
- How do changes in the updated package affect my application?
Looking at git diff
yields answers to both questions, however combing through all the changes can be painstakingly slow.
EdgeBit’s static analysis can display a list of modified symbols (e.g. functions) and highlight if and where they are used in the application.
Using static analysis
Static analysis is a powerful and continually improving field with many Ph.D. theses focused on it each year. The biggest flaw is that it can sometimes miss certain types of code changes. While we’re working everyday to minimize these blind spots, they cannot be entirely avoided.
We’ll look into why such blind spots exist later in the post but first, we’d like to present Code Diff, a new way to review the JavaScript & TypeScript package changes to help mitigate the shortcomings of static analysis.
What is a Code Diff
A git repository for an npm package certainly contains the source code but also many supporting files and directories: tests, build and CI configuration, scripts, documentation, etc.
A Code Diff is a smarter form of a git diff
that highlights changes in relevant source files, instead of every single line that was added, updated or removed.
This allows a reviewer to get into the meat of what changed and understand the potential impact on the application.
Example: Upgrading react-redux 9.1.0 → 9.1.2
Looking at the git diff
for these versions on GitHub, you’re presented with 61 changed files for these 2 patch releases. Code Diff intelligently filters out uninteresting files to leave us with 13 for review.
The 48 hidden files include changes to .github
folder (CI), rollup.config.js
(bundler configuration), example code, and more.
Let’s take a look at one of the relevant source files that Code Diff flagged for review:
This TypeScript file just added a trailing comma to all the interface method declarations. This is purely a syntactic change with no impact on semantics. In fact, most of the source changes in this changeset just added trailing commas or tweaked whitespace.
Click over to the Reachability Analysis tab and see the static analysis in action — all these trivial changes are ignored and what’s left is a handful of functions with non-trivial modifications.
The Reachability Analysis is the best starting point for code review but Code Diff is a great supplement to double-check that the static analysis is working as expected.
A graceful fallback
There are cases when static analysis is unable to attribute a particular code change to a function or another symbol. This typically happens when edits are made to code that is executed at a module level. For example:
window.addEventListener("beforeprint", (event) => {
- console.log("Before print");
+ alert("Before print");
});
The anonymous function that is modified does not have a symbol associated with it since it is executed at the module level and is not assigned to a variable. For the time being, EdgeBit’s static analysis will miss this change but Code Diff will properly display it. We are always working on making our static analysis more accurate but a text based diff is a robust alternative to never miss a change.
Speed up & stay focused during code review
Reviewing dependency updates is much more tractable when your engineers are presented with a targeted list of changes and how they impact your app, with pointers into your codebase.
Simply starting from a ticket or pull request with this info already gathered cuts out all of the toil and soul-sucking information collection from the review process.
Finding bugs is a technical problem, fixing them is a human problem
Collin Greene used this phrase back in 2017 and it’s just as relevant today.
EdgeBit’s Dependency Autofix analysis can empower code reviewers that are less familiar with a particular library or unaware of shared library usage outside of their team. All in the pursuit of finding, fixing and merging dependency updates instead of letting security debt pile up.