UNPKG

beekeeper-util

Version:

CLI utility for managing the beekeeper-service

200 lines (175 loc) 6.87 kB
_ = require 'lodash' get = require 'lodash/fp/get' replace = require 'lodash/fp/replace' isEqual = require 'lodash/fp/isEqual' url = require 'url' colors = require 'colors' moment = require 'moment' path = require 'path' request = require 'request' cliClear = require 'cli-clear' notifier = require 'node-notifier' BeekeeperService = require './beekeeper-service' getVersion = replace('v', '') class StatusService constructor: ({ options, @config }) -> { @repo @owner @tag @json @watch @exit @notify serviceUrl @filter } = options @serviceUrl = @getServiceUrl serviceUrl @beekeeperService = new BeekeeperService { @config } getServiceUrl: (serviceUrl) => return unless serviceUrl? unless _.startsWith serviceUrl, 'http' serviceUrl = "https://#{serviceUrl}" urlParts = url.parse serviceUrl, true urlParts.pathname = '/version' urlParts.protocol ?= 'https' urlParts.slashes = true return url.format urlParts run: => @clear() @beekeeperService.getTag { @repo, @owner, @tag, @filter }, (error, deployment, latest) => return @die error if error? return @printJSON deployment if @json @printHeader "#{@owner}/#{@repo}:#{@tag}" unless deployment? return @printNotFound() unless deployment? @printDeployHeader { latest, deployment } if deployment.ci_passing? and not deployment.ci_passing return @printFailed deployment, 'CI failed' if deployment.ci_passing and deployment.docker_url? return @printPassing deployment, 'CI passed but no docker build' @printPending deployment clear: => return unless @watch cliClear() console.log '[refreshed at] ', colors.cyan moment().toString() end: ({ exitCode, pending, passing, notFound }) => return _.delay @waitForVersion, 3000 if @serviceUrl? && passing return _.delay @run, 10000 if @watch and pending @doNotify { passing, notFound } process.exit exitCode if pending doNotify: ({ passing, notFound }) => return unless @notify message = 'Service Deployed!' sound = 'Purr' unless passing message = 'Deployment Failed!' sound = 'Basso' if notFound message = 'Deployment Not Found!' sound = 'Funk' notifier.notify { title: 'Beekeeper' subtitle: "#{@repo}:#{@tag}" message: message icon: path.join(__dirname, '..', 'assets', 'beekeeper.png') sound: sound open: @serviceUrl timeout: 10 } waitForVersion: (successCount=0) => @clear() @checkVersion (error, matches, currentVersion) => return @die error if error? successCount++ if matches @printVersionResult { currentVersion } return _.delay @waitForVersion, 3000, successCount if successCount <= 3 @doNotify { passing: true } process.exit 0 checkVersion: (callback) => request.get @serviceUrl, { json: true }, (error, response, body) => return callback error if error? currentVersion = getVersion(get('version', body)) matches = isEqual(getVersion(@tag), currentVersion) callback null, matches, currentVersion printJSON: (deployment) => console.log JSON.stringify deployment, null, 2 @end { exitCode: 0 } printHeader: (slug) => console.log '' console.log "#{colors.cyan('Deployment:')}", slug printDeployHeader: ({ latest, deployment }) => return unless deployment? latestSlug = "#{latest.owner_name}/#{latest.repo_name}:#{latest.tag}" if latest? deploymentSlug = "#{deployment.owner_name}/#{deployment.repo_name}:#{deployment.tag}" console.log '' colorTitle = (str='') => return colors.cyan(str) colorValue = (str='') => return colors.white(str) colorList = (arr=[]) => return colors.italic(_.join(arr, ', ')) if @serviceUrl? console.log colors.gray('Service: '), colors.gray(@serviceUrl) unless latest? console.log colorTitle('There is no latest version, maybe it has never been deployed?') console.log colorTitle('Desired'), colorValue(deploymentSlug) else if deployment.tag == latest.tag console.log colorTitle('Running'), colorValue(deploymentSlug) else console.log colorTitle('Running'), colorValue(latestSlug) console.log colorTitle('Desired'), colorValue(deploymentSlug) unless _.isEmpty deployment.tags console.log colorTitle('Tag '), colorList(deployment.tags) printPassing: ({ created_at, docker_url }) => console.log '' console.log "#{colors.bold('Build')} ", colors.green('Passing') console.log "#{colors.bold('Docker')} ", colors.underline(docker_url) console.log "#{colors.bold('Created')} ", @prettyDate(created_at) console.log '' @end { exitCode: 0, passing: true } printVersionResult: ({ currentVersion }) => console.log '' message = "Service is running v#{currentVersion}!" if getVersion(currentVersion) == getVersion(@tag) console.log colors.green(message) else console.log colors.white(message) console.log colors.yellow("Waiting for service to run #{@tag}...") console.log '' printPending: ({ ci_passing, docker_url, created_at, updated_at }) => waitlist = [] waitlist.push '"CI Build"' unless ci_passing? waitlist.push '"Docker URL"' unless docker_url? console.log '' console.log "#{colors.bold('Build')} ", colors.yellow('Pending...') console.log "#{colors.bold('Waiting on')}", colors.magenta(waitlist.join(', ')) console.log "#{colors.bold('Created')} ", @prettyDate(created_at) @printComponents updated_at console.log '' @end { exitCode: 0, pending: true } printFailed: ({ created_at, updated_at }, reason) => console.log '' console.log "#{colors.bold('Build')} ", colors.red('Failed') console.log "#{colors.bold('Created')} ", @prettyDate(created_at) console.log "#{colors.bold('Reason')} ", "'#{reason}'" console.log '' @printComponents updated_at console.log '' @end { exitCode: 1, passing: false } printNotFound: => console.log '' console.log "#{colors.bold('Build')} ", colors.yellow.underline('Not found!') console.log '' @end { exitCode: 1, notFound: true, passing: false } printComponents: (components) => return console.log("#{colors.bold('No completed components')}") if _.isEmpty components console.log "#{colors.bold('Completed Components')} " _.each components, (date, key) => console.log " #{colors.cyan(key)} ", @prettyDate(date) prettyDate: (date) => return "@ #{colors.gray(moment(date).fromNow())}" die: (error) => return process.exit(0) unless error? console.error error.stack process.exit 1 module.exports = StatusService