UNPKG

huxley-cli

Version:

CLI for Huxley Deployment Platform

110 lines (91 loc) 3.77 kB
#=============================================================================== # Huxley - CLI Helpers #=============================================================================== # This file specifies some handy helper methods. {resolve, join} = require "path" {async, read, merge, exists, mkdir, has, deep_equal} = require "fairmont" Configurator = require "panda-config" #-------------------- # Exposed Methods #-------------------- module.exports = # Prepare a basic error object to return to the UI. build_error: (message, value) -> return { message: message value: value } # Use until Fairmont bug is repaired. empty: (x) -> x.length == 0 # Output an Info Blurb and optional message. usage: async (entry, message) -> docs = yield read( resolve( __dirname, "..", "docs", entry ) ) if message? throw "#{message}\n" + docs else throw docs # Sometimes we don't care if a promise is rejected, we just need to wait for it to be done one way # or another. This function accepts an input promise but always resolves. force: async (f, args...) -> try yield f args... catch e null # Make a directory at the specified path, but throw an exception if that directory already exists. safe_mkdir: async (path, mode) -> unless yield exists path mode ||= "0777" yield mkdir mode, path else throw "Error: #{path} already exists. \n" # In Huxley, configuration data is stored in multiple places. This function focuses on # two levels of configuartion. # (1) The first is the user's home configuration, located in the huxley dotfile # within their $HOME directory (holds persistent data attached to their account). # (2) The second is the application-level configuration, located in the repo's huxley # manifest file. TODO: Currently, we only look in the execution path, so we require the # CLI to be run in the repo's root directory. This should use an env variable like Node and git. pull_configuration: async () -> if yield exists join process.env.HOME, ".huxley" # Load the configuration from the $HOME directory. constructor = Configurator.make prefix: "." format: "yaml" paths: [ process.env.HOME ] home_config = constructor.make name: "huxley" yield home_config.load() else throw "You must establish a dotfile configuration in your $HOME directory, ~/.huxley" if yield exists join process.cwd(), "huxley.yaml" # Load the application level configuration. constructor = Configurator.make extension: ".yaml" format: "yaml" paths: [ process.cwd() ] app_config = constructor.make name: "huxley" yield app_config.load() # Create an object that is the union of the two configurations. Huxley observes # configuration scope, so application configuration will override values set in the home-configuration. if app_config? config = merge home_config.data, app_config.data else config = home_config.data # Return an object we can use to make requests, but also return the panda-config instances # in case we need to save something. return { config: config home_config: home_config app_config: app_config if app_config? } # Nifty function that returns an array of objects when given an array of # objects and an object subset to search for. where: async (array, query) -> final = [] for obj in array count = 0 for key of query break unless yield has key, obj break unless yield deep_equal obj[key], query[key] count++ final.push obj if count == Object.keys(query).length return final