Three ways to plan an upgrade when your codebase is a patchwork
Welcome to No Compromises. A peek into the mind of two old web devs who have seen some things. This is Joel.
And this is Aaron. Joel, let me set up a situation or a scenario, and I'm just going to kind of doodle a little bit more vague.
But we want to upgrade a project, and in that project doesn't matter really the technology either. But in that project there's maybe... I'm going to say, 10 surfaces we need to upgrade to the most recent version of the technology. Right?
Services?
Surfaces. So, places that things were used-
Oh, okay.
... that we know need to be upgraded.
Okay. I thought you said surfaces, but I'm like, "I don't understand," so I'm glad we clarified. Okay.
Yeah. I mean, this doesn't really even apply. It can apply to PHP, it can apply to Laravel, JavaScript. It's language agnostic, so I don't want to focus on a specific thing.
I'm thinking Laravel, though.
Okay. So, we have these different areas that we need to upgrade. And, in one surface or area is maybe the way we did it three times ago. Another maybe four or five of them is two versions old, one of them one version old.
So there's a mix of different ways of implementing whatever technology this is, too. And the final result is of all these 10, which are in at least three different states, I need them at their fourth most updated state. Make sense?
Okay. And, the fourth is like a new state that's not in the app yet?
Yeah, mm-hmm (affirmative).
Okay. I mean, I feel like I've lived in this project for my whole life, but okay.
Right.
All right.
So, we have various different things, and we need to plan the upgrade. So, let's just say for this example, it's a measured thing. I know where you're coming from. It's like, "Yeah, all of our projects have different ways of doing stuff."
I get it, but let's focus on very specific things. It's like changing a language structure or changing a... if you want to go Laravel, maybe using a new facade, or something like that. So it's very small, predictable, but they're done in three different ways.
Okay.
So, there's two different ways that we might tackle this upgrade path when we actually start doing the work. And I'll outline those two, I'm curious kind of which one you pick and why.
Pop quiz.
Yeah. The first one is, let's take a look at all of the 10 that we have, make our to-do list, and then go through each one and identify how far behind it is and run the full upgrade path. And there, as we check off each bullet point, we're getting to our final four state on each one.
And then the second way is to look at all of those and kind of group them into, are they three times old, two times old, or one time old? And bring the three to the two, and bring all the twos to the one, and maybe bring all the ones fully up. Well, there's two different ways to do it.
Okay.
Which way would you pick and why?
I'm going to ask a clarifying question.
Okay.
Is this something like either way we go, we could finish it in a week? Or, is this a big multi-month project?
I don't think that matters, the point is, it has to be all done at once.
Oh, okay. I was having sort of a negative reaction to your second scenario. So, I think by default I'm going to pick the first one because the second one seems like more work to me.
Oh, interesting. Why do you think it's more work?
When I think in terms of mechanical steps, the number of times I'm going to have to edit a file, the one that is three versions behind, I'm going to have to update three times.
hereas with the first approach, I would only update that file one time. Granted, it would potentially be a bigger change, but I don't know. It's like to me, just in the abstract, it feels like less work to do just to make the leap to the end result if the end result is known.
Interesting. Actually, you said it's more work or less work or whatever, but for you, maybe not for the person who's reviewing it.
I never think of them.
Yeah. You never think of me, I got it. So, let me throw this out there a different way. I'll just expand this a little bit more so you get an idea of what I was actually aiming at. So, the first way we actually... it sounds like the way that I want to go too.
And it may work, and maybe, like you said, it depends on the size of the project. But in general, that first way, we are doing a different logical step on each file potentially, right?
So, the first file or the first area we open up, we have to think, "What is the steps I need to do to bring this up to current? 1, 2, 3." So, you have to remember that, then you do that work. The second one, you look at it, and you're like, "Oh, this is only two far, two behind. Okay, cool. I don't need to remember what I... Okay, I can bring this up."
And then the third one, you're like, how far is this behind?Oh, it's three behind, again. Okay, so I have to go do that. So that's perfectly fine, especially when you know there's a perfectly fine, valid end state... But on the flip side, if we're looking at those other ways of doing it.
So let's just say we bring all the threes to the second state and all then all the twos to the first state, and et cetera, move them together as that. You actually have a lot less context in your brain as you're a developer to kind of remember.
Now it feels a little gross because you know what the end state is, but if you are bringing something up from one state to the next, the changes are probably more mechanical. So, there's less of a thought and less of a review. Whereas if I'm reviewing your first code, I have to be like, "Oh, here he did a bunch of work. Here, he did a little bit of work."
I have to remember each pattern is going to be probably different depending on the surface. Whereas, as I'm reviewing, maybe the first one, as you're kind of going, stepping through it, like, "Oh, all the ones that are three, he brought up to two. Which is still out of date, fine. But then all the twos..."
Again, the review for me is pretty easy. It's just another pattern that moves all of them forward. And then there's another pattern that moves all of them forward. So, I can look at that as well. So that's kind of the core of why I was bringing up those two different ways.
There's two different ways of thinking about developing them, there's two different ways about communicating them. There's two different ways of taking milestones and stop patterns through those and having your reviews done as well.
So, in this scenario, you were just walking through, I'm submitting the PR when I moved all of the oldest ones to the second to oldest one? Like, you're reviewing that, and then I'm doing the next step? Or, I'm doing those as commits, and then you're reviewing it commit by commit?
I guess it doesn't matter. It's about reviewable blocks and keeping those the same type of work versus all kinds of different work.
Yeah, I can see that. I can see that, but in my mind, the end result is the same, right?
Yep.
Like, the final diff coming to the reviewer, if they just look at the diff as a whole and they don't break it down by commit, they're seeing essentially the same thing.
Mm-Hmm (affirmative).
Okay, all right.
But kind of like you said, if you were doing it. If you weren't doing PRs but you were doing commits, if you are a person who looks to the commits during part of your reviews, you would be able to see like, "Hey, this first commit is all one type of work, second one is all kind.
Now, third and then fourth, et cetera." Versus when you're looking at the full, you kind of have to be like, "Okay. I have to reset my brain and recognize the pattern on each one of these files."
Yeah, I think I'm tracking with you. I would say this, the way you described the first scenario isn't probably exactly how I'd do it.
I wouldn't just march through the 10 files in any order and like, "This one has to go three steps and that one has to go two steps." I probably would do like, "All right, let's do all of the oldest ones. Boom, get them done."
Because then, as a developer, again, I'm still not thinking of the reviewer, as a developer, it's the same mechanical thing. Three to one, three to one, three to one. Then I do all the ones that are one step behind, right?
Mm-Hmm (affirmative).
So, from that perspective too, I guess the reviewer could look at those commits and it would be a different slice of the context, but would still be kind of grouped the same way.
Yeah, that's a method that I didn't bring up or think of. But, yeah, there's really kind of three ways of doing it then, too. So, I just wanted to bring it up-
This is like a personality test for developers. Like, you know, those Rorschach images. Like, what do you see here? Is it a tree or a nuclear bomb? And you're like, "Ooh, I don't know. He picked that one." Anyway, what were you going to say?
Well, I think the point of bringing it up is because all different developers think differently as well. But then also the work you do, depending on how you deliver it, has different implications.
So, if you're working with someone, it might actually be more difficult to look at all those big changes versus small little changes, you know? A huge pattern from state four to one might be harder to review because there's so many different code changes versus from one to another.
I don't know, it could not. It just depends on the case. But I just want to bring that up because there's many different ways that we can kind of approach these things, there's not one right answer, and it kind of depends.
Yeah, I like that. And I just, a PSA, don't let your app get like this, then you never have to think about it. Right?
Right, you shouldn't have to decide this. Okay. Now, don't skip, don't hit the next track on the podcast player. Just stay. You're on Laravel 5, and you need to get to the newest Laravel. Let's do it all at once.
Aaron, what did we just talk about? Actually, there might be a better way. Why don't you get in touch with us, and we can help you make a plan to get to where you want to go, but in an orderly way.
Head over to masteringlaravel.io and schedule a call.