 Hello. Wow. There are a lot of people in this room. My goodness. This is my third WordCamp Europe. I'm really, really, really delighted to be here. This has been a really good day and a half so far, right? So my name is Andy Nason. I'm one of the lead developers of WordPress. And as Sarah mentioned, I did join government a few years ago. I like working with legacy software. Now, WordPress is, at this point, it is, when I started contributing, the code base itself was already nine years old. It was written in PHP, my SQL, this is a stack that isn't used as much as a choice, perhaps today. Maybe not as much in 2009. A lot, of course, in 2003 and even 2001. Really, what I like is I like to fix things. I'm a fixer. I don't necessarily always like to build the new shiny thing. A lot of this is normally called green field development. I prefer, in many cases, working in legacy land. And one of the reasons is because I personally like a challenge. I enjoy to deal with the things that are really bad, and then how can we make it better? So, of course, that's one of the reasons why I joined government. So, today, I'm going to be talking about inheriting large and legacy projects. To some extent, this applies, of course, to what I was doing with WordPress in many ways. It was already nine years old at the time. I had stumbled across it, not necessarily legacy, but certainly very large. 250,000 lines of code, hundreds of people had contributed over the years. Many of them were no longer there. There are a lot of definitions of legacy. Not all of them are bad. Some of them are code without tests. For example, if you don't have tests in your code, that's legacy. Some of it is anything you didn't write yourself is legacy. So, when you come into a new project and you inherit this, let's say you work in an agency and you're hired to say, hey, so we hired this other company and they have it half done and it launches in three days. Can you help us? This is a thing that I'm sure has happened to many of you. Or maybe you get pulled on as an engineer on a brand new project and you're realizing, well, the project isn't all that brand new and you really need to be able to help very quickly to get to a launch. So, in many ways, I'm really drawn to WordPress not so much because, like, it's old. 13 years. All right. But really because I like having what I work on well grounded in a mission. I like the idea that with WordPress we can democratize publishing. I like the idea that with WordPress we can enable people to publish around the world without censorship, without any kind of government intrusion, without really just being able to allow people to publish on the open web. And I also really like the ability to make a product that is ultimately compelling for users, even if it's 13 years old. And this has, in many cases, for WordPress and in spite of, there are a lot of other projects that are this old that simply do not work well for users. They have never focused on the user or even if they did 10, 15 years ago, it feels dated. And that's not normally something you're going to say about WordPress. So, when we're talking about inheriting large projects, what are the kinds of steps that we might want to do? The very first thing we inherit a project, it's ours now. It's our agencies. It's yours personally. Can you please do a code review? We have a problem. Some of the main reasons why we're going to be dealing with something in many cases in a crisis mode, but even if it's not a crisis mode, hey, we need you to take over this project that it needs to launch in a few months, is probably going to be along the areas of performance, security, and then also, oh, by the way, we need this new feature. No big deal. It's just like an e-commerce store, right? So, one of the things that we want to do is we want to size it up. We want to understand what are we dealing with. And when looking at this, it's really interesting. You can size up code in a number of ways. There are static analysis tools that you can run over it. One of the metrics that I like to do is I just generally like to do a software lines of code count, which is a terrible metric for measuring software generally. It's not good for measuring productivity or anything like that. But the one thing you don't want to do is be told, please review this theme. And you say, okay, sure. And then the very last value open, buried in that includes directory inside the PHP folder, is like 14,000 lines of code that ends up touching literally everything else and you just missed it that entire time. So the first thing that you're probably going to want to do, because this is very common to just receive, let's say, a zip file, is to get the code into version control. And ideally, something that you're used to, of course, GitHub, something along those lines. I once had to review an entire code base. This is a government story. I once had to review an entire code base using the only tools I had available, which was searching in the windows file explorer and opening the file up in notepad. This was last week. And so we want to just generally understand the scale of what we're working on. How big is this? What are we dealing with? If it's maybe a few thousand lines of code, it's a theme, you can probably get away with code reviewing that entire thing end to end. If it is suddenly hundreds of thousands of lines, or it's a thing that you've never dealt with before, or it's built on top of something you haven't dealt with before, it's going to take a lot more time. You want to, of course, get this into a development environment, something that is easily reproducible, something that you can set up over and over again, something that another engineer on your team can set up. In WordPress, this may be, for example, VVV, something like Vagrant, maybe a Docker instance, bonus points, if it's the same thing that you're deploying into production, if you're working in a development environment into production. And then ideally, you should find some of these tests. Chances are you won't. But if you do, you should try to figure out how much of the code is actually covered by these tests. Something like 2%, well, they've tested one thing that's good. If it's closer to 80 or 90%, you might not be dealing with that much of a legacy code base, which also means it's going to be a lot easier for you to make changes. It's going to be a lot easier for you to make a change and not realize, oh no, I just broke everything. This is something that happens in WordPress sometimes, where we end up, perhaps, someone opens a ticket and they say, I would really like this change to be made. And we say, well, actually, if we make this change, it will break these five other things. But then three years later, what's to stop someone else from opening a ticket and say, we really want this change to be made. And now I'm not around or someone else didn't notice it. And they're like, oh, yeah, this is a great idea. And now it suddenly breaks things. So one thing that we often do in WordPress is we write tests to enforce decisions. So specifically in this case, it could be a situation where we're like, no, we're not going to make that change. This function can never return an integer. It would be very bad if it returned an integer. So we would write a test that can ideally evaluate whether that function maybe always returns an integer or never does whatever it may be. And that way, three or four years later, rather than needing to find that bug report, that original bug report, it can just be a situation where, oh, if we try to make this change, the test will immediately reject it. So tests are ultimately very important, especially for decision making. If there are things like security concerns, one of the easiest way, if we're doing a fast, fast audit, there's probably a few specific things that you can do. In addition to using a number of tools out there to do static analysis and pen testing, just generally seeing how the HTML is rendered is a pretty good indication. If you need to suddenly go through an entire theme or a plugin or some application and just add escaping absolutely everywhere, you can do that if you needed to. It's a quick way to understand how is this site vulnerable. Along those same lines, if there are a lot of queries, very quick it's normally able to see where these queries actually run. It's a Java application and they're all buried in a single file somewhere, so they're off to the side. It's a theme that they're calling it on the home page. How are they actually being run? Are they secure? Again, these are stupid, simple steps, but nonetheless this is the first thing you're going to look at. If you're dealing with performance issues, with WordPress is a great plug-in query monitor, which is a great way to check this, but there are some other ways that you can do this as well. Ideally you would want to use profiler, something along those lines, maybe like call grind, cache grind, something like that, to be able to understand what is going on on the site quickly. It's a very quick way to size it up. I don't need to do anything, I don't need to inspect the code in many cases. I can simply say tell me what is taking so long because the client's home page is loading in 37 seconds and that's before all the JavaScript starts. That's not good. We need to fix that. Monitoring is of course very important in production, but there are some other things that we can do as well for performance. If we're really trying to do something very fast and quick and dirty, we can just add some caching to that site, but not necessarily in the way you might think. There are some other techniques for this as well. For example, you can cache something for a limited amount of time, and by a limited amount of time, I mean maybe seconds. You can have the home page rebuild every five seconds, for example. You can do this in Nginx pretty easily as well. You can make it so if the person has never visited before and they're just hitting a single page, you could serve a page out of cache and keep a cache always hot. This isn't necessarily the best approach for all of this, but certainly what it ends up doing is it allows you to have a very quick way to handle a scaling problem, especially on launch day. You really want to make small changes. Ideally, every single change should be well documented in a single commit message. This is both for you as well as for others. Because really what you don't want is you don't want to be in a situation where you don't really remember why you made that change three hours ago. You want to make sure that you're practicing continuous integration and deployment. You want to make sure that your code is going through a pipeline, is being built, is being tested, and then is getting, end up being deployed. And so if your tests fail, you're not getting far. And then ideally another technique is let's say you have two different systems that need to talk to each other. One is pretty old. You could put a modern API in front of that other system. And now your new system that you need to integrate with it can simply talk to that API. This is a really nice way to be able to at some point then remove that old system out of the way. That API is still that contract. It's still that important piece. Often the best way to approach this is actually I have this crazy application that I really don't know what it does. But I need to build a JavaScript front end application on top of it. So what you can do is you can build a quick and dirty API. In fact, in best case scenario, you're building this on top of the WordPress API. Use that to interface with all of your data. And then at some point, if we're able to go back and rewrite all that code, you can. But in the meantime, in the meantime, you have all of that available to you. And you have that API. You can work with it. You can maybe deal with the legacy code another day. There's a really great book out there by Michael Feathers called Working Effectively with Legacy Code. I'm not going to get into too much detail. A lot of it is focused on tests in particular. But the one thing I need to say is that it may get worse before it gets better. There are going to be situations where I need to ship something, and I'm going to be adding hacks before I am removing hacks. It's ultimately very important. But at the same time, everything you do should still be able to move your goal posts, or move your goals forward. You should be able to say, I ultimately want to get rid of this thing. So everything that I do gets me closer to getting rid of it. So perhaps I am, for example, adding more unit tests to that thing, which is then allowing me to get rid of it at a later time because I know exactly how it works. And this is perhaps a lesson from government, is that perfect is the enemy of good. If you have this big waterfall project that you're working on for potentially years, you want to make sure that it actually ships. And a lot of the times, people aren't willing to adopt a more agile methodology because they're not willing to just like say, okay, well, we might ship something that's not perfect. And this is a line that we end up using a lot in the digital service as it happens, is this will have to be okay. This will be good enough. We've gotten to the point where we think it's good enough. There are a number of other aspects to this as well, though, in terms of legacy projects and large projects, because it's more than just the code. It's way more than that. It's communication, very clear lines of communication with the people who hired you, with the people who, your end users, things of that nature. You need to make sure that there's extremely clear decision making. If you are a hired gun coming onto a project and maybe the existing company is already there, you need to make sure that your communication is good and you need to make sure that your decision making is very, it's clear as to who knows what's going on, who has the authority and who has the accountability for whether that project succeeds or fails. You also want to make sure that you're showing understanding. You want to make sure that you know that, you know what, I don't entirely know why they did it this way. In that particular case, rather than saying, wow, this is absolutely terrible, maybe ask, why did they do this? Because it's entirely possible that that was a very reasonable decision to make at the time. Another aspect of this as well is to be wary of just like throwing more people onto a project. There's a great book on the Mythical Man Month, very classic, 1975. If you're trying to rescue a project, you have to be very careful that you are not necessarily the problem. Along these lines as well, it's also really important to understand what is truly needed. In this particular case, what I find is one of the biggest problems is that you get called to fix something and you're fixing the implementation of a solution that never actually addressed the problem in the first place. The problem maybe wasn't defined well. The user didn't entirely know what they were asking for. All of these different problems that we might have. Really what you want to make sure you're approaching is first, take a step back, understand exactly what the requirement is, understand what did we need to fix in the first place, and does this solution actually match the resulting problem? Does this match the user's needs? Is this truly maintainable? Because the one thing you don't want to do is go down a rabbit hole to make something work and then realize, oh, I was hired to fix the thing that was actually the problem in the first place and I'm going down the wrong path. If you're a consultant, there are a number of things that you can do that will work very well for you in your pocket. One example is if you like to do migrations of sites, there is a great market out there. It's very hard to do a migration. Very few people enjoy it. Very few. And ultimately, if you're able to specialize in, oh yes, I can fix this thing, it will pay off for you. You will learn a lot, you will be challenged, and at the same time, you will be able to have quite a good hourly rate. At the same time, the pay off is many times going to be, of course, way more than money. In WordPress 3.5, which I had led, we decided to tackle the Media Library. And for those of you who have used WordPress for more than four years, you may remember how the Media Library was back in five, six, seven years ago. It was not what we would call shiny and modern. It was written in 2007, 2008. It was designed for, best described as an earlier web, didn't support a lot of things along the lines of audio and video. Didn't really, frankly, support photos all that well either. And in particular, it's, we found it to be quite a challenge in terms of how we ended up needing to approach this. So, what we initially did is we were like, okay, what is the problem? We defined the problem, we did some user research, we did some usability testing, we established what the problem was. Then, we ended up writing an API. We wrote a small API, layered on top of the old, complex legacy code. That was then, it was JSON, it was Nimble, it was exactly what we needed. We can tweak it exactly how we needed it for what we needed to build. Then, we proceeded to build a new front end. We built an entire new JavaScript application on top of that API. Then, we added unit tests to all the legacy code, which in many cases didn't have it, and began to remove, piece by piece, the things that we knew we no longer needed. We were able to pull those pieces off. When we got done, we had a thing that we realized didn't break any plugins, which is incredibly important for WordPress with WordPress being backwards compatible, and we don't want to break plugins deliberately, and yet we had an entirely new interface that still worked on the old way, worked with the new way, was modern, was sleek, was exactly what we needed, and set us forward in the future. In this particular case, what I really realized is that I like that. I like to doing it. We did this in six short months. It was incredibly stressful. I was working very long hours. A lot of the others were as well, but I enjoyed it. I'm not going to do it again tomorrow. I skipped a release. I didn't lead 3.6, I led 3.7, and then 3.9. It was busy time. But I really enjoyed being able to fix and address these kinds of problems, and so I hope the next time that you are able to inherit a large or a legacy project, that you also end up finding that reward. Thank you very much.