UNPKG

5.53 kBJavaScriptView Raw
1#!/usr/bin/env node
2"use strict";
3var __importDefault = (this && this.__importDefault) || function (mod) {
4 return (mod && mod.__esModule) ? mod : { "default": mod };
5};
6Object.defineProperty(exports, "__esModule", { value: true });
7const os_1 = __importDefault(require("os"));
8const path_1 = __importDefault(require("path"));
9// @ts-ignore
10const yargonaut_1 = __importDefault(require("yargonaut"));
11const yargs_1 = __importDefault(require("yargs"));
12const js_yaml_1 = __importDefault(require("js-yaml"));
13const VERSION = require('../package').version;
14const DockerCompiler_1 = __importDefault(require("./DockerCompiler"));
15const errors_1 = require("./errors");
16const CachingUrlFetcher_1 = __importDefault(require("./CachingUrlFetcher"));
17const cli_nix_1 = __importDefault(require("./cli-nix"));
18const compiler = new DockerCompiler_1.default(new CachingUrlFetcher_1.default());
19yargonaut_1.default
20 .style('blue')
21 .helpStyle('green')
22 .errorsStyle('red');
23yargs_1.default
24 .scriptName('dockter')
25 // Help global option
26 .alias('h', 'help')
27 .usage('$0 <cmd> [args]')
28 // Version global option
29 .alias('v', 'version')
30 .version(VERSION)
31 .describe('version', 'Show version')
32 // Nix global option
33 .option('nix', {
34 describe: 'Use NixOS base image'
35})
36 // Ensure at least one command
37 .demandCommand(1, 'Please provide a command.')
38 // Provide suggestions regarding similar commands if no matching command is found
39 .recommendCommands()
40 // Any command-line argument given that is not demanded, or does not have a corresponding description, will be reported as an error.
41 // Unrecognized commands will also be reported as errors.
42 .strict()
43 // Compile command
44 // @ts-ignore
45 .command('compile [folder]', 'Compile a project to a software environment', yargs => {
46 folderArg(yargs);
47}, async (args) => {
48 const folder = path_1.default.resolve(args.folder);
49 let environ = await compiler.compile('file://' + folder, false).catch(error);
50 if (args.nix) {
51 cli_nix_1.default.compile(environ, folder);
52 }
53})
54 // Build command
55 // @ts-ignore
56 .command('build [folder]', 'Build a Docker image for project', yargs => {
57 folderArg(yargs);
58}, async (args) => {
59 const folder = path_1.default.resolve(args.folder);
60 if (args.nix) {
61 await cli_nix_1.default.build(folder);
62 }
63 else {
64 await compiler.compile('file://' + folder, true).catch(error);
65 }
66})
67 // Execute command
68 // @ts-ignore
69 .command('execute [folder] [command]', 'Execute a project', yargs => {
70 folderArg(yargs),
71 yargs.positional('command', {
72 type: 'string',
73 default: '',
74 describe: 'The command to execute'
75 });
76}, async (args) => {
77 const folder = path_1.default.resolve(args.folder);
78 if (args.nix) {
79 await cli_nix_1.default.execute(folder, args.command);
80 }
81 else {
82 const node = await compiler.execute('file://' + folder, args.command).catch(error);
83 output(node, args.format);
84 }
85})
86 // Who command
87 // @ts-ignore
88 .command('who [folder]', 'List the people your project depends upon', yargs => {
89 folderArg(yargs);
90 yargs.option('depth', {
91 alias: 'd',
92 type: 'integer',
93 default: 100,
94 describe: 'The maximum dependency recursion depth'
95 });
96}, async (args) => {
97 const folder = path_1.default.resolve(args.folder);
98 const people = await compiler.who('file://' + folder, args.depth).catch(error);
99 if (!people) {
100 console.log('Nobody (?)');
101 }
102 else {
103 // Sort by number of packages descending and then alphabetically ascending
104 let sorted = Object.entries(people).sort(([aName, aPkgs], [bName, bPkgs]) => {
105 if (aPkgs.length > bPkgs.length)
106 return -1;
107 if (aPkgs.length < bPkgs.length)
108 return 1;
109 if (aName < bName)
110 return -1;
111 if (aName > bName)
112 return 1;
113 return 0;
114 });
115 // Output in a CLI friendly way
116 const output = sorted.map(([name, packages]) => {
117 return `${name} (${packages.join(', ')})`;
118 }).join(', ');
119 console.log(output);
120 }
121})
122 .parse();
123/**
124 * Specify the [folder] argument settings
125 *
126 * @param yargs The yargs object
127 */
128function folderArg(yargs) {
129 yargs.positional('folder', {
130 type: 'string',
131 default: '.',
132 describe: 'The path to the project folder'
133 });
134}
135/**
136 * Print output to stdout
137 *
138 * @param object The object to print
139 * @param format The format use: `json` or `yaml`
140 */
141function output(object, format = 'json') {
142 if (object)
143 console.log(format === 'yaml' ? js_yaml_1.default.safeDump(object, { lineWidth: 120 }) : JSON.stringify(object, null, ' '));
144}
145/**
146 * Print an error to stderr
147 *
148 * @param error The error to print
149 */
150function error(error) {
151 if (error instanceof errors_1.ApplicationError) {
152 console.error(error.message);
153 }
154 else {
155 console.error('Woops, sorry something went wrong :(');
156 console.error('Please help us fix this issue by posting this output to https://github.com/stencila/dockter/issues/new');
157 console.error(` args: ${process.argv.slice(2).join(' ')}`);
158 console.error(` version: ${VERSION}`);
159 console.error(` platform: ${os_1.default.platform()}`);
160 console.error(error);
161 process.exit(1);
162 }
163}