UNPKG

savory

Version:

A command-line interface for operating your Codefresh account

114 lines (108 loc) 5.3 kB
#!/usr/bin/env node const fp = require('lodash/fp'), fs = require('fs'), os = require('os'), path = require('path'), yargs = require('yargs'), chalk = require('chalk'), assert = require('assert'), { randomString } = require('../lib/util'), httpClientFactory = require('../lib/api_client'); const DEFAULT_CONFIGURATION_FILENAME = ".savory", DEFAULT_CONFIGURATION_PATH = path.join(os.homedir(), DEFAULT_CONFIGURATION_FILENAME), DEFAULT_API_ENDPOINT_URL = "https://g.codefresh.io/"; const selfFileName = path.basename(process.argv.slice(1,2).join('')), validateApiKey = (apiKey)=> /^[0-9a-f]{24}\.[0-9a-f]{32}$/.test(apiKey), validateApiEndpointUrl = (apiEndpointUrl)=> /^https?:\/\/[^\/]+\/$/.test(apiEndpointUrl), parseFileConfiguration = (configurationFilePath)=> { let configurationJson = fp.attempt(()=> JSON.parse(fs.readFileSync(configurationFilePath, 'utf8'))); assert(!fp.isError(configurationJson), `Failed to parse the configuration file at ${configurationFilePath}`); let activeContext = fp.get('active_context', configurationJson); assert(activeContext, `The configuration file at ${configurationFilePath} doesn't contain a valid active context`); assert(fp.has(["context", activeContext], configurationJson), `Context "${activeContext}" doesn't exist in the configuration at ${configurationFilePath}`); return fp.mapKeys(fp.camelCase, fp.get(["context", activeContext], configurationJson)); }; let argv = yargs .strict(true) .version() .config() .wrap(100) .usage(`${chalk.green('Savory')} is a command-line interface for operating your Codefresh account`) .option('config', { default: [DEFAULT_CONFIGURATION_PATH].find(fs.existsSync), describe: "Use a custom configuration file", config: true, configParser: parseFileConfiguration }) .option('api-key', { describe: "Sets the API key to be used when contacting Codefresh's API", required: `Please specify an API key, or run "${ chalk.whiteBright([selfFileName].concat('login <your-api-key>').join(' '))}".\nTo obtain an API key, refer to "https://g.codefresh.io/account-admin/tokens"`, global: true, coerce: (apiKey)=> { assert(validateApiKey(apiKey), 'The API key used is invalid'); return apiKey; } }) .option('api-endpoint-url', { describe: "Sets the URL of Codefresh's API", default: DEFAULT_API_ENDPOINT_URL, required: true, global: true, coerce: (apiEndpointUrl)=> { assert(validateApiEndpointUrl(apiEndpointUrl), `The API endpoint address (${apiEndpointUrl}) used is invalid`); return apiEndpointUrl; } }) .command( 'login <api-key>', 'Sets a default login context', (argv)=> { return argv .positional('api-key', { coerce: (apiKey)=> { assert(validateApiKey(apiKey), 'The API key used is invalid'); return apiKey; } }) .example('$0 login 123456789012345678901234.12345678901234567890123456789012'); }, ({ apiEndpointUrl, apiKey })=> { let client = httpClientFactory(apiEndpointUrl, apiKey); client('user/context') .then((response)=> { if(response === "OK"){ let configurationJson = (function(maybe){ return fp.isError(maybe) ? {} : maybe; })(fp.attempt(()=> JSON.parse(fs.readFileSync(DEFAULT_CONFIGURATION_PATH, 'utf8')))), context = { "api_endpoint_url": apiEndpointUrl, "api_key": apiKey }, contextName = fp.findKey(fp.equals(context), configurationJson["context"]) || ["login", randomString()].join('_'); fs.writeFileSync(DEFAULT_CONFIGURATION_PATH, JSON.stringify(fp.merge(configurationJson, { "active_context": contextName, "context": { [contextName]: context } }), null, '\t')); console.log([ chalk.whiteBright(`You've successfully logged-in!`), "Try running commands such as:\n", ` ${selfFileName} builds ls --status running success`, ` ${selfFileName} images ls --external`, "" ].join('\n')); } else { return Promise.reject('The API key used is invalid'); } }) .catch(console.warn); } ) .command(require('./command/builds')) .command(require('./command/images')) .command(require('./command/compositions')) .command(require('./command/triggers')) .command(require('./command/contexts')) .command(require('./command/browse')) .command(require('./command/pipelines')) .command(require('./command/version')) .demandCommand(1, 'Please choose one of the commands above') .argv;