- Avdi Grimm (twitter github blog book)
- David Brady (blog twitter github ADDcasts)
- James Edward Gray (blog twitter github)
- Josh Susser (twitter github blog)
- semver.org – Semantic Versioning
- Version 1.0.0
- Release Process
- Alphas, Betas and Release Candidates
- Versioning an API
- RFC 2616
- Managing versioning separate components developed in concert
- GIT tags, version numbers, path tags
- 3.0 is the new 1.0
- NOCOMMIT (David)
- Book Yourself Solid by Michael Port(David)
- faraday.gem (Avdi)
- gem Maintainers (Avdi)
- Lasik Surgery (James)
- Rubies in the Rough (James)
- codeclimate.com (Josh)
- The Invisibles by Grant Morrison (Josh)
- Red Dwarf (Josh)
JAMES: Okay. So, whatever we say, we’ll invite Steve to come back and yell at us again for getting…
DAVID: Let’s just bait him in the show, without actually saying we’re baiting him. Let’s just bait him through the whole show.
JAMES: Hello everybody and welcome to the Ruby Rogues podcast. I’ll be your host today, I’m James Edward Gray II. Chuck can’t be with us today, he had to take his kids to school which just proves his priorities are all screwed up.
DAVID: I wonder if that’s a metaphor.
JAMES: Oh, it’s a metaphor? Wasn’t it euphemism?
DAVID: Euphemism, yeah.
JAMES: Oh, sorry. With us today, as you can tell because he’s already interrupting me, is David Brady.
DAVID: Hi, I’m David Brady and I interrupt people.
JAMES: Also, Josh Susser.
DAVID: Hi, I’m David Brady and I interrupt people.
JOSH: Oh, it’s going to be that kind of episode. Hey guys, it’s Josh. Good morning.
JAMES: And Avdi Grimm.
AVDI: Hello again.
DAVID: He was waiting for me. That was awesome!
JAMES: He was afraid. David put the fear in him.
JOSH: He wasn’t waiting for the collision to back off and retry it.
JAMES: Right. This is episode 37.0.1 release candidate three today where we will be discussing versioning and release process and things like that. This topic was Josh Susser’s. So, I’m going to let him tell us where we’re going with it.
JOSH: Okay. So, versioning and release process, obviously two intimately related topics. I asked yesterday on Twitter for some particular questions people had around these topics. So, we’re going to be trying to address those things as we go. I think we can get to most of those. So, versioning is all about the numbers that you put on your package, you know, your library or your gem or your application or your API. They get used for a couple of different purposes.
And then, release process is, at some level, it’s the moment at which you’re changing the numbers on your version, but the process around that and how to make the two fit together as painlessly as possible for your consumers. How does that sound, James?
JAMES: Sounded awesome to me.
JOSH: I’m all defined out today.
JAMES: Josh, my main question is what made you want to talk about this?
JOSH: Oh, what made me want to talk about this? My ongoing theory around the Rails project and the lack of a coherent release process, how about that?
DAVID: Josh, you promised us a good rant.
JOSH: We’ll get there. I’ll get there.
DAVID: Okay, we’ll do it in version two.
JOSH: Yeah, right.
AVDI: Well, Josh, just to help you along, hasn’t HTML5 proven that release processes and versioning don’t matter anymore.
JAMES: Wait, what?
JOSH: What are you talking about?
AVDI: HTML5 is officially now an ongoing rolling, sort of, troll? A mystery standard that, they officially stopped working towards a un-HTML5 definition and it is now defined as, whatever we put in the standard last week. Forever, for all eternity, not like they’re going to put a fork in it and it’s done at some time. It’s just an ongoing standard that keeps getting added to.
DAVID: Wait, so they managed to skip the QA and the ratification process. What did they go, Agile?
AVDI: Essentially, how come I’m the only one who knows about this?
DAVID: It’s continuous standardization. It’s like continuous deployment for standardization.
DAVID: This is brilliant! I wholeheartedly endorse this idea and I realize that that’s cascading indictment.
JOSH: You know, I’m not a parent, I’ll never have children but I think this is sort of like redefining the rules so that when you’re on a road trip, whenever your children ask, “Are we there yet?” You say, “Yes.”
DAVID: How does that fit in? Because the other thing kids say is, “I have to pee.” How does that fit in? Well, it’s the same thing, right?
JOSH: Go right ahead.
AVDI: Yeah, go right ahead.
DAVID: I have a funny story about that that I’m not going to tell.
I go to GitHub.com and I don’t care what version the website is. I don’t have any software that’s interacting with the UI or what have you. You don’t need versions for that. People don’t interact with versions of software that way. I can fire up a version of Safari 4 versus Safari 5 and as a user I’ll see differences in how the application operates. But that’s not really what we’re talking about when we talk about versioning and releases.
DAVID: Can I do a micro rant about versioning?
JOSH: Oh, please do.
DAVID: This is relevant to Ruby. If you’re releasing a gem, there’s a couple of different ways that you can version your product. One way is that you can go into your gem spec and you can say, “This is version 1.2.3, yada…yada…yada.” The other way that’s really, really common is to have like an ERB file that gets compiled into your gem spec by a Rake task and whatnot. And you have a VERSION.YAML file somewhere in your project that gets included. You’ve got Rake tasks to increment and decrement whatever your version and all this other stuff. Here is my rant. If I come to your GitHub page and I’m looking at your source code and I can see gemspec.erb, I know that I’m not going to be able to find the version number inside that file.
Please, please, please, for the mother of all that is holy, put your VERSION.YAML file in the root of your project, or let’s make a rolling standard about where it should go. It makes me absolutely bat poop crazy when the VERSION.YAML file, and I’ve seen this, is three directories deep in the file tree, there’s no freaking way to find out what version this is. I just checked out of GitHub, without actually cloning the project and building the gem and seeing what version comes out. Don’t do that!
JAMES: Is it Bundler that actually, when you make a new gem, it goes ahead and makes the constant, and then the version file under that header with the conflict?
DAVID: Really? Bundler will do that?
JOSH: Yeah, it’s a VERSION.RB file and it goes under the top level name space directory.
JAMES: So, if you make a project called, all I can think of is Nick’s example from last time, RoflCopter, then it will make the RoflCopter module that should contain everything. And then, under that, it will put a VERSION.RB file which just sets a constant.
DAVID: That’s awesome.
AVDI: I think that VERSION.RB is a little less silly than a YAML file too.
JAMES: Yeah, me too.
DAVID: I’m okay with either. As long as there’s a file that I can see on your GitHub project home page or one directory down like in lib or whatever it’s supposed to be, that’s named version and I can click on it from the GitHub website, I’m happy.
JOSH: Okay. So, we’re at the point where David’s happy. Let’s end the micro rant and talk about what versioning actually is. [Chuckles]
JAMES: Okay. But just to be clear, Bundler fails David’s test because it would be three directories down lib, or two directories down lib, then RoflCopter.
DAVID: Are you serious?
JOSH: Yeah, but he knows how to find it now.
JAMES: Yeah, that’s the good part is that it’s in the standard place.
DAVID: I’m kind of out of my happy place.
JAMES: Ouch! This is the part where Dave hangs up on all of us.
DAVID: I’m normally in the tank for both RVM and Bundler, and I’m in the tank for using both at the same time which makes a lot of people like James crazy – well, crazier. And yeah, that’s all there is to say about that. I need to end my rant.
Josh, you were about to give us a definition of versioning.
JOSH: I’m going to link up semver.org. So, Tom Preston-Werner wrote up this nice description of what he titled Semantic Versioning and this is now up to version 2.0.0-RC.1.
DAVID: Which is great.
JOSH: It’s a little meta. So, the approach in what Tom writes up as Semantic Versioning is not new. Tom, I think, has done a good job at documenting this but this is very similar to what was talked about in the Java publications in the ‘90’s. When you see one of these number dot number dot number versions, then the positions in that string of digits mean different kinds of things. So, the first number is the major version, the second is the minor, the third is the patch and then after that is the pre-release information. And since they’re numbers, you can order them.
So, two is greater than one. Version two follows version one, great. So, the numbers, the important thing about having version numbers that follow this standard is that you can tell which version of the software, your client software, is going to be compatible with. So, the major version is where big discontinuities and breaking off backward compatibility falls. The minor version is where you’re changing the API and adding features. And the patch version is where you’re not disturbing compatibility at all, and you’re just fixing bugs. So, you’re not adding any new features, you’re not changing the external API.
DAVID: I want to pin you down here, Josh. The minor version, the middle number, if you increment that, clients that have been using a lower middle number should still work, correct?
DAVID: You are adding. You are not breaking backwards compatibility.
JOSH: Yeah. And if your old clients, if the clients are using the 2.0.0 version, try and use the 2.1.0 version, they should still work. That’s a contract.
DAVID: Right. So, what good is the micro version then?
JOSH: The patch version?
DAVID: Yeah. It’s micro in the old Microsoft and Java books, yes.
JOSH: Well, that would be something like if you have a bug in your library and people have to do things to work around it, like, “Oh, great. I can’t put capital letters in that string that I submitted.” Then you have to put a work around in your client code that makes everything down case before you call the API. So, if they have a patch release that fixes that bug, then, “Oh, great. I have client code. It doesn’t need to be doing the down case before I call the API.” So, that lets you know, do you have to keep doing your workarounds or can you move forward?
AVDI: Specifically, patch versions do not add any new functionality.
JOSH: Thank you.
JAMES: Which is what Josh was trying to say.
JOSH: Right. And this also bleeds over into the release process because the things that come after patch and in Semver, Tom is using dashes and I kind of hate that. [Chuckles]
DAVID: And plusses.
JOSH: Yeah, dashes and plusses, I don’t think those things should be used in version numbers. They don’t add anything semantically and it makes processing the version numbers in software a little bit harder.
DAVID: This means that Ruby does not follow this.
JOSH: Yeah. Well, this is a release candidate. So, I guess this is the time to respond to this draft.
JAMES: There’s a lot of things I want to say there. What do you like to use instead of dashes, Josh? Just dots?
JOSH: Yeah, just dots. Why do you need more than one delimiter?
JAMES: Gotcha. So then, you would just split on the dot and work with that basically?
AVDI: I think one argument for it is anything, the dot delimiters are for versions which are compared numerically.
JOSH: Yeah, they’re sortable.
AVDI: Well, I think they are all supposed to be sortable but I think the dash or plus might be splitting off the part which may be a string, which you see this in Debian software versions where you have the Debian version. And then, if you have some slight patches on the Ubuntu version of a package, you’ll see, I think it’s like –Ubuntu1, Ubuntu2, Ubuntu3, if you have the downstream patch versions.
JAMES: Okay. So, David asked, does Ruby follow this?
DAVID: Actually I want to add, before we jump to that, I want to be gratuitously clever because I never get the chance to do this. The reason why Semantic Versioning has dashes and plusses in it is because the data contained after the dashes and plus has a different semantic meaning. Ha! And I used the word semantic right there in the definition.
JOSH: We’re so proud of you.
DAVID: Yeah, thank you. However, the argument, like in the case of Ruby and this will seg nicely into James, could be made that instead of Ruby 18.104.22.168-P290, really could be 22.214.171.1240.
JAMES: True. Agreed. Also, I just wanted to point out earlier, we were kind of talking about the names of the different parts of the version. I think, usually, what did you call them? You called it major, minor, and patch? Is that what you did, Josh?
JOSH: Well, that’s what Semver calls it.
JAMES: Semver, gotcha.
JOSH: Major, minor, micro is also fairly standard in some circles.
JAMES: I was going to say Perl, I think, usually calls them major, minor, and teeny.
DAVID: Oh, that’s awesome.
JOSH: I’ve seen tiny.
DAVID: But the only danger with major, minor, and micro is that there’s also, if you’re pulling this from the old Microsoft days, there’s occasionally a fourth number and that is either the build number or the patch number. And so, there, you get a naming conflict with Semver. So, I’m going to drink the Kool-Aid. I’m going to get on the bandwagon. I’m going to stop saying micro. I’m going to say ‘patch’ to refer to the third number, and build and whatever stream of consciousness annotation the thing is.
JOSH: In looking at the Semver update, which I haven’t looked at in a long time, so the plus and minus stuff was new to me. I think the plus and minus does have some utility because it gets you out of the numeric without having to fully specify all the digits. So, if you had just version 2.0 with a build, then you wouldn’t need to say 2.0.0 in the build. I guess that’s okay. However, I know that the Ruby Gems version system does not support the plus and the dash as distinct from dot separators. So, if Ruby is going to be compliant with this, we’re going to have to go fix that. While I’m mentioning that, I’ll just cop to the fact that I’m kind of responsible for the fact that there are non-numeric ways of versioning Ruby gems. [Chuckles]
This was a rant response where I got really tired of the Rails team releasing like version 2.0 of Rails was released, with the release candidate being the numbered 1.9.99, which just drove me freaking insane. [Chuckles] It made using Ruby Gems very hard because, okay, what’s compatible? How do I…?
Anyway, there’s a huge discontinuity between 1.9 and 2.0 in the semantic versioning system. So, you can’t really deal with the pre-release stuff that way. So, the logical way to do that is to create a way to express that you have a pre-release version in the actual version, and that’s what Ruby Gems supports now.
So, when you do gem install roflcopter –pre, that means it will go find a version of the library that includes the alpha forms of the version number. And it assumes that anything that’s just 2.0.1 is a release version, not a pre-release version.
DAVID: So, I just want to point out that there is actually a SEMVER.GEM. Because I’m looking at this and I’m thinking, “Somebody needs to write the <=> for this so that I don’t have to figure out how to sort two version numbers.” And then I thought, “I bet there’s a gem that does this.” And Semver does that. It also gives you the tools to manipulate major, minor, patch, et cetera.
JOSH: So, the version class that’s built into the Ruby Gems package also has a <=>.
DAVID: Okay. Does it support the patching thing like you said?
JOSH: Well, it supports pre-release. It doesn’t support the plus and minus, as far as I know.
JOSH: But you can just do Rubygems::version new and then compare them using the <=>.
JAMES: So, that’s kind of a good point, we’re talking about comparing version numbers. The Ruby Core Team has kind of some different ideas about versioning and some of those are not well understood. So, I will try to explain it from their point of view as best I can.
First of all, they believe that it’s number dot number dot number and that none of those numbers should ever exceed 9 because then, you can’t sort them as strings.
DAVID: You can’t sort them ASCIIbetically, yeah. You can’t sort Semver ASCIIbetically either though, because the patches will come after.
JAMES: That’s true. I didn’t say it was right or wrong. I just said that that’s the way it is. I am sympathetic to it. I wish that we could sort them as strings. Or maybe another solution would be to include something with Ruby that can correctly parse version strings so that we can compare them, which I guess we’re kind of there now since Josh said, Ruby Gems can do the comparison and Ruby Gems now ships with Ruby. So, I guess, we’ve kind of reached that point.
My complaint was that if we had versions that didn’t sort as strings and then Ruby doesn’t include anything to deal with versions. That kind of sucks, right? So basically, what we’re saying is build your own every time and yeah, that’s going to work well.
JOSH: No, you don’t want that.
JAMES: Yeah. Anyway, that is one of the points and that’s one of the reasons for kind of the whole Ruby 1.9 issue and stuff like that. One of the other things that Ruby takes kind of an unusual approach to in versioning recently, is it used to be that the odd versions were used as…
JAMES: Yeah, experimental branches.
DAVID: Oh, you see, this is the thing that kills me. Parody error, parody error. Even numbers are test and good luck to you, and the odd numbers are the one’s that work. And see Josh, now, you’re out of parody.
JOSH: Yeah, okay. [Chuckles]
JAMES: The issue though that they didn’t like about that because they believed no version could be above nine, they were losing half of their versions to that and they didn’t like that. So, they’ve adopted a new rule that they use, which is that the patch level zero is the experimental version, and then above that. So, that’s why you had Ruby 1.9.0 was the experimental version of Ruby 1.9. And the first release to the public was Ruby 1.9.1.
JOSH: I don’t think there’s anything horribly wrong with that. But doesn’t Python do the same thing?
JAMES: I don’t know. That’s a good question.
DAVID: I thought it was almost a ubiquitous standard in Linux.
JAMES: The Linux standard is using the odd numbers for the experimentation.
DAVID: I thought it was the other way around but okay, which explains so much about my software.
JOSH: And I was right just about the wrong thing.
JOSH: Okay. We have a lot to cover. So, let’s keep moving forward here.
DAVID: The binary clock is right half of the day.
JOSH: Thanks. Okay. So, release process, the reason why we want to have these alpha numeric numbers is that — can I say alpha numeric number? Alpha numeric version identifiers, is to enable us to tag specific releases with some extra semantic information about where they are in the release process. So, released code should always, like the fully released code should just be numbers. There shouldn’t be any alpha numerics in there except I guess in the case of Ruby where you put a ‘P’ on the patch release, which frankly, I don’t agree with that commention but it’s understood enough that it’s not a problem for people. And you don’t install Ruby using Ruby gems, so that’s not a problem.
In the release process, there are certain stages that you go through. And what we’re going to talk about here today, I wouldn’t call it authoritative. It’s just our experience of things.
DAVID: Let’s call it partisan.
DAVID: Let’s take a side and people can disagree with us, there’s five of us, we can probably take them.
JOSH: Occupy releases.
JOSH: In the development process, there’s when you’re writing code and you’re developing it internally and you’re not releasing them. So, you do not need a release number on it or a version number. Then there’s when you want to start putting it out there and having it interact with other pieces of software and get installed by your automated software that installs things for you. Dave, is there a good name for that? Avdi? James?
JAMES: An automated software that installs things for you?
JOSH: [Chuckles] Yeah.
DAVID: There ought to be.
JOSH: Your package system.
DAVID: Why does every conversation with you end up being about my package? Or do I make it that way?
JOSH: It’s you, Dave.
DAVID: It’s me. Okay, alright.
JOSH: [Chuckles] Okay. So, there’s a couple of stages we can talk about. Probably the most important one is the release candidate. But leading up to the release candidate, you have things like your development builds and there’s a couple of ways that you can do this. There’s development builds and oftentimes, if you’re in a big enterprise development organization, those might be the things that development tags and then you throw over the wall to QA for them to test. And then at some point, you get a good test off of that. Or if you’re using a CI system, you can do this in an automated fashion. I worked in a place where every build that CI went through that was green, got a tag and got a version number because it went through CI.
Then that became a build artifact that you could go and do acceptance with and do acceptance testing. The interesting thing is that you can have a build artifact like that which is exactly the same bits throughout the whole process, that you can promote its version number from one category to another. So, “Okay this is a development build. We’re promoting this to a testing build. We’re promoting this to something that we’re going to push out to staging.” And at different times in the process, you might have the same build artifact and promote its version number. That’s one way of doing it.
DAVID: Prior to everybody sane switching to git, I’d say some version had revision numbers but prior to, I’ve used systems like — oh, God help me. Like, VSS, Visual Source Safe which didn’t really expose any kind of commit number index. And so, build numbers were critical because there was no way for QA to communicate back to you which version was broken. I’m a lot less dictatorial about, “Thou shall tag and release every freaking thing that comes out of the developers,” now that we can just refer to it by a SHA hash or by a revision number.
JOSH: Yeah, it definitely makes things easier. James, Avdi, have you worked in systems where they do the promoting build numbers to versions and release numbers?
JAMES: Not anything that specific, no.
DAVID: I actually — I’m sorry, I’ll give Avdi a chance. I have a funny story though, it’s short.
AVDI: I don’t know off the top of my head, build numbers to version numbers.
JOSH: It seems like something that only happens in bigger organizations where you have a lot of people who have to get their hands on the same build to validate it for release.
AVDI: Actually, that’s not completely true. It’s just sort of in the dim recesses of my memory. I’ve definitely actually cut some build number, blah…blah…blah…CD’s that were officially, this is the CD that we deliver to the client and stuff like that. And there’s all kinds of weird stuff that goes on in the really big organizations because of like old revisioning standards that pre-date modern revision systems. Like in order to cut a release, we must print out all the source code and then photocopy it and then put it in a box.
JAMES: That’s awesome.
JAMES: I’m adopting that.
DAVID: There’s a daily WTF in which the client was a small Eastern European Government. And part of the spec required that they have not less than one meter of documentation.
DAVID: And so, they printed out the code in like a 24pt font and stacked it for him.
AVDI: Well, for some government contracts, you have to have, or at least, you used to have to have figures. Like for every deliverable, there would be a figure which would depict it, like depicting the deliverable which makes sense for a lot of the hardware. If you’ve got like radar dipole, you have a figure that reflects the dipole. But what do you depict for software? What you do is you have figures which depict a three and a half inch floppy disc.
JOSH: I remember drawing some figures for patent applications that was basically two [no audio] with a line between them.
DAVID: Nice, were you patenting the shortest distance?
JOSH: There was an interface involved.
DAVID: There was an interface, okay.
DAVID: This actually touches on my funny story about versioning which is that once people get involved, it all goes political. I worked at, it wasn’t a government contractor but it was fabrication software so it was kind of big business, a lot of money going around, a lot of semiconductors going around the fab and that kind of thing. And we had contracted out to a third party company in Austria to build them a robot controller to move these waivers around their fab and we were experimenting. They had an experimental thing that they were writing and we had an experimental thing that we were writing. It became critical for us to be able to get bugs back from the Austria team and go, “Okay, which exact build were you using?”
So, I started putting the build number on the splash screen. So, it said 126.96.36.19919 or whatever. And that got flunked by our senior management because they did not want the customer to know that it had taken us 4219 attempts to build the software. And I’m like, “What are you talking about? Every time I hit F12, it makes a new build of this thing. I’m doing this a hundred times a day.” And they’re like, “Yeah, stop doing that.” And I’m like, “Okay, you know what? I need the build number. I’ll tell you what, what if it’s a random number?” And so, I actually built a database of random release numbers and heaven help us.
JOSH: You could have just used the git SHA.
DAVID: This was like in 2004, but yeah.
JOSH: You could have just invented git and then used the git SHA.
JAMES: That’s right. Yeah, why didn’t you do that?
DAVID: I actually kind of did because what I ended up doing was taking the last 16 digits of the MD5 checksum of all the source code. And heaven help us.
JAMES: I have a couple of questions. Here’s one we’ll go around the horn on, is there anything special about version 1.0.0?
JOSH: And related to that, why is Rake not a version 1.0 yet?
JAMES: Yeah, how many years do you need?
AVDI: I think Jim has actually been making some noises about putting out a 1.0.
DAVID: Rake, you’ve been out forever!
JOSH: How many years does software have to be used by thousands of people as one of the core pieces of the infrastructure of the language before you’re willing to state that it’s 1.0?
DAVID: I think Jim should just start answering the question, “Why isn’t Rake 1.0?” And he’s like, “People are still using it?”
AVDI: So, implicit in that question is the assumption that there is something special about 1.0. So, what is special about 1.0?
JOSH: So, 1.0 is where in the semantic versioning process, you sort of tighten up the screws on backward compatibility requirements.
JAMES: What we’re saying is, if you’re in version 0.6.4, you can still decide, “Oh, I’m going about this all wrong.” Totally screw everything up and call that 0.7.0 or something.
JOSH: Yeah, I think that’s true. I don’t know what the Semver spec here say about major zero. Oh, it says, “How do I know when to release 1.0.0?” And it says, “If you have a stable API on which users depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should already be 1.0.0.” So, if you’re not making any guarantees about 1.0 or about backward compatibility, then you should be 0. something.
AVDI: Yeah. I don’t think people should be afraid of version one. I mean, I’ve had a few gems that I’ve released at 1.0 because they were in use in production at that point. They had been extracted out of a project and then used in that project and they were in use in production. I considered the API might not have been optimal or it might not have been the API I imagined it one day having, but it’s stable. And so, when I released the gem, I released it as 1.0. I’ve got other gems that are very definitely zero versions because I’m rapidly iterating on them.
JOSH: Yeah. Okay. So, I want to finish the stuff about the non-crazy enterprise way of doing the release process because it’s important and I have a whole rant behind it. [Chuckles]
JAMES: Go for it.
JOSH: The whole thing I talked about with promoting build members of build artifacts, et cetera, set that aside for a moment and let’s just talk about how we deal with things in the Ruby world. Rails is a great thing to look at because they get a lot of it right and they also get a lot of it wrong. And so, when you’re releasing a framework or a library and you want to try it out working with other pieces of software, that’s a great time to do an alpha release number. And alpha just basically says, “I want to put a number on this so I can start testing the interaction with either people or other pieces of software.”
And you’re not nailing down much of anything when you say alpha except you probably want it to be very close to feature complete because what’s the point of starting to test something if you’re going to keep changing it a lot? And then, as you broaden the circle to include the general public, that’s when you want to make it beta. So, you very rarely see anything with an alpha release on the net because alpha is meant to be a small circle of people and it’s easier to manage.
Then you do a beta release that can either be a private beta or a public beta depending on how many people you want involved in reviewing your beta quality software. But generally, it’s a much bigger circle than alpha. And beta, you probably want that to be feature complete because you want your API to be stable, you want your UI to be stable so that you don’t have a moving target for people to evaluate and to test.
And then, once you feel good enough about — definitely at the end of the beta process, you want to be feature complete, you want your API not to be changing anymore. You don’t want to only be changing what the parameters or arguments are to API calls or changing what goes on in the UI.
And at that point, you call it a release candidate. Release candidate means this is our best guess at what we’re going to be shipping. Have at it, find critical bugs. If we find critical bugs, by definition that means we have to fix them and then at that point, we’ll roll out a new release candidate and start that clock going again. And if we find bugs that we don’t think are critical, we’ll just hang onto them for the next release.
So, in terms of Rails, they get some of that right. And one of the things they’ve been doing in recent releases that I like is that when they come out with a release candidate and they realize, “Oh, there’s something we’ve changed.” They reset the clock. It’s like a two-week clock and they reset that, then they get more feedback. And if they come up with anything critical in that time, they reset it again. Otherwise, they’ll release it at the end of that two-week baking period.
The thing they get wrong, and this is really huge is that when the Rails Core Team releases a release candidate, that’s effectively a beta release for them because they are not saying, “Here’s our best guess at what we’re releasing.” They are saying, “Oh, we’re getting close to wanting to release a new version of Rails. Start giving us public feedback on what we’re doing and we will happily change the API willy-nilly during the release candidate process.”
And I have no end of ranting about that. [Chuckles]
DAVID: Which is a good thing to do but it’s the wrong name for it, is what you’re saying.
JOSH: Yeah, absolutely. That should be a beta release. By definition, that is the beta release of the new version of Rails.
JAMES: Just to make sure we get that right in the hate mail, Josh thinks you guys are wrong, Rails Core.
JOSH: Oh, yeah. I’m sorry. At least, they’re doing a better job now than they were a couple of years ago. It was like a Wild West shootout as things changed during the release process. And a lot of people on the Rails Core Team are getting this right and they have the right attitude and I’m just not sure why it’s not baked into the process.
I get that it’s a political thing, as David said. As soon as you get people involved in anything, it becomes politics. And some of it is just trying to get people who are using Rails to pay enough attention to a release to give them feedback. And it may be that everyone on the Rails Core Team understands what I just talked about and would prefer to do things that way. And they are just grappling with the reality of trying to get thousands of people with Rails applications to pay enough attention to a release candidate to test their software with it. So, I’m not pointing fingers at any particular person that they’re incompetent or don’t know what’s going on. It just drives me a little crazy that the release process is getting abused this way and that it’s educating a lot of web developers in poor practices.
JOSH: So, that’s the end of my rant about that.
JAMES: That’s it, you’re all wrong. I’m sure we’ll get some great Email about that.
JOSH: I’m looking forward to it. I’m up for a fight this week.
JAMES: Alright. All those Emails can be directed to Josh, by the way.
JOSH: Yeah, thank you. What’s your Email address, James?
JAMES: Right, yeah.
JAMES: So, I did want to hit a couple other questions that we were asked over Twitter. Some of them I really liked, at the risk of calling down the raft of Steve Klabnik. One of the questions that we were asked is, what is the proper way to version an API? And so, I’ve been desperately looking it up because I remember that Steve Klabnik said that you never ever, ever, ever do it in a URL which is what we always see with the V1, V2, in the URL. And I was looking up what the correct place to put it and I think I found it. I knew it was in one of the headers but I couldn’t remember which one. I believe it’s the Accept Header where it’s supposed to go.
AVDI: Yeah, it’s all about the content type. It’s really no different than the way the web has always worked. Because browsers, whenever they request something, they say, “Here are some content types that I support. And here’s the order that I support them in. I like this one better than that one. Maybe I like XHTML better than HTML, maybe I like…” and stuff like that. And that’s what content negotiation is all about. The server looks at that and says, “Okay, this client supports this level of stuff, or at least wants this level of stuff. So, I’m going to give it this resource which complies with what it was written to understand, it was written to expect.”
And if you’re really doing rest which means you’re not constructing URLs, you’re following links in your client, then that will work because you ask for the root node or whatever of the API and it serves you a document based on what your client says it supports and that has appropriate links in it and all the other resources or transitions that you want to do, you do by following links from that. Where it breaks down is where you start wanting to construct URLs on the client side and then the server doesn’t really have any options because it can’t tell you how to, it can’t decide, “The location of this resource has changed but, you know, I’ll just update the links in what I send out.”
DAVID: So, that’s kind of the core of my ‘are you freaking kidding me here’ which is that how do I type the header? When I open a browser, how do I type the version number into the URL if I can’t type the version number? And of course, the glib answer is, “Well, this is for machine consumable stuff.” And bull crap, I’m a machine. I want to be able to look at this and debug it, and figure out what the hell is going on.
AVDI: Well, that’s what Perl is for.
JAMES: I agree that David Brady is a machine, I just want to say.
DAVID: A hopelessly defective and ill conceived machine, sure. Like a death ray that runs on Golden Retriever puppies or something.
JAMES: Sent back from the future but we do not yet know the purpose.
JOSH: Nerd moment here. You remember in the Matrix when Neo is learning how to do Kung Fu by getting hooked into the chair on the ship?
JOSH: And what the guy says about him in terms of admiration is, “He’s a machine.” In their culture, wouldn’t that have been a serious insult?
JAMES: Yes, seems like.
DAVID: It’s okay. We don’t use the M word.
JAMES: Avdi, if I’m understanding correctly, if you wanted to have say a version one and a version two of your API and say maybe it served XML and JSON, so if you wanted the JSON for the version 2, you’re Accept Header should be, application/JSON-V2, or something like that.
AVDI: Yeah, it would be something along those lines. If my application is Avdi, it might be something along the lines of ‘VND.Avdi.’ whatever the actual resource type is, V2+JSON. That’s one way of doing it.
A little known fact about content types is they can actually take parameters. You can actually include parameters, like you can include a care set parameter in some content types. So, another possible way of doing it is to actually have a version parameter in the content type. Unfortunately, this is something that, last I checked, Rails totally does not support. But there’s actually, I can include a link in the show notes which talks about this approach a little bit.
DAVID: Yeah, this bugs me. And maybe it’s just because it’s different from what I expect and because the tool support isn’t really there. This really feels like one of those ideological windmills that we want to tilt at. I don’t know. We said in the pre-show that we were going to troll Steve Klabnik as much as possible.
JAMES: So next week, very likely will be Steve Klabnik coming back to yell at us again for everything we got wrong, just so you know.
DAVID: Yup. And I’ll be sure in four days to go help out at the pre-school so that I can get through the incubation period and be out sick for the show next week. So, Steve can burn me in effigy.
I don’t know. For me, like Avdi said, the versioning stuff isn’t there in Rails. So, it isn’t really easy to link to these URLs and to change the version. It’s not really clearly defined. If I request version 3.0.3 and the server has 3.1.3, is that an acceptable return type? Is there a min/max negotiation? Does the version numbering have to match?
AVDI: Well, there’s plenty of reading material in the RFC 2616, there’s plenty of reading material on the content negotiation algorithm which is pretty carefully specified.
DAVID: Which RFC?
DAVID: 2616. I’m going to go read it. I’ll check. I’ll totally fact check you.
JOSH: So Avdi, one of the variations on this that I’ve read about but I haven’t seen play out in the wild is doing versioning using the host name in the URL. One of the main things I saw along this line is that Netflix started changing their API versioning by adding different endpoints, different hosts for the URL to have different flavors of clients talk to different versions of the API. And that seems to keep things happy in terms of the server can rewrite URLs because all it’s changing is the path part of the URL. And that lets the client have some ability to specify which semantic version of the API that it wants to talk to.
JAMES: That’s interesting. It all still passes David Brady’s test of ‘I’d like to be able to copy this and paste it into my browser’ kind of thing.
DAVID: I have to call a flag on Avdi’s play for RFC 2616. This has nothing to do with API versioning. It’s just the HTTP 1.1 protocol which also supports URI. So, I cite the same source to you, sir, as my defense.
AVDI: I don’t understand that argument at all but we can revisit it later.
DAVID: I think the short version is 2616 provides a framework for doing it either way. And Steve Klabnik has a very strong opinion about how it should be done. And he’s smarter than me, so he may be right.
AVDI: Well, you were asking specifically about how the negotiation is done, of versions of content and that was my answer is that it’s very well specified.
DAVID: Oh, okay. So, you’re also smarter than me. Alright, never mind.
DAVID: Josh and James, you’re next.
AVDI: Actually, there’s sort of a rant here that brings things back to programming APIs a little bit and I think is relevant to the versioning discussion as a whole. The issue with the restful APIs is when you specify your API in terms of, “This is how you will construct all the URLs. This is where all the resources are found.” You drastically limit the flexibility on the server side because it has to continuously support the client’s imaginary object model of how your servers work. And there’s an analogue to this in programmatic APIs which is where the way you use the API is to construct lots of objects directly.
So, the way that you create something in the API is you say, mylib::foo::bar.new which is basically the same exact thing as constructing that URL. You are putting a big structural dependency in that client code that the API now has to support for a very long time which is that it has to have classes structured in this particular way. It has to have that Foo module and ::bar module. And then it has to have the Baz class and it really limits the ability of APIs top move things around.
I think this is related to versioning. You buy yourself a lot of flexibility if you don’t tie your clients to constructing their own objects everywhere and just telling them which class they need to construct. If you can make all the object construction available from the root module or something like that in some way that’s a little bit more dynamic, it makes it a lot easier to move forward on your versions. Does that make any sense, guys?
DAVID: It does and it actually, I find myself in this weird spot where I still disagree with it but I know that I’m going to change my mind and agree with it for a very specific reason. And that is that by putting the version number in the content header instead of in the URL, like you said, it lets you create the same object everywhere. Now, the downside is that this is now an implicit thing and you might get back the wrong version. You might get back a version that you weren’t expecting. And that’s my reason for hating it. And that’s the reason Python users hate Ruby is everything is implicit and everything should be explicit. And my defense of Ruby is that once you understand, once everybody understands that that’s how it is, explicit is just noise. And so, I disagree with it. I’m going to go learn it and study it and play with it and I will probably agree with it soon.
JAMES: So, we all know I’m terrible compared to Chuck as far as tracking time. And I think we’re seriously in danger of running way over here, so I better push this forward. But do we have any other questions we wanted to tackle before we go into the picks? Because I do have one I think I’d like to cover.
DAVID: No, I’m ready to go to release candidate.
JOSH: Let’s ship it.
JAMES: I know that Josh got one interesting question that he showed us. And that was, what if you have a gem that’s maybe the core of your system and then you have the application you’re building on top of that or whatever and you’re developing them both up at the same time. How do you manage that? And do you want to keep them in sync as far as version or anything like that? I thought that was an interesting question. Any thoughts on that?
JOSH: Well, I think there’s a slightly different way to look at that question about whether it’s an application, et cetera. If you look at, say a web API, like say [inaudible], which is a common protocol on the web and the server or the provider has some sort of API that you have to talk to. And then there’s, say a Ruby gem that you run locally as part of your client application to talk to the [inaudible] server, and that local gem is the implementation of talking to that API in Ruby. And the question was about keeping those things in sync and do you want the version number of the API and the version number of the library that is your local way to talk to that web API. Are those version numbers the same? And I’ll just throw out there, what if you have a bug in your [inaudible] Ruby gem?
JAMES: But not in the API.
AVDI: I have a comment for this, a really handy thing. Anytime that you have two things that talk to each other which may be versioned independently, one of the first things to add is a way for them to determine each other’s version. You see this in a lot of Internet RFCs. So, the thing that HTTP 1.0 added was the ability, (a) the client and the server would tell each other which version of HTTP they support, they were requesting and replying with, and (b) there was a mechanism built in for upgrading the connection. So, there was a way to say, “I support this, do you support it too? If so, let’s bump up.”
And that’s the thing to add really early on, especially if you have a gem client that talks to a server is just some way for them both to say, “What version are you?” And some kind of negotiation where the gem can say, “I’m too old, I’m quitting.” Or, “The server says I’m too old,” or something like that. Just make that an early feature and it can solve a lot of problems down the road because you don’t have issues where the wrong version of the gem is talking to the wrong version on the server and they don’t know it.
JAMES: So, just to be utterly specific about what I think we’re saying here is, you really should treat them as two separate entities because they are. Like Josh said, you could have a bug in one that’s not in the other. It just deals with how you’re parsing arguments or sending up the message or something. So, if you’re going to follow semantic versioning which obviously we’ve recommended, then you’re going to need to be able to increment the patch number on one of them. Otherwise, you to have to treat them as a whole and you’ll need to release a new version of the other one that’s not broken which is just silly.
AVDI: Yeah. You don’t have to keep them in lock step just make sure they have a way to find out. And you can do other things then because you can have the server offer older versions if it sends as an older client, stuff like that.
DAVID: I have a really good answer to what might be the wrong question on this which is, specifically with regard to when you’re doing development and you’re on a team, and you’re also simultaneously developing a gem because you’ve split some functionality out into a gem. I did this on a project recently where basically, we needed this tool to help the project and the project needed the tool, but we wanted the tool to be open source and free. The two step negotiation that we came up with is — I’ll get to the gem in a minute.
But what I did is, I split off the gem, built the gem and I pushed it to GitHub. And I went into the gem file for the rest of the team and I basically said, “Use the Migratrix gem, and here’s the URL to it on Git.” And it would basically get the most recent version from GitHub every time that they ran bundle install. And that made it so that I could go off into a story branch and do a story branch over on Migratrix and add a new feature to Migratrix, and I could push it and they could use it.
But at the same time, I needed to be able to make a change to Migratrix locally and have it be immediately available in the client software. And the trick for doing that if that if you look at the Bundler documentation, you can give it a Git tag instead of a version number. If you give it a version number, it goes to Ruby gems and gets that. If you give it a Git tag, it goes to GitHub. You can also give it a path tag that will look for a gem file or a Gemspec file on your local file system. And so, I basically forked the gem file. And on my local copy version of the development project, it actually referred to the Migratrix path. And whenever I needed a new feature or needed to fix a bug in Migratrix, I would go over and do that.
Now, the Git hook thing, obviously, if you’re as absentminded as me, you’re going to end up committing the gem file. So now, everybody is like, “Oh, crap! I’ve got this thing that needs a gem file out of home DBrady. What do I do?”
Maybe this will be my pick. I have a Git hook that I wrote that if you put a comment and in all caps you write, ‘NO COMMIT’, Git will refuse to let you commit that file. And basically, if you need to change a file and have it be changed on your system but not pushed up, you just put that tag NO COMMIT in there, and that’s how I kept myself from pushing my monkey patched gem file up to the team.
JOSH: You’re the kind of guy who puts a carton of milk that has gone bad back in the fridge with a post it note on it saying, “Don’t drink.”
DAVID: Actually, I’m the kind of guy that writes down on a piece of paper, “Check to see if roommate gets sick.” Put that in a sealed envelope and puts it on his To-Do list for next Friday, and then puts the milk back in the carton with no Post-it note.
JAMES: I would never want to program with you.
DAVID: Just don’t raid my fridge.
JAMES: Or drink your milk.
JOSH: Okay. So, if we’re getting close to wrapping things up here, I will add a little bit of wisdom from the days when I worked at Apple Computer. We actually had a QA team that we worked with. And the letterhead that they sent around their Emails with, really embodied what I think is the development philosophy at Apple Computer in the ‘90’s and the ‘80’s when I was working there. And it said, “Apple Computer, where quality is Job 1.1.1.”
DAVID: Nice, which is better than the little bumper sticker, or it wasn’t a bumper sticker. Nut it was the Internet sig going around in the mid-90’s that said, “Intel Computer, where quality is job 0.999948122.”
JOSH: So, 1.0 is supposed to be this awesome moment in the history of development of a product and you release it and everything’s wonderful. But then, you look at how Microsoft made its empire and that was basically releasing 0.5 quality software as 1.0. And it’s basically their beta release and they would let everyone find and fix their bugs in public and charge them for the opportunity to do so.
JAMES: Josh, are you going for a record on the amount of hate mail you can get. Rails Core Team, Microsoft…
JOSH: Dude, who’s pointing fingers? That was brilliant.
DAVID: It was. Actually, I’m going to back Josh up on this. Has anybody every heard the saying, “3.0 is the new 1.0?”
JOSH: No, but I like it.
DAVID: I honestly have worked with people who literally wanted us to release version 3.0 first, like the very first version needed to be called 3.0. And I said, “Why? It’s still a version one.” And he said, “If Microsoft has taught us anything, it’s that the product is not stable and ready for public consumption until version three.” And I’m like, “So, what makes you think our 1.0 is ready?”
JAMES: That’s awesome.
JOSH: Well, it used to be that OS 10 would come out with a new major release. And with OS 10, the Semver is all screwed up because the 10 will never change. So, the major releases are all the minor number. So, you’ve got 10.6 to 10.7, that’s a huge breaking backward compatibility, major upgrade.
So, I’m not a crazy early adopter when it comes to these OS rollouts and I always let the crazy early adopters find the bugs for me because now, Apple is following the pattern that Microsoft set. And they’ll just roll out, OS 10.7.0, I’m not touching that. I’m waiting for 10.7.1, or 10.7.2 even to make sure that they found all the corner cases. And there were significant problems with the 10.7.0 release where if you were doing Ruby development, you were kind of hosed. So, it was definitely prudent to wait a little bit.
DAVID: I personally have gone through the Lion upgrade and then oh crap, go find the Snow Leopard disc and upgrade back to Snow Leopard with a time machine backup. And I’m still on Snow Leopard as a result, yeah.
JAMES: Alright, guys. I would love to let us talk forever but while Josh is getting hate mail from everybody, I’m going to be getting hate mail from Chuck because of the size of this episode. So, we’re going into the picks now. David, you already kind of gave one pick. Do you want to give another one?
DAVID: Yeah, ‘Book Yourself Solid’ by the guy that wrote it.
JAMES: By the guy that wrote it?
DAVID: Yeah. I’ll put a link in the show notes. It’s a consulting thing that, short version of the book if you reduce it down to two sentences is, be nice, make people happy to work with you and then leverage that and work that. It’s a guide for, I think somebody’s already picked, probably me, ‘Get Clients Now!’ I’m speaking to the independent contractors out there or the contractor wannabes out there. Book Yourself Solid is a book about how to basically, if you hate marketing, how to find clients that you love and want to engage with, without actually doing the sleazy, slimy side of marketing.
Speaking of that, I’ve had a couple of people contact me in the past couple of weeks because I mentioned that I was looking for employees and I misspoke. I am looking for contractors. I got taken to task for misusing that word. I’m not big enough to be looking for employees. We are looking for contractors. And we’ve recently taken on a couple of Rails Rescue projects where we kind of un-screw your Rails project, and we were getting pretty good at it. So, if anybody out there has got a Rails project that’s screwed up, give me a holler.
DAVID: Did you see? I totally shield myself in my pick? That’s awesome! James is like, “Edit this out!”
JAMES: No. It just made me think, “Wow! I can do that too.”
JAMES: Avdi, your picks.
AVDI: Alright. This is another of those picks that I could swear I did this before but I couldn’t find it in the list. So, the gem Faraday. Faraday is, if you took Rack and you turned it upside down so that you could use it on the client’s side instead of the server side, it is an abstraction layer for HTTP client libraries. It lets you plug in whichever client library you want and talk to them all the same way. So, you can talk to NET HTTP, or Typhoeus, or Patron, or EM HTTP or whatever else. You can talk to them all the same way using the same API. But more importantly, it gives you a middleware layer, so you can take whatever adaptor you have on the end of the chain. And then, you can plug in any kind of intermediaries in between your requests.
So for instance, if you decide, “I want to start caching all of my API requests.” Instead of changing the way you call the API’s, you can just gem in a new middleware into the Faraday stack which handles caching. So, super handy for programming against HTTP APIs.
Secondly and this is kind of not a specific thing, I want to pick gem Maintainers. I will confess to being really bad at maintaining gems. I create them and then, once I get my idea out there or I get the thing that I need to use, they’re kind of boring to me. So, I have a bunch of gems that I don’t take as good care of as I should. There are people out there that have this amazing quality of just being good at maintaining gems.
Like Myron Marston took over NullDB for me. Josh Nichols has given me some help with a few of my gems. And most recently, Larry Marburger has took on the task of actually extracting out a gem from a project that I was working on, and doing the grunt work of turning it into a gem in its own right. These people are great to have. And if you’re looking for one good reason to be nice to your gem users, it’s that you might be lucky enough that one of them will step in and become a maintainer when you don’t have the time to maintain the gem anymore.
JAMES: Hear, hear for using other people. Yey! Let’s see. I guess I’ll go next since I wanted to comment on some of the things Avdi said. One of the things about Faraday, I’ve got a funny story about that. I used Faraday in one of my examples at Ruby Mid West and I actually showed how I was doing all these requests and then I just made one tiny change. And all of a sudden, they were all parallel. And technoweenie posted after that, “James just showed off how to do parallel requests in Faraday and I don’t think I know how to do that.” But to be fair, I had to read a lot of source to figure that out. So, it was not easy.
Anyway, for my own picks. For my first pick, I’m going to go with Lasik surgery. I think I mentioned that I had it done back in November. So, if I’m picking it now, this should be a good clue to anybody listening. It really did take me about two months to get comfortable with it. I was seeing pretty good right after, about 20/25 within the first week but I did have a minor complication. It had to of work itself out over time. So, it kind of took a while to get to the point where I was comfortable with it. But I have to say, it is an amazing thing. You go in. I was on the operating table 12 minutes. I never felt anything you would call pain and they just flipped a switch and fixed my moderately bad eyes, you know.
When I was young, having glasses didn’t really bother me and it didn’t really affect me much but as I got older it just got more annoying every day, having to keep track of glasses, keep them clean and all that kind of crap. So, just not having to do that is amazing. It’s really good. And my wife had it done in December and she’s almost even with me because she didn’t have the complications. It does take a while. There’s still a few nagging, minor complaints I have that I’m told will probably ease up over time. So, just don’t think that it’s one of those things where you do it and the next day you’re great but it is pretty cool.
If you haven’t looked into it a long time, used to be they cut a flap in your eye with a microkeratome, I think. And now, they’re kind of bleed-less, these things. So, you never even have to have a bleed on your eye. They just make the flap with another laser. It’s pretty impressive stuff that we can do with science.
DAVID: That’s cool.
JOSH: Yeah. I’m looking forward to using stem cells from your own cornea to clone up new corneas. My family has a history of cataracts. So, I’m hoping in like 20 years, I’ll be able to just get new corneas and not have to worry about that.
JAMES: Absolutely. It’s amazingly cool stuff. My wife had a really bad vision. In fact, she’s right on the borderline of what Lasik can even do and it’s only because she basically met all the other criteria perfectly that they even did her. But I mean, you’re talking about somebody who has to buy the highest level of thin glasses just so they’re not ridiculous. Her surgery took a little longer than mine, maybe 20 minutes. And then, she’s a couple weeks out now and seeing great without glasses.
DAVID: That’s awesome.
JOSH: Yey! We’re all Cyborgs now.
JAMES: That’s right. So, if you want some cybernetic upgrades, I recommend Lasik. My other pick today is I’m going to do a self-serving pick. So, feel free to tune me out if that…
DAVID: [Chuckles] Blah…blah…blah…blah…blah…
JAMES: I’ve been writing a series of articles called Rubies in the Rough. And everybody’s always asking me how I think about things or do things. And I am trying to write all that down, quote it up and tell you how I think about things. So, these articles are kind of unusual in that I don’t just show Ruby features or something like that. I actually tell you how I’m thinking about things, how I do experimentation, how I handle the rules of programming, how I do refactoring, all that kind of things. I’m trying to help people understand how I think about problems instead of specifically syntax and stuff like that which is always easy to come across.
DAVID: That’s cool.
JAMES: If that kind of thing sounds interesting to you, I’ve been writing them for a while now. I released three of them, I released another one today. There’s lots of great articles out there and people have been talking about them and stuff. It’s not free. I do charge a little bit for the article, $6 a month. So, it’s like $2 an article. So anyway, that’s my self-serving pick of the day. But if it’s the kind of thing that interests you, I hope that you would like it.
DAVID: That’s awesome.
AVDI: I just want to add that every one that I’ve read so far, I’ve learned something from.
AVDI: Usually a few things.
DAVID: Alright, that’s it. I’m signing up.
JOSH: [Chuckles] Okay.
JAMES: Okay. So, we haven’t had Josh do his picks.
JOSH: Okay, great. I totally wimped out on picks last week. So, I have all sorts of goodies this week starting with errata. So, last week in the bonus feature, I misspoke and I was comparing the silly names of gems. I was talking about rack-rewrite and I said ‘versus Informal’ but I actually meant refraction. So, taking the opportunity to correct myself and hopefully, I haven’t confused anyone really horribly and they’re trying to use Informal to rewrite URLs.
Okay, my first pick is for Code Climate. You can go to CodeClimate.com. David, do you remember a couple of weeks ago, we were doing the profiling performance benchmarking stuff? And you said, “Why don’t we have tools for benchmarking the complexity of things rather than the performance?”
JOSH: So, Code Climate is what you want.
DAVID: Oh, hell yes!
JOSH: You take your GitHub repo, you hook it up to CodeClimate.com, you give it a deploy key and an integration hook in GitHub. And then every time you push something up to GitHub, Code Climate notices your changes and it goes and it gives you a report on how cool your code is or how un-cool it is. And it tells things like the complexity of the code, it finds repetition across various classes where you might want to extract things into modules to dry it up and Churn, Hot Spots. It’s pretty cool, so I’m using it now. I’m just starting to get into it but I hooked it up and immediately, I started seeing things that I could improve in my code.
The guy behind it is Bryan Helmkamp. He’s spoken at Golden Gate Ruby Conference and a bunch of other conferences and he’s written a lot of great code and has been a big player in the Ruby community. So, I definitely appreciate him and support his work and I hope that Code Climate goes on to be a success because so far, I’ve been really pleased with it.
DAVID: That’s awesome.
JOSH: So, check that out. And then, I have a fun pick which is an old comic book that I just recently re-read and I love it more every time I re-read it. It’s called The Invisibles by Grant Morrison. This came out in the ‘90’s. It’s a really hard comic book to describe but it’s been republished as I think seven volumes of graphic novels. It’s basically a bunch of weirdo, hippie, anarchist freedom fighters who are up against the mystical conspiracy that’s trying to control everybody in the world. It’s really smart. They have incredibly bizarre characters like this young street punk from Liverpool who’s the new Buddha, Brazilian drag queen Bruja witch, [chuckles] telepaths from the future, James Bond with a shaved head and tantric powers. So, it’s a lot of fun. I love reading it. It’s really worth going back and checking it out. So, have fun with that.
DAVID: I totally want to be that guy.
DAVID: James Bond with a shaved head and tantric powers. That’s kind of naughty. I like it.
JAMES: You had me at Brazilian drag queen, just saying.
JOSH: [Laughs] There you go. And then, I got to put a little note in here saying how excited I am that they’re now filming a new season of Red Dwarf.
DAVID: Oh, you’re kidding me.
JOSH: No, I’m not. [Chuckles] If you lived in London now, you could get tickets to go watch the filmings. They are going on right now. Yes, I’m excited.
DAVID: Honey, can we move to London?
JOSH: [Laughs] Nice. Okay.
JAMES: Alright. Well, I’ve bungled along this episode as much as I possibly can and taking us out is just too much for me. Luckily, Chuck has flown in to save the day and will now close this episode.
CHUCK: Woohoo! It’s me! So, a couple of things that I wanted to tell you about real quick. First off, we are doing our Book Club on February 22nd. We’re going to be doing ‘Land of Lisp’.
DAVID: Best Book Club ever!
JAMES: It is going to be an awesome Book Club.
DAVID: Tell them why it’s the best Book Club ever.
CHUCK: Because I still need to start the book?
DAVID: Because Conrad Barski gave us…
CHUCK: A discount code, that’s right. If you go to NoStarch.com and you use the code ‘RubyRogues’, it’ll give you 30% off the book. RubyRogues is all one word.
JOSH: Not 10%, not 20%, but 30% off.
CHUCK: But wait, that’s not all.
CHUCK: Anyway, just another thanks to Conrad. He’s been really cool about helping us get our hands on the book and everything. So, if you want to buy the book, go to NoStarch.com. RubyRogues is your code and you get 30% off. He said the discount code is good through the end of July. So, if you’re listening to this after we recorded it, you can still get it for a discount.
DAVID: What’s it called?
JOSH: Oh, cool. So, you guys are going to be Jabberers?
CHUCK: Something like that.
DAVID: Chuck, you are not doing enough podcasts. You should do some more.
CHUCK: I know I should get to work, right?
DAVID: Yeah, seriously.
CHUCK: Well, I’m actually putting together a podcast network page thing, kind of like 5by5.TV. So, we will be pulling all of the podcasts into that.
JOSH: I’m waiting for you to do the podcast about podcasting.
CHUCK: I’ve been tempted.
CHUCK: Anyway, so that’s what’s going on. And again, as per normal, we would really appreciate any reviews that you have for this podcast on iTunes. You can follow us on Ruby Rogues or on Twitter at RubyRogues.com.
And finally, we have our first sponsor and that is New Relic.
CHUCK: So, if you want statistics on how your app’s performing, you can go to NewRelic.com and check them out. We will get a link up on the website and after that, it would be nice if you click that because that actually tells them that you came from us.
DAVID: If you’ve got the old relic, get rid of that crap and get the New Relic, it’s awesome.
CHUCK: Yeah. I was actually using it last week to speed up some requests for one of my clients and it’s a pretty cool tool.
JOSH: It’s nice and a little bit of trivia about New Relic, the name of the company is an anagram of the Founder’s name.
DAVID: Oh, really?
JOSH: Yeah, Lew Cirne.
JOSH: Yeah. Anyway, moving right along.
CHUCK: Alright. So, that’s all I’ve got. Anything else you guys want to bring up before we wrap this up?
JOSH: I have one last thing and that’s I want to say we’ve talked about yak shaving in the past and I just want to say that in re-watching an episode of Cosmos, I noticed the greatest yak shave ever in which Carl Sagan said, “In order to bake an apple pie from scratch, you must first create the universe.”
JAMES: Yes. And by the way, Cosmos is absolutely awesome. If you haven’t seen it, you need to go watch it. But they’re also remaking it with Neil deGrasse Tyson who is basically the modern day Carl Sagan. So, that is awesome.
DAVID: You know, with as many Rubyists that are shaving yaks, there ought to be a yak swim teams out there somewhere.