Max Krebs

TIL: /usr/local/bin
>>

This is the first in a series of shorter blog posts I am going to start writing semi-regularly called TIL, in which I go into the smaller programming or operational tricks I pick up in the course of my day. Posts will be limited to 200 words. This was inspired by Hashrocket’s Today I Learned blog.

The sub-title for this one is, “Patrick States the (fairly) Obvious.”

Untill today, whenever I needed to save a short script or executable, I would put it in a folder called bin and then add an alias to my zshrc.local file that would call that command. For example:

alias achive_tweets="~/bin/archive_tweets"

Well today I learned that I can just drop any old executable into usr/local/bin and it will be automagically added to my path!! This was incredibly exciting for me to realize. Now I can throw my scripts into ~/bin, where they are checked in to version control, and then create a symlink between that file in ~/bin and /usr/local/bin. This is incredibly empowering for me, and it gets rid of the messy list of aliases in `zshrc.local.

tat
>>

tat

As I went into a little bit in my previous post, I have recently been taking another crack at working in tmux, after a less than stellar first crack at it a couple of months ago. One of my inital problems with tmux was that it was annoying to try and keep track of what sessions I had open and in which directories. The default naming scheme for sessions is just to assign each one a number unless you manually rename it.

So I would have to go through the steps each time of 1) opening Terminal 2) running “tmux ls” to see if I had any existing sesions open then (this is if I remember to) then having to either 3) run “tmux a -t ”, which normally takes a couple of attempts because I can’t remember the order of arguments, or I would get the name wrong, or 4) I would start a new session (which only adds to the mess) and remember to either 5) set the name when I created the session or 5) set the name once the session attached.

Phew.

Luckily, Thoughtbot and thier incredible repo dotfiles has a solution for this exact problem. Included in the bin directory, is a shell script called tat. When you run tat, the script will “Attach or create tmux session named the same as current directory.” This is great. Now, if you want to attach to a tmux session, all you do is run one command “tat” and either you pick up where you left off in an existing sesion, or you get a new one, with the correct name and everything. Then using the session switcher (which I bind to s) you can easily switch between all the directories you have open.

The last piece of the puzzle is that I added a small script to my zshrc.local file to make sure that whenever I open a new shell, if I am not currently attached to a tmux session, tat will get called.

_not_inside_tmux() { [[ -x "$TMUX" ]] }

ensure_tmux_is_running() {
  if _not_inside_tmux; then
    tat
  fi
}

ensure_tmux_is_running

And that is that. Whenever I open a new shell, I get thrown into a tmux session right away. This effectively eliminates the friction I was feeling with creating and managing tmux sessions.

Vim-Tmux Runner
>>

Vim-Tmux Runner

As the kind of person who is always looking for new ways to expand my development skills, I recently signed up for Thoughtbot’s Upcase service. Upcase is a “finishing school” for developers featuring screencasts, tutorials, exercises, and discussion forums. One of the first trail of videos I went through was a course on tmux by Chris Toomey.

I’ve experimented with tmux before, but I always thought it was a little too much for my needs; more trouble than its worth. But then I went through the tmux course on Upcase. One of the more interesting and useful things I got out of that course, was a vim plugin called Vim-Tmux-Runner.

Vim-Tmux Runner solves I problem I had with vim, while leveraging the power of tmux panes. It defines some vimscript commands that, when run from within a vim session, it sends the current line to be evaluated in an attached tmux pane. Here are some of my most-used vim keybindings for Vim-Tmux-Runner.

<leader>osr :VtrOpenRunner {'orientation': 'h', 'percentage':50}
# Opens new runner pane vertically split from the current vim session

<leader>t :VtrSendFile
# Sends current file to be run in attached runner pane
# will run file with appropriate command e.g. ruby <file>

<leader>va :VtrAttachToPane
# Menually attachs to an existing tmux pane

<leader>sl :VtrSendLinesToRunner
# Sends current line to runner for evaluation

Its a small thing, but it makes rapid development much easier. Especially when writing tests. Its definitely one of the little efficiency that makes complicated tools like tmux and vim worth learning.

So My Computer Exploded
>>

So My Computer Exploded

Something you never expect to be doing is wiping your hard drive ad 5pm on Friday. Its not as fun as it sounds.

When macOS Sierra was released a couple of weeks ago, I updated right away, because that is usually the kind of person I am. Everything seemed fine for the first couple of weeks. Record scratch. Cut to yesterday.

In the middle of the day, my laptop kernal panicked, an occurrence that is not uncommon with my aging MacBook Pro. But after it rebooted, I started having problems. We had a client demo today, so as the meeting was starting, there were some issues that came up that needed addressing. I went to run rails console to make some database changes and this is the error I got.

/usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/irb/completion.rb:9:in
`require':  /usr/local/lib/libreadline.so.6: undefined symbol: UP -
/usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/x86_64-linux/readline.so
(LoadError)
    from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/irb/completion.rb:9:in
`<top (required)>'
    from
/opt/mammie/web/icosole/vendor/bundle/ruby/2.1.0/gems/railties-3.1.3/lib/rails/commands/console.rb:3:in
`require'
    from
/opt/mammie/web/icosole/vendor/bundle/ruby/2.1.0/gems/railties-3.1.3/lib/rails/commands/console.rb:3:in
`<top (required)>'
    from
/opt/mammie/web/icosole/vendor/bundle/ruby/2.1.0/gems/railties-3.1.3/lib/rails/commands.rb:37:in
`require'
    from
/opt/mammie/web/icosole/vendor/bundle/ruby/2.1.0/gems/railties-3.1.3/lib/rails/commands.rb:37:in
`<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

I am not entirely sure what this even means. Something about not being able load the readline library or something. Definitely not the kind of errors I am used to. But it was scary. I’ve had similar problems with my rails environment before. I once spent an entire day debugging a nokogiri compilation error. But for some reason, no matter what I did, I could not get rails commands to execute.

I tried reinstalling Rails, I removed and installed all the versions of Ruby I had on my machine, I reinstalled rvm. I considered switching to rbenv. No result. My entire development environment was ruined. As the day went on, I got more worried that I would end up having to do a clean install of my operating system.

During the many times I attempted to reinstall everything, I finally spotted this error message when I was running brew install qt

This formula either does not compile or function as expected on macOS
versions newer than El Capitan due to an upstream incompatibility.

So qt, a gem required for my rspec workflow, does not support macOS Sierra. And that was that. I packed it up and went home, rebooted into internet recovery mode, erased my hard drive, and reinstalled OS X. (Sidebar: I had to install Mac OS X Lion at first and update from there, because that was the OS my Mac originally shipped with, and wow the does it look outdated. Sure it was 5 OSes ago, but it did not age well. There was something charming about it though. I almost considered staying in the old OS, but then YouTube wouldn’t even load in Safari, so that dream died).

All things considered, once I made the decision to just nuke everything and start from scratch, it went pretty smoothly. All my passwords are saved in a 1Password Account, my documents are in Dropbox, and all my code is stored on Github. So in terms of data, I didn’t lose anything but time. I had a Taskpaper checklist of applications that I needed to re-download. So all of that was tedious, but fine. What I really worried about was getting my development environment back up and running where it was before.

The good news was that this was a chance to get rid of the extra cruft from the couple of years since that last time I started my setup from scratch. For example, when I was in college, I wrote a lot of Java for classes, and now I got to delete all of the JVM and framework mess from my machine. Finally I am free of Java.

The downside of this was that I had started to experiment with being fussy about my configuration at a command line level. I had switched to zsh and started using tmux and vim. And because I am me, there was all kind of fiddly configurations that I made. Luckily, Thoughtbot saved my ass.

As I learn more about technology that I hope will make me a more effective web developer, I’ve been copying a lot from the setups of the developers I admire, and while browsing through the Github repos of people like Sean Griffin and Derek Prior, I found my way to the Thoughtbot Github page. Over the last few weeks, I’ve found a lot of helpful tools like Factory-Girl and Clearance on that page, but the repos that saved my ass this time were dotfiles and laptop. Dotfiles are a collection of config files (which conventionally start with a full stop) and the latter is a shell script that sets up and downloads all the dev tools you need for rails work.

I’ve been using the dotfiles repo for a couple of months now and keeping all my fiddly changes in my own fork. How this works is that the main dotfiles repo contains the base config file (zshrc for zsh, vimrc for vim etc.) which has some basic config, but the key here is that those base dotfiles load in a version of the same file with the .local post-fix at the very end. This allows you to add your own config to zshrc.local and have those settings loaded in after the default dotfiles. This maintains configurability while keeping a stable base to build on top of. Then all you need to do is run “rcup” which is a script that creates symlinks of all the files in the dotfiles directory and puts them in the home directory, with the proper dot prefix. After you run rcup, you can then continue editing your .local files, and the symlinks will keep everything up to date.

Between my fork of the dotfiles repo, and the scripts to setup the symlinks from the repo to your home directory, and the laptop script to install the tools I need, setting up a clean development environment couldn’t have been simpler. I had mentally blocked the entire weekend off for what ended up taking half an hour.

I know a lot of developers who run two or three year old versions of their operating systems. And now I understand why. I prided myself in being an “early adopter” but I think I am going to become one of those people who holds off on updating critical software until I know its safe. I will for sure be staying on OS X 10.11 for awhile. Its just not worth the risk anymore.

Also, a message to all devs everywhere: keep your configs in version control and have some script that sets up your dev environment. If you do, then if your computer explodes, you will be able to set up your new machine in hours, instead of days.

Authentication with Clearance
>>

Preamble

When I was writing this website, I knew that I needed some kind of authentication solution. If nothing else, I couldn’t have Internet randos posting stuff. My goals for putting this site together my #goals were to keep everything simple and custom. I wanted to learn as much as possible but have a functional website that wasn’t entirely vulnerable (I tried this many a time, but it never really worked out. I will have to tell that story one day). So I wanted more than security through obscurity, but I also didn’t want to have to waste time putting together a solution that was far more complicated than what I needed.

Act 1: “Authentication”

I’ve worked on maintaining a few projects with existing authentication implementations such as devise, but this was the first time I had to come up with my own solution. Previously, I had used Devise, and it felt a little overwhelming and unnecessarily complicated. I had some experience writing my own authentication model from going through Michael Hartl’s Rails Tutorial so I adapted an old Railscast solution for simple authentication.

Basically, it boiled down to a hard-coded password (groan) compared against a password input by the user (me) and stored in session storage.

class SessionController < ApplicationController

  def create
    session[:password] = params[:password]
    flash[:notice] = "Successfully logged in"
    redirect_to root_path
  end

  def destroy
    reset_session
    flash[:notice] = "Successfully logged out"
    redirect_to login_path
  end

end

This value stored in session would be then checked against the hard-coded password as a before_action (née before_filter).

before_filter :authorize, :except => [:index, :show]

This used a helper method authorize.

def admin?
  session[:password] == "j{XccXVhh=a2#KYqfUWWmy#,7v2h67" 
end

def authorize
  unless admin?
    flash[:error] = "Unauthorized access"
    redirect_to root_path
    false
  end
end

Obviously, there are many things wrong with this. Technically, this was enough for my needs, but all the problems nagged at me. It was my website’s Jacob Marley.

Act 2: Fixings

One of my favorite developer podcasts is The Bike Shed and every now and then, c0-host and Thoughtbot Development Director Derek Prior would talk about Clearance, an open source authentication engine that he maintains.

I don’t remember exactly when I had the idea to look at Clearance, but in retrospect it seems obvious.

From the README:

Clearance is intended to be small, simple, and well-tested. It has opinionated defaults but is intended to be easy to override.

Sounds about right.

After adding Clearance to my Gemfile and running bundle, there was almost only one step to get it up and running.

rails generate clearance:install

When the install script finishes running, it gives you some next-steps, mainly configuring the ActionMailer email addresses, and running db:rake.

That is basically it. Simple right? Right. I love it. Its basically just a couple standard models, controllers, and routes with good encryption (at least more encryption than I was doing before).

Act 3: I’m fussy

At this point, I have a sign_in form, and a sign_up form. The before_action statements pretty much look the same.

before_action :require_login, except: [:index, :show, :feed]

The only problem is that I don’t want the aforementioned Internet randos to be able to sign up for an account and then post on my site at will. That wouldn’t have solved the problem, just added another step.

So I braced for the oncoming struggle. My experience with other frameworks and languages have trained me to think that when you need something done differently than your third-party library is doing, its never an easy process. I ran the commands to dump the default views and routes into my application, thinking I would need to remove the button from the view and do some kind of meta-authentication to prevent sign ups. I was thinking something with IP addresses. It was not going to be pretty.

Luckily, Derek (and the Rails community at large) are not like those other languages and the solution to my problem was one line.

Clearance.configure do |config|
  config.allow_sign_up = false
end

Okay, that is technically three lines, but you get the idea. Setting allow_sign_up to false made everything just right. I create!‘ed a new User in the console, and that was that.

In (short) Summary

I’ve heard a couple times that when you are blogging, you should write to yourself two weeks ago and write about what would have helped you then. Well this falls into that category. If I had known about Clearance when I was starting work on this site, I would have saved a lot of time and hassle. If you need email and password authentication in your Rails app, and don’t need a solution as complex as Devise, then you should really check out Clearance.

On Salesforce/Twitter
>>

So, today there was some talk online about Twitter being close to accepting bids for sale. And among those potential buyers: Salesforce. FFS.

Salesforce, for those lucky enough to be unaware, was originally a CRM platform that basically claims to have invented the cloud, and has since expanded into a more generalized computing platform. Recently, they have been on a bit of an acquisitions spree so its not out of the question that they would be buying Twitter, although it would be laughably bad.

On a personal note, this would be the worst possible outcome. Okay, maybe the second worst next to Facebook. I care less about who buys Twitter. Like Marco says in some of his later tweets, Google, or whoever, will probably run Twitter better than the current leadership. Hell, maybe Google will do what they did with YouTube, and monetize the hell out of it and start editing content to be more “Ad Friendly”, which is barf but Twitter could use some content editing.

Anyway, digression. What really bothers me is the Salesforce side of things. If Salesforce buys Twitter, I might as well just quit the Internet.

At my Joby-Job, I work in Salesforce a lot. In fact, I have a Salesforce login window open as I write this. The bottom line of my feeling is this: if Salesforce buys Twitter, their products would dominate both my professional and personal life.

I use Salesforce (unwillingly) at work, I host my websites (both personal and for clients) on Heroku (owned by Salesforce), I used to be a Quip user (now owned by Salesforce). I value Twitter. It can be a real mess sometimes and its downright dangerous to be a women on twitter. But I find value in it. Is a window into the lives of people who I find interesting or follow in other contexts. I follow mostly podcast hosts and software developers. So I enjoy it. Its one of my most important social interactions. If that is controlled by Salesforce, I might lose my mind. I know its unlikely, but the fact that it is part of the conversation is alarming to me.

Why can’t Salesforce just buy companies that I don’t like?

What the Hell is Enterprise?
>>

A couple of months ago, a former intern at my job-y job brought their sister’s into the office to visit. They were in town and it was the usual coming to see where their sibling worked kind of stuff. They asked us what we studied in university. My boss gave his explanation about his engineering and science background. I had to think for a second. I had graduated maybe two weeks earlier. I explained my major as it appeared on my degree “BS in Computer Science with a Concentration in Software Engineering.” Fine. But inferiority complex. So I say this. “I specialized in cloud-based enterprise application development.” Later: I thought, “What does that even mean?”

So, “Enterprise”

In most of the internet circles I run in, if you mention “enterprise” to someone, they will probably cringe. And judge you. Even I throw up in my mouth slightly when I think about enterprise software. Let alone say its my speciality. It’s such a nebulous term with no clear or easy definition. What are the mental associations of enterprise software? Companies like Oracle or Microsoft? What determines what is Enterprise software? Multiple people using it? A lot of people use Facebook. Is Facebook Enterprise software? Probably not. Is all enterprise software cloud-based? Is all cloud-based software enterprise software? Also, probably not. What the hell even is enterprise software?

On Scaling

What is the part of software that scales the worst? Network bandwidth is pretty good. Moore’s Law has pretty much taken care of local machines feeling slow. These days, I would argue that the limiting factor of computing ability is battery and storage. If a business needs software to meet the needs of the entire organization, they are going to quickly hit thermal and storage limits if each of their employees run a local application that saves data to disk. It sounds ridiculous to put it this way, but that is because it is ridiculous.

Local file storage is fine if you are a designer working in the Adobe suite or a developer in your local environment, but at a certain scale, having your work save to disk stops working. And so we started connecting our applications to databases, which can store offsite, structured data in a way that is both scalable and easy for application developers to work with.

Enterprise software is just a CRUD to a database with maybe some extra computing steps thrown in. Then what is the difference between big, boring Enterprise software and more attractive apps that are coming out of start-ups the world over? Facebook (while not the best example) is just CRUD to a database (or many many databases). So what is the difference? Perception maybe.

Dear Myke and Casey
>>

Dear Myke and Casey,

As I write this, I am listening to the Squarespace ad in Analog(ue) 75 which took place immediately after the discussion of Becky Hansmeyer’s blog post about how more and more of the people she enjoys following on Twitter are moving their conversations to Slack, where they are more private.

While much of my experience and feelings are similar to Becky’s (My life is hectic and don’t have much time to make many friends with similar interests and hobbies) I have at least one counterpoint to her post.

Most of the interesting people on the internet that I enjoy following are on podcasts, and podcasts are at their best when it feels like listening in on a couple of friends talking about interesting topics. As popular as shows like Serial and 99% Invisible are, I still find the most joy out of the conversational shows. Whether its getting deep with you guys on Analog(ue), or the rambunctious groups of the Incomparable family of shows, I feel incredibly fortunate to be able to observe these little snippets of the lives of some interesting people who I admire.

I could ramble for awhile (I am maybe even a little obsessive about podcasts) but the point is, you (and all people) are entitled to their private lives. You are already giving up so much of your life by putting it into the public sphere every week when you put out a podcast.

So maybe my Twitter timeline is a little sad, but thats okay, I’ll just put on a podcast.