251 RR Automating Code Reviews with Mindaugas Mozūras
02:04 - Mindaugas Mozūras Introduction
02:36 - Automating Code Reviews
03:17 - What is a code review and why do it?
03:39 - Styles of Code Reviews: What parts should be automated?
08:26 - Workflow
10:14 - Runners
11:42 - Feedback
13:21 - Use Cases for Pronto
14:28 - How has pronto changed your codebase?
15:34 - Feelings and Code Reviews; Agreeing on Standards as a Team
17:38 - Return Values
19:43 - Reviewing Pull Requests and Code Review Ethics
25:56 - Feature Flags
- Martin Fowler: Feature Toggles
- iPhreaks Episode #136: Efficient Engineering Practices for Software Projects with Neal Ford
27:21 - Managing Open Source Projects and Communities
30:37 - What’s next for pronto?
- Bitbucket Support Picks
Manic Panic Hair Dye (Jessica)Kenneth Reitz: MentalHealthError: an exception occurred. (Jessica)Frinkiac (Coraline)Erik Trautman: Why Learning to Code is So Damn Hard (Coraline)AppSumo (Chuck)AddThis (Chuck)CircleCI (Chuck)Freelance Remote Conf (Chuck)Ruby Remote Conf (Chuck)RescueTime (Mindaugas)Dan McKinley: Choose Boring Technology (Mindaugas)Brandon Sanderson (Mindaugas)
[This episode is sponsored by Hired.com. Every week on hired they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on Ruby developers providing them with salary and equity upfront. The average Ruby developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with a company or deny them without any continuing obligations. It's totally free for users. And when you're hired, they give you a $2,000 signing bonus as a thank you for using them. But if you use the Ruby Rogues link, you'll get a $4,000 instead. Finally, if you're not looking for a job but know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept the job. Go sign up at Hired.com/RubyRogues.]**[Snap is a hosted CI and continuous delivery that is simple and intuitive. Snap's deployment pipelines deliver fast feedback and can push healthy builds to multiple environments automatically or on demand. Snap integrates deeply with GitHub and has great support for different languages, data stores, and testing frameworks. Snap deploys you application to cloud services like Heroku, DigitalOcean, AWS, and many more. Try Snap for free. Sign up at SnapCI.com/RubyRogues.]****[This episode is sponsored by DigitalOcean. DigitalOcean is the provider I use to host all of my creations. All the shows are hosted there along with any other projects I come up with. Their user interface is simple and easy to use. Their support is excellent. And their VPS's are backed on solid-state drives and are fast and responsive. Check them out at DigitalOcean.com. If you use the code RubyRogues, you'll get a $10 credit.]**CHUCK: Hey everybody and welcome to episode 251 of the Ruby Rogues Podcast. This week on our panel we have Jessica Kerr. JESSICA: Good morning. CHUCK: Coraline Ada Ehmke. CORALINE: New phone, who's this? CHUCK: I'm Charles Max Wood from DevChat.tv. And this week we have a special guest and that is Mindaugas Mozūras. I think I slaughtered that properly. MINDAUGAS: Yeah, close enough. Hey, everyone. CHUCK: Do you want to introduce yourself really quickly? MINDAUGAS: Yeah. My name is Mindaugas Mozūras. And it's not a common name so don't worry about pronouncing it slightly incorrectly. As you probably already understood, I'm not from USA. I'm from Lithuania. And I work at a company called Vinted, a company that aims to make second-hand first choice worldwide. I'm also an author of the gem called Pronto which tries to automate code reviews. And that's the topic today. CHUCK: So, when you talk about automating code reviews, what exactly do you mean? Because it seems like it's mostly, when I think of code reviews it's, “Okay, hey, come look at this really quickly,” or putting in a pull request and then having somebody else check my work. MINDAUGAS: Yeah, so you can also ask a robot to check your work, right? It doesn't have to be a human. So of course, a robot can't do everything. It can only check a certain amount of things. I guess simpler things like style violations, duplication, et cetera. But it's also a sort of code review. CHUCK: Okay. CORALINE: Can we take a step back and talk about what a code review is and why you'd want to do it? MINDAUGAS: Yeah. So, code reviews and examination of a source code, trying to find mistakes, violations, and just trying to make the code better in some sort of way. And there are a lot of ways to make the code better. Do you agree or do you have something to add? CORALINE: I think that's basically it. But I think that there are different styles of code review depending on who's performing the code review. And so, I'm interested in: What sort of parts do you think should be automated? Like some people will get really picky about, “Oh, you should use an underscore in front of that variable name because it's not actually used in your method,” or other people are going to be more conceptual about the abstractions that you use, and other people are going to be like, “Hey, you don't have enough tests.” So, what are the valuable parts of the code review process that you think can be automated? MINDAUGAS: I think it's going to depend on the situation. Everything depends. For that I want to take a step back and tell a little bit about why I wrote Pronto. So, when I started working at Vinted I was like the fifth developer. And in three months the company grew from three developers to eleven. That's a really fast pace of growth. And the source code, it wasn't really clean. It had a lot of various styles within it, some parts written one way, other parts another. And now the team grew, quickly grew to 11 people and every one of those 11 people brought their own way of writing code. And we suddenly ended up in a situation where not only do we have a project that has various styles within it, new people are also bringing their own styles to that source code. And we needed to find a way to make the whole project conform to a single style. And at first I was, we tried just reviewing each other's code on the pull request, on the GitHub pull request. And there were a lot of comments like, “Oh, this variable,” like you said, “This variable should not start with an underscore.” I don't think that's a very valuable thing for us humans to review, right? CORALINE: Sure. MINDAUGAS: So, that's a very easy thing to automate. There are a lot of tools that can check these things automatically, like Rubocop. The thing is you can run Rubocop on the old project but what you want is that immediate feedback on the pull request, like a code review. And that was one of the reasons why I wrote Pronto. CORALINE: So, we do use Rubocop at my work to do style checks and things like that. What is different about Pronto? Between Pronto and Rubocop? I'm not clear on that. MINDAUGAS: Pronto integrates tools like Rubocop, Flay, Brakeman, and a dozen others. And instead of running them on the whole project, it runs them just on the latest change or on a change in a pull request, and then quickly provides feedback on the code that actually changed. So, we had a situation where if we ran Rubocop on the whole project we would get a thousand warnings. And you can't do a lot with that. So, what we wanted is just having this feedback on the single pull request, the newest change, and that way improving the code bit by bit. CHUCK: Yeah, it makes sense. The thing is I remember way back in the day there was metric_fu and so it ran Flay and Flog and all of those against your entire project and gave you a report of where your complexity was and where your test coverage fell flat and all of that stuff. But yeah, it was across the whole project so if you have 10,000 lines of code or 100,000 lines of code, it's going to run it against the whole project and you get this huge report that is really hard to make any kind of meaningful dent in. however if I make some small change to the project, something that I'm just working on that I submit to the project, then I get the feedback on my code that says, “You're not matching up with the style of the rest of the project and here are a few things for you to look at.” And since it's fresh in my mind it's something that I was just recently working on and it's hopefully a small enough commit for me to get meaningful feedback on, it's something that I can go in and at least look at and possibly make those quick changes and have those changes mean something within the context of what it just did. MINDAUGAS: Absolutely. And actually, we did try using metric_fu. And we would open this huge report with a huge list of violations and that didn't get us anywhere. You'll look at it and you'll say, “So, huh. Now what?” CHUCK: So, do you just put this in GitHub or is it part of a CI setup? How does this fit into somebody's workflow? Where do you put it? JESSICA: So, Pronto runs only on the change you've made, right? MINDAUGAS: Yes. JESSICA: That sounds super useful. We're having problems right now occasionally at my work in our Ruby code where we're running Rubocop and some new linters were added. And that makes it harder to make PRs because you're getting errors that are not related to your change. MINDAUGAS: Yes. You can run Pronto locally or you can run Pronto on a pull request. And Pronto will provide the comments on your pull request using the GitHub user you specified. And if you want to do that you obviously need to integrate it in your CI workflow. Pronto also supports GitLab. There's also a feature request for Bitbucket but no one got around to implementing that. CHUCK: Could you also put it into a Git hook? So that before you push it runs? MINDAUGAS: Yes, absolutely. I don't use it that way but no one's stopping you from doing it that way. JESSICA: So, that's neat that unlike Rubocop, for instance if I push a commit and I've got some syntax that it doesn't like, “Oh my god, the trailing white space.” CHUCK: [Laughs]**CORALINE: **Oh my god, yes. [Laughs]JESSICA: [Laughs] Then what I get back is a test failed. I have to click on that. It takes me to Jenkins. I look at the console log, look at the output of that, and then trace that back to the line of code. Whereas this automated commenting on the pull request in GitHub is going to be right there in my pull request at the line of code in question, right?**MINDAUGAS: Right. JESSICA: That's so much friendlier and easier to fix. CORALINE: That sounds pretty amazing. Yeah, definitely. Oh, I see… I'm looking at the GitHub readme right now for Pronto and I see you have runners. And there are runners for things like Brakeman and Coffeelint and Flay and lots of other things. I have a gem that does non-opinionated complexity analysis, because Flay does ABC complexity measurement but with some additional metrics around meta-programming and other things that the author thought make code more complicated. And so, I have a more vanilla ABC code measuring tool. How easy would it be for me as a developer of a metric tool to create a runner for Pronto? MINDAUGAS: It would be pretty easy. The easiest way would be to go look at an existing source code of some runner and just using it as a template. There's no more than a single file with maybe 30 or 40 lines of code. CORALINE: What does that integration tend to look like? MINDAUGAS: You get an array of batches from Pronto that's a list of changes basically. And you use those batches to figure out which files you actually need to check. And then you run Flay or Brakeman or Rubocop or your tool on those files and return the results back to Pronto. CORALINE: Okay, cool. Worth checking out, then. CHUCK: So, what does the feedback look like from Pronto? MINDAUGAS: It looks however you want it to look. It's just a warning message provided by the tool Pronto uses. So, if you're used to messages that Rubocop provides, you'll get those messages exactly like Rubocop would provide from Pronto. JESSICA: Except it shows up as being from whatever GitHub user you've configured Pronto to be? MINDAUGAS: Exactly. Yes, exactly. JESSICA: So then, I could set up a GitHub user with a funny picture. MINDAUGAS: **Yes. [Chuckles]CHUCK: Or an angry picture. JESSICA: [Chuckles] Well the important thing about that is that you're taking all of these comments that one, you're saving the code reviewers the trouble of complaining about trailing whitespace, but more important to me is that you're saving yourself feeling judgment from your team. It's just the computer that's complaining. It's not a person who's… so, it's a lot harder to take it personally when it's coming from an automated code reviewer.**MINDAUGAS: Absolutely. CORALINE: **That's not to say you shouldn't personify the automated code review thing, give it a funny name like Jerkins or something. [Laughter]MINDAUGAS: We're using a much friendlier name. We're using EVE from WALL-E. JESSICA: Aw. MINDAUGAS: [Chuckles] You can't be angry at EVE, right? [Laughter]**JESSICA: True. She's offering helpful suggestions. CORALINE: **Try me. [Laughter]**CHUCK: Coraline reserves the right to direct her anger at anyone. CORALINE: Yes. JESSICA: Or any cartoon. CHUCK: Yeah. So, I'm curious. How does your team use Pronto then? MINDAUGAS: **We have it running on every pull request. We have it integrated into our CI workflow. So, [all the] tests run and Pronto also runs with them. And then it posts comments on every pull request we have. Then the person that made the pull request fixes the violations that Pronto points out, pushes again and hopefully doesn't get any messages from Pronto then.**JESSICA: Is there a check that Pronto didn't have anything so it won't let you merge your pull request if you haven't corrected those? MINDAUGAS: Not yet. But hopefully it's coming in the next Pronto version. So, on GitHub you can have multiple statuses on a pull request. We're working that Pronto would be able to return for each runner a status to a GitHub pull request. So, if you have multiple runners configured like Brakeman, Flak, and Rubocop, you would get a status for each one of them. JESSICA: Cool. How has, since you've implemented Pronto at Vinted, how has it changed your codebase? MINDAUGAS: **For the better. So, it changed two things. One thing is yes, the codebase. It's a lot more consistent. And I believe that consistency is very important both at the code level and also at the technology level. Another thing that's changed, there's a lot less angry people. [Laughter]**CORALINE: **I'm noticing a trend. You don't want people to be angry. And I really feel offended by that. [Laughter]**CORALINE: As an angry person, I don't feel like you're respecting that. JESSICA: Okay. Well, can we be less angry at our teammates? CORALINE: **Fine. [Laughter]**MINDAUGAS: **I can relate to that. I was one of those people that would write [dirty] comments about misplaced brackets in the pull request. So, I was called angry a lot and I made a lot of other people angry. Pronto solved that.CORALINE: Jessica mentioned this earlier and I really think it's worth reiterating that when the review is coming from a tool that is objective, I think that people's feelings are a lot less likely to be hurt. I know sometimes when I'm doing code review I'm like, “Am I saying too much?” Should I just say the couple of things that are the most important and let other things slide because I don't want them to feel like I'm attacking them? Or like I'm being too critical. So, I like the idea of having a tool that is just going to tell it like it is and get the mechanical things out of the way so that in my code reviews I can focus more on things that are conceptual or how an object is modeled or overall flow or things that are beyond syntax. JESSICA: Yeah. Yeah, you mentioned first that there are fewer angry people and there are also fewer people who are perceived as being angry. MINDAUGAS: Yeah. CORALINE: So, I have to ask. How do you as a team arrive and agree on what the standards are? MINDAUGAS: So, in the world of Ruby it's quite easy. We have the Ruby style guide. And that is that. You can just take it and use. I believe there's really no good reason to come up with something on your own. There were a couple of discussions about part of the style guide but eventually we agreed to follow it, to follow the whole of it. CORALINE: Did you have to settle the question of Seattle style with parens around method arguments? MINDAUGAS: I don't remember what the Seattle style looked like. CORALINE: Method calls without parentheses if possible. That's the thing that always sticks out in my head. CHUCK: [Chuckles]**MINDAUGAS: No, we didn't. No, we didn't. CORALINE: **Good. [Chuckles]**CORALINE: **See, I am thankful for that Ruby style guide existing but even so, I found that in my company we've had to customize Rubocop quite a bit because there are things like the whitespace. It wants there to be whitespace at the end of the file, like an extra new line at the end of the file, and little things like that. But we spent a lot of time [inaudible] and customizing it. So, there's always something. One of the things that… I've been pairing over the past month or so with this great developer. He's a polyglot. He's really into functional programming and he's been [really insistent] and taught me a lot about return values. I think in Ruby we tend to use constructs where it's like, “Oh, this condition is met so I'm going to return this object. Oh, the condition is not met. I'm going to return nil.” And he's impressed on me the importance of always returning a thing of the same object type. And I'm curious as to like, could that be codified into a code style, do you think?**MINDAUGAS: I'm now trying to come up with a way to do that in Ruby. JESSICA: Well, a few episodes ago we talked about Crystal which does that. But unfortunately you can't use it as a Ruby linter. MINDAUGAS: Yeah, yeah. I don't think you can do that in Ruby. But if someone knows a way, please tell me. CORALINE: **I think that would be pretty cool. That's like one of the main things I picked up from him. It's like yeah, as a method caller I should be able to depend on the return type of this function. So, he [inaudible] that importance on me now. I guess you could look at the AST and see if there are conditions where it's going to return nil. But I guess you couldn't really predict being a real-time language. [inaudible] predict what the possible return values could be if you say, “Oh, this has a chance of returning nil.”**JESSICA: Clojure schema does that check at runtime. MINDAUGAS: How does it do that? JESSICA: **It just wraps the method in an assertion. Well, by runtime usually it's configured to only happen during tests. So, if you ever get something back of a different type or shape I should say than you specify, then it throws an exception. [Inaudible]**MINDAUGAS: Okay. JESSICA: But that wouldn't help you with your pull request. MINDAUGAS: Yeah. CORALINE: **I think that my brain has been [polluted] with types. [Laughter]**JESSICA: **Uh-oh. [Inaudible]**CORALINE: It has started. JESSICA: The conversion to functional programmer. CORALINE: **It has started. And we're using a pipeline architecture too. So, there are so many functional paradigms that are coming to [inaudible].JESSICA: Sweet. MINDAUGAS: I don't think you can do that in a stylistic check but you can do that with tests, right? JESSICA: Right. At Vinted now that you have Pronto, do you still review all the PRs? MINDAUGAS: Absolutely. We don't… nothing gets merged and deployed without getting a pull request and a code review. At least one thumbs up or ideally at least two. But what Pronto did, instead of focusing so much on the stylistic things that are already automated, we can focus on more important matters. So, architecture, code design, et cetera. CHUCK: Gotcha. So, you can go in and say, “There's probably a better way to do this,” or, “There's a method in the Ruby standard library that already does what you wrote here,” or, “I think you should probably extract a class or extract a method,” as opposed to worrying about, “Well, you have too many spaces here,” or, “You put parentheses here and not there,” or things like that. MINDAUGAS: Absolutely JESSICA: I have a question about code review ethics? Convention? Because one thing I've noticed is that different teams have different traditions around code reviews. Some teams will prioritize, “Oh, there's something to review. At my next stopping point I need to review that.” Some teams will have just one reviewer and some of them all try to review it. Sometimes as soon as you get a thumbs up you get merged. And then there's the part about sometimes people will have whole discussions about PRs. Personally, I really like it when people say, “Yes, this is good and let's talk about this other thing,” and just let me ship the thing. Because sometimes I'm very discouraged by making a PR because people will say, “Oh, but have you thought about doing it this way? Oh, but have you thought about doing it this way?” And I'm like, “Look, look. This is a bug fix. Can we just get it in and then…” CHUCK: [Laughs]JESSICA: “Talk about the stylistic things?” Have you all encountered trade-offs with styles of code review etiquette? CORALINE: I gave a talk at RubyConf Australia last year where I talked about a lot of the things that we do like the patterns that we follow that aren't necessarily effective. And one of the things I talked about was a code review bomb. And the circumstance you just spoke about Jessica reminds me of that, although it would not apply in the case of a bug. But if you are doing a feature and maybe you're working alone or maybe you're working with a pair, and you're making lots of decisions along the way in terms of how it's designed and how it interacts with other parts of the system, and you do all this work and you get to the end and maybe it's a sprint-long project, and you send it up for code review, at that point in time it is inappropriate and way too late for anyone to say, “Have you thought about doing this a different way?” even if they are right. It's just too late because you've already put all this effort into it and invested all this time into it. So, one thing I actually don't like about code reviews is when they happen only at the end of a project. I would much rather see people checking in, like doing interim check-ins and having discussions maybe during stand up or during a team huddle about like, “This is the approach I'd like to take. Does anyone have any feedback?” Because code reviews should not be the first time you see a major change to your system. JESSICA: So, code review: early and often. CORALINE: That's my argument, yeah. Because otherwise you feel like a big jerk saying, “Oh, you forgot about this thing which means you have to redo everything you just did.” And you're just not going to say it. So, you're going to accept code that's not optimal. CHUCK: That's kind of like the huge merge that people do, where they go off and they work on their feature branch for three months and then they come back and they have this major merge back into things. That's kind of what causes some of this, is the… JESSICA: But it works the other way, too. The comment on my pull request caused me to do a big merge because I did the code changes the same day and I was ready to commit it at the end of the day. But no, somebody's like, “Oh, well you should have this test. Oh, well if you're going to do this over here, why don't you do this similar thing over there as well?” which is totally an additional feature request. CHUCK: [Laughs]JESSICA: Well couldn't you just let me put my pull request in and then… but no, I have to like… and this isn't even my job. I'm just fixing a bug in your infrastructure, okay? So, let me put it in because otherwise it's going to be weeks before I get back to it and then I'm going to have that three-month merge problem. CHUCK: Yeah, but… CORALINE: I'm sensing some hostility, Jessica. Can you tell us how you really feel? CHUCK: [Laughs]**JESSICA: Do you have a problem with hostility, Coraline? CORALINE: **Maybe. [Laughter]**JESSICA: But not anger. CHUCK: **I'm going to go sit in the corner now. [Laughter]**CHUCK: **But no, what I [inaudible]…**CORALINE: **I think all of us [inaudible]**CHUCK: Is that if you're merging one day's worth of work, that's one thing. But code reviewing three months' work of worth off of a huge merge that goes back into master… JESSICA: Ugh. CHUCK: Then you have this big code review problem where, as Coraline said, you're basically seeing this huge amount of change in your project all at once that you've got to go and review instead of doing things more along the lines of single branch or what is it, master only, I forget. Anyway, but merging often as well as committing often. MINDAUGAS: Absolutely. And we had situations where we had people make pull requests with weeks of work. And now we just try to avoid that. And we practically try to tell people that this is not okay. If you're making a pull request and we see you have… we receive 30 commits, two weeks of work. That should never happen. CHUCK: Mmhmm. MINDAUGAS: And that's both a cultural thing and a tool thing. So, in terms of tools there are things like A/B testing and feature switches that enable you to release half-finished features to production and not break what your users are doing. JESSICA: **I like that phrase. I like the point about we're releasing half-finished features to production, which sounds terrifying. [Chuckles]**JESSICA: But yet a lot of places have figured out that this beats that big fat merge. MINDAUGAS: Yeah. As long as you have the right tools like feature switches and A/B testing, et cetera, it's completely fine. You merge it in, enable that feature just for yourself in production. Yeah, it's not complete but it's not breaking anything. Yeah, fine. JESSICA: Oh we have a thing with feature flags lately of there have been a couple tasks that have come up of, “Ah, what are all these flags and why are they still here and do we still need them anymore?” Can you do something with an automated checker that maybe Pronto runs to say, “Hey, this feature flag, it has been in there for a month and you ain't done nothing with it. Should it come out?” MINDAUGAS: I don't think that's a job of Pronto since Pronto checks the changes. And what you're talking about is code that's probably not, that has not been touched in a while. JESSICA: Good point. MINDAUGAS: Another thing that I remember is that Martin Fowler just recently wrote this huge thing about… or not Martin Fowler. Someone that might have been someone else. But wrote this huge thing about feature switches that's worth checking out. CHUCK: Yeah, it was Martin. At least the one that I saw. Yeah, we actually had a discussion about that on the iPhreaks show with Neal Ford who also works for ThoughtWorks. And the title of the episode is 'Efficient Engineering Practices'. But yeah, he went into that whole single-branch development and feature toggles and things like that and really made a terrific case for why you would want to do things that way and some of the issues that it helps you avoid. JESSICA: And the issues that it introduces, which… CHUCK: Yes. JESSICA: Then we could find ways to avoid those. CHUCK: Yeah. CORALINE: So, I've been doing open source for about 20 years. And I've had some projects that no one paid any attention to and some projects that got big. And I'm always interested to hear the perspective of other open source developers in terms of how you go about managing your open source project. So, you have a lot of contributors to Pronto. And I'm curious. How do you manage the community and how do you get new people interested in contributing? Or is it mainly your coworkers? How exactly is the project run? MINDAUGAS: I don't think any of my coworkers contributed directly to Pronto. I'm not remembering an instance of that right now. They did contribute a couple of runners. Well first, when you have an open source project, you can't believe that if I wrote it, they will come. You have to do some marketing. I view an open source project just like I view… I view an open source project just like, as just a project. You build a minimum viable product and then you build to try and sell it to people. I think there's a lot of value in having open source contributions and you can't achieve that without doing some additional work that's not just coding. So, the first step is marketing. And posting on various websites such as RubyFlow, Hacker News, and reddit. And then if, hopefully, contributors come, just being positive with them and treating them just like you would a coworker. CORALINE: Is there any particular outreach that you did to get new people to contribute? Or is it just like whoever showed up? MINDAUGAS: Yeah, it's just whoever showed up, whoever got interested in Pronto and found it useful. CORALINE: And how do you manage the fact that as people add features they may not be in line with what your vision of what Pronto is as it evolves? Have you run into that situation where someone wanted to make Pronto do something and you're like, “That's not really in our charter”? MINDAUGAS: So far, there wasn't a pull request that introduced a feature that I wouldn't want. There were issues that were created. And people wrote about stuff they would like Pronto to have. But at that point, it's still easy enough to say, “Yeah, sounds interesting but that's not exactly what Pronto is for.” So no, I haven't run into the situation where someone would make a pull request and I would have to reject it. But if there were a case, I guess I would be capable to make that hard decision. CORALINE: About how many hours a week do you spend on Pronto? MINDAUGAS: It varies from a couple of hours to eight hours I guess. JESSICA: Do you like check Stack Overflow and answer questions, that kind of thing? MINDAUGAS: **I don't check Stack Overflow but people were helpful enough to provide links to Stack Overflow via Twitter. [Laughter]**JESSICA: Okay. So, if we have questions on Pronto, we should tweet at you. MINDAUGAS: **Yeah, that works. [Laughs]**JESSICA: For the record, your Twitter handler is mmozuras. MINDAUGAS: **Yes, that's correct. [Laughs]**CORALINE: So, what's next for Pronto? What are you working on right now? MINDAUGAS: The next big thing is Bitbucket support. So right now, Pronto supports GitHub and GitLab. And Bitbucket is the next thing. JESSICA: So, more integration. Yeah, Pronto is really a cool integration project of on the one side, GitHub, GitLab, Bitbucket and local running. And on the other side, Rubocop and Flay and all of the linter thingies that it runs. And this project pulls all of those together and makes all of them even more useful. CHUCK: Alright, well is there anything else that we should talk about with Pronto or code reviews before we get to our picks? MINDAUGAS: I think it's worth mentioning that Pronto is not the only tool that is meant for automating code reviews. When I started writing Pronto there were none. But now there are a slew of them. And some of them are paid for, like you have to pay for them to use them, like HoundCI or PullReview. They have different features but as far as I'm aware, Pronto is the only open source gem that's meant for this. JESSICA: Sweet. CHUCK: Awesome. Alright, well let's go ahead and do some picks. Jessica, do you have some picks for us? JESSICA: **I do. I do. I have some picks today. So, my first pick is a little bit silly. But I recently dyed my bangs again. And I did them with blue and yellow-green stripes. And it was just an experiment but it turned out great. And also now little kids stare at me in the grocery store. [Laughter]JESSICA: It took me a little while to figure out why that was. CHUCK: That's great. JESSICA: But it's my obnoxious hair. So, my first pick is Manic Panic hair dye. Because it's just so fun. And it'll only last a few weeks. It's fine. CHUCK: I could dye my scalp. JESSICA: You could color on your scalp with Sharpie. CHUCK: Oh, there we go. That would only last a few weeks, too. JESSICA: Yeah, exactly. And you can have, yeah, mini-tattoos for a short period of time. It's awesome. And if you don't like it, put on a hat CHUCK: [Chuckles] My girls would have a field day with that. Anyway.**JESSICA: Alright, so my other pick is rather serious. There's a post I came across my Twitter feed this week. It's about mental health. It's by Kenneth Reitz so it's on KennethReitz.org. And it's about a mental breakdown that he had and it describes in great detail the delusions that he experienced after not sleeping for entirely too long. And the Amazon Dynamo paper comes up and has prominence. It's a really meaningful post about what can happen when your brain just gets a little bit off and how that can spiral. I highly recommend this. It's called 'Mental Health Error: an exception occurred'. That's my serious pick. CHUCK: Alright. Coraline, what are your picks? CORALINE: **Okay. I also have one silly pick and one serious pick. My silly pick is a site called Frinkiac. A friend of mine was involved in putting this together. It is a search engine for Simpsons memes. It contains nearly three million screen captures with subtitles you can search for your favorite snippet of dialogue, see the scene in which it takes place, select the exact frame that you want, and edit the text to whatever you want. It was created by Paul Kehrer, Sean Schulte, and my friend Allie Young. And it's pretty fun. And I was able to find my favorite Simpsons quote which was 'In this house, we obey the laws of thermodynamics'. So, that was pretty cool. [Laughter]**CHUCK: Nice. CORALINE: My more serious pick is an article by Erik Trautman. So, I found it in an IRC channel called new2ruby. It's ##new2ruby on freenode. And I was talking to someone in there about their frustration around learning Ruby and how the resources tend to dry up when you get to a certain phase in your learning process. And they reference this article and talked about one particular phase that the article discusses. So, the article is called 'Why Learning to Code is So Damn Hard'. It's written by Erik Trautman. The article is written for people who are just beginning to code but it provides a useful perspective to people who teach and mentor I think as well. It breaks the journey toward job readiness into four phases: the hand-holding honeymoon, the cliff of confusion, the desert of despair, and the upswing of awesome. And it talks about the wealth or dearth of resources that are available at each of these phases and gives you guidance on how to successfully work your way through it by setting goals and setting reasonable expectations. So, basically it acknowledges the hard truth that getting started learning to code is really, really easy. But getting yourself to the point where you're job ready is really, really hard. So, that's my pick. CHUCK: Alright. I'll jump in with a couple of picks here. The first pick that I have, I'm just going to put out there regardless of whether or not it's been picked last week. I've been using a system called AppSumo on DevChat.tv. And I'm really liking it. It allows me to see the analytics just right there on the page. I don't actually have to go to Google Analytics. It also does all of the email forms and stuff like that, that you see on there. So for example, if you go to RubyRogues.com and you haven't seen it before, you'll see a form come up first that allows you to get the top 10 episodes of Ruby Rogues in your inbox, which is something that a lot of people have asked me for and I just wanted to make sure they saw it. After that it shouldn't show up for a while. But anyway, so things like that, it makes it really easy for me to make a lot of things available to you. And I'm super happy with it. It also allows me to put up links to for example follow Ruby Rogues on Facebook or Twitter or share the episodes and things like that. So, really happy with that. Another pick that I have that I'm also using on there is AddThis. Now, AppSumo actually has the sharing links on there. And I'm thinking of switching it over but I've been really happy with AddThis. So, if you're looking for sharing links and follow links on your website, then go ahead and put those up. And finally, I'm going to pick CircleCI. It's interesting. I hooked that up to Slack and it's nice because I get notifications now whenever something gets pushed to one of my projects and tests fail or tests pass and I can kind of see where things are at. And I'm really liking that. Trello also incidentally has an integration for Slack. So, whenever somebody finishes a ticket that I need to go review or anything else, I can go and actually look at those and get the work done. So, I'm really happy about that. Finally my last pick, sorry I'm picking a lot of stuff. Last week was Freelance Remote Conf which is one of the remote conferences I'm putting on, and it was awesome. It was dead on, if you're looking at going freelance, the talks were all excellent about pricing and how to find clients and different options you have for different kinds of work and all kinds of things. So, if you are freelance or looking to go freelance, I highly, highly recommend the content from that conference. It was excellent. If you go buy a ticket, it'll just give you access to those recordings. I'm also doing Ruby Remote Conf here in a couple of weeks so definitely check that out as well. RubyRemoteConf.com. Mindaugas, that's how you say it. Something like that. MINDAUGAS: Yeah. [Laughter]CHUCK: What are your picks? MINDAUGAS: Close enough. So, I have one serious pick and one not so serious pick. So, for my serious pick I wanted to pick RescueTime but Avdi already picked it in the show I listened to today about Crystal I think. CHUCK: Yeah. MINDAUGAS: I've been using that for a couple of months and it's been really useful for me. It helped me phase a couple of things I spent too much time on. So instead, for my serious pick I'll choose an article by Dan McKinley. It's called 'Choose Boring Technology'. These days, we talk a lot about how we should choose the right tool for the job. Or sometimes we choose the bright and shiny tool. But what Dan argues for is that choosing the boring tool is much better. So for example, Memcached is boring. But boring is not bad. Memcached works. Huge companies like Facebook already use it. And then there are failure scenarios. Facebook probably already found them out and they are known and understood. And for my other pick, I'll choose Brandon Sanderson. So, Charles already picked a couple of his books before. But I just want to pick all of his books. CHUCK: [Laughs]MINDAUGAS: So, I've been reading his 'Mistborn' series lately. And the previous year, I completed two books of his 'Stormlight Archive' series. And before that I read some other books of his. And they're all amazing. So, just pick any of his books and go read it. He's a great fantasy author. CHUCK: Yeah, I really enjoy his books. Also incidentally, he lives in Provo which is like 20 minutes from here. So anyway, awesome. Well, if people want to contribute to Pronto or find out more about what's going on, I know we've asked these questions before, but kind of give us the spiel on how to get involved and how to get a hold of you if we want to connect with you. MINDAUGAS: The easiest way to connect with me is just tweet at me at 'Twitter.com slash M-M-O-Z-U-R-A-S'. If you want to contribute to Pronto, just go to GitHub, read contributing files in the project directory, and create an issue or make a pull request. Right now there's always not enough of documentation for open source projects. So, if you don't have the time to contribute a code change, contributing some documentation is great, too. CHUCK: Alright. Well, we'll go ahead and wrap up the show. Thank you all for coming and we'll catch you all next week. [Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.]**[Bandwidth for this segment is provided by CacheFly, the world's fastest CDN. Deliver your content fast with CacheFly. Visit C-A-C-H-E-F-L-Y dot com to learn more.]**[Would you like to join a conversation with the Rogues and their guests? Want to support the show? We have a forum that allows you to join the conversation and support the show at the same time. You can sign up at RubyRogues.com/Parley.]**