|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +comments: false |
| 4 | +title: "What's new in your dependencies? Advanced Recipe and Source Diffing in Conan" |
| 5 | +description: "Meet the new conan report diff command. And learn how to easily compare your sources and more-" |
| 6 | +meta_title: "What is in your dependencies updates?" |
| 7 | +categories: [cpp, diff, report, conan] |
| 8 | +--- |
| 9 | + |
| 10 | +## What has changed in my package? |
| 11 | + |
| 12 | +In modern software development, **understanding what has changed** between different versions of |
| 13 | +your dependencies is crucial. However, many real-world workflows often raise questions that |
| 14 | +are not easy to answer: |
| 15 | + |
| 16 | +* What differences exist between the recipe in my **local** cache and the one published on a **shared remote**? |
| 17 | +* What has changed in the packaged sources between **two versions** of a package? |
| 18 | + |
| 19 | +In the daily work of development teams, CI/CD pipelines, and repository maintainers, these |
| 20 | +questions typically arise in scenarios such as: |
| 21 | + |
| 22 | +* **Compliance reviews**: when it’s necessary to verify what changes have been introduced in a specific |
| 23 | +package and their impact. |
| 24 | +* **Debugging issues**: when investigating why a binary behaves differently between different versions. |
| 25 | + |
| 26 | +## Why existing solutions fall short |
| 27 | + |
| 28 | +Until now, addressing these problems has usually meant relying on **manual, time-consuming** processes: |
| 29 | +if you’re lucky and your sources are hosted in a version control repository that provides a **change |
| 30 | +viewer**, that might help. But what if the library you’re using does not have one? Or worse – what if |
| 31 | +there are so many changes between versions that the tool provided by your version control system can’t |
| 32 | +even load all of them? |
| 33 | + |
| 34 | +Just as critical, though often overlooked, is the need to inspect **changes in the recipes** themselves. |
| 35 | +Yet, up until now there’s been no easy way to view changes in both the packaged sources and the |
| 36 | +packaging code side by side. No existing tools offer a unified diff that spans both areas. |
| 37 | + |
| 38 | +Moreover, there’s the challenge of knowing exactly what changes exist in the version you have on |
| 39 | +your remote. Sometimes **versions get retagged**, and in those cases, you lose the ability to see |
| 40 | +those changes reliably. Or, if you want to compare the exact differences between two specific |
| 41 | +revisions of your recipes, none of those tools can help you do it accurately. |
| 42 | + |
| 43 | +This can get even more complicated when **patches** have been applied to our code, introducing an entirely |
| 44 | +new dimension that also needs to be tracked and verified. |
| 45 | + |
| 46 | +The process we usually end up following is downloading packages, extracting recipes, sources, and |
| 47 | +patches, applying these patches, and finally using external tools (such as diff or git diff) to |
| 48 | +compare them. This approach not only requires time but also leaves room for **human errors** and makes |
| 49 | +automation more challenging. |
| 50 | + |
| 51 | +## A new command to compare recipes and sources |
| 52 | + |
| 53 | +To solve this problem, we’ve created a new Conan command, the **conan report diff** that acts |
| 54 | +like a *git diff wrapper*, but for packages and recipes stored in remotes or local caches. |
| 55 | +With this command, you can **compare two recipes with their sources** (including patches) and see |
| 56 | +exactly what has changed, not only between tagged versions, but even between revisions. |
| 57 | + |
| 58 | +It’s very simple to use. For example, if we want to check the differences between “zlib/1.3” and |
| 59 | +“zlib/1.3.1” and see if there are any changes to the recipe, and the difference between their sources, |
| 60 | +we can use the command like this: |
| 61 | + |
| 62 | +{% highlight bash %} |
| 63 | +$ conan report diff --old-reference=zlib/1.3 --new-reference=zlib/1.3.1 |
| 64 | +{% endhighlight %} |
| 65 | + |
| 66 | +This command will take the latest revision of each version. If Conan finds the package in the cache, |
| 67 | +it will take that; if not, it will search in all available remotes, or the ones passed using the |
| 68 | +*--remote* argument |
| 69 | + |
| 70 | +If you prefer a fine-grained search, **specifying the revision**, you can simply add it to the reference |
| 71 | +like this: |
| 72 | + |
| 73 | +{% highlight bash %} |
| 74 | +$ conan report diff --old-reference=zlib/1.3 --new-reference=zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76 |
| 75 | +{% endhighlight %} |
| 76 | + |
| 77 | +Another typical case is when we have a new version that we are testing locally, and we need to compare |
| 78 | +these changes. In this case, we can add the path to the new recipe to the command. Here’s an example: |
| 79 | + |
| 80 | +{% highlight bash %} |
| 81 | +$ conan report diff --old-reference=zlib/1.3 --new-reference=zlib/1.3.1 --new-path=path/to/new/recipe |
| 82 | +{% endhighlight %} |
| 83 | + |
| 84 | +This can also be done for the old reference if you need to specify its location directly too with the |
| 85 | +*--old-path* argument. |
| 86 | + |
| 87 | +## Output Formats |
| 88 | + |
| 89 | +The new command provides three formats for the output, which can be selected using the *--format* attribute. |
| 90 | + |
| 91 | +{% endhighlight %} |
| 92 | + |
| 93 | +The first one, **"html"** format, generates a self-contained **static website**. In this |
| 94 | +web output, **functionality takes priority**: it includes a small index listing the changed files, |
| 95 | +a search bar to look for files, and another to exclude files from view. |
| 96 | + |
| 97 | +<div style="text-align: center;"> |
| 98 | + <img src="{{ site.baseurl }}/assets/post_images/2025-07-07/conan-report-diff-web.png" |
| 99 | + alt="conan report diff web interface"/> |
| 100 | +</div> |
| 101 | +<br> |
| 102 | + |
| 103 | +Next, we have the **"text"** format, it is the default format, and it displays the differences in the classic |
| 104 | +**git diff format**. You can use this to pipe its **output to any diff tool** of your liking. Here’s an example: |
| 105 | + |
| 106 | +{% highlight bash %} |
| 107 | +$ conan report diff --old-reference=zlib/1.3 --new-reference=zlib/1.3.1 |
| 108 | + |
| 109 | +... |
| 110 | + |
| 111 | +diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml |
| 112 | +index 1531782fc4..aee6ff7660 100644 |
| 113 | +--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml |
| 114 | ++++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml |
| 115 | +@@ -1,12 +1,11 @@ |
| 116 | + patches: |
| 117 | +- '1.3': |
| 118 | +- - patch_description: separate static/shared builds, disable debug suffix, disable |
| 119 | +- building examples |
| 120 | +- patch_file: patches/1.3/0001-fix-cmake.patch |
| 121 | ++ 1.3.1: |
| 122 | ++ - patch_description: separate static/shared builds, disable debug suffix |
| 123 | ++ patch_file: patches/1.3.1/0001-fix-cmake.patch |
| 124 | + patch_type: conan |
| 125 | + sources: |
| 126 | +- '1.3': |
| 127 | +- sha256: ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e |
| 128 | ++ 1.3.1: |
| 129 | ++ sha256: 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23 |
| 130 | + url: |
| 131 | +- - https://zlib.net/fossils/zlib-1.3.tar.gz |
| 132 | +- - https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz |
| 133 | ++ - https://zlib.net/fossils/zlib-1.3.1.tar.gz |
| 134 | ++ - https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz |
| 135 | +diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt |
| 136 | +index 1698be4430..98bd55b280 100644 |
| 137 | +--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt |
| 138 | ++++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt |
| 139 | +@@ -1,4 +1,4 @@ |
| 140 | + 1733936230 |
| 141 | +-conandata.yml: f273879c230e45f27a54d0a4676fda02 |
| 142 | ++conandata.yml: 7388d3b9c983326938e00bcdaadb8533 |
| 143 | + conanfile.py: 01438040394b477d740d8c84f58cf682 |
| 144 | +-export_source/patches/1.3/0001-fix-cmake.patch: 133be1fe5e1ccd96b8da0f43ef0314f3 |
| 145 | ++export_source/patches/1.3.1/0001-fix-cmake.patch: 258ad7382f40ea5933cd48a5501f843d |
| 146 | + |
| 147 | +... |
| 148 | + |
| 149 | +{% endhighlight %} |
| 150 | + |
| 151 | +Finally, we have the **"json"** format, which returns the diff in a **simple structured representation**, |
| 152 | +so that it can be consumed by other scripts. This is perfect if you want to extract the specific diff |
| 153 | +of a file and feed it into some kind of pipeline. |
| 154 | + |
| 155 | +{% highlight bash %} |
| 156 | +$ conan report diff --old-reference=zlib/1.3 --new-reference=zlib/1.3.1 --format=json |
| 157 | + |
| 158 | +{ |
| 159 | +... |
| 160 | +"/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml": [ |
| 161 | + "diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml", |
| 162 | + "index 1531782fc4..aee6ff7660 100644", |
| 163 | + "--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml", |
| 164 | + "+++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml", |
| 165 | + "@@ -1,12 +1,11 @@", |
| 166 | + " patches:", |
| 167 | + "- '1.3':", |
| 168 | + "- - patch_description: separate static/shared builds, disable debug suffix, disable", |
| 169 | + "- building examples", |
| 170 | + "- patch_file: patches/1.3/0001-fix-cmake.patch", |
| 171 | + "+ 1.3.1:", |
| 172 | + "+ - patch_description: separate static/shared builds, disable debug suffix", |
| 173 | + "+ patch_file: patches/1.3.1/0001-fix-cmake.patch", |
| 174 | + " patch_type: conan", |
| 175 | + " sources:", |
| 176 | + "- '1.3':", |
| 177 | + "- sha256: ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e", |
| 178 | + "+ 1.3.1:", |
| 179 | + "+ sha256: 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23", |
| 180 | + " url:", |
| 181 | + "- - https://zlib.net/fossils/zlib-1.3.tar.gz", |
| 182 | + "- - https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz", |
| 183 | + "+ - https://zlib.net/fossils/zlib-1.3.1.tar.gz", |
| 184 | + "+ - https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz" |
| 185 | + ], |
| 186 | + "/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt": [ |
| 187 | + "diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt", |
| 188 | + "index 1698be4430..98bd55b280 100644", |
| 189 | + "--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt", |
| 190 | + "+++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt", |
| 191 | + "@@ -1,4 +1,4 @@", |
| 192 | + " 1733936230", |
| 193 | + "-conandata.yml: f273879c230e45f27a54d0a4676fda02", |
| 194 | + "+conandata.yml: 7388d3b9c983326938e00bcdaadb8533", |
| 195 | + " conanfile.py: 01438040394b477d740d8c84f58cf682", |
| 196 | + "-export_source/patches/1.3/0001-fix-cmake.patch: 133be1fe5e1ccd96b8da0f43ef0314f3", |
| 197 | + "+export_source/patches/1.3.1/0001-fix-cmake.patch: 258ad7382f40ea5933cd48a5501f843d" |
| 198 | + ], |
| 199 | +... |
| 200 | +} |
| 201 | + |
| 202 | + |
| 203 | +## What’s next |
| 204 | + |
| 205 | +We’re excited to share this new feature with the community, but this is just the beginning! We’d love to hear |
| 206 | +how you use **conan report diff** in your workflows. Your feedback, ideas, and suggestions are key to improving |
| 207 | +and shaping the future of this tool. |
| 208 | + |
| 209 | +You can always [submit feedback here.](https://github.com/conan-io/conan/issues) |
0 commit comments