So today, welcome back to the Laravel News Creator Series. In this episode, I have with me Len Woodward, who is the creator of quite a few projects, but today I wanted to talk to him about whiskey. So Len, as far as introduction, anything, any other projects you want to mention are off the top of your head that you're doing a lot of work with that is not whiskey? Yeah, I got a couple.
So one that got a little bit of traction on Twitter a couple of weeks ago was Conductor, which is basically NPX, but for PHP. So it allows you to run composer packages in an ephemeral way. So if you've got stuff like just one rector or a shift from the Laravel shift that you want to run, you can do that on the CLI and it doesn't necessarily need to be installed.
I'm putting a lot of work into community prompts, which is an extension of Laravel prompts, which allows you to do some interesting things. I've worked on an async prompt that lets you unblock rendering to the terminal and reading from the file system and everything so that you can trigger renders at any point in time. And then it's open to community suggestions as well.
So if you had a prompt that you wanted to submit to Laravel prompts and it got closed because he doesn't want the maintenance burden, we're open to taking that on. Other projects, I've got some stuff for FFmpeg, managing on demand disks. Yeah. I think that's a few. I think that's probably enough packages. I got enough on my plate. Yes. I know because I think, I mean, this is going back maybe one of the first times we spoke was on the FF, is it FFmpeg? Yeah, FFmpeg. MPEG.
Yeah. Because you were doing some cool stuff with that. But today let's talk about Whiskey. So Whiskey is a project you created, I think it's been out about a year now. Is that sound about right? Yeah. I started it out as a package just called Laravel Git hooks. And that would register a couple of commands that you would bring into a package. And then I went to Chicago for PHP tech last year. And Nuno suggested to me that I write it as a standalone CLI using Laravel zero.
And by the end of the conference, I had a working proof of concept. And then I just kind of kept improving it over time. I still haven't hit 1.0 yet. There's one more little thing that I want to squash. But yeah, I mean, it's useful. It's being used out in the wild in projects. It's been great for my own projects. And I love not having to rely on Husky in my node dependencies. That's nice. So as someone that's never used it, don't know anything, say that they're just listening in.
What is the, basically what is Whiskey and what is the selling point on why you would want to use it? Yeah. So we, at a client I was working at, we had a need to manage all of our Git hooks across the entire team. Previously I've used Husky and like it worked fine, but it's a little bit higher friction to install than I was hoping for.
And so my goal was to just build something that's only PHP that only depends on the PHP version and no other dependencies and something that would be the lowest friction barrier to entry possible. So the name Whiskey is kind of an homage to Husky. But yeah, I went through this, tried to make it as easy as possible. It's easy to disable. It's easy to update. Well, I was going to say, so let's say you're a developer and you've not really used Git hooks before.
What's the selling point to even start using those? Like what are some common scenarios where you'd want to use Git hooks there? Yeah. So Git hooks are kind of a controversial thing. It's a really useful tool in certain scenarios, but it's really easy to go overboard. So when you're doing your commands and push and pull and merge and all that sort of stuff, each time that's called, Git is going to trigger a hook. And if you've got something registered in that hook, it's going to run it.
If you don't have anything registered, it's just a no op and it's going to keep going. So for myself, every time that I make a commit, I want to run the linter. And so I've registered that I've got my composer lint command. And in my Git hook, it just calls composer lint on push. It's going to run composer lint, composer types, composer stan, composer test. If that's too slow and it's slowing you down, you can always just tack on the dash dash no verify flag and it'll skip it.
But that's what it is. So it can slow you down. You don't always have to use it. It is easy to go overboard. So I would warn people against going with a Git hook that ends up being like two minutes. Try to keep it fast. Yeah. I was thinking like so, like in a team environment, if you have a ton of like, say you have a two minute Git hook and does it, is it blocking for the other person? Like if you push and it's running and then I push, that's not, it's still going to push, right?
It's just going to, it's just going to rerun. On the client. So this has nothing to do with Git at all. So this will, if any of your Git hooks return a non-zero exit code, it's going to stop the process of going to GitHub. So this is a way to save minutes on CI and stuff like that, because you know that when you're pushing, it's already going to pass the lint check. So you're not having to push your code up there and it's like, oh, I missed, I missed my spacing on this.
I had all my stuff on one line when it should have been split up and it, and it doesn't pass. So then you need to have another commit going in after it. That's just tagged linting. And then you have it run and sometimes you've got multiple, multiple checks on GitHub. So you're pushing these things up. You're still running your test suite and then you've got multiple things running at the same time. It's just, it's a bit of a pain.
And then for an organization, you've got a limited number of minutes in your, your GitHub actions as well. And so if you've got a lot of stuff going on, you kind of want to minimize that by offloading that burden to the client first. Gotcha. Gotcha. And, and then now as far as like whiskey, it's, it's all, you know, the way you build, I guess, build, create the way you implement everything. It's just straight normal things, right?
Like I know you were comparing it to one called Husky, but this one's designed just to be simple so that way you can define everything you wanted to do sort of in a normal fashion, I guess is the right word. Yeah. So the, the big issue with git hooks is that in your dot get slash hooks directory that, that doesn't get committed to your get tree. So you can't really track things that way. What whiskey does is it registers its own git hooks directory and then that's committed to, to the repo.
And so that's what your, your native get hooks are going to be calling. That's a little bit more complicated to set up than, than whiskey. I mean, it's not, it's not a huge difference anyways, but I was just curious about what it would look like to build this tool. So I built it and then I just kind of kept going and it was like, Hey, this is cool. So I was going to release it.
So my goal was to just have it be you require the package and then you just run whiskey install and it does the whole thing for you. I've structured it in a way so that if you've upgraded whiskey and you're trying to install it again, it's going to look for all the legacy ways that I've ever installed it and it's going to replace those as well. So you're usually not going to have to go in and modify these things manually.
So it's a, I'm trying to have it just be really, really smooth, really smooth, straight forward. Is this something you run on all your projects, even for like your personal stuff or do you kind of think of more of like these get hooks and, and whiskey being more in like a team environment? I run it on most of my projects. Yeah. And I didn't know this until recently, but apparently, uh, verbs from, uh, from thunk, they have it installed in there too. So that's kind of cool.
And yeah, they told me that they like it because it just works. It's one of those things where you just kind of set it up once and you can forget about it. And you don't need to, it's not one of those things that's constantly blocking you from, from getting your stuff done. So it's nice to know that at least it's tolerable. Yeah, that's true. That's funny. Um, so, so what is like, um, this was sort of off the wall, but what is sort of the most advanced thing you've ever done with the package?
Like are you doing anything crazy in any, in any of your other projects that, uh, so I don't do a whole lot of crazy stuff with, with whiskey because normally, normally I just register all my scripts as composer scripts. So I just do like composer, Len, composer types, composer coverage, composer, all of this. And then in my whiskey dot Jason, Oh yeah, that was the other change. I don't register a get hooks directory. I just have a single composer dot Jason in your directory route.
So that's where you do it. And every time you make an update in there, as long as you're not adding a new hook, you don't have to update whiskey. Um, so that's usually the only stuff that I'm doing. I'm not doing crazy stuff. Like a lot of people will add in like a scripts directory where they can have lint staged. So it'll only lent anything that's been staged. I usually try to avoid that.
My biggest suggestion with whiskey and get hooks in general, do not let your get hooks modify the, um, the, the files, just have it do checks because if it's modifying files, especially if you're doing patch commits, then it's going to overwrite the, it's going to recommit the whole file instead of just that patch section. So I try my best not to do anything ambitious and a get hook. I try to just keep it simple and fast.
Do you, um, I, since you want it simple and fast, do you run tests through there too, or do you kind of keep those for only like sort of the sea outside? Uh, I mean, of course running them locally, but do you also do that as part of this or, or how do you usually run the tests before pushing? So my, my pre-commit hook is usually just a linter and then my pre-push hook is usually like the, the linter again, um, static analysis and the test suite and sometimes type coverage. Nice, nice.
Um, and then of course, you know, like if anybody's listening or watching and they want to, um, just sort of see what you do, I assume you, you have a sample set up there, um, with the package to kind of get them started or is it best to look at, like, look at one of your other projects just to, just to see how you're doing things? Um, yeah, I mean, there's, there's not really a whole lot to it to demonstrate. The read me I spent a lot of time on, so it's pretty descriptive of it.
So it goes through a couple of scenarios where, where you might want to skip using whiskey and stuff like that. Um, yeah, I don't think there would be a whole lot of benefit in showing how it's used in a project just because it's such a small narrowly targeted tool. Um, one thing that I did want to include in there though, was there's certain actions in get that aren't compatible with the no verify flag.
So if you're doing something where someone used the no verify flag to push something that wasn't passing the linter and then they skipped the CI step and they merged anyways. So you've got changes in your main branch that don't pass the linter. You're going to bring that down into your local branch and then you're going to merge from main and then as you're merging, it's going to fail because it doesn't pass the lint stage because we're not, we're running the pre-commit hook.
So if you try to run get merge dash dash continue dash dash no verify so that you're skipping the hooks, it's not going to work because that function doesn't work with the no verify. So I added into whiskey, uh, just a whiskey skip once command. And so if you do that, it'll skip it. You can merge from main, uh, or rebase from main. And then at that point you run the linter on a separate commit and then you can keep on going with your work.
So there's some, there's some edge cases and everything, but I try to, I try to demonstrate those in the read me. Yeah. It's funny. Like, yeah, I was going to say, like get, get in general, like, um, you know, I'm sort of this old man developer now. You know, we started off with no version control and then it was a, what CVS or CSV and then Mercurial and then, uh, SVN at one point. Uh, but I love that like sort of get seems to have won the space of, uh, of, uh, version control.
It just seems so much easier now. Um, then, you know, way back in the day when it was sort of the, you know, the merges and stuff were just terrible and all that. But, uh, um, I was sort of a random tangent, but, uh, so going back to the name, you said the name came from sort of, uh, uh, a call out to Husky. Yeah. And the name was like a hundred percent credit to Nuno on the name.
I don't know how he just like pulled it out of thin air because, uh, he suggested, why don't you make it a, into a CLI instead. And like, yeah, geez, I wonder what I would name that. He was like, why not whiskey? It's like, it was perfect because it's pretty similar to Husky and that's definitely how it was inspired. I don't know where he got that name from, but props to him. Well, so Husky, I'm, I keep thinking of a dog, like a Husky dog.
Um, and then I assumed you were drinking whiskey the night you created this and that's where the name came from. No, I haven't developed my palette for whiskey yet. I've still got a very unrefined palette. But uh, but you do have the logo there with a little whiskey glass, um, with a little ice cube. So that's pretty sweet. Yeah. And then I just, I just spell whiskey the correct way, much too much to the chagrin of J Mac.
He thinks I should be spelling whiskey the other way, but it's, it's just not the right way. I will die on this hill. What's funny though, is if you Google like Len Woodward whiskey, like there's actually like whiskey that comes up, not the, not the project. And you keep, you would think that like, you know, that would be sort of random, but it was like, cause cause when I was doing research, I was like, Hey.
And then it was like all these, I guess Woodward and then Woodford and you have all these other different whiskey actual brands, um, which is kind of funny. Uh, but, uh, but who did, who did your logo? Did you design that one yourself or? Yeah, I just, I just went in Figma and tried to do something a little bit stylized. It was just a really quick and dirty thing. I think I was, it was me anyways. Did I steal it? I don't think I stole it. I'm pretty sure I did it myself.
I'm not even sure anymore. I don't know what I have and haven't done. If I stole your artwork, let me know. I will give you money. I was going to say it all, it all runs together in the end on it. But how's the, um, you know, as far as the usage and stuff is, is the community picking up and using it or, um, yeah, I mean, it's been a slow and steady grind. Um, I think I'm up to like 38,000 installs or something like that. And I'm up to like 160 stars on GitHub.
So it's not like a super smash hit, but I think get hooks are kind of a niche thing. So not everyone is looking for it, but every once in a while open Twitter and someone's like, Oh, I found this cool tool. And I'm like, Oh shit, that's awesome. I wasn't expecting that. It was just a nice little surprise.
That is also, I've actually, I don't, I'm trying to remember if I use get hooks that often and I don't, I'm trying to, I don't, I'm not pulling up anything out of my mind that where I've been using them lately. Um, so may I need to actually research more on, you know, setting those up and give them a try cause I get, just seems so useful. Um, especially like the running tests, like, well, you said that was a pre-commit hook, but, um, just even the linter and all that stuff.
I mean, it seems super useful to have all that just set up once. And then everybody just, you know, has the same stuff all the time. Yeah. It's funny every once in a while, I got this little uptick and installs too. Cause, uh, I think like every six months or so, um, Roman Pronsky ends up writing like a little tiny blurb about it in the PHP foundation newsletter. Like people are talking about this again. I wonder what happened and it's always Roman. That's great. That's great.
Um, so they, they do, well, I guess they pick up that's on like the official PHP news there, is that what Roman writes that? Or is that on the, um, I can't remember if he does it through the foundation or if he does it through the jet brains. I think it's jet brains, but yeah, every once in a while there's something on there. And then, uh, and then yeah, every once in a while there's another project too, like FFmpeg stuff or a conductor was on that people are really excited about.
But I still got some heavy work to do on that before it's, before it's ready to properly announce and release, I've got my proof of concept in there, but it's, it's gross. Well, so I think you alluded to it earlier, whiskey, you, you think it's pretty much feature complete or you got one, one or more, one or two more things you want to do to it before jumping over.
So there's one bug that's still, that's still annoying me and some GitHub, uh, some git hooks will accept parameters and I'm not set up to handle that. And I just haven't been able to sit down and properly crack this, this problem. So where that becomes an issue is if you're using an extension or a plugin, like, um, Oh, what's it called? It's like lint commit message.
So if you have a certain style that you want your commit messages to abide by, um, it'll, it'll look at the actual message and we'll do that, but I'm not sure how to handle that yet. The other thing that, um, that I had fought with for a while was just an architectural thing where it was really gross the way I had to register everything.
So I had a, like a shell script in my, in my vendor folder that the get hook would call that shell script would then ask the Laravel CLI from Laravel zero for a list of the, the commands to write. Then it would bring that back. And if you're supposed to skip it, that list will just come back empty. But the reason I had to do that, that was so that I was getting the output as it came out. Um, I ended up discovering the process for sad has this TTY mode.
So it basically attaches the input and output to the, to the actual currently running terminal. So it had a benefit of being able to be interactive. So if something stops and asks for user input, you can do that, but it also maintains the colors in the terminal. And that was like a really unexpected, nice side effect. So you still get all like the, the green checks and the red X's. So that brought me like way closer to feature complete. I've just got that one last little thing to do.
I'm pretty sure we're even windows compatible. It's been a while since I've tested that out, but I'm pretty sure it works. Well, I guess kind of eluding into that, are you looking for sort of community help on any of these things? Or you think you're just going to knock them out one day when you get some time? Yeah, there's been, there's been like three other people that just pop up every now and then with a PR and like most of the time they're, they're great.
Like they're just this really narrowly targeted banger of a PR and like they list the, the issue, they list why it's an issue, how to fix it. They got the fix in there. And then every time I tag a new release, I try to tag them so that I can show them out and thank them and yeah, it's been, it's been fun having a project that other people care about, even if it's just like this tiny little bit. Yeah. And, and to have people that commit and do what you just said is, is pretty impressive now.
You know, it's always great when somebody does all that and it's really isolated to the one thing that they're having the issue with, you know, so, you know, that was where I was going to, like, if, you know, if you're listening or watching and you know, you've not made commits or pull requests to any projects, keep it small, keep it contained and focused on one thing, and then it's your likelihood of getting it merged is way greater than, you know, if you're trying to tackle 50,000
files or anything else like that. Yeah. And if you are trying to develop a thing and you're not really sure why, why certain things aren't working, I do have some hidden commands in there as well, which you can usually find in the not in the read me, but in the source.
So I've got like a whiskey audit command, and that'll just give you a table that prints out a whole bunch of the variables that I'm using within all these different classes, like where the composer home directory is, where the project directory is, where vendor things are being kept, like, and then ways to determine the platform and all that type of stuff, ways to determine if whiskey is being run globally or locally.
So if you're trying to add in a little feature or a bug fix and things aren't working, you got some tools like that built in. That's awesome. That's awesome. Well, I guess we'll kind of any other sort of highlights or anything else, you know, that we didn't, uh, why I didn't ask you about as far as whiskey goes. Not that I can think of no. And it's a pretty small tool. So it's not really, those are the perfect ones.
Yeah. Yeah. It's, uh, um, I forgot what I was trying to say there, but yeah, the, uh, I like the little small, well-defined tools, you know, and you just pull them in and they work and you don't really have to think about them too much. It just seems to, seems to make life easy. Yeah. That's kind of the theme that my buddy Ed and I are trying to take where we're building a suite of tools called scalpels. And so there's meant to be just very narrowly targeted sharp tools.
So each one just does one thing and does it well. And we're just going to try to have a, like a suite of these ready to go for a Laracon and see if people are interested. It's not going to be like this giant revenue generator, but if we can pay our AWS bill, I think that'll be fun. Hopefully you don't get the dust. But yeah, I like those kinds of tools, just very small. Um, there's, you're not having things interacting with all sorts of other stuff. Limited complexity.
Yeah. It's a good way to do it. That's awesome. So this scalpel tool you're planning launching sort of right around Laracon or sort of before or after. We're not quite sure yet. We don't even know if we'll have enough tools finished yet, but, uh, putting you on the spot there. We got about four or five tools that we're trying to get done in time. I don't know if we'll be able to. Um, so we'll see what happens. Yeah. That's great.
Well, um, or any, any other thing, you know, maybe anything I miss, anything else you want to say before we close out this, um, this creator series spotlight. Um, yeah, go to get hub and give me a star on whiskey. It makes me feel good. And then follow me on Twitter. Um, follow me on YouTube as well. I started making a couple of videos. So if you just go to YouTube slash artisan build, that's, um, that's where I'm putting those videos out.
And yeah, just seeing those numbers go up, it gives me the warm and fuzzies. Yeah. So those are wonderful. And we'll be sure we'll have all those in the show notes as well with links to the repos, his Twitter, his YouTube and sort of everything else. Um, I think this is going to conclude this, uh, episode and we want to thank everybody for tuning in and watching. And, uh, we will see you next time. Thanks. Thanks, Len. Yeah. Cheers.
