S05E21 1h 08mSeason 5

Episode Summary
Software maintenance is an integral part of any software development project, but it can often be neglected, leading to a range of problems down the line. M. Scott Ford, the co-founder, chief code whisperer, and CTO of CorgyBytes, is passionate about helping teams make improvements to their existing software systems rather than throwing them away and starting from scratch. In this episode of The .NET Core Podcast, Ford and Jamie discussed the challenges of maintaining software and some of the tools they use to make it easier.
One of the tools they discussed was Freshli, a tool that visualizes tech debt and shows how difficult a codebase is to work with. It tracks the age of dependencies and can help identify potential risks before they become major problems. They also discussed the Equifax hack from 2017, which was caused by a single outdated dependency. This highlights the importance of keeping dependencies up to date and the potential risks of neglecting them.
The conversation also touched on the need for more spaces for developers to meet up and exchange ideas and feedback. Ford and Taylor believe that the real nuggets of information are shared in the conversations that happen between talks or at the pub afterwards, and that these sessions allow people to do that organically.
One key takeaway from the discussion was the idea of making small, incremental improvements to a project rather than trying to fix everything at once. This approach is similar to a sports team focusing on individual attributes to improve overall performance. It can be more manageable and less overwhelming for a team to make small changes rather than trying to tackle everything at once.
The podcast also highlighted the challenge of dependencies becoming out of date and the importance of tracking and updating them regularly to reduce risk. Ford and Taylor discussed the use of dependency freshness metrics, specifically the libyear metric, to track the age of dependencies and how it changes over time. This metric can be used to communicate the level of risk a development team is carrying to leadership.
Overall, the conversation in this episode sheds light on the importance of software maintenance and the tools available to make it easier. Outdated dependencies in software projects can have a significant impact on productivity and security, but it is often an invisible problem that goes unnoticed by leadership. By implementing tools like Freshli and tracking the age of dependencies, teams can reduce the potential risks and make software maintenance more manageable.
Episode Transcription
Hello everyone and welcome to THE .NET Core Podcast. An award-winning podcast where we reach into the core of the .NET technology stack and, with the help of the .NET community, present you with the information that you need in order to grok the many moving parts of one of the biggest cross-platform, multi-application frameworks on the planet.
I am your host, Jamie “GaProgMan” Taylor. In this episode, I talked with M. Scott Ford of the Legacy Code Rocks podcast and CorgiBytes about Freshli, libyear, and how you can visualise both your tech debt and how difficult a code base will be to work with.
Along the way, Scott teaches us about libyear, talks about the standard sawtoothed chart that most projects will have for their dependencies, and we discuss ways to attempt to get buy in from the decision makers about how and when to give us budget for fixing this problems. We also talk about the fact that the Equifax hack from 2017 was due to a single dependency being out of date.
So let’s sit back, open up a terminal, type in dotnet new podcast and let the show begin.
Jamie
Scott
Jamie
So, yeah. Ford the folks who didn’t maybe haven’t caught part one of our discussion. I was wondering perhaps, could you give folks a bit of an elevator pitch as to, “who Scott is and the wonderful work he does?”
Scott
But yeah. So I am the co founder, chief code, whisperer, and CTO of CorgyBytes. We focus on helping teams make improvements to software systems they already have with hopes that they won’t necessarily have to throw away the mess that they’re currently working on. So kind of help people dig their way out of messes that they’ve got themselves into. That shows up in a lot of different ways. It can be a legacy code project with lots of aging technologies, or it could be just something that was built in a hurry because there was a need to figure out whether or not the idea would work. And now it’s a mess and it needs to be maintained. And so getting some help cleaning that up.
A lot of that cleanup work that we do comes in the form of adding test coverage. That’s something we advocate for a lot. We also do reviews of people’s code bases and provide recommendations. We help hit on technical debt upgrade dependencies, which I think we’re going to dig into a little bit later, and pretty much any maintenance activity that you can think of on a software project that most developers don’t enjoy doing. We actually do; we genuinely enjoy doing that stuff, and it really started because I genuinely enjoy doing that stuff and have kind of built a community around it over at legacycode.rocks.
Hopefully. That’s elevator pitch, I think that might have been an elevator ride. Kind of a long elevator ride.
Jamie
Scott
Jamie
Scott
Jamie
Scott
Jamie
Scott
Jamie
Scott
But it’s online virtual conference focused on software maintenance and kind of everything around it. We run it as a dual track. Sit down and watch talks is kind of one half, and the other track is an open space. So if you’ve got an idea that you want to share with somebody else, if you want to get practice speaking, that can be a great forum for that. And the open space tends to be way more interactive, which is a little bit more ideal, I think, ford a virtual conference than the typical sit and stare your screen and wonder if anybody else is watching.
Jamie
Scott
Jamie
In tabs and spaces, we started that up and obviously you were on it very recently. We started up as, “what if we could capture the lightning that is, the talks between the talks in the conference hall or the talks that happen at the pub afterwards or at the bar or whatever you want to call it.” And I feel like that’s where the real nuggets of information are shared, right? You’ll go to a talk, someone will get up and give a fantastic talk for 45 minutes to an hour and you’ll learn loads. And then maybe you’ll go up to the person who gave the talk and ask them a question. And that right there is where the real knowledge is shared because everything else is practice. You’re coming to that speaker with a question that they haven’t been able to prepare for and so they give you meet the real person in that moment. And I feel like these sessions that you’re organizing, this whole thing that you’re putting on allows people to do that organically, I feel.
Scott
Another thing that’s kind of come out of that is one question we ask everyone. It’s kind of the final question we ask everyone who’s on the show is, “what do you love about Legacy code?” And Andrea pulled together a talk a couple of years ago where she went through and kind of catalogued everyone’s answers that we had accumulated over all the episodes and gave a little bit of a report about that kind. Of categorizing the different responses we got and just kind of what does that say about the variability of the definition of the term, attitudes towards it? Or it’s a data set of people who actually were able to answer the question where I think there are many folks who when presented with that question be like, “nothing.”
Jamie
And I feel like if more developers took a little bit more time to think with I’m worried about saying it, but maybe with compassion for the other developers who are going to read the code to try and come up with a way of sharing that knowledge. Maybe in a wiki or maybe in comments. Not the what but the why, because that’s my thing, right? It’s got to be the why net because I can see that
i increments every time we go around the loop. But why are we going around the loop and why are we going around this many times, right?Scott
Jamie
Scott
Another one is kind of like little incremental improvements. There are stories of sports teams or sports groups just looking at all the things they could possibly improve, all the things that they can improve that might have an impact on where they want to be. And they focus on those one at a time, recognizing that they can’t fix everything all at once. But the focus on improvement, they measure how much the individual value improved and then how much kind of the bigger picture that they’re trying to achieve, how much that improved, and just make small, little incremental changes. And eventually those really add up. It doesn’t have to be everything done all at once or kind of boil the ocean, so to speak, especially on a project where there has been a fair amount of neglect for whatever reason; the problem can seem intractable, and the temptation can certainly be there to, “oh, we’ll do this right on the next project. Once we start this microservice that we’re thinking of extracting out, that’s where we’ll start doing the practices that we really want to be practising.”
I think it’s important to kind of recognize the systemic effect that generated the state of the system that you’re working with. And are you addressing those systemic issues? Because if you’re not, there will be organizational pressure to kind of put you back in that state.
Jamie
Scott
Jamie
So let’s talk about ways that people can do that then. So we touched last time we talked on this project called Freshli that you’ve started. So let’s talk a little bit about that and how that helps with legacy code and dependencies and such.
Scott
So one of the things that I really wanted to do was really experiment with the idea that if information about just how out of date things are, whether or not behaviour would change as a result and kind of, kind of two aspects of that. One being, “is the team aware” and the other, “is their management aware” and and in addition to just providing a spot metric of this is how things are now, I wanted to show how things have changed over time. So I was really interested in seeing how the delta between the versions of the team is currently on and the latest available versions. Kind of how that grew over time. There is a dependency metric and it’s “dependency freshness” is the term. And there’s a paper forget the name of the paper. You can find the paper by going to libyear.com and then scrolling down to the bottom of the page and there’s like a little footnote for it. But I think that paper is the paper that introduced the term dependency freshness and it proposes a few different dependency freshness metrics ways to evaluate how far out of date a library is. And I think at least one of them looks at kind of assumptions around semantic versioning. So how many major releases behind are you? How many minor releases behind are you? How many patch releases behind are you? I think that’s pretty useful.
But the metric that I like the most and one that I’ve been experimenting with the most recently is libyear. And the way that’s computed is you take the release date of the version you’re currently using for a particular dependency, and you take the release date of the latest version and I would say the latest version with the highest version number, because sometimes the latest version could be the most recently released version could be 1.2. But 2.0 may have been released two months ago. Right? So 1.2 is technically, if you sort just by date, 1.2 looks newer than 2.0 if you sort by date, but 2.0 is the one to look at. So looking at that metric and checking to see how far out of date things are and looking at how that’s changed over time, and looking at it at a project wide level. So across all of the dependencies that a project is using, what is the average, what is the total.
Comparing libyear for a project, comparing project to project is a little challenging because it’s highly the number you get is highly dependent on the number of dependencies. So you’re kind of only comparing apples to apples if two projects have the same number of dependencies. But I think in general, probably around 100 as a total score for a project is probably okay. Hopefully that’s not if you only have ten dependencies, then 100 is really bad, right? Because each one is ten years out of date. But assuming you’ve got 100 dependencies, ten is not so bad because on average you’d have each package be six months out of date in order to get a ten, in that case.
I think that metric when graphed over time is really neat because the shape of the graph tends to be up and to the right. So teams start out when you kind of dig into the project’s history and look at the very first commit and you compute this metric on that commit, the project total libyear is pretty much zero. And then as time goes on, the libyear just slowly creeps up and creeps up and creeps up and creeps up. And every now and then there’ll be kind of a spike downwards where the team has kind of upgraded a major dependency. It tends to be around kind of a base framework upgrade is what I’ve noticed. So there’ll be, say, a Ruby on Rails web application looking at how that has increased. The libyear metric will kind of go up and to the right until the team upgrades the next version of Rails. And then it’ll drop maybe by a third, and then it’ll continue to go up to the right, and then it’ll drop, usually by the same delta that it did before, but it’s no longer a third, it’s now like a seventh. And then it continues to go up into the right. And there will be occasionally that dip down, but the team’s never getting back to it’s very rare for teams to get back to zero.
And if I were to kind of tell leadership and show them this graph and say, “this is a graph of how much risk your development team is kind of carrying while they’re working on your project,” I wish I could translate it to kind of an actual risk metric and put that in terms of risk, in terms of dollars. I think there’s a little bit more research needed to be able to do that because otherwise it’s kind of hand to wavy like, “oh, it’s risk.” But I do think it’s a pretty decent stand in ford that as a concept, I think for kind of communicating to someone who doesn’t understand the underlying metric and what it means. But that’s pretty useful.
I also like graphing the maximum value. I think that’s really interesting. So across all the packages that the project is depending on what’s the highest libyear value across all of them, and graphing how that’s changed over time. And usually this kind of stair-steps for the projects that I’ve graphed, where it’ll start out at zero and then it’ll kind of jump to one, and then it’ll jump to two and kind of stay there for a little while and the it’ll jump to three and say that for a while. And then it’ll jump to eight and just kind of stay there and the jump to twelve. But you end up with that kind of stair-step effect and very rarely does that number go down. But that number across the projects that I’ve looked at, that number goes down more often than others. So you’ll have a project that gets to like a libyear of three or four and might hang out there. So even though the, the total, the total metric is expanding and expanding, expanding, you know, it, it does show that the team is doing a pretty decent job at making sure that nothing is more than three years out of date. So that is a measure of up-to-date-ness, I guess. But it’s not something that the average team member is likely really happy with.
And then I think the, you know, the pain of outdated dependencies shows up in a couple different ways. I think one comes in terms of working with, working with the library and wanting to do certain things with it. I often find that I’ll go look up the documentation ford a library that I’m using, and I’ll find a method that I want to use in the documentation and then I go to use it in my project only to find out, no, the version that the project is on doesn’t have that method yet. So then I have to make a decision. Do I upgrade this library just to net that method? And what’s the impact of doing so? And there are a lot of projects where that upgrade is risky. Like doing that upgrade is risky, like the safety net that’s needed to keep dependencies up to date. If it’s not there, it can be difficult to build, it can be difficult to build the trust and the confidence that you can upgrade dependencies without breaking stuff. So that’s definitely a real challenge.
But the frustration shows up in that way of like, “I had a problem, I went searching for the answer to it, I found the answer, I came back to my problem only to learn that the answer I found I can’t use. So now I have to go do more searching and figure out like okay, before the library added the support, how are people solving it then?” And that can be really difficult to tease out. Finding Stack Overflow posts that are old enough, you know, kind of around the era of, you know, when the library was created or, you know, looking for blog posts of a particular, that were of a particular publication date, you know, that can be challenging. Looking through the issues list and seeing if somebody posted an issue and if there might have been a workaround. Is it something that you can backport to the version that you’re using? If it’s an open source library, is it possible to kind of copy that methods implementation into your project and get that capability? That’s a lot of work. All to do something that if you had the safety net in place where you knew you could upgrade a dependency safely and you would know whether or not anything is broken. Kind of the happy path for that is you upgrade the dependency and you just use the new method and that’s a disruption of a few minutes and you’re on your way. Whereas the other route is hours or days of trying to figure this out. And I think that is something that happens often for developers when they’re working with an older library. And I think that is part of why it’s invisible is it’s kind of baked in to people doing their work and leadership doesn’t see it. Leadership might see it in terms of things are taking longer than they used to. And I think this is one of the ways that things can take longer than the used to take is that you’re kind of fighting the tool in order to get the job done.
So I think that’s a big impact, a big invisible impact. And then you also have the security vulnerabilities which is another thing that’s a big impact and that’s something that I want to add better support for in Freshlii. I want to be able to, in addition to graphing libyear, I want to graph number of vulnerabilities of different type. So I’d like to see how the number of critical vulnerabilities has changed over time and how the number of major vulnerabilities has changed over time. I think this would be one where you could do a stacked area graph and see how that’s changed over time. And my fear is that it’s going to be kind of up and to the right as well, and that the number of critical vulnerabilities will kind of go up and up and up, and most teams won’t be upgrading to package versions that don’t have the vulnerability. And that is part of what really kind of got me interested in dependencies in the first place as a problem area. Equifax, I don’t know if you’re familiar with Equifax, I know you’re in the UK. I don’t know how distributed they are in terms of credit monitoring. I don’t know if it’s just a US thing or how global their reach is.
Jamie
Scott
And things like that happen all the time, no big deal. When I hear about a breach like that, I think like, “oh, it was probably someone on their team accidentally wrote a SQL injection vulnerability or something like that. Had they done penetration testing, they might have found it.” That’s the kind of thing that seems harder to me. Having security expertise on your team is a bigger challenge, and it’s one of those challenges that kind of smaller companies often struggle with. But that’s not the kind of breach - that wasn’t really the reason for their vulnerability.
It was they had one library that was out of date, one library, it was Apache Struts and their underlying web framework, so it was a big one. So just to say “one library” is a little flippant because there was probably a lot of probably half the dependencies they had in their dependency list all dependent on that. But there was a two month window between when the vulnerability was published and when they were hacked. So during that two month period, if they had taken action and done the upgrade, then people’s data wouldn’t have been, you know, wouldn’t have been exposed, at least not in that way. Right?
Jamie
Scott
Jamie
Scott
A Request To You All
If you’re enjoying this show, would you mind sharing it with a colleague? Check your podcatcher for a link to show notes, which has an embedded player within it and a transcription and all that stuff, and share that link with them. I’d really appreciate it if you could indeed share the show.
But if you’d like other ways to support it, you could:
- Leave a rating or review on your podcatcher of choice
- Head over to dotnetcore.show/review for ways to do that
- Consider buying the show a coffee
- The BuyMeACoffee link is available on each episode’s show notes page
- This is a one-off financial support option
- Become a patron
- This is a monthly subscription-based financial support option
- And a link to that is included on each episode’s show notes page as well
I would love it if you would share the show with a friend or colleague or leave a rating or review. The other options are completely up to you, and are not required at all to continue enjoying the show.
Anyway, let’s get back to it.
Jamie
Scott
There’s also the Martin Fowler has a blog article that talks “about when things are difficult, do them more often”. Like when things are painful, try to do them more often. So like dependency upgrades tend to be really painful. So if you do them more often and work on making it easier; kind of like we were talking about continuous improvement earlier, the thing that you can be trying to continually improve very well could be, “how painful is it to do an upgrade?” and try to make that easier each time you upgrade a dependency? Another metric is, “how much trust do you have in your automated testing or your manual testing?” whatever your QA strategy is, how much trust you have in that approach to find problems that might be introduced when you upgrade a dependency. I think measuring that trust over time and trying to figure out how to make an improvement there, that could go a long way.
But yeah, I do think leadership has a big role to play and I think a challenge with technical debt and kind of different contributors to technical debt and of course I kind of view dependency freshness as a technical debt measure. There are leaders that have become numb to hearing about it. People are complaining all the time about technical debt. Developers always want to, you know, you know, they always want time to refactor. This is something that I’ve heard from, you know, from leadership at organizations that have custom software systems. You know, if this is a complaint that I’ve heard often is that, you know, “teams are, are kind of continuously complaining that they don’t have enough time to do clean up work.” It’s kind of just been something that leadership starts to ignore. It’s kind of like the little beep-beep-beep when the car backs up. The person driving that doesn’t hear it any more after a little while they just tune that out. The person who happens to be walking by might hear it but that becomes a sound that does get tuned out. You get acclimated to it. And I think some of the ways that technical debt issues get brought up can have the same effect or can kind of fall victim to the same kind of cognitive effect where if the complaint is too repetitive that it can start to be ignored.
Jamie
Whereas if you look at smartphone operating systems, you buy a brand new smartphone, on the day of release, you have three years, or sometimes five years if you’re going down the Apple route, I think. You have so many years of, “we will support this hardware by releasing security updates.” And then after that point, we’re just going to cut you off. Because the whole time that say Samsung or whoever, Motorola, Google, whatever, the whole time that they’re releasing updates, they’re having to the backport those updates into the version that’s on your phone, not the version that’s in developer. Right. And that takes engineering time. And so obviously the companies then have to then say, “hey, we’ve got X amount of engineering time. We’ve got so many people working with this is now legacy code and we’re not making any money from that.” So I totally understand why companies will go, “it’s not really worth it. It doesn’t matter right up until there’s a breach, right? Or right up until there’s an issue.”
And there’s something that Tanya Juncker talks about in both her book App Security, I think it was Alice and Bob Learn App Security, but also in a conversation she had with me about I can’t remember the phrase she uses, but it’s like a responsibility sheet. You point out someone, “hey, there is a problem here and if we don’t fix it in this amount of time, something bad will happen. I don’t know what the bad is, but something bad will happen.” And they say, “well, that’s not on our roadmap, so we’re not going to do it.” You then present them with a document that says, “I accept the risk that if I don’t give you the time to update this thing or perform this maintenance or do this thing, then it is my fault for not giving you that time.” Problem with that, of course, is that works if you’re external to that team, right? If you’re like a contractor or an external person, you can make that claim. You can say, “well, okay, I’ve told you you’re accepting responsibility.” But in a team, like using the sports analogy, right, if I said to you, “hey Scott, you’re going to play point guard and if somebody scores a basket,” can you tell I don’t know anything about basketball. “Somebody gets the ball, it’s your fault, not mine.” Whereas actually we’re supposed to be working as a team to stop that from happening. Right? And so it’s a great idea, but I feel like for internal teams it maybe doesn’t work so well.
But maybe we need something like that. Maybe we need to shake it up to say, “no, we as a team are not taking responsibility. We have told you and we’re signing it off. You’re signing off and saying you’ve taken responsibility so that when the breach happens, it’s on your head.”
Scott
Jamie
Scott
That’s the dream of what I want to build the product into is to be able to, you know, one support a large variety of language ecosystems. You know, I used to, used to have more support than I do now because of an architectural change that it ended up needing to make. And so I’ve got to build support backup for language communities that I used to have it for. So right now there’s only support for the Java ecosystem, specifically Maven as a package manager. But in the past and again in the future, I’ve had support for Ruby and Bundler, Python using requirements.txt file, you know, any kind of, any of any of the .NET project files was able to read any of those - especially the csproj files - and pull the dependency information out of those. And the started working on the JavaScript ecosystem, specifically Node and Yarn. We had PHP support is another one that we had through Composer.
So I want a wide variety of dependency measures because there are projects that have a variety of dependencies. I think it’s pretty common for a web project to especially if they’re kind of new. The back end technology is different from the front end technology and that’s a common pattern that you see or let’s say it’s a mono repo with ten microservices in it. Each one of those microservices might be used in a different language and I think it would be nice to see the collective effect of how each of those dependency manifest is being managed. So like the dependencies that are defined for Node, are they being managed better than the ones that are defined in .NET? Or are the dependencies for project A being managed better than the dependencies for project B? So being able to see kind of like at a portfolio level how well things are doing, that’s what I want to build up to.
So I want to have really rich support for lots of language communities. I want to have support for various dependency freshness measures instead of just libyear. I want to add some of the others. I want security vulnerability information to be in there so you can graph it too. And then I have plans to come up with some kind of composite score that kind of boils all that stuff down into a five star rating to say that your project is doing this. And then I want to also be able to make recommendations and say, “hey, if you focus just on this library and the libraries that would get dragged along with it, and you upgraded it just to the next X version or whatever, and you upgrade the libraries that would come along with it, then these metrics would be improved to this degree.” So maybe on that composite score it would take you from three stars to four stars or from one star to three stars or something like that. Otherwise plan on using lemons. So the Freshli icon has a lemon in it.
I think that would be really useful. So these are things that I plan on doing right now. The ambitions are a little bit greater than the implementation but as with many things that are built as labours of love, they take time.
Jamie
Scott
Jamie
Scott
There is freshli.io, which you can plug in the URL for a Git repository. And this will analyze the project using the older infrastructure. Not the latest infrastructure I built, but the older version of it. But still you’ll get a sense from the graphs that it generates.
You can also go to github.com/corgibytes/freshli and this is kind of a parent repository for all of the related projects. All of the components except for the website are closed source at the moment. I am considering taking the CLI closed source as well. I’ve gotten feedback from folks that it’s the CLI that they’d actually be willing to pay for. And so as a project that needs to be monetized in some form. I am considering taking the CLI private.
But the language ecosystem support, which is right now being built in the form of like a small little executable that implements a gRPC API, that those programs, all of those will be open source, is kind of my intent. So right now the only one that’s out there is the Java one. JavaScript is probably the next one that I’m going to tackle, and then it’ll be Ruby after that. So that’s kind of the kind of the order.
And then also behind the scenes, Freshli is generating software bill materials files. So SBOMs, which have been getting a little bit of buzz recently, but that’s essentially what the community specific programs are doing is they’re generating the SBOMs and then the Freshli CLI is using the data in the SBOM to figure everything else out and do the calculations. So the SBOM is kind of a common consistent file format for dependency information, so that way the core implementation doesn’t need to know about the details of those dependency ecosystems. So that’s kind of the dividing line.
And I did that, I Pivoted to that approach because the old infrastructure, I wrote app and C#. Everything in Freshli except for the Java specific stuff is written in C#. So the website C#, the command line is C#. And so I just wrote code to parse the Ruby dependency manifest file format for bundler. I wrote code to parse the composer file format for PHP. Wrote code to parse requirements.txt file. Wrote code to communicate with the Ruby Gems website and API to figure out what versions have been released when. Same thing for PyPy and the same thing for - I don’t know what the name of the repository is called for composer; it might just be composer, but wherever the PHP packages are kept. And also I had support for Perl and that worked pretty well.
And then added support for C#, where C# was easy because I was able because C# is kind of the host language. The tooling to get dependency information out of csproj files was pretty simple. But then when I went and looked at, when I started to do JavaScript, the npm lock file and the packages.json file, that was pretty easy to read. It’s just json, it’s pretty simple. The yarn lock file is not easy to read. The file itself has an optimization built into it that I found difficult to unroll and started to get really frustrated because it’s like, “oh, I’m having to write all this complicated parsing code and I’m writing it all in C#. But there’s already great JavaScript code in the Yarn project that knows how to parse this. It would be awesome if I could just use that code and then I wouldn’t have to stress about incompatibilities between my implementation and their implementation. If I just use their implementation. The it’ll work, it’ll work the same way it works for them.”
And so that’s where that kind of got me started thinking. And then when I started to look at the Java ecosystem, and specifically Maven, and the POM.XML file, and how it can reference parent POM files, and those parent files can have an effect on the child. And you can have any number of chains of parents. So a parent can have a parent, and a parent can have a parent, and a parent can have a parent, and then you can have sub modules, so you can have subdirectories in each one of those as a POM file. And all of that gets kind of built, kind of gets brought in together. And version numbers can be defined in interpolated strings, and those interpolated string values can be defined in six different places. So I did not trust myself to be able to get that right. And it was one of those things of like, if I really want to get it right, then I need to use Maven itself. And so that’s kind of what has led to the pivot. It’s just kind of like, “okay, well, I’ll start with the hard one.” And so that’s why I started with Java and Maven.
Jamie
Scott
Because what Freshli is doing is it’s mining the historical information in the source code repository. So it walks all the way back to the date of the first commit. It finds the data, the first commit, and then it moves forward to the start of the next increment. And you can tell it what increment you want to use. The default is one month, but you could set it to two weeks, you could set it to three months, you could set it to five days, ten days, whatever. But it’ll go to the oldest commit, and then it’ll go forward in time from the oldest commit to that next starting point. So the delta between the oldest commit and kind of step one, if you think of the oldest commit as step zero, then the, the delta between step zero and step one, you know, might be it’s almost always a fraction of that increment size. And then it walks forward in time at that increment, and it computes libyear on that day. It computes libyear as it would have looked on that day. So if you hopped in your time machine and you went back to your project and you ran libyear on that day, then the value that we spit out is the value that you would have gotten.
We have to be careful about a couple of nuanced details with the way different package managers work, especially with how version numbers get resolved. So if you’ve got a range expression on your version numbers, then we have to make sure we only resolve to a version number that was published on that day. So if you’ve got your possible valid versions set up to like 2.0+, then we need to make sure that we don’t use 7.0 because that would match them on the day that we’re running the command. No, it needs to be what you would have gotten on the day you would have run the command back in time. And so we produce an SBOM at that point in time. So you get an SBOM for every interval that we’re looking at, and those all end up get collected in a
.freshli directory.You end up getting those SBOMs ford free. The SBOM is how I plan on adding support for security information because there’s lots of really good tooling out that will take an SBOM that you’ve generated and will augment it with security vulnerability information. So that’s what I plan on doing. And then again, for that, I want to make sure that it’s only augmenting with security vulnerabilities that were published at that point in time. So I need to do some filtering for that. But yeah, that’s kind of the idea is you get the SBOM for each point in time and then the metrics are computed using that SBOM.
Jamie
Scott
Jamie
Scott
Jamie
So, real quick, the Scott, where can people go to find out more about you and legacy code rocks and stuff like that?
Scott
Jamie
Scott
Jamie
Scott
Jamie
Scott
Or ASP .NET MVC targeting .NET Framework 4.8. That’s doable today. Right. It’s still supported. It’s doable. I don’t know if that’s still going to be true three years from now. So even though it might be an older technology and it might be okay to work with it today, even though it’s old, if you were to happen to, for some reason, stop looking at that code base and because you’re focused on something else for a while, and then, “oh, we have to make a change.” You come back to it, and now it’s suddenly that much older, and it’s like, “oh, wow, this is really challenging to work with.” And I think that’s a big part of it is like, okay, “what version of Visual Studio do I need to download to even open this project? File in the pre .NET Core days.” So that’s a challenge.
Jamie
Scott
Jamie
Scott
Jamie
Scott
Wrapping Up
That was my second interview with M. Scott Ford about dependencies. Be sure to check out the show notes for a bunch of links to some of the stuff that we covered, and full transcription of the interview. The show notes, as always, can be found at dotnetcore.show, and there will be a link directly to them in your podcatcher.
And don’t forget to spread the word, leave a rating or review on your podcatcher of choice - head over to dotnetcore.show/review for ways to do that - reach out via our contact page, and to come back next time for more .NET goodness.
I will see you again real soon. See you later folks.