Shell commands with Node

Running CLI Node scripts, capture the return value of a shell command:

const execSync = require('child_process').execSync;
const nodeVer = execSync('node -v', { encoding: 'utf8' });

Shell command reports in the CLI:

const execSync = require('child_process').execSync;
execSync('npm -g ls', { stdio: 'inherit' });

Colored Console Output

const out = {

  end: '\x1b[0m',

  // Modifiers.
  blink: '\x1b[5m',
  bright: '\x1b[1m',
  dim: '\x1b[2m',
  hidden: '\x1b[8m',
  reverse: '\x1b[7m',
  underscore: '\x1b[4m',

  // Foreground Colors.
  black: '\x1b[30m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
  green: '\x1b[32m',
  magenta: '\x1b[35m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  white: '\x1b[37m',

  // Background Colors.
  bgBlack: '\x1b[40m',
  bgBlue: '\x1b[44m',
  bgCyan: '\x1b[46m',
  bgGreen: '\x1b[42m',
  bgMagenta: '\x1b[45m',
  bgRed: '\x1b[41m',
  bgYellow: '\x1b[43m',
  bgWhite: '\x1b[47m',
};

Usage:

console.log(out.red, 'Something went wrong:', err, out.end);

Validate the Crickets’ Nest

I have a problem getting values from deeply nested objects: if one of the properties along the namespace is incorrect|modified|removed, Javascript throws. To avoid this, you can end up with obnoxious validation:

// Trying to get this.data.homeScene.user.name
const isValid = (
  typeof this.data === 'object' &&
  typeof this.data.homeScene === 'object' &&
  typeof this.data.homeScene.user === 'object' &&
  typeof this.data.homeScene.user.name === 'string'
);
if (isValid) {
  const { name } = this.data.homeScene.user;
  ...
}

What if I made a reusable helper to validate the namespace and return the value?

export default function getNamespace(startObj, path) {
  const isValidArgs = (
    typeof startObj === 'object' &&
    typeof path === 'string'
  );
  if (!isValidArgs) return undefined;

  const finalValue = path
    .split('.')
    .reduce((obj, p) => ((typeof obj === 'object') 
      ? obj[p]
      : undefined
    ), startObj);{

  return finalValue;
}

Now the obnoxious validation looks like this:

// Trying to get this.data.homeScene.user.name
const name = getNamespace(this, 'data.homeScene.user.name');
if (name) { ... }

Dude! Sweet!

Alias for Git sanity

Git command line is pretty confusing. Here are some aliases that I found helpful that normalize it with other command line commands and add a little bit better context.

Open global .gitconfig file:

$ open ~/.gitconfig

If there isn’t an [alias] section already, add one:

[alias]
  cd = checkout
  ll = branch
  ls = branch
  delete-merged = !git branch --merged | egrep -v \"(^\\*|master|development)\" | xargs git branch -d
  mk = checkout -b
  new-up = !git push -u origin `git symbolic-ref --short HEAD`
  stage = add
  unstage = reset HEAD

Update 2018-07:

To set VS Code as the default editor for commit and merge messages:

[core]
  editor = code --wait