Home

Awesome

NPM

Build Status img img img

kody

alt tag

An interactive .files and environment configuration tool created with node

Inspired by Zach Holmans popular dotfiles, stripped down and written in node

alt tag

Index

What is kody

kody is more than a dotfiles installer. Out of the box, it can handle symlinking your version controlled files to a desired directory. It will also backup your originals if you wish 👍

But it can do much more! And it's up to you how creative you want to get 🐻

You create some tasks to set up your machine, run kody, and kody will go ahead and run the tasks you tell it to!

What else would I use it for

You can use kody to automate most things.

For example, fed up of installing a bunch of apps when you set up a machine? Create a small task to install homebrew, configure a list of apps you want and tell kody to do it for you! 😉

Or how about automating your shell configuration or IDE set up! They can be time consuming 😅

You can see some examples in the examples section below 👍

Installation

You'll need to install node/npm first as this is a dependency of kody. Then, install kody globally 👍

npm i -g kody

Usage

Installing Dotfiles

Out of the box, kody comes with dotfile installation. kody will symlink your version controlled dotfiles to a directory of your choosing. The default is $HOME.

kody needs to know which files to symlink. So any files or directories you wish to symlink should have the suffix .link.

For example; I want to install a dotfile for a .gitignore file. Rename your version controlled .gitignore to .gitignore.link and then run kody in that directory. The same works for directories if you want to symlink the contents of a directory.

/my/version/controlled/dotfiles/repo/.gitignore.link -> $HOME/.gitignore

kody will also prompt you to see if you'd like to backup your original dotfiles. It will backup the original to the same destination with the .bak suffix.

That's all you need to manage and install your dotfiles 💪

Tasks

Now the fun starts! 😉

You can also use kody to automate various defined tasks.

Let's start with the basics.

By default, all tasks live inside a kody.tasks directory. You can configure this (we will get to that). kody will search the directory for all the JavaScript files it can find. You can nest tasks.

Each task file exposes an object that must consist of at least a name and an exec function. The description property is metadata to give a friendly description of tasks. description will be rendered when choosing which tasks to run.

module.exports = {
  name: '🦄',
  description: 'A truly magical task',
  exec: (resolve, reject, shell, config, log, ora) => {}
}

The exec function is what gets run by kody. You can do whatever you like inside this function but the arguments passed in are important. This is how kody exposes various things to the user. You are of course free to name the parameters however you wish 😄

Let's run through them 👍

Hello World

For our first task, why not "Hello World!"? 😅

We will use shelljs to invoke say.

const task = {
  name: 'Hello World 👋',
  description: 'Hey from kody 🐻',
  exec: (resolve, reject, shell) => {
    shell.exec('say hello world!')
    resolve()
  }
}
module.exports = task

That's it! Run kody in the parent of your tasks directory and choose the Hello World task. Depending on your OS, you should hear Hello World! 🎉

.kodyrc file

The .kodyrc file was mentioned briefly above. It's used to define values and configuration for your tasks. It also has two special keys. Both are optional

An example .kodyrc

{
  "task_directory": "./awesome-tasks",
  "running_order": [
    "b",
    "a",
    "*"
  ],
  "brewInstalls": [
    "google-chrome",
    "visual-studio-code"
  ],
}

In this .kodyrc file we specify that tasks are under ./awesome-tasks. We also state that tasks run in any order but b must run before a. It's important to note that running order entries are task file names and not the name of the task. The extension is not necessary.

Any other keys in the .kodyrc file are user defined and made available in any tasks you write/use. In this example, we have brewInstalls which could be an array of homebrew casks to install.

A real task

For a real task example, let's install Homebrew.

const { info } = console
const HOMEBREW_URL =
  'https://raw.githubusercontent.com/Homebrew/install/master/install'
const task = {
  name: 'Homebrew',
  description: 'Install and set up Homebrew',
  exec: function(resolve, reject, shell, config, log) {
    const { brew_installs: packages } = config
    const brewInstalled = shell.which('brew') !== null
    if (!brewInstalled) {
      try {
        info(log('Installing Homebrew'))
        const result = shell.exec(`ruby -e "$(curl -fsSL ${PROPS.URL})"`)
        if (result.code !== 0) throw new Error(result.stderr)
        else info(log('Homebrew installed'))
      } catch (err) {
        throw new Error(err)
      }
    } else info(log('Homebrew already installed'))
    info(log('Running brew doctor'))
    shell.exec('brew doctor')
    info(
      log(
        `NOTE: Any info from brew doctor may account for any issues with package installs`
      )
    )
    if (packages && packages.length > 0) {
      info(log(`Installing ${packages.join(' ')}`))
      shell.exec(`brew install ${packages.join(' ')}`)
      info(log('Brew packages installed'))
    } else {
      info(log('No brew packages to install'))
    }
    resolve()
  },
}

module.exports = task

It may look like there's a lot going on here. But the majority of this is actually logging to the console 😅

Tasks that have already been created

Examples

Development

kody is easy to work on. It uses a self-documented Makefile.

Just run make to see what tasks are available.

First things first is to pull in dependencies with make setup.

Then you'll be wanting to use make develop to start work. Use npm link to get a global instance of what you're working on available in the shell. You can test this by running kody --version.

It's best to create a dummy folder that you can test things out in. This reduces the risk of breaking your $HOME setup.

Enjoy! 😎

Under the hood

kody is written using es6 with babel and is developed using a self-documented Makefile.

Disclaimer

I've only used kody on OSX. I'm not responsible if you bork your machine configuration 😅 However, I'm happy to try and help you out if you get stuck!

Contributing

Any problems or questions, feel free to post an issue or tweet me, @jh3yyy! 🐦


Made with 🐻s by @jh3y 2018