import os from 'os' ; import path from 'path' ; import { Command } from '@serverless-devs/commander' ; import { CommandManager } from '../core' ; import { version , Parse } from '../specification' ; import { PROCESS_ENV_TEMPLATE_NAME } from '../constants/static-variable' ; import storage from './storage' ; import logger from './logger' ; import { emoji } from './common' ; import _ , { get , forEach , size } from 'lodash' ; import core from './core' ; const { makeUnderLine , loadComponent , fse : fs , getYamlContent , publishHelp } = core ; const { getSubcommand , getServiceConfig } = version ; export async function setEnvbyDotenv ( templateFile ) { const spath = path . dirname ( templateFile ) ; require ( 'dotenv' ) . config ( { path : path . join ( spath , '.env' ) } ) ; const data = await getYamlContent ( templateFile ) ; const { services } = data ; for ( const key in services ) { const element = services [ key ] ; let codeUri = get ( element , 'props.function.codeUri' ) ; if ( codeUri ) { codeUri = path . isAbsolute ( codeUri ) ? codeUri : path . join ( spath , codeUri ) ; require ( 'dotenv' ) . config ( { path : path . join ( codeUri , '.env' ) } ) ; } } } export function createUniversalCommand ( command , customerCommandName ? , description ? ) { const _command = new Command ( command ) ; const processArgv = [ ] ; let params = [ ] ; let _customerCommandName = customerCommandName ; let start = false ; for ( let i = 0 ; i < process . argv . length ; i ++ ) { if ( ! start ) { processArgv . push ( process . argv [ i ] ) ; } else { params . push ( process . argv [ i ] ) ; } if ( process . argv [ i ] === command ) { start = true ; } } if ( params . length !== 0 ) { process . env . temp_params = params . join ( ' ' ) ; process [ 'temp_params' ] = params ; } process . argv = processArgv ; _command . description ( description || '' ) . action ( ( ) => { const template = process . env [ PROCESS_ENV_TEMPLATE_NAME ] ; if ( template ) { const commandManager = new CommandManager ( template , command , _customerCommandName , process . env . temp_params ) ; commandManager . init ( ) ; } } ) ; return _command ; } export async function getCommandDetail ( name , provider , version ) { let command_list = [ ] ; return command_list ; } export async function getParsedTemplateObj ( templateFile ) { const parse = new Parse ( templateFile ) ; const parsedObj = parse . getOriginalParsedObj ( ) ; const result = await parse . getRealVariables ( parsedObj ) ; return result ; } export function getCustomerCommandInfo ( parsedTemplateObj ) { return getSubcommand ( parsedTemplateObj ) ; } export async function createCustomerCommand ( templateFile ) { const customerCommands = [ ] ; const doc = await getParsedTemplateObj ( templateFile ) ; const subCommands = getCustomerCommandInfo ( doc ) ; const commandListPromise = subCommands . map ( async ( projectName ) => { const projectDocDetail = getServiceConfig ( doc , projectName ) ; return { projectName , projectDocDetail } ; } ) ; const commandListDetail = await Promise . all ( commandListPromise ) ; forEach ( commandListDetail , ( { projectName , projectDocDetail } ) => { const customerCommand = new Command ( projectName ) ; customerCommand . _componentName = get ( projectDocDetail , 'component' ) ; const [ _customerCommandName , methodName ] = process . argv . slice ( 2 ) ; if ( _customerCommandName === projectName && methodName && methodName . indexOf ( '-' ) !== 0 ) { customerCommand . addCommand ( createUniversalCommand ( methodName , projectName ) ) ; } customerCommand . option ( '-h, --help' , 'Print usage document' ) ; customerCommand . action ( async ( ) => { const { component } = projectDocDetail ; const componentInstance = await loadComponent ( component ) ; if ( componentInstance ) { try { const publishYamlInfor = await getYamlContent ( path . join ( componentInstance . __path , 'publish.yml' ) ) ; console . log ( `${ emoji ( '🚀' ) } ${ publishYamlInfor [ 'Name' ] }@${ publishYamlInfor [ 'Version' ] }: ${ publishYamlInfor [ 'Description' ] }\n` ) ; if ( publishYamlInfor [ 'Commands' ] ) { const helperLength = publishHelp . maxLen ( publishYamlInfor [ 'Commands' ] ) ; console . log ( publishHelp . helpInfo ( publishYamlInfor [ 'Commands' ] , 'Commands' , helperLength ) ) ; console . log ( `${ publishYamlInfor [ 'HomePage' ] ? `${ emoji ( '🧭' ) } ${ makeUnderLine ( 'More information: ' + publishYamlInfor [ 'HomePage' ] ) } ` + '\n' : '' }` ) ; } } catch ( e ) { logger . error ( 'Help information could not be found' ) ; } } else { logger . error ( 'Help information could not be found' ) ; } } ) ; customerCommands . push ( customerCommand ) ; } ) ; if ( size ( commandListDetail ) === 1 ) { const componentInstance = await loadComponent ( get ( _ . first ( commandListDetail ) , 'projectDocDetail.component' ) ) ; const publishYamlInfor = await getYamlContent ( path . join ( componentInstance . __path , 'publish.yml' ) ) ; _ . set ( _ . first ( customerCommands ) , '_componentPublish' , publishYamlInfor ) ; } return customerCommands ; } export function registerCommandChecker ( program ) { program . on ( 'command:*' , ( cmds ) => { const commands = program . commands . map ( ( command ) => command . name ( ) ) ; if ( ! commands . includes ( cmds [ 0 ] ) ) { logger . error ( `  error: unknown command ${ cmds [ 0 ] }` ) ; program . help ( ) ; } } ) ; } export async function registerCustomerCommand ( system_command , templateFile ) { if ( templateFile ) { const customerCommands = await createCustomerCommand ( templateFile ) ; forEach ( customerCommands , command => { system_command . addCommand ( command ) ; } ) ; if ( size ( customerCommands ) === 1 ) { return _ . get ( _ . get ( _ . first ( customerCommands ) , '_componentPublish' ) , 'Commands' , [ ] ) ; } else { return _ . map ( customerCommands , item => ( { [ `${ item . _name } [options]` ] : `Please use [s ${ item . _name } -h]  obtain the documentation` , } ) ) ; } } } export async function registerUniversalCommand ( system_command , templateFile ) { if ( templateFile ) { const parsedTemplateObj = await getParsedTemplateObj ( templateFile ) ; const customerCommands = getCustomerCommandInfo ( parsedTemplateObj ) ; if ( process . argv [ 2 ] && ! customerCommands . includes ( process . argv [ 2 ] ) && ! [ '-h' , '--help' ] . includes ( process . argv [ 2 ] ) ) { system_command . addCommand ( createUniversalCommand ( process . argv [ 2 ] ) ) ; } } } export function registerVerbose ( program ) { if ( process . argv . includes ( '--verbose' ) ) { process . env . VERBOSE = program . verbose ; } } export function recordCommandHistory ( argv ) { const file = storage . getHistoryFile ( ) ; fs . appendFileSync ( file , argv . join ( ',' ) + os . EOL ) ; } export default { registerCommandChecker , recordCommandHistory , registerCustomerCommand , registerUniversalCommand , } ;