No Compromises

How do you like to upgrade your app when the next new major version of Laravel comes out? Aaron and Joel share two different approaches they've used, and what added benefits you get from doing a version upgrade.

Need help getting tests on your Laravel app before upgrading?

Creators & Guests

Host
Aaron Saray
Host
Joel Clermont

What is No Compromises?

Two seasoned salty programming veterans talk best practices based on years of working with Laravel SaaS teams.

Joel Clermont (00:00):
Welcome to No Compromises, a peek into the mind of two old web devs who have seen some things. This is Joel.

Aaron Saray (00:08):
And this is Aaron.
One of the most challenging tasks to do on a brand new project is upgrading the Laravel version, but at the same time, it's also kind of cool because you get to see kind of how the project is put together. And depending on the way that you do it, you get to understand what files are where and all that stuff. Because there are paradigms but people do stuff differently.

Joel Clermont (00:36):
Just to clarify something. When you say brand new, you mean a project that existed and we are joining the project.

Aaron Saray (00:43):
Oh, right. Yeah.

Joel Clermont (00:43):
Not a brand new laravel-new type situation?

Aaron Saray (00:46):
Right.

Joel Clermont (00:46):
Okay.

Aaron Saray (00:47):
But what I want to talk about applies to both situations. Not a brand new, but if you are doing the upgrade yourself or-

Joel Clermont (00:54):
Oh, sure, yeah.

Aaron Saray (00:54):
... if you're a brand new contractor coming in.

Joel Clermont (00:57):
Okay.

Aaron Saray (00:57):
What's cool about that is that you get to, like I said, see how the project's put together. You kind of have a reason to look through some of the stuff and understand it. But the dangerous part about it too though, is if there's not a lot of unit tests or you don't know exactly what you're looking at, you're basically changing potentially many files or requirements and stuff and not knowing if what you did broke anything. Because you have to either use each thing by hand again if you are part of the project or you have to just hope if you're brand new to it that you didn't break anything.

Joel Clermont (01:30):
I like how diplomatic you were when you said, "If there's not a lot of unit tests." As opposed to, "The only test is example test in the feature directory," and you just close your laptop in anger and walk away.

Aaron Saray (01:43):
My favorite is maybe three or four tests that have either been all commented out or like, "The say the tests don't work anymore."

Joel Clermont (01:51):
Yeah, I guess that's worse. A full test suite that fails is almost worse. I think it is worse than not having any tests at all.

Aaron Saray (01:59):
Yeah. Because you get to know what maybe someone thought it should do at some point.

Joel Clermont (02:02):
Yeah.

Aaron Saray (02:04):
Anyway, there's a couple of different ways to upgrade. I'll tell you a specific way that I do it for projects that I want to look at all the different files and I think it's a little bit different than I think I've seen most people. I'll have the project running, let's just say it's Laravel 9 application. I have that running in one directory and on another directory I'll do a brand new create project from Composer with Laravel. I'll install 10. whatever is the newest thing or 11, or whatever the version is right now. I'll get the brand new Laravel configuration there, which of course doesn't have a Git in it, it's completely separate. What I'll do is I'll copy that Git folder from the old project into the new project.

Joel Clermont (02:52):
Say that again. The literal .git folder that has the-

Aaron Saray (02:55):
Yeah.

Joel Clermont (02:55):
Okay, all right.

Aaron Saray (02:56):
Okay. Because what I'm doing there is I'm trying to make sure that I have a record of all the files that should be there at some point and make sure that I copy them or move them over, or whatever. A lot of times I'm using PhpStorm so I'll do that and then I'll right-click it and I'll choose commit and I'll show all the missing files or something. Maybe I'll look at the controllers and I'll start copying over file by file. And before you know it, either it goes away and PhpStorm is like, "There's nothing to commit in here," because it recognizing there's no changes since last time. Or if you have to put them in there it might show you have to extend a different controller or something like that. So you'll see all of the ones that are there but they're all modified.

Joel Clermont (03:43):
Interesting. Just two comments I had. I've kind of done what you're talking about but I would always go the other direction. The project repo is there, the new project is in a separate folder and I would use a tool to diff them and see what changed. Like, in the kernel or the routes file or something. But that's interesting you go the other direction and actually using Git as a tool to track what's left to do. I like that, Aaron. That's cool.

Aaron Saray (04:12):
Thank you. I realize it's not easy and it's not what everyone would do.

Joel Clermont (04:17):
Yeah, it's tedious. Right?

Aaron Saray (04:17):
Yeah. The added benefit though is I get to look at every single file in a way. I don't have to read them all or understand what they're doing. But using this process, I at least know that, "Oh, there's 30 controllers and they're broken up into three folders," or whatever. You can tell that by looking at the old project, but when you have to move them over it's sort of like... It's like when people tell you to take notes during a lecture. I don't want to do that, but when you write things down you tend to remember them a little bit better. This is my sort of version of that, is when I actually have to touch everything and move it all over I start to understand it. Then at the same time, depending on, like I said, your setup, is if you have new code standards or something as you move each file in or whatever, you'll be able to see, I need to apply the code standards to this file and then when I go to commit, I'll see the difference between the old version from the old project based on Git to my new version that is extending or using the new Laravel features and is up to code standards. You can kind of see the difference file by file that way.

Joel Clermont (05:23):
Yeah. I see the benefits of that approach and I think I see it, especially in the context you set up. Which is like you're joining a legacy project that is completely new to you. This little bit of extra manual labor, tedious file-by-file stuff, actually is serving another benefit in addition to just upgrading the app. So I like that.

Aaron Saray (05:46):
It does take forever and it is tedious. But it's at least for me, which we've already talked about, I'm a little weird. But at least for me, it gives me the most value as a programmer that wants to stay with that project.

Joel Clermont (06:00):
Yeah, I can see that. I mean, I'm not going to do it but I can see that.

Aaron Saray (06:05):
What would you do?

Joel Clermont (06:07):
All right. Personally, I'm a fan of Laravel Shift. For those that don't know, this is a service. You pay a nominal amount and I'm talking... I think it's $19 or some very low amount to... Basically, it opens a PR against your project and does the upgrade for you. Maybe just to kind of contrast this, what you set up, Aaron, the very thorough file-by-file thing is also kind of what Shift does. I feel like a lot of people that upgrade Laravel don't do either of those approaches. They look at the change log and do the things that says you have to do or they fix things that break. But for example-

Aaron Saray (06:53):
They just Composer update whatever the new version is and then see if anything broke.

Joel Clermont (06:59):
Yeah. But if all the config files, for example, things change in there, right? Database options, or defaults, things change.

Aaron Saray (07:07):
Mm-hmm (affirmative).

Joel Clermont (07:07):
You don't have to do it. If you don't do it your app will work, but it kind of makes the app feel less consistent and out of date with what it would look like if you just did a fresh Laravel 10 install, versus upgrading an in-place Laravel 9 app to Laravel 10.

Aaron Saray (07:26):
That's true. We've been doing Laravel for a long time so it's not going to be weird if I go into a project and I see all the models at the top level, the app folder. But if you just learn Laravel or you've only been doing it for a year, you see that and you're going to be like, "What's going on here? Why is it not in a models folder like all my other brand-new projects have been?" I can see where maybe adjusting some of the things. You're saying basically, it not only upgrades the code, it upgrades the paradigms and moves all that stuff around too.

Joel Clermont (07:58):
Exactly. Because things evolve over time. One I'm just thinking of is in the HTTP kernel, you used to have to list out a bunch of different facades and middlewares and things. Now it's like those are the default. It comes from the vendor folder, it comes from the framework. You can override it if you want to but now that file gets a lot smaller. And this trend is going to continue, I think Laravel 11 is going to really strip down the skeleton even more, so keeping up with it along the way. But one thing to say about Laravel Shift, it does cost money but it's faster. I'm pretty confident it took me less time to do it than it took you to do it, Aaron.

Aaron Saray (08:38):
Oh, yeah.

Joel Clermont (08:43):
From a trade-off perspective, it's worth the money. The other thing I like about it, I will say sometimes it does things I would not do in my project. For example, we kind of established this pattern, we don't put return types on public controller actions. We're not going to get into why right now but we just don't do it. Shift will add those. The nice thing is it adds everything as atomic commits in Git so you can just revert something. If you don't like it just revert it. Not a big deal. It leaves copious notes too. Either things it changed that it thinks you should review or things it's like, "This has to change but I'm not going to do it because I can't." For example the change to custom validation rules, it extends a different interface now and the methods are different. But it'll list those out for you to say like, "Go look at these 10 files, you need to manually change it." I just like it, it's a very checklist-type approach. I open the PR, five minutes later... or I pay for the Shift, five minutes later I have a PR and I just work down the comments and commits it leaves. Then I send Aaron a 500-file pull request for him to review.

Aaron Saray (09:49):
Yeah, you don't need to get into how angry I was when I saw that.

Joel Clermont (09:52):
Oh, I'm sorry. It's not normally that way but again this was a new project. We inherited it, there was a lot of stuff that had to be changed, but sorry.

Aaron Saray (10:02):
I can see the benefits of that. And I'll be honest, for a long time I didn't see the benefits of it. I think it was because there was a project I took on once and I ran a Shift through and according to what I understood it didn't work. I don't know if that is true anymore. But when you get something stuck in your head, you start to kind of gravitate towards that. It took me a long time to kind of be like, "Oh, I'll at least accept it into my world again," or something like that. That may not be fair but that's how people think. Sometimes you just have to recognize what you're saying to yourself and be like, "I need to readjust this." But one of the things that I'm kind of scared about is we have a very disciplined way of going through our projects and understanding what's happening. We have the pull request system and all that kind of stuff that we do with each other. I'm concerned about those sort of tools when they go and change stuff that, A, maybe I don't think necessarily needs to be changed. Which you said of course it's in atomic or individual commits. Or that as an individual developer or something I can't keep up with all the different changes.

Joel Clermont (11:16):
Yeah, I can see that. Again, tests is like another big factor on top of this. You feel a lot more confident letting the tool do an upgrade if you have that rock-solid test suite underneath it to verify nothing broke.

Aaron Saray (11:31):
I'll give you one example here before we wrap up that I saw it on one of our projects. I'm still not sure how I feel but it isn't bad, I think it's just preference. At some point, the migrations went from being named classes to anonymous classes. As a rule, you don't edit your migrations once we can commit, right?

Joel Clermont (11:57):
Right.

Aaron Saray (11:58):
So when it migrated from that older version to newer one it changed all of our existing ones on that project to be all anonymous classes. I get it, at the same time I just didn't like it because I'm like, "Well, from what I understand that wouldn't break." Those are all been used and now I have a bunch more things I need to review, much more changes in my Git that didn't really give me anything because by design I'm never going to touch those files again, I just want to have a reference of them. Now, I can't tell you for sure how I really actually think about whether it should have upgraded those or not. But I do know that my risk brain was going like, "Did I need to have these files changed?" Then, "How much trust do I put in into an automated tool?"

Joel Clermont (12:46):
Right. I mean, that particular change I'm with you on because I'm torn. I think the whole point of anonymous classes was to prevent, what if you ever had two migrations with the same name? Now the class names will collide. It's like, it's not really a problem if all those classes were left there going forward.

Aaron Saray (13:05):
Yeah, because moving forward they're anonymous.

Joel Clermont (13:06):
I think I could see maybe the argument to back out that commit in the future. But on the other hand, it's like it didn't really hurt anything either so I'm torn too. I don't have a clear opinion on that one.

Aaron Saray (13:17):
That's the only one I can think of off the top of my head, where it was a really good example of it didn't actually matter. But it's still, for me, I'm always like, "Well, do we really want to change files in our project if it's working?"

Joel Clermont (13:29):
Right.
I've noticed that this isn't some big revelation, but the different generations have a very different view of pop culture, right?

Aaron Saray (13:49):
Mm-hmm (affirmative).

Joel Clermont (13:49):
Like music, movies, what resonates with them. It has to do a lot with maybe when you were a teenager what was popular and kind of maybe even your early twenties. But I was having dinner the other night and my 10-year-old son brought up Danny DeVito. I'm like, "You don't know who that is." He's like, "Yeah, I do. I know who that is." Like, "Really? How do you know who that is? Who is it?" He's like, "It's the guy in Angry Birds." Like, "What are you talking about?" So he brought it up on his phone and sure enough in the latest Angry Birds game there's a Danny DeVito Angry Bird, and that's the extent of his knowledge of Danny DeVito. For me, I'm thinking the penguin from Batman Returns or Twins-

Aaron Saray (14:34):
Twins.

Joel Clermont (14:34):
Yeah, exactly. But other people-

Aaron Saray (14:35):
Maybe It's Always Sunny In Philadelphia.

Joel Clermont (14:37):
Yeah, exactly. I was just thinking, and I bet if I asked my dad, he might say Taxi or like some other show that's like even a generation before. But we were just laughing so hard about Danny DeVito as an Angry Bird and that's all my son knows about him.

Aaron Saray (14:53):
Does he do the voice or is it just the Angry Bird is named Danny DeVito?

Joel Clermont (14:58):
What? I don't know. But the picture definitely looks like Danny DeVito. I didn't play the game, so I don't know what the gameplay is like.

Aaron Saray (15:04):
I don't do it on purpose that you're not just saying, "This Angry Bird looks like Danny DeVito and it's a completely different person."

Joel Clermont (15:11):
Well, it has the name on it so it must be officially licensed. But I'm sure there's an interesting backstory.

Aaron Saray (15:17):
There could be other people named Danny DeVito.

Joel Clermont (15:20):
That's true.

Aaron Saray (15:21):
Maybe it was the son of one of the lead animators and he is like, "I'll name it after my kid."

Joel Clermont (15:26):
That's right.

Aaron Saray (15:26):
He's just like, "Oh, you look like a really old man." He's like, "That's my beautiful son as an Angry Bird."
We joked about a test suite but if you're kind of stuck and you don't know where to start or maybe how your tests could be better, we can help.

Joel Clermont (15:44):
Head over to masteringlaravel.io and click on the Get Unstuck page and we can talk.