Lover of all things beautiful

Create a file in Vim Jul 11 2014

There are two primary was to work with the filesystem while in Vim. These two tools will allow you to create a new file, create a new directory, copy files, delete files and folders. Everything you need.

The built in File Explorer.

To use this built in file explorer, just think :Sex, that’s right Sex. This will open up the built in file explorer in a buffer and allow you to naviate around the filesystem. It can open up files on remote systems too by using SFTP, and other remote file reading tools. Some commands you can use

D      Delete a file/folder
R      Rename a file/folder
d      Create a directory
%      Create a folder

A better way

If you’ve been using Vim for more than a day, you should have already installed the NERDTree plugin. It’s pretty much indispensable. You can use NERDTree to navigate around the filesystem and open up files, but you can also, create, copy, move, and delete files and folders really easily with NERDTree.

So open the NERDTree sidebar, then put the cursor over a file and press the m key. A menu like the one below will appear at the bottom of the screen.

NERDTree Menu. Use j/k/enter and the shortcuts indicated 
==========================================================
> (a)dd a childnode
  (m)ove the current node
  (d)elete the current node
  (r)eveal in Finder the current mode
  (o)pen the current node with system editor
  (q)uicklook the current node
  (c)opy the current node

From here you can press a to add a file in the same directory. Type the name of the file and press enter. BAM! Try it out, you’ll love it.

Read More

Using Environment Variables in Node.js with Amazon OpsWorks May 6 2014

I find it hard to believe that I could not find a good article online of how to get env vars working in OpsWorks. I think even more astounding is that it takes a custom recipe to accomplish this end. When you host your app on Heroku, you can easily just do an heroku config:set FOO=bar with the Heroku Toolbelt. In AWS OpsWorks, it’s a little more involved. Let’s see just how.

The Key Elements

Add a Custom Chef Cookbook to your Stack Settings

Here you are going to have to go to your Stack Settings and Edit them. You will see a section to Use custom Chef cookbooks. In this section you are going to choose git as the repository type and https://github.com/vlamic/OpsWorksEnvy.git as the repository URL. NOTE: You are more than welcome to fork this repo and use your fork.

Config Management

Add your JSON

Now while we are in the Stack Settings, we’ll add our Custom JSON that will specify our environment variables. Replace the information below with your own. NOTE: There are two sections below, one for the server instance, and one specifically for each App

{
  "environment_variables": {
    "NODE_ENV": "production"
  },
  "deploy": {
    "THE_SHORT_NAME_OF_YOUR_APP": {
      "environment_variables": {
        "NODE_ENV": "production",
        "PORT": 80,
        "mongoUri": "mongodb://xxxx",
        "adminUsername": "admin",
        "adminPassword": "password",
        "s3Key": "XXX",
        "s3Secret": "XXX",
        "s3Bucket": "BUCKET",
      }
    }
  }
}

Integration Custom Recipe into your Layer.

I think this was the hard part for me since I’m not real familiar with Ruby or Chef. Go to Layers, then Recipes, then Edit. Now you want to add environment_variables::default to the Deploy section. Then press the + to add it. When you are done, it will look like this.

Custom Recipe

Deploy your App

Now when you deploy your app, those variables will be in process.env. Use these like a boss and have pity on those that include passwords and such in their app source code.

One More Thing.

This is a plug for the best friend of your Environment Variables, the Node.js module nconf. It makes using these variables in your app a snap. I usually have it set up like this in my apps. That way you can easily provide env vars in a gitignore’d file in your app directory.

// Load config vars from commandline, ENV, file, and defaults
nconf.argv()
     .env()
     .file(YOUR_APP_ROOT_DIR/.env.json)
     .set('VERSION', pkg.version);

Just to be sure, I have this in my .gitignore file to ignore anything that starts with .env...

.env*

Happy Camping.

Read More

Deploy Web App with Grunt Compiled Assets to Heroku Apr 22 2014

The conundrum is how do you deploy a web app to Heroku that needs to be compiled without including compiled files in your source?

Maybe you have some SASS that needs to be compiled into CSS. Maybe you want to minify your Javascript, or cache bust with some appended hash tags. In any case you want to run some tasks on your code to produce your distribution or build.

Here are some options.

Just include them in your your source code

This is the least desirable, but you could just include your dist or build folder in your source code. This gets to be messy as you will have compiled assets in your source code and if you have multiple people deploying you will get merge conflicts and what not. Only use this if you’re nuts.

Have Heroku compile them for you

You can do this by including all your devDependencies in your dependencies in your package.json file. Then have a Grunt task for compiling that is hooked to npm prepublish. Here is an example that will run grunt --env production on Heroku when Heroku runs npm install.

"scripts": {
  "prepublish": "grunt --env production"
},

This works, but the drawbacks are having to include all those devDependencies in your code and then having Heroku download them and run. My Grunt tasks are kind of elaborate, so this becomes a pain for me. This can blow up in your face in the rare instance that npm is having issues :D.

Use a local distribution Git branch

This is a strategy I’ve started to use and works pretty good. It uses a local branch to add commit your compiled assets to Heroku, but doesn’t pollute your main branches (master and develop). Here is how it goes.

Setup

  1. Your dist or build folder is listed in .gitignore so that the files there are generally ignored by git.
  2. You create a branch that is used just to compile and push to heroku.

    git checkout -b dist
    
  3. Run your Grunt task to create your distribution files

    grunt buildprod
    
  4. In that branch you force git to include all the dist or build files that your Grunt task just made

    git add -f ./dist
    git commit -m 'Adding dist files'
    
  5. Now you can deploy to Heroku using the dist branch to push like this. This command tells git to push the local dist branch to the remote heroku branch of master. We use force.

    git push heroku dist:master --force
    
  6. Now your files are on Heroku and have the compiled version

Updating Heroku

  1. Back on your develop branch you do a bunch of work, commit, etc.
  2. When you get ready to deploy again you will checkout your dist branch, then rebase against your develop branch

    git checkout dist
    git rebase develop
    
  3. Run your Grunt task

    grunt buildprod
    
  4. Add newly created dist files

    git add -f ./dist
    git commit -m 'Adding dist files'
    
  5. Now you can deploy to Heroku using the dist branch to push like this. This command tells git to push the local dist branch to the remote heroku branch of master. We use force.

    git push heroku dist:master --force
    
  6. Now your files are on Heroku and have the compiled version

Somethings to keep in mind, you can change these values to match your environment.

  1. My remote is called heroku
  2. My local branch for deploying to heroku is called dist
  3. My local folder that holds compiled assets is in ./dist
  4. I originally created the branch dist from develop, use master if that’s your gig.
Read More

Essential Node.js Development Concepts, part1 Apr 14 2014

Every project tends toward insanity, it’s your job to Keep it Sane, Stupid.

This is the first in a multipart series on Node.js concepts that I consider to be essential to writing sane web apps. You already know how to Node and now it’s time to get serious about building apps. The problem you’ll run into every growing project is complexity. These concepts will help you keep things sane.

Fat Models, Skinny Controllers

Somewhere back in my PHP days while working with Zend Framework I read an article that talked about keeping your controllers small and put all your work / logic in your models. This rings true in every language / framework that I have encountered. Let’s see why.

// Don't do this, this is a Fat Controller
exports.controller = function(req, res, next) {

    var id = param('id');

    // Look up doc in DB
    Model.find(id, function(err, doc) {

      var data = req.body;
      var error = null;

      // validate input
      if (!data.name) {

        // Assign an error
        error = 'Missing name';
        return res.send(400, error);

      } else {

        // Set new data
        doc.set(data.name);

        // Save to db
        doc.save(function(err, doc) {
          if (error) {
            return next(error);
          } else {
            res.send(200, doc)
          }
        });

      }
    }
}

There is so much bad in this example, not just a Fat Controller.

Testing Controllers is hard

Controllers are hard to test, in fact I would say near impossible to unit test. It takes an integration test to see if your controllers are operating as you expect.

To unit test this controller you’ll first going to have to stub out req, res, and next. You’re going to have a DB set up to hit because there is no way to stub out the Model object in this piece of code, so it’s going to hit the DB. We’ll now you’re going to have seed the DB with a document that matches the id we are trying to update.

See how what should be a simple unit test has erupted into a whole lot of setup?

Controllers also offer no opportunity for reuse.

Take the above controller. What if we wanted to use this code in another controller? You’d end up replicating the code in another controller (and it’s crazy unit testing).

Rules of Thumb

  1. All functions (Controllers especially) should not be more than a screen size. Preferably only 5-15 LOC.
  2. Controllers should have very little logic in them. They gather data (from input), pass it off to a Model, receive a result and write that to output.

So with these new Rules of Thumb to code by, how do we redo this example.

// Do this, this is a Skinny Controller
exports.controller = function(req, res, next) {

    var id = param('id');

    // Look up doc in DB, let the model validate and handle errors
    Model.updateName(id, req.body, function(err, doc) {
      if (err) return next(err); // Early return, an awesome design pattern.

      // If we've made it here, it's all good
      res.send(200, doc);

    });

}

In this example, the Model layer is doing all the work of validating, error checking etc. This function is so simple it doesn’t warrant a unit test.

So we’ve seen how to put a Fat Controller on a crash diet to become a Skinny Controller. Stay tuned for the next part in the series as we go over the 12 Factor App rules in our Node.js apps.

Read More

Using GulpJS, Browserify, and Watch for AngularJS Development Feb 5 2014

That’s quite a mouth full, but in a nutshell we just want to develop AngularJS and have Gulp watch our files and recompile them when they change.

var gulp       = require('gulp'),
    _          = require('lodash'),
    fs         = require('fs'),
    nodemon    = require('gulp-nodemon'),
    ini        = require('ini'),
    config     = ini.parse(fs.readFileSync('./.env', 'utf-8')),
    concat     = require('gulp-concat'),
    uglify     = require('gulp-uglify'),
    htmlMin    = require('gulp-minify-html'),
    browserify = require('gulp-browserify'),
    clean      = require('gulp-clean'),
    watch      = require('gulp-watch'),
    ngHtml2Js  = require('gulp-ng-html2js');

gulp.task('default', function(){
  // Update process.env with our .env values
  _.assign(process.env, config);
  nodemon({
    script: 'index.js',
    options: '-e html,js -w lib'
  });
});

gulp.task('clean', function(cb) {
  gulp.src('./build')
    .pipe(clean({
      force: true
    }).on('end', function() {
      cb();
    }));
});

gulp.task('ng', ['clean'], function() {
  buildTemplates("./public/src/**/*.tpl.html", "partials.min.js", "./build/js/");
});

gulp.task('copy', ['clean'], function() {
  copyIndex();
});

gulp.task('bundle', ['clean'], function() {
  buildAppJs('public/src/app.js', './build/js');
});

gulp.task('build', ['ng', 'copy', 'bundle']);

gulp.task('watch', ['build'], function() {
  gulp.src('public/**')
    .pipe(watch(function(files) {
      buildAppJs('public/src/app.js', './build/js');
      buildTemplates("./public/src/**/*.tpl.html", "partials.min.js", "./build/js/");
      copyIndex();
    }));
});

function copyIndex() {
  return gulp.src('public/index.html')
    .pipe(htmlMin({
      empty: true,
      spare: true,
      quotes: true
    }))
    .pipe(gulp.dest('./build/'));
}

function buildAppJs(files, outfile) {
  return gulp.src(files)
    .pipe(browserify())
    .pipe(uglify())
    .pipe(gulp.dest(outfile));
}

function buildTemplates(src, file, dest) {
  return gulp.src(src)
      .pipe(htmlMin({
        empty: true,
        spare: true,
        quotes: true
      }))
      .pipe(ngHtml2Js({
          prefix: "/"
      }))
      .pipe(concat(file))
      .pipe(uglify())
      .pipe(gulp.dest(dest));
}

But what does it all mean ???

Glad you asked. Let me break some of the essential parts down.

We are going to run gulp watch. That will set the task watch in motion. As you see it’s going to run the build command first. This build command will run ng, copy, and bundle, which all of them will wait until the the clean task runs.

  1. clean empties the ./build folder
  2. ng creates builds the AngularJS templates (stores them in the templateCache)
  3. copy this just copies the index.html into ./build
  4. bundle this runs browserify on our AngularJS files and spits it out to ./build
  5. watch will first run all the above to set things up, then it will watch all the files under public/** for changes. When it sees a change it will run the tasks again (except for clean)

I should note that my default task just runs nodemon

Read More

Open current file in Chrome with Vim Dec 5 2013

Most of the time when I’m working on a Markdown document like a README, I want to preview it in Chrome as markdown. Perhaps I’m working on an HTML document and want to preview it in Chrome. It would be a real pain to go to Chrome and then look for the file I’m working on. Luckily Vim makes this really easy.

The Setup

Add this to your .vimrc

" Open up current file in chrome
nmap <silent> <leader>ch :exec 'silent !open -a "Google Chrome" % &'

(Optional) Add a Markdown viewer to Chrome. I use Markdown Preview Plus.

Now in Vim you just need to enter these commands in Normal mode (hint: my <leader> is ,)

,ch[Enter]

That’s all there is to this. It allows you to simply open the current file in Chrome.

References

Read More

iTerm open tab in current working directory Dec 3 2013

I can’t believe I lived so long without looking for a fix to a common issue I have while in iTerm2. Maybe I’m running some GruntJS task that is updating the screen, but I want to do something in the CWD. So I would open another tab ⌘ + t, then cd ... to my cwd.

Instead just tell iTerm you want new tabs to open in the CWD.

  • Open up iTerm2 preferences ⌘ + ,
  • Go to Profiles > General
  • Now click on Edit under Advanced Configuration for Working Directory
  • Now just select when you want it to open in the same directory like so

Now you have an extra 10 seconds a day to do with whatever you want…. live the freedom.

Read More

Instant Messanger Clients Compared Nov 23 2013

Instant messangers are so vital to communcation on the web these days, both in and out of an organization. Let’s take a look at some of the popoular ones out there with their pros and cons. As we compare them, we’ll consider cost, features, portability, and easy of use.

Google Hangouts

Gtalk has been sort of reborn as Hangouts. This web based solution has even just recently had another update that makes it very appealling for group video chats. With hangouts you can contact anyone that has a Google account. Hangouts also supports third party pluggins that help do things like record a video chat session or have your name appear below your video like a news caster does on TV. Screen sharing in Hangouts works great while on a video call.

Pros

  • Ubiquity of the Google network (many people have at least one Google Account)
  • Great video chats right in your browser
  • Free

Cons

  • Poor support for chat rooms and being able to see the history of a chat room.
  • Video chat is browser based, this is a con in my opinion

Campfire

Campfire was developed by 37Signals and integrates well with their products. Campfire was very early on, offering web based chat. You can drag and drop images right into the chat and they are preserved there for reference. I’ll be honest, I’ve only really played with Campfire

Pros

  • Web client

Cons

  • No voice or video, just plain old text chat

HipChat

HipChat and Campfire have a lot in common, but HipChat goes well beyond Campfire. HipChat has a web client as well as native clients for Windows / OS X / iPhone / Android.

Pros

Cons

  • It’s easy to miss undread messages as it does not track these like other instant messaging service.

Skype

Pros

Cons

Read More

Javascript Casting Tricks Oct 22 2013

Here I want to go through some casting tricks that can be used for better data manipulation.

Booleans

Build in Boolean()

The easiest way is to use the builtin Boolean() method.

Boolean('true'); // true
Boolean(1); // true

Boolean('false'); // true !!!!GOTCHA!!!!!
Boolean(0); // false

// Careful
Boolean([]); // true

Double Negative

This will cast anything as either true or false, there are of course a few quirks that may not be obvious.

// FALSE
!!false;
!!null;
!!undefined;
!!0;
!!'';

// TRUE
!!true;
!!'true';
!!1;
!!-1;
!!{};
!!function(){};


// GOTCHA!!! ... TRUE
!!'false';

JSON.parse

This will parse the text 'true' to the boolean true

// TRUE
JSON.parse('true');

// FALSE
JSON.parse('false');

// If using a variable, you'll want a fallback
JSON.parse(undefined || 'true');
JSON.parse('' || 'true');

Numbers

Check for a decimal using modulo

5.5 % 1 != 0; // true
5 % 1 != 0; // false

Reference: http://stackoverflow.com/a/2304062/179335

Strings

Built in tools toString() and String()

var hello = String('hello')
10.0.toString();

Casting an Array as a String

Strings are of course mostly just an array of characters so arrays and strings have a lot in common. You can cast an array to a string simply by joining them with nothing.

var hello = ['h', 'e', 'l', 'l', 'o'];
hello.join('');  // Yields "hello"

Convert from an Array to a String

Strings can be converted to an array easily using split. Here’s how.

var hello = "hello";
hello.split('');  // ['h', 'e', 'l', 'l', 'o'];

Arguments

In Javascript the arguments object in a function is array like, but to convert it to an actually array you can just use a simple trick.

Array.prototype.slice.call(arguments);

Or more simply if Array generics are available (like in node.js).

Array.slice(arguments);

Have one to add? Comment below.

Read More

They shoot email, don't they? Oct 8 2013

So the year is 2013, you send an email off to two coworkers and cc four other people in the company. Think for a minute the utter black hole of despair you just created for six people. Six poor souls now have to read your email and file it away. Let’s take a look at what you’ve set in motion.

Read More