I've previously written about how much we love HipChat. HipChat is still awesome, but there's a new player in the space and it seems to have some things that it does better out of the box: Slack. Like HipChat, Slack offers a free price tier. Unlike HipChat, the free plan is not limited to a small number of participants, so if you couldn't use HipChat for free because you have more than 5 people on your team, maybe you should give Slack a try. They make their money by selling other premium features.
Slack offers a bunch of easily enabled and configured "integrations" with other services -- think IFTTT, but built-in. Things like GitHub, Jenkins, Dropbox, and Trello to name but a few.
Unfortunately I was dissatisfied with the Trello integration. In fact, many of them are pretty basic, which I can understand. Each integration probably equates to a cron job running somewhere. Allow too much flexibility and you'll soon be drowning in recurring jobs. It could quickly eat up a server's bandwidth or available CPU cycles.
Fortunately, Slack offers webhooks as one of those integrations. They offer both inbound and outbound webhooks, but for my purposes I only need inbound.
Node to the rescue!
I had previously been using a python script to pipe activity from a number of our Trello boards into our hipchat room. That had some drawbacks too: I don't have any cloud python hosting (nor do I really want to seek any). I would consider Heroku but (at least last time I checked) they don't support Python. So I only ran the script locally with cron.
A couple of helpful developers have open sourced libraries for working with Trello and Slack from node.js (node-trello and node-slack, of course), so really all that's needed is some glue to bring everything together.
At the time that I wrote about integrating with HipChat I had started to port the python code to node, but was having trouble and didn't really have time to figure it out. I'm happy to report that the port is complete and functional, and I'm running it right now, on Heroku -- for free, of course.
Because it's a port of synchronous Python code to asynchronous Node.js code, it's kind of messy and not really typical node-ish code. Maybe I'll refactor it down the line if I ever get the time and the motivation.
What does it do?
My library is setup so that you can just download it, fill out
config.json with your Trello and Slack api tokens, and run it. You can run it locally or in the cloud.
config.json file, you can specify which Trello boards you want to watch, and in which Slack channel to post about their activity. That is, each board's activity can be displayed in a different Slack channel, if you want.
So far, we're really liking Slack over HipChat, and this more sophisticated Trello integration goes a long way to making it possible to be a permanent replacement. Hopefully you find it useful too.
Yesterday morning the internet was abuzz about something called "atom" that was "leaking" from GitHub. It was either a very clever and very successful marketing ploy, or (Occam's Razor, and all) they were just making private repositories public in preparation for beta launch and a few people that happened to be paying close attention realized something was up.
Basically, it's kind of a mashup of the idea behind Brackets and Sublime Text. There was even speculation that perhaps GitHub bought Sublime, because of how similar they look. And to be fair, it looks like the folks at GitHub have been working on this for something like 6 years -- long before either Brackets or Sublime was around.
By lunch time the website was up and you could request an invite to the private beta. I managed to get an invite, and while I haven't had a ton of time to play with it yet, I did manage to put together a CFML Grammar plugin (the thing that provides syntax highlighting and snippets). I don't want that to sound like I'm taking credit for some monumental work -- they provide a tool that will convert a TextMate Bundle into an Atom grammar, and I simply ran it against the latest official CFML TextMate Bundle, checked it into GitHub, and published it.
As the title of this post implies, it's not that great. The last commit to the TextMate bundle was roughly a year ago. Script-component support is basically not there, and I've only barely checked it against a few CFML files. But it's a start, and better than nothing. Feel free to file bugs or if you're feeling adventurous, submit pull requests.
I just wanted to get a baseline available ASAP, and then make sure you knew that it exists.
For now the Atom beta is limited to Mac OSX and you have to be running OSX 10.8 Mountain Lion or 10.9 Mavericks to run it. I have 1 beta invite that I'm willing to part with, but please remember: OSX 10.8+ only! I also ask that if you do get my invite, please pass some of your invites on to others that comment here asking for one. Pay it forward.
I wanted to write and tell you about the two presentations I'll be giving at cf.Objective() this year; but on the off chance that that's not the sort of thing that grabs your attention span by the eyeballs and super glues it to the screen, I thought it wise to lead with this: One of my sessions will be a collection of thoughts on and lessons learned from running a successful open source CFML project for 4+ years, and if you've got questions that would be appropriate for that audience, I wanted to give you the chance to ask them now, in advance of the conference, so that I can have a well thought out and meaningful answer for you, baked right into the presentation.
So take a moment to read through the session description(s) below and if you've got any questions, particularly about the one titled "Building Communities," please leave them here as a comment -- or send them my way via my Contact Form if you'd rather ask in private.
And while we're on the subject of cf.Objective(), the "Early Bird" pricing for the conference -- saving you $100 -- has been extended through the end of February. Book before March 1st and spend that extra $100 on adult beverages and, quite possibly, a ticket to the Minnesota Twins game! (More on this later, as well...)
Building Communities: Lessons Learned from 4 Years Running a Successful Open Source CFML Project
This session will explain why you (yes, you) should be participating in open source; how to decide what to build or contribute to; what makes an open source project successful; and how to encourage a community to thrive around that project -- all by using examples of my own "failed" open source projects and what I consider my single "successful" project. What differs between those projects? Did I behave differently? You'll have to attend the session to find out!
We'll also see that open source participation is an excellent path (though not the only one) to becoming an expert developer, and in doing so: demanding a higher salary and having jobs hunt you. And while it sounds scary that other people will be scrutinizing your code, I'll explain why they still appreciate your project even if they have criticisms for you.
Open Yourself to Closures
Minnesota Twins Game (Maybe)
There's a Twins game on Wednesday the 14th (of May, of course) at 7:10pm -- and it's Dollar Dog Night ($1 kosher hotdogs) if you're into that sort of thing, too.
Last year we had a group of somewhere around 10 people come -- mostly internationals that wanted to see what American Baseball was all about, if I'm not mistaken -- and we had a great time walking around the stadium sampling the local beer and then watching the game and talking about Baseball. I'm inclined to help organize this event again this year, but before I commit myself I want to take a look at what the conference itself has on offer on Wednesday night. I'm not sure I want to skip the BOFs for a baseball game (I do love my board & card games!), but I might skip something else.
If you're interested in attending the Twins game as a group from the conference, please do leave a comment and let me know. Last year I bought tickets for international attendees and let them pay me back on-site so that they didn't have to go through the hassle of purchasing from abroad; and I'm happy to do the same again this year assuming I decide to attend the game.
I found a small bug in Mach-II 1.9; the final release before it was EOL'd. I wasn't really sure what the best way to handle this was. I'm still not, but I figure some action is better than no action. So I'm going to blog it in the hopes that regular users of Mach-II will see this and be able to file it away in the back of their minds for later reference. And hey, if someone wants to fork the project and fix it, all the more power to them. I considered doing so myself, but honestly I don't want to take on stewardship of the project; and the bug is an extreme edge case with a pretty simple workaround.
The bug is that if you change the filesystem path to your webroot/config files, no amount of reloading the framework will clear the cached location to the
mach-ii.xml configuration file.
More concretely: I was doing some reorganization on one of our servers. We've been standardizing on
c:\web\com.foo.bar\www ("reverse dns notation") as the location for application webroots, with their non-web-accessible files (e.g. the majority of files in a Mach-II app) organized a level up, e.g.
I made a fresh git clone of one of our projects and pointed IIS to the new file path and archived the old folder into a backup in case we would need it later. I opened up the site and reloaded the mach config, but was getting an error that the config xml could not be found -- and this was the head scratcher: It was listing the old path for the XML file. I spent probably an hour trying to find references to the old location in our code, bad relative paths in the config, or something like that. Frustrated, I just started dumping values and aborting from Application.cfc:
<cfdump var="#application.bootstrapper.appLoader.getConfigPath()#" abort="true" />
Oddly, this still showed the old path. So clearly, even with a reload triggered (
MACHII_CONFIG_MODE = 1), there's a component with that path cached somewhere in the object graph and it's not being updated.
The solution was simply to restart the ColdFusion service. Now that I think about it, if you have the option, changing the application name (
this.name = 'foo';) should be just as effective.
Like I said, it's an extreme edge case -- how often do you really move your source code around? -- and the workaround is simple. I just thought you should all know.