UNPKG

6.67 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict';
4const Command = require('commander').Command;
5const program = new Command('fun install');
6const getVisitor = require('../lib/visitor').getVisitor;
7const handler = require('../lib/exception-handler');
8const notifier = require('../lib/update-notifier');
9
10const { autoExit } = require('../lib/unref-timeout');
11const { getSupportedRuntimesAsString } = require('../lib/common/model/runtime');
12const { install, installAll, init, env, sbox } = require('../lib/commands/install');
13
14const _ = require('lodash');
15
16const convertOptions = (program) => {
17 // convert long option to camelCase variable name,such as '--package-type' to 'packageType'
18 const optionNames = _.map(program.options, (opt) => _.camelCase(opt.long));
19 // pick the option properties into a new object.
20 return _.pickBy(program, (_val, name) => _.includes(optionNames, name));
21};
22
23// [ 'A=B', 'B=C' ] => { A: 'B', B: 'C' }
24const convertEnvs = (env) => (env || []).map(e => _.split(e, '=', 2))
25 .filter(e => e.length === 2)
26 .reduce((acc, cur) => (acc[cur[0]] = cur[1], acc), {});
27
28program
29 .usage('[-f|--function <[service/]function>] [-r|--runtime <runtime>] [-p|--pacakge-type <type>] [--save] [-e|--env key=val ...] [packageNames...]')
30 .option('-f, --function <[service/]function>', `Specify which function to execute installation task.`)
31 .option('-r, --runtime <runtime>', `function runtime, avaliable choice is: ${getSupportedRuntimesAsString(['dotnetcore2.1'])}`)
32 .option('-e, --env <env>', 'environment variable, ex. -e PATH=/code/bin', (e, envs) => (envs.push(e), envs), [])
33 .option('-d, --use-docker', 'Use docker container to install function dependencies')
34 .option('--save', 'add task to fun.yml file.')
35 .option('-p, --package-type <type>', 'avaliable package type option: pip, apt, npm.')
36 .arguments('[packageNames...]')
37 .description('install dependencies which are described in fun.yml file.')
38 .action(async (packageNames, program) => {
39
40 const options = convertOptions(program);
41
42 // merge options default values.
43 const opts = Object.assign({
44 local: true
45 }, options);
46
47 opts.verbose = parseInt(process.env.FUN_VERBOSE) > 0;
48 opts.env = convertEnvs(options.env);
49
50 install(packageNames, opts).then(() => {
51 autoExit();
52 }).catch(handler);
53 });
54
55program
56 .command('init')
57 .description('initialize fun.yml file.')
58 .action(() => {
59 getVisitor().then(visitor => {
60
61 visitor.pageview('/fun/install/init').send();
62 init().then((runtime) => {
63 visitor.event({
64 ec: 'install',
65 ea: `init ${runtime}`,
66 el: 'success',
67 dp: '/fun/install/init'
68 }).send();
69 }).catch((error) => {
70 visitor.event({
71 ec: 'install',
72 ea: `init`,
73 el: 'error',
74 dp: '/fun/install/init'
75 }).send();
76
77 handler(error);
78 });
79 });
80 });
81
82program
83 .command('env')
84 .description('print environment varables.')
85 .action(() => {
86 getVisitor().then(visitor => {
87 visitor.pageview('/fun/install/env').send();
88
89 env().then(() => {
90
91 visitor.event({
92 ec: 'install',
93 ea: 'env',
94 el: 'success',
95 dp: '/fun/install/env'
96 }).send();
97
98 autoExit();
99 }).catch((error) => {
100
101 visitor.event({
102 ec: 'install',
103 ea: `env`,
104 el: 'error',
105 dp: '/fun/install/env'
106 }).send();
107
108 handler(error);
109 });
110 });
111 });
112
113program
114 .command('sbox')
115 .usage('[-f|--function <[service/]function>] [-r|--runtime <runtime>] [-i|--interactive] [-e|--env key=val ...] [-e|--cmd <cmd>]')
116 .description('Start a local sandbox for installation dependencies or configuration')
117 .option('-f, --function <[service/]function>', `Specify which function to execute installation task.`)
118 .option('-r, --runtime <runtime>', `Function runtime, avaliable choice is: ${getSupportedRuntimesAsString(['dotnetcore2.1'])}`)
119 .option('-i, --interactive', 'Run as interactive mode. Keep STDIN open and allocate a pseudo-TTY when in a interactive shell.', false)
120 .option('-e, --env <env>', 'Environment variable, ex. -e PATH=/code/bin', [])
121 .option('-c, --cmd <cmd>', 'Command with arguments to execute inside the installation sandbox.')
122 .option('-t, --template [template]', 'Path of fun template file.')
123 .action((prog) => {
124
125 getVisitor().then(visitor => {
126 visitor.pageview('/fun/install/sbox').send();
127
128 const options = convertOptions(prog);
129 if (program.function) {
130 options.function = program.function;
131 }
132 if (program.runtime) {
133 options.runtime = program.runtime;
134 }
135
136 if (!options.function && !options.runtime) {
137 console.error('The `--runtime` or `--function` option is missing.');
138 visitor.event({
139 ec: 'install',
140 ea: `sbox`,
141 el: 'error',
142 dp: '/fun/install/sbox'
143 }).send();
144 return;
145 }
146
147 if (!options.interactive && !options.cmd) {
148 console.error('The `--interactive` or `--cmd` option is missing.');
149 visitor.event({
150 ec: 'install',
151 ea: `sbox`,
152 el: 'error',
153 dp: '/fun/install/sbox'
154 }).send();
155 return;
156 }
157
158 options.envs = convertEnvs(program.env);
159
160 sbox(options).then(() => {
161 visitor.event({
162 ec: 'install',
163 ea: `sbox`,
164 el: 'success',
165 dp: '/fun/install/sbox'
166 }).send();
167 }).catch((error) => {
168 visitor.event({
169 ec: 'install',
170 ea: `sbox`,
171 el: 'error',
172 dp: '/fun/install/sbox'
173 }).send();
174
175 handler(error);
176 });
177 });
178 });
179
180program.parse(process.argv);
181
182notifier.notify();
183
184
185if (!program.args.length) {
186
187 if (program.packageType) {
188 console.warn('Missing arguments [packageNames...], so the `--package-type` option is ignored.');
189 }
190
191 if (program.save) {
192 console.warn('Missing arguments [packageNames...], so the `--save` option is ignored.');
193 }
194
195 getVisitor().then(visitor => {
196 visitor.pageview('/fun/installAll').send();
197
198 installAll(program.function, {
199 verbose: parseInt(process.env.FUN_VERBOSE) > 0,
200 useDocker: program.useDocker
201 }).then(() => {
202 visitor.event({
203 ec: 'installAll',
204 ea: 'installAll',
205 el: 'success',
206 dp: '/fun/installAll'
207 }).send();
208
209 autoExit();
210 }).catch(error => {
211 visitor.event({
212 ec: 'installAll',
213 ea: 'installAll',
214 el: 'error',
215 dp: '/fun/installAll'
216 }).send();
217
218 handler(error);
219 });
220 });
221}
\No newline at end of file