 Hey, folks, my name is Chris Manson and you might know me online as Relate in most places You can find me on Twitter Twitch The Ember community Discord all is Relate, but apart from GitHub where I am Mansona That's because for some reason GitHub really don't like the underscore So if anybody watching this knows anybody at GitHub that has the power to allow underscores in this form Please do get in touch. I will push that button as soon as it's allowed Today I am talking to you about a process that you can adopt to Improve your code base That may sound very broad and vague But it's actually true. The process isn't tied to any single technology It isn't even ember specific and you're already using parts of it probably There are just two things that I hope that you will take away from this talk that might Fundamentally change your approach to improving any of your code bases in the future. At least that's my hope and If I didn't quite convince you or I didn't quite explain it well enough Please do get in touch and let me know. I am personally on a constant journey to slowly improve How I communicate this process over time and yes, that is a bit of foreshadowing for the content of this talk So let's start our journey together with a bit of a story You are a developer and You are pretty confident enough in your language of choice We might be thinking JavaScript here since we're at Emberconf But it could just as easily be HTML and CSS or if we wanted to go even more lo-fi We could be talking about someone who writes exclusively in Markdown But let's say that this developer in our story has been working on an established code base for a few months And they started to get to know it some of the nice bits that feel all slick and modern and some of the Flaws and things that countless developers before them have vowed that they will come back to and fix But never did Let's say our developer has been participating in this new process that their team is trying called code reviews Where a team member reviews their code before it's added to the code base Remember folks not every good practice that you believe in is truly universal Trust me. I know that there are teams out there that don't even use version control Anyway, our developer has begun to notice that Everybody in the team keeps making this one mistake every so often Not every day or even once a month, but often enough that there are quite a few files in the code base that this Problem is going to be a bit problematic to work out and to find and fix all of the files that have it Our intrepid developer has come up with a plan to fix this problem though Step one in this plan is that they're going to start a rules document that everybody needs to follow when reviewing code and On this rules document They're going to make the first rule be a bit be about that mistake that they started to notice everyone making Every so often. So let's let's name this mistake so that we have a concrete example to think about Let's say that it is people forgetting to add alt text on images Generally the developers on the team remember to include them But sometimes the deadlines are a bit tight and the code reviews are a bit rushed So a few cases have fallen through the cracks But now that we have this rules document We will double-check that alt text on each and every image for all the new ones that are getting added So that's step one in fixing this particular code base. No new images are going to be added without an alt text But what about the cases that slipped through the cracks before we enforced our rules document? Don't worry. Our developer has thought of step two and they've put together a plan for the existing issues in the code base They don't actually have the time right now to stop everything and write a proper alt description for every broken image in the massive code base right now, but They have put together a list of all of the images that still need alt descriptions and They've shared this list with the team Now they're all going to slowly work together to fix the existing images over time alongside their existing work and Not only that to help motivate the team Our developer has even put together a little graph to show the progress being made as each image is fixed Never underestimate the power of the graph Now I would suspect that everyone here at EmberConf Will have picked up on my very thin allegory But let's just spell it out in case anybody missed it Our rules document is actually our linting rules if you have ever worked in an Ember app You will have experience with using linting because Every newly generated Ember app has a whole plethora of helpful rules enabled by default and Automatically baked into the default testing process What I mean by that is that if you generate an Ember app and run npm test You will automatically run all the preconfigured lint rules And you know what the rule in our example alt text images is one of the lint rules that is automatically enabled for you Thanks to Mel Sumner and the amazing work by the whole accessibility team There is a whole host of accessibility rules enabled by default So far I Probably haven't told you anything new I'm trying to set the scene and hopefully make sure that everybody listening has a good foundational understanding of the purpose of a lint rule But there are two examples in my little story that I suspect a lot of people listening don't actually have Embedded in their daily routines yet And these are two things are the ones that I said I wanted people to take away with them So firstly I said that our developer wrote a new rule in the rules document Sure, our example happens to be one of the ones that comes with every new Ember app But what if I give a different example? What if I give you a real example that I recently worked on with a client and that I can not only guarantee There isn't a pre-written rule out there And I will also say with some confidence that this rule will be of no use to anybody else This client has a simple button component and they call it a UI button It's like almost perfect naming for a component. Mwah beautiful for some reason my Code highlighting here is removing the capitalization. I don't know why but imagine this capital is there and So it turns out that we needed to change the CSS on the inside of this button Just a little bit to make sure that The button gets rendered properly everywhere in the app To cut the long part of this story short after this change Turns out that we can't use the flex class on You know from tailwind on this button anymore. So essentially that second version is now banned The question now is how do we turn this rule into a linting rule? So what even is a linting rule? I'm not going to go super deep into the details here Just because I'm not here for an hour long talk Instead, I'll give you a bit of a conceptual overview and if you want to dig in any deeper I would highly recommend a workshop that a colleague of mine did for ember conf I'm gonna say two years ago. Maybe it was three years ago I don't know what time is anymore and it's all free and you can do it at your own pace You just go to that link that I'm showing there on the screen So Let me give you a quick overview anyway I said earlier that it's likely that you have that you have lints baked into your testing flow When you submit a pull request, you will likely have broken the build if your lints have failed I think that's interesting thing that we've moved to be so rigid on linting in our daily development habits It's useful in some regards, but it's also a bit problematic Linting isn't a it's not a functional thing. You're not testing functionality when you write a lint rule You're asking a little program to read your code and tell you if it thinks it looks right or if it sees any mistakes This is important because firstly, it's just a little computer program It can get things wrong and secondly linting rules read your static code It doesn't actually try to run anything so it can't actually tell you when something is actually broken It can just make suggestions when it thinks something doesn't look quite right Next up We're going to look at what it what it's like to write one of these then rules because as I was saying It's a little bit different than writing functional tests But before I do I want to partake in a little bit of audience participation So can everybody raise their hands if you've ever written a test? Oh, hold on. I can't actually see your hands So let's try this a different way. Hey Twitter people have you ever written a test? Okay, okay, this is pretty substantial margin For the last few holdouts there and you got to try testing. It's pretty epic. Okay next question How many of you have ever written a custom lint rule that was specific for your code? Okay, okay, I'm actually quite impressed by this number I knew that there was going to be significantly fewer people having written a custom lint rule But I'm impressed that it's hanging around about the 30% mark Hopefully I will inspire a few of you to try this out and and we can bump that number up a little so let's write a Slightly simplified example of a lint rule together. I said earlier that there is That AST workshop and that will go into all of this in way more detail But for now we're going to look at an absolutely crucial tool to use for writing lint rules AST Explorer This is an incredibly powerful tool and it supports loads of languages We just have to make sure that see in the top bar there It says handlebars and glimmer Set those two right and because otherwise this can get pretty confusing pretty quickly So you'll see that I've added our example from earlier on UI button class equals flex In and that's on the left hand side. That's our code and on the right hand side. You'll see the AST Representation of that template. I'm not going to too much detail here about what an AST really is again There's a workshop for that But you'll see why it's useful now in a second one of the best tricks of AST Explorer is you can just click the bit That you care about in your code on the left hand side and it highlights the bit in the AST representation of That bit that you just clicked so there's a lot to see here But I've clicked on the class itself or I think yeah In fact, I clicked on flex in the class and you'll see on the right hand side that we're inside an element node and that element node has an array of attributes and those attributes have a particular attribute node that is Named class and has a value of flex okay, so hopefully you can see that on the right hand side and If that doesn't if that isn't a hundred percent clear, I would recommend just Copying and pasting that example into the AST Explorer right now because it's pretty cool And so now that we have that in mind. That's all we need to Find that classic was flex with our lint rule So let's move on to actually writing a lint rule and You can follow the instructions in the read me of ember template lint and I think the AST workshop that I was talking about goes into more detail of this But again, we're going to skip ahead and we're going to just use the example that they have in their read me Which is? Trying to find a comment statement and I Assume that that's useful to some people to be able to go and find comments in your code but we're just going to copy that structure and Use it for our element node So this is from what we saw in the previous example in the AST Explorer We know that we're trying to find an element node So we are returning a function called element node from this visitor function And again, I'm not going to go into too much detail here, but this is a visitor pattern essentially it just means that That function called element node will be run Every time we find an element in any of our templates so What we need to do is we essentially need to find a specific element, so let's do that by Putting a little if statement to check if the tag is UI button and ignore every other element then we will go through when we find a UI button and find any Attributes that are Named class, so we're just doing node dot attributes dot find where that name is class Next we check if that class attribute exists because We could have buttons in the system that don't have any class and we check if the value of That class attribute Includes the text flex and This is this is it. This is the last bit essentially We just need to complain to the lint system here and this is going to be different for every Lint system that you're using or every kind of lint rule that you want to write But with ember template lint you just call this dot log Pass it a message. So try and be as descriptive as possible here help your developers if they come across this error and Then you just need to pass in the node as well So that say if you're using Linting in your editor it would know where to draw the little squiggly line And that's it It's been a bit of a whirlwind example, but I'm telling you now That although this is a bit of a simplification because I'm leaving out a few edge cases. This is the essence of a simplified linting rule and I hope That a few people watching will be looking at this and saying to themselves. Wow, that's more Approachable than I expected And as I said earlier This isn't a master class. I'm just trying to inspire or to encourage more people to Try writing their lint rules if I have inspired you to try it out. Do let me know on Twitter I'm always interested to hear when people are trying out things that I've talked about so now that we've covered that creating that lint rule I want to and I want to talk to you about the one of the other things that our developer story had and they said that they wrote down a list of all the places in their code that needed to be Changed and even put together a graph So this is where the little tool that I built comes into the picture and it happens to be the namesake of this talk Oh, let's get away from me again lint to the future lint to the future was built to solve a very Specific problem and it's a remarkably simple tool let's talk about the problem first and Then we'll get into what the tool actually does once we understand the problem a bit more So let's imagine that we have just written our don't use flex class on buttons lint rule And we wanted to enable it on our massive code base We put it in the right place and configured it correctly and suddenly our CI system Explodes and tell us tells us that we found a thousand lint errors across all the files in this giant code base Turns out buttons are quite common web apps. Who knew? So I know I said earlier that lint Rules don't actually break things But for better or for worse our CI systems are usually set up to explode if even a single lint rule fails So you can't just turn on the rule committed and push it to master and It turns out that this particular rule isn't something that we can blindly fix We can't just find and replace and remove all the flex classes because when people were adding those buttons They added flex for a particular reason and we need to go in and manually check Each of the buttons before we remove the class. So what do we do? One method that we might have done in the past would be to add the rule But either configure our system to just ignore it So this doesn't really help us very much because we might as well have not added the rule if we're Instantly going to configure our system to ignore it at all times So there is another approach and we can set the system to think of it as a warning and not an error So that's what this looks like And as you can see it's not all that much different the big difference here is that it isn't Erroring at the end. So our CI system will allow you to merge your pull request But we've also just created, you know a thousand lines off Unmanageable comments and warnings. We can't really do anything with this so We can either set our system to ignore it globally or There's another approach if we want to improve things slowly over time What we could do is we can use we can make use of a special Comment format that can ignore a particular rule in a particular file So every lint system has one of these every lint system that I've come across anyway And you just have to know how to write one of these comments and what it needs to be formatted like and in ember template lint It looks like this Template lint disable and then the names the rules So what's the actual benefit of this didn't I just say that if you disable something you might as well not have added it well Remember I said that We need to Make sure that all new files in our example in our developer example all new files conform to this New rules document or the lint rule well by setting up the File-based ignores like this as a one-time thing when we enable our new rule That means that any new file that we create won't have these file-based ignores at the top of it And they need to conform to the new rule that we've just configured So you might think that this might be a bit tedious to find all the files and either add a new comment or add our Rule to an existing comment and I would tend to agree and this is where the first feature of lint of the future comes in Let's install it into our repo first We just do npm install lint of the future and lint of the future ember template this installs the main lint of the future package and The ember template lint plug-in for lint of the future. It's a plug-in based architecture, which is pretty useful So now any time we run any of the commands against lint of the future It will know how to deal with files that are covered by ember template lint So now that we've installed it we need to make sure that we Configure our rules so that the ones we want to ignore are Currently failing so in this case we go back to our custom rule example that we had and we see all of the errors there and We wouldn't be able to commit this as I said, but we just run npx Lint to the future ignore and it will automatically add those file-based ignores to each of the files that we've checked so Now you're ready to commit and push your work This is a great first step For enabling a new rule tier code base if the code base is still growing then all the new files from this point will Be just that little bit better from the way they were before and now all we need to do is find something to do with our Existing files and this is where the second feature often into the future comes in the dashboard I plan to reveal the dashboard right at the end But I couldn't contend myself. I just had to show it here I'll show you a bit of a demo just kind of navigating through it right at the end But for now we'll go into a bit of detail on how the dashboard works and how it gets its data So we're an example from before we talked about this big list of files that needed to be fixed essentially the fact that we are now using file-based ignores for ember template lint or whatever other em Plug-ins you're using is all we actually need to tell the system what files need to be improved So in lint to the future We have this little command that asks each of the plugins What the files are that have these file-based ignores and if we just run NPN? Mpx lint to the future list and ST Standard out just prints it out essentially. This is what the output looks like It's kind of cool. It's not the graph that I showed you a second ago But it's Interesting for one particular reason you'll see the way that this output is actually structured We have the date which is when this was run And then we have it grouped by each of the plugins in our case ember template Plug-in and ES lint plug-in and then for each of the rules and then of course You don't see the array, but that's just an array off the actual file name that has the file-based ignores at the top There's one more Command for lint to the future. That's interesting and it's the thing that actually outputs our lovely graphs it is lint to the future output and dash o Just tells you where to create the folder that it generates for you So what that actually gives you and I'm just going to look inside the folder here You'll see that it's actually built a static web app for you and you'll notice that that there's also a data.json And it happens to be the same as the output of list from before So if you booted this static site up right now, you would see a set of graphs with exactly one data point Because it only knows about today when you run it just now If you want the app to do what it's supposed to do and allow you to track things over time You need to tell it where to find yesterday's data by just passing in a link to the previous results so if you run this and then took a Another look inside the data.json You'll see that it's gone and Downloaded yesterday's data and you can go and take a peek at yesterday's data If you wanted to by just looking at that link and it's merged it into the json with the output from the list command from today I think this is a pretty neat trick to allow you to keep track of your data Using only a HTTP server and not needing a database It means that you can even host your lint to the future dashboard on GitHub pages without needing any other infrastructure So on top off building into the future I've built a little reusable github action that allows you that actually does the lion's share of all this work for you So all you need to do is add this little snippet to a workflow document And I know that probably looks a little bit small on your screen But I couldn't zoom in because the length of the length there and I could probably Rename the repo to be a bit shorter and then it would be cleaner for demos, but That's it. That's all you need to get started with link to the future dashboard if you wanted to try this process out and If you've gotten this far, what does it actually give you? I've teased you with a screenshot. So let's go and do a quick demo and I'm just kind of randomly moving through the dashboard here and a few things to note first of all, you'll notice that there's Awesome styling dark mode here major props to and cret for this And a little birdie tells me that she'll be talking a little bit about designing for dark mode So watch this space You'll see that we have a graph for each of the rules that are failing You'll see that we have like a continuous graph from when it first showed up to today And that's it's actually filling in any gaps of days that you That you didn't run the process and which is pretty handy and And you'll see that most of these graphs kind of started out in the month view That's just because there's so much data after it After there's so much data. It just kind of defaults to monthly rather than daily or weekly. This is another Thing that and great actually contributed. So thanks again for that And and you saw me do it a few times there But at the top of each graph you have this view files link that you can just open and see which files need Still need improvement And that's it really and that's it for my talk I hope I've given you a nice foundational perspective on what lints are or how useful they can be to actually unlocking Improving your code base slowly over time and if you're writing your own lint rules That's just an incredibly powerful tool that will change your game a lot if you get into the habit of it And don't forget to try out lint of the future set up your dashboard and Tweet me if you do and I'll leave you one thing never underestimate the power of a nice graph Thanks for having me