Coder Social home page Coder Social logo

jh3y / kody Goto Github PK

View Code? Open in Web Editor NEW
137.0 7.0 7.0 610 KB

.files and environment configuration manager created with node

JavaScript 94.08% Makefile 5.92%
symlink-files osx javascript dotfiles dotfiles-manager dotfiles-resources dotfile dotfiles-automation dotfiles-setup dotfiles-install

kody's Introduction

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

  • One command
  • No restrictions on where you run from or store your dotfiles
  • Easy to configure, extend and tweak
  • Interactive CLI that prompts which tasks you want to run
  • Just needs node and your dotfiles!

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 ๐Ÿ‘

  • resolve/reject - kody uses Promises so the first two arguments enable you to inform kody of when to move on. If your task is complete, invoke resolve. If your task stumbles, make use of reject ๐Ÿ›‘
  • shell - one of the main things when automating set up etc. is running various shell commands. kody exposes the shelljs API to your tasks. We will use this in the Hello World example
  • config - a major thing with set ups is being able to keep everything in one config file. This way you won't have to hard code values into your tasks. kody will search for a .kodyrc file on start and pass that configuration object to your tasks. In here you can define any JSON you want. For example, a list of apps to install, editor plugins to install etc. Define under keys and access them in your tasks ๐Ÿ‘Š
  • log - kody exposes a simple color logging utility that uses chalk. It's a function that takes three parameters. The first is the message you want to display. The second and third are the text color and background color respectively. The function expects color represented by a hexidecimal value ๐Ÿ‘ You use this log function inside your standard console invocation.
  • ora - kody exposes the ora API so you can fire up a terminal spinner when needed too!

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

  • task_directory - this specifies the location of your tasks relative to your current working directory
  • running_order - this specifies a running order for your tasks

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

  • Set up git
  • Write OSX defaults
  • Install and set up Homebrew
  • Install programs supported by brew cask such as Spotify, Chrome, etc.
  • Set up fish shell
  • Set up oh-my-zsh
  • Install Atom IDE packages
  • Install and set up Visual Studio Code
  • Remove unwanted default system applications

Examples

  • Jhey's .files - My personal kody set up. Sets up IDE, installs programs, configures shell etc.

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

kody's People

Contributors

dependabot[bot] avatar jh3y avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

kody's Issues

Don't prepend dotfiles with "."

Issue summary

When a user sets up their kody_env they should prepend their dotfiles files with .. Else it's counterintuitive to know that kody will prepend the . for you.

Expected behavior

Don't prepend .. Just symlink to $HOME.

If no tasks selected or available, strange logs

Issue summary

For example, if I don't select a task and then press enter, kody will log that it ran a "generic task"

Expected behavior

Just tell me that no tasks were ran

Actual behavior

Get strange logs ๐Ÿ˜ข

Steps to reproduce

Run kody and select no tasks

Add common tasks to examples folder

Issue summary

Decrease the barrier for entry to use by having a folder of common example tasks;

  • Installing homebrew
  • Installing global node modules
  • etc.

After reading the README back, it doesn't feel instantly easy to pick up and use, maybe show an example task within the README showing how easy it is to create a task for kody to pick up.

Also, link to personal set ups. For example; github.com/jh3y/kody_env has my personal tasks for doing various things like running shell scripts etc.

There is potential to raise awareness of kody and make it a go to solution for maintaining dotfiles. It has been picked up and shown on different blogging platforms but I still feel the barrier to entry may be holding it back.

Expected behavior

User should feel at ease to give kody a spin and not think about passing it up because it's too much overhead to get started.

Actual behavior

It's not super intuitive or doesn't come across as something that can be just picked up quick without major knowledge.

Steps to reproduce

Read the README as if you've never heard of kody or .files.

Resolution

Improve the README so that kody is easier to pick up and get going. Add examples into the repo so potential users can see how easy it is to get started with kody.

Better error handling for invalid JSON

Issue summary

If I have invalid JSON, kody tells me it can't find any tasks but doesn't inform me that my .kodyrc file is invalid ๐Ÿคฆ

Expected behavior

More descriptive error handling where I'm told that the JSON is invalid

Actual behavior

Fails telling me there's an issue with .kodyrc which makes me question whether my node version is compatible etc.

Steps to reproduce

Create an invalid JSON file with say a missing comma as the .kodyrc file

Unhandled Promise rejection Error

Issue summary

Noticed when firing one of the tasks on my own kody_envfor installing apm packages.

More info on this error here. From what I can tell, the task is still successfully carried out but we just get the error noise in addition at the end.

I think the solution is to make processTask within processTasks potentially return a promise so that a rejection error can be handled.

Expected behavior

Runs with no errors or noise.

Actual behavior

We get noise ๐Ÿ˜ข

Steps to reproduce

Personally, I ran the install apm package installer task from https://github.com/jh3y/kody_env.

@jh3y

Task ordering not respected

Issue summary

Task ordering not respected by order key in .kodyrc.

Expected behavior

Tasks should be displayed by kody in order.

Actual behavior

Tasks just get displayed in file order.

Steps to reproduce

Just run kody with multiple tasks and pass the order key to define an order different to what you get by default.

If .files directory in place, kody will throw error

Issue summary

If you set up a new machine using kody. Unless the .files task is set first(?) an error will be thrown about not being able to unlink the current existing directory.

Expected behavior

No errors are thrown and the symlink for the directory is set

Actual behavior

Error thrown because an existing directory is in place.

Current work-around

Manually rm -rf the directory within the $HOME directory before running the Dotfiles task.

Steps to reproduce

Try setting up a fresh machine using kody.

Add atom package manager installs task

From kody.json allow user to define the atom packages to install so that it works out of the box like it did on their other machine.

Will simply have to check that which apm is not null.

@jh3y

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.