import path from 'path' ; import fs from 'fs-extra' ; import axios from 'axios' ; import wget from 'wget-improved' ; import { exec } from 'child_process' ; import { ESLint } from 'eslint' ; import * as prettier from 'prettier' ; import ora , { Color } from 'ora' ; import { getGlobalInfo } from '@arco-design/arco-dev-utils' ; type DependenceInfoMap = { [ propName ] : string ; } ; /**
 * Default logger implementation with ora
 */ export class DefaultLogger { private _spinner : ora . Ora ; public constructor ( startText ) { this . _spinner = ora ( startText ) . start ( ) ; } public log ( text , color ? ) { if ( color ) { this . _spinner . color = color ; } this . _spinner . text = text ; } public succeed ( text ) { this . _spinner . succeed ( text ) ; } public fail ( text ) { this . _spinner . fail ( text ) ; } } /**
 * Get the scope and name of the NPM package
 */ export function getPackageScopeAndName ( npmName ) { const segIndex = npmName . indexOf ( '/' ) ; const scope = npmName . substr ( 0 , segIndex ) || '' ; const name = npmName . substr ( segIndex + 1 ) ; return { scope , name } ; } /**
 * Get the NPM package download address
 */ export async function getNpmTarSrc ( name ) { const hostNPM = getGlobalInfo ( ) . host . npm ; const { data } = await axios ( { url : `${ hostNPM }${ name }` , method : 'GET' , responseType : 'json' , } ) ; const version = data [ `dist-tags` ] . latest ; return { npmTarSrc : data . versions [ version ] . dist . tarball , version , } ; } /**
 * Use wget to download files
 */ export async function wgetAsync ( src , output , options ? ) { return new Promise ( ( resolve , reject ) => { const download = wget . download ( src , output , options ) ; download . on ( 'error' , function ( err ) { reject ( err ) ; } ) ; download . on ( 'end' , function ( output ) { resolve ( output ) ; } ) ; } ) ; } /**
 * Get dependencies already installed
 */ export function getExistingDependencies ( filePath ) { const breakCondition = '/' ; let curPath = filePath ; while ( curPath !== breakCondition ) { const pathPackageJson = path . resolve ( curPath , 'package.json' ) ; if ( fs . existsSync ( pathPackageJson ) ) { const pkg = require ( path . resolve ( curPath , 'package.json' ) ) ; return pkg . dependencies || { } ; } curPath = path . resolve ( curPath , '../' ) ; } } /**
 * Get dependencies need to install
 */ export function getNewDependencies ( existingDependencies , willInstalledDependencies ) { const allKeys = Object . keys ( willInstalledDependencies ) ; const keys = allKeys . map ( ( item ) => { if ( ! existingDependencies [ item ] ) { return item ; } } ) ; return keys || [ ] ; } /**
 * Get the name and version of the dependent package
 */ export function getDependenceNameAndVersion ( dependencies , filters ) { let dependenciesArr = [ ] ; const keys = Object . keys ( dependencies ) ; dependenciesArr = keys . map ( ( item ) => { if ( filters . includes ( item ) ) { return `${ item }@${ dependencies [ item ] }` ; } } ) ; return dependenciesArr . join ( ' ' ) . trim ( ) ; } /**
 * Get the way of dependency management
 */ function getProjectPackageControlType ( curPath ) { const breakCondition = '/' ; while ( curPath !== breakCondition ) { const packageLockPath = path . resolve ( curPath , 'package-lock.json' ) ; const yarnLockPath = path . resolve ( curPath , 'yarn.lock' ) ; if ( fs . existsSync ( yarnLockPath ) ) { return 'yarn' ; } if ( fs . existsSync ( packageLockPath ) ) { return 'npm' ; } curPath = path . resolve ( curPath , '../' ) ; } return 'yarn' ; } /**
 * Install npm dependencies
 */ export async function installDependency ( npmName , cwdPath , logFun ) { return new Promise ( ( resolve ) => { const type = getProjectPackageControlType ( cwdPath ) ; const registry = getGlobalInfo ( ) . host . npm ; const ls = exec ( type === 'yarn' ? `yarn add ${ npmName } -S --registry=${ registry }` : `npm i ${ npmName } -S --registry=${ registry }` , { cwd : cwdPath , } ) ; ls . stdout && ls . stdout . on ( 'data' , function ( data ) { logFun ( data . toString ( ) ) ; } ) ; ls . stderr && ls . stderr . on ( 'data' , function ( data ) { logFun ( data . toString ( ) ) ; } ) ; ls . on ( 'exit' , function ( exitcode ) { resolve ( exitcode ) ; } ) ; } ) ; } /**
 * Format error message
 */ export function stringifyError ( e ) { return `${ e . message }\n${ e . stack }` ; } export async function formatCodeWithPrettierAndEslint ( code , filename , parser ? ) { const resolvePrettierConfig = await prettier . resolveConfig ( filename ) ; const prettierConfig = resolvePrettierConfig || { } ; prettierConfig . parser = parser || 'typescript' ; const prettyCode = prettier . format ( code , prettierConfig ) ; const eslinted = await lintAndFixCode ( filename , prettyCode ) ; return eslinted ; } async function lintAndFixCode ( filename , source ) { const eslint = new ESLint ( { fix : true } ) ; const messages = await eslint . lintText ( source , { filePath : filename } ) ; const lintResult = messages [ 0 ] ; return lintResult . output || source ; }