Tools for Developer Productivity

Published by Michael de Silva on Thursday, 12 March 2015


Here are some recent additions that I've made to my dev workflow.

HTTPie: a CLI, cURL-like tool for humans

https://github.com/jakubroztocil/httpie

Pick

https://github.com/thoughtbot/pick

Here's one of the OhMyZSH aliases I've made,

git_stash_apply(){ git stash apply $(git stash list | pick | awk 'NR==1{printf $1}' | cut -d : -f 1,3) }


Code & Tech

Mixing in Namespaced Classes in Ruby, a Template Method implementation

Today I was searching on a means for mixing in a namespaced class into another class and stumbled onto a gist of mine that I had saved back in October 2013.

Here's w ...(continued)

Graceful locale-based content fallback in RefineryCMS

This hack took me through the refinerycms-i18n gem, and I discovered that it does not aid in achieving graceful content fallback, amongst other issues.

It should b ...(continued)

'DevOps': Killing the Developer?


Screen%20shot%202014-08-07%20at%2000.39.03

Preamble

I started this week sorting out some widgets for a couple code bases that I am looking after at work. One's a legacy CMS app (Ruby 1.8.7/Rails 2.x) th ...(continued)

DevOps

Simple Scalable Infrastructure with DigitalOcean, Terraform, and Docker


Img_20141102_025514

While my primary system is a Ma ...(continued)

'DevOps': Killing the Developer?


Screen%20shot%202014-08-07%20at%2000.39.03

Preamble

I started this week sorting out some widgets for a couple code bases that I am looking after at work. One's a legacy CMS app (Ruby 1.8.7/Rails 2.x) th ...(continued)

Getting to Grips with Chef via Knife-solo, Berkshelf, and Vagrant ~ Part One

To get started, I've put together an example chef-repo (a.k.a 'kitchen') chef-server-with-vagrant, which was set ...(continued)


There's More to Ruby Debugging Than puts()

Published by Michael de Silva on Friday, 27 February 2015


This is a worthwhile read, There's More to Ruby Debugging Than puts().

One of the most useful has been #method, with #source_location, #arity, #to_proc etc. I regularly work with Rails 4.2 and Ruby 2.2 — as such my debugger is byebug with pry-byebug.

A Treatise on Resolving Module Dependencies with ActiveSupport::Concern#append_features

Published by Michael de Silva on Tuesday, 17 February 2015


Here's a quick script to play with which details the process by which ActiveSupport::Concern resolves module dependencies by hooking into Method#included, Method#extended, and Method#append_features.

I'll include a snippet of the full-source below, which at least contains the gory details on internal mechanics. You'll find it far more useful to read this and then compare it with the output of my script excuting rails runner lib/scripts/concerns.rb, which gives a sense of context as to which bits are eval'd first

# Notice how module B's dependency on D is resolved by `ActiveSupport::Concern`
module B
  extend ActiveSupport::Concern

  @_dependencies = [D]

  def self.append_features(mod)
    super
    puts "B.append_features: mod=#{mod}, self=#{self}\n\n"
  end

  def self.included(mod)
    super
    puts "B.included: #{self} included in #{mod}\n\n"
   ...(continued)

Nygma - Signing and encrypting data with tools built-in to Rails 4

Published by Michael de Silva on Saturday, 29 November 2014


Screen%20shot%202014-11-29%20at%2013.57.27

Having stumbled on Signing and encrypting data with tools built-in to Rails I was quite pleased to see this approach use the same tools that Rails uses for encrypting the user session (cookie).

This lead me to building Nygma to allow encrypting tokens received from Stripe. Since this was built rather quickly, I haven't been able to document its API as I normally do, but I will be cleaning this up in due course.

For those curious engineers amongst us, Rails' encrypted cookie implementation looks like

    class EncryptedCookieJar #:nodoc:
      include ChainedCookieJars

      def initialize(parent_jar, key_generator, options = {})
        if ActiveSupport::LegacyKeyGenerator === key_generator
          raise "You didn't set config.secret_key_base, which is required for this cookie jar. " +
             ...(continued)

Mixing in Namespaced Classes in Ruby, a Template Method implementation

Published by Michael de Silva on Saturday, 22 November 2014


Today I was searching on a means for mixing in a namespaced class into another class and stumbled onto a gist of mine that I had saved back in October 2013.

Here's what I implemented today, and you'll find a link to the original Gist at the end of this post.

The essence of the approach is to simply call const_set on the base class, _klass, and in this example setting that constant to class of interest via Class.new(ClassOfInterest).

You would also see this being used in specs such as

MyFancyException = Class.new(StandardError)
raise MyFancyException

In this context, the receiver, self is in fact the class in which you call the above, so self.MyFancyException = Class.new(StandardError) would also be perfectly fine, although not strictly idiomatic Ruby, as most often the receiver is implicit.

module Snowden
  module Utility
    extend self

      class Response
        attr_reader :error_message

        def initia ...(continued)

Simple Scalable Infrastructure with DigitalOcean, Terraform, and Docker

Published by Michael de Silva on Monday, 03 November 2014


Img_20141102_025514

While my primary system is a Mac, I like to keep my development workflows as linux dependent as possible. Therefore, rather than relying on tools such as boot2docker, I setup a custom image of Ubuntu 14.04 with various tools installed along with Docker 1.3 using Packer

My build template can be found on Github. My workflow from this point onwards is to simply start my customised version of Ubuntu via vagrant up and ssh vagrant@10.33.33.33.

Docker Build

Last weekend, I focused on creating a docker build for Rails, Nginx, and Unicorn with a MySQL data store. My aim at the time was to build a proof of concept, so I broke this down into several sessions ...(continued)

Graceful locale-based content fallback in RefineryCMS

Published by Michael de Silva on Monday, 13 October 2014


This hack took me through the refinerycms-i18n gem, and I discovered that it does not aid in achieving graceful content fallback, amongst other issues.

It should be noted this bit of work focused on Refinery v2.0.9 and may not be entirely applicable with the current release.

My solution involved adding the following decorator,

puts "Overriding Refinery::Page - #{__FILE__[/(vendor[\/\w\.]+)/]}"

Refinery::Page.class_eval do

  # The `Refinery::Page.find_by_path_or_id` call in
  # `Refinery::PagesController#find_page` calls `Refinery::Page.find_by_path` if
  # `params[:path].friendly_id?` is true.
  #
  #   # With slugs scoped to the parent page we need to find a page by its full path.
  #   # For example with about/example we would need to find 'about' and then its child
  #   # called 'example' otherwise it may clash with another page called /example.
  #   def self.find_by_path(path)
  #     split_path = path.to_s.split('/').reject(&:blan ...(continued)

Inside the Shellshock Vulnerability: The 25-year old Bash bug

Published by Michael de Silva on Saturday, 04 October 2014


You'll find posts such as "Everything You Need To Know About The Shellshock Bug" covering the basics of the bug and how to locally test it out on your, Mac or linux desktop. TL;DR — give this a spin

-> % env X="() { :;} ; echo vulnerable" /bin/sh -c "echo stuff"
vulnerable
stuff

Notice how my Mac is infact vulnerable to this. But how do attackers leverage this against web servers running say, Apache?

Cloudflare have a fantastic write up Inside Shellshock: How hackers are using it to exploit systems providing simple examples that anyone can try via curl.

For example, take this

curl -H "User-Agent: () { :; }; /bin/eject" http://example.com/

Apache internally creates a variable HTTP_USER_AGENT=() { :; }; /bin/eject but this would only work if this variable is passed to bash. This article runs into various int ...(continued)

Better Productivity with Tmux, iTerm2 and Tmuxinator

Published by Michael de Silva on Saturday, 13 September 2014


http://www.railsonmaui.com/blog/2014/03/11/rocking-with-tmux-tmuxinator-and-iterm2-for-rails-development/
https://gist.github.com/MohamedAlaa/2961058
https://gist.github.com/andreyvit/2921703

On Holiday...!

Published by Michael de Silva on Thursday, 21 August 2014


I don't always go on holiday, but when I do

class Resource < Struct.new(:employee)
  define_method(:enable_vacation) { "Whoo! Employee '#{employee.handle}' is on holiday!!"}
end

Resource.new(
  Object.new.instance_eval { self.class.send(:define_method, :handle, ->{'@bsodmike'}) }
).enable_vacation

# => "Whoo! Employee '@bsodmike' is on holiday!!"

Blog: Upgrading to Ruby 2

Published by Michael de Silva on Saturday, 09 August 2014


Today I decided to upgrade this blog to Ruby 2+ and along the way noticed my VPS was running 1.9.2 and one of the dependencies needed at least 1.9.3.

So I set about removing RMV via rvm implode; then performing a system-wide re-install

curl -sSL https://get.rvm.io | sudo bash -s stable

This was followed by installing the new version of ruby and installing Passenger

gem install passenger
passenger-install-apache2-module

From this point, it was simply a matter of following the instructions for updating Apache's passenger.load and passenger.conf files with the path to the new ruby (installed in /usr/local/bin/rvm), and restarting the Apache service.