{"id":377,"date":"2013-04-11T16:03:41","date_gmt":"2013-04-11T16:03:41","guid":{"rendered":"http:\/\/a1webdesignteam.com\/blog\/?p=377"},"modified":"2013-04-11T16:03:41","modified_gmt":"2013-04-11T16:03:41","slug":"automating-tedium","status":"publish","type":"post","link":"https:\/\/a1webdesignteam.com\/blog\/automating-tedium\/","title":{"rendered":"Automating Tedium"},"content":{"rendered":"<p>Here\u2019s where I\u2019m supposed to say, \u201cBullshit! Learn the command line,\u201d and then check my d20 to see if the hit was critical. Except he\u2019s right. Doing all that stuff <strong>is<\/strong> annoying. Between CSS preprocessing, JavaScript transcompilation, image optimization, concatenation, minification, and source control, your average dev needs to launch a navy just to make their Hello World blink. Nobody wants to have to remember and type all this crap.<\/p>\n<h2 id=\"another-option\">Another Option<\/h2>\n<p>I\u2019m no command line junkie. Borderline competent, at best. Yet I find myself in projects that require something to happen in the command line. Spin up a node.js process. Connect to a local Mongo database. <code>rails c<\/code>. There\u2019s no fancy omnipotent Cocoa app that will manage these things for me. The good news: I don\u2019t even try to remember it all.<\/p>\n<div>\n<pre><code>before { run 'cd ~\/Sites\/imakewebthings.github.com' }\r\n\r\ntab :name =&gt; 'Jekyll' do\r\n  run 'rvm 1.8.7'\r\n  run 'jekyll --server'\r\nend\r\n\r\ntab :name =&gt; 'Sass' do\r\n  run 'sass --style expanded --watch css:css'\r\nend\r\n\r\ntab :name =&gt; 'Git' do\r\n  run 'git st'\r\nend\r\n\r\nrun 'subl .'\r\nrun 'open http:\/\/0.0.0.0:4000'\r\nrun 'exit'\r\n<\/code><\/pre>\n<\/div>\n<p>This is a <a href=\"https:\/\/github.com\/achiu\/consular\">Consular<\/a> script. The Consular script for this blog, as a matter of fact. Consular is a terminal automator written by <a href=\"https:\/\/github.com\/achiu\">Arthur Chiu<\/a>. You create projects which are nothing more than a Ruby file like the one above. This file defines any number of terminal tabs and the processes to run within them. From then on you can just type a few words into the command line and the whole thing is executed. No more trying to remember the tedious crap.<\/p>\n<p>To install Consular:<\/p>\n<ol>\n<li><code>gem install consular<\/code><\/li>\n<li>Install the consular core for whatever terminal app you use. I use <a href=\"http:\/\/www.iterm2.com\/\">iTerm2<\/a> so it\u2019s <code>gem install consular-iterm<\/code>. The project page has a list of all the supported cores and their corresponding gem names.<\/li>\n<li><code>consular init<\/code><\/li>\n<li>Open the newly created <code>~\/.consularc<\/code> file and add a require statement for your core to the top. The project page for each core will have this snippet. For iTerm it\u2019s <code>require 'consular\/iterm'<\/code>.<\/li>\n<\/ol>\n<p>Now you can create projects with <code>consular create projectname<\/code>. Write the \u201cTermfile\u201d like the one above. Then you can launch the project with <code>consular start projectname<\/code>. Let\u2019s take a look at that project definition from earlier, line by line, to see what it does.<\/p>\n<div>\n<pre><code>before { run 'cd ~\/Sites\/imakewebthings.github.com' }\r\n<\/code><\/pre>\n<\/div>\n<p>Anything in a <code>before<\/code> block is executed immediately and at the beginning of every new tab creation. Since I may be anywhere in the file system when I run the <code>consular start<\/code> command, I want to make sure I go to the project directory. Many terminal apps also have a default setting to go to the home directory when creating new tabs rather than keep the location from the previous tab. There are settings to change this, but it\u2019s good to know this annoyance is out of the way regardless.<\/p>\n<div>\n<pre><code>tab :name =&gt; 'Jekyll' do\r\n  run 'rvm 1.8.7'\r\n  run 'jekyll --server'\r\nend\r\n<\/code><\/pre>\n<\/div>\n<p>If you can believe it, <code>tab<\/code> blocks create a new tab. You don\u2019t have to name your tabs, but I prefer it. Inside that tab I switch to ruby 1.8.7 and start up <a href=\"https:\/\/github.com\/mojombo\/jekyll\/wiki\">Jekyll<\/a>, the static site generator that powers this blog.<\/p>\n<div>\n<pre><code>tab :name =&gt; 'Sass' do\r\n  run 'sass --style expanded --watch css:css'\r\nend\r\n<\/code><\/pre>\n<\/div>\n<p>Here is the <code>sass<\/code> watcher Chris brought up. For tabs that only have one command you don\u2019t even need to place commands inside a block, you can just pass it the string to execute. For example: <code>tab 'tail error.log'<\/code>.<\/p>\n<div>\n<pre><code>tab :name =&gt; 'Git' do\r\n  run 'git st'\r\nend\r\n<\/code><\/pre>\n<\/div>\n<p>Runs <code>git status<\/code> just to see where things are. Since this tab doesn\u2019t have a running process like the others, it\u2019s also where I do any terminal work going forward. Because our original tab that everything started from is about to go away.<\/p>\n<div>\n<pre><code>run 'subl .' #Opens project directory in Sublime Text 2\r\nrun 'open http:\/\/0.0.0.0:4000\/blog'\r\nrun 'exit'\r\n<\/code><\/pre>\n<\/div>\n<p>It is in no way a requirement of a Consular script, but if I\u2019m using it to create tabs I run <code>exit<\/code> at the end. This closes the original tab. That original tab may be unnamed or named from a previously run script, and I no longer need or want it. Before exiting I launch anything that needs launching but doesn\u2019t concern itself with the terminal. In this case, I open the local Jekyll instance in my default browser and open the project directory in <a href=\"http:\/\/www.sublimetext.com\/2\">Sublime Text 2<\/a>.<\/p>\n<h2 id=\"who-shouldnt-use-this\">Who Shouldn\u2019t Use This<\/h2>\n<p><strong>If you\u2019re a purely front-end developer<\/strong>, you work on mostly static web projects, and <em>never<\/em> need to touch the shell then by all means, grab CodeKit and <a href=\"http:\/\/mac.github.com\/\">GitHub for Mac<\/a> and be happy. This is probably your ideal setup. If you can avoid using the command line altogether, that\u2019s awesome. But keep reading. You may have reasons for using a terminal automator beyond your development projects.<\/p>\n<p><strong>If you do everything in vim<\/strong>, remote pair-program, have never sullied the hair on your neck with the edge of a razor, or otherwise spend <strong>a lot<\/strong> of time on the command line then you want something more advanced. But if you fit this description, you already know about <a href=\"http:\/\/tmux.sourceforge.net\/\">tmux<\/a> and <a href=\"https:\/\/github.com\/aziz\/tmuxinator\">tmuxinator<\/a> and stopped reading a long time ago.<\/p>\n<h2 id=\"not-black-and-white\">Not Black and White<\/h2>\n<p>Here\u2019s a false dichotomy for you. <em>Either you use the UI tools or you rock the command line.<\/em> Keep this from creeping into your head. These tools don\u2019t have to be used exclusive of each other. You can easily use something like Consular to launch a bunch of apps and quit the terminal altogether. Let\u2019s take a look at my script for <a href=\"http:\/\/imakewebthings.com\/jquery-waypoints\">Waypoints<\/a>:<\/p>\n<div>\n<pre><code>run \"cd ~\/Sites\/waypoints\/jquery\"\r\nrun \"subl .\"\r\nrun \"open http:\/\/local.jquery.waypoints.com\/test\"\r\nrun \"open http:\/\/github.com\/imakewebthings\/jquery-waypoints\/issues\"\r\nrun \"git st\"\r\n<\/code><\/pre>\n<\/div>\n<p>Aside from the <code>git st<\/code> I\u2019m just launching applications. Two Chrome tabs and Sublime. If I didn\u2019t use git from the command line this could just as easily end with\u2026<\/p>\n<div>\n<pre><code>run \"github\" # You've installed the GitHub for Mac command line tool, right?\r\nrun \"exit\"\r\n<\/code><\/pre>\n<\/div>\n<p>I find this terminal-less ending appealing because it hints at what we\u2019re <strong>really<\/strong> doing with these scripts.<\/p>\n<h2 id=\"come-for-the-terminal-automation-stay-for-the-context-switches\">Come for the Terminal Automation, Stay for the Context Switches<\/h2>\n<p>If there\u2019s anything we can agree on as an industry it\u2019s this: <a href=\"http:\/\/www.joelonsoftware.com\/articles\/fog0000000022.html\">Context switches are bad<\/a>.<sup id=\"fnref:1\"><a href=\"http:\/\/imakewebthings.com\/blog\/automating-tedium\/#fn:1\" rel=\"footnote\">1<\/a><\/sup> But even in the most optimal environment \u2014 free from interrupting phone calls, hour long \u201cdesign meetings\u201d, and shoulder-perched micromanagers \u2014 there will come a time when you need to switch contexts on purpose. Let\u2019s look at a contrived but plausible day in the life of yours truly (computer activities only):<\/p>\n<ul>\n<li>Wake up. Check email.<sup id=\"fnref:2\"><a href=\"http:\/\/imakewebthings.com\/blog\/automating-tedium\/#fn:2\" rel=\"footnote\">2<\/a><\/sup><\/li>\n<li>Work on <em>Client Project<\/em>.<\/li>\n<li>Eat lunch. Check email.<\/li>\n<li>Work on <em>Client Project<\/em>.<\/li>\n<li>After dinner, fix a bug in Waypoints.<\/li>\n<li>Make an improvement to a transition theme in deck.js.<\/li>\n<li>Work on a draft of this blog post.<\/li>\n<li>Check email.<\/li>\n<li>Screw around. Facebook, games, read blogs, fantasy baseball, etc.<\/li>\n<\/ul>\n<p>You know what I do when I want to work on <em>Client Project<\/em>, Waypoints, this blog, or any other coding project. But what about the other stuff? Each one of these items is a context switch, <strong>including the email and screwing around<\/strong>. And every time I want to switch contexts I go through the same three steps, no matter the type of task.<\/p>\n<ol>\n<li>Quit everything. By everything I mean every visible window. When I activate Expos\u00e9\/Mission Control I just see background.<sup id=\"fnref:3\"><a href=\"http:\/\/imakewebthings.com\/blog\/automating-tedium\/#fn:3\" rel=\"footnote\">3<\/a><\/sup><\/li>\n<li>Launch iTerm2.<\/li>\n<li><code>consular start contextname<\/code><\/li>\n<\/ol>\n<p>That\u2019s right. <code>consular start email<\/code>. <code>consular start dickaround<\/code>. Now my day turns into a series of <em>Quit, Run Script, Do Work<\/em>, <em>Quit, Run Script, Do Work<\/em>, ad infinitum. That may sound boring or robotic, but I see it as relief for the brain. I don\u2019t need to ask myself what programs and files to open. I just need to ask myself what I should be working on <strong>right now<\/strong>. Then focus on doing that thing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here\u2019s where I\u2019m supposed to say, \u201cBullshit! Learn the command line,\u201d and then check my d20 to see if the hit was critical. Except he\u2019s right. Doing all that stuff is annoying. Between CSS preprocessing, JavaScript transcompilation, image optimization, concatenation, minification, and source control, your average dev needs to launch a navy just to make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0},"categories":[7],"tags":[],"_links":{"self":[{"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/posts\/377"}],"collection":[{"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/comments?post=377"}],"version-history":[{"count":0,"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/posts\/377\/revisions"}],"wp:attachment":[{"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/media?parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/categories?post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/a1webdesignteam.com\/blog\/wp-json\/wp\/v2\/tags?post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}