import * as child_process from 'child_process' ; import * as path from 'path' ; import { IBuildifierResult , IBuildifierStdinResult } from './result' ; import { BuildifierConfiguration } from './configuration' ; /** Whether to warn about lint findings or fix them. */ export type BuildifierLintMode = 'fix' | 'warn' ; /** The type of file that buildifier should interpret standard input as. */ export type BuildifierFileType = 'build' | 'bzl' | 'workspace' ; param fileContent param type param applyLintFixes returns export async function buildifierFormat ( cfg , fileContent , type , applyLintFixes ) { const args = [ '--mode=fix' , `--type=${ type }` ] ; if ( applyLintFixes ) { args . push ( '--lint=fix' ) ; } return ( await executeBuildifier ( cfg , fileContent , args , false ) ) . stdout ; } param fileContent param type param lintMode returns export async function buildifierLint ( cfg , fileContent , type , lintMode ) ; param fileContent param type param lintMode returns export async function buildifierLint ( cfg , fileContent , type , lintMode ) ; export async function buildifierLint ( cfg , fileContent , type , lintMode ) { const args = [ '--format=json' , '--mode=check' , `--type=${ type }` , `--lint=${ lintMode }` ] ; const outputs = await executeBuildifier ( cfg , fileContent , args , true ) ; switch ( lintMode ) { case 'fix' : return outputs . stdout ; case 'warn' : const result = JSON . parse ( outputs . stdout ) as IBuildifierResult ; for ( const file of result . files ) { if ( file . filename === '<stdin>' ) { return { success : result . success , file : file , stderr : outputs . stderr } ; } } return { success : false , file : { filename : '<stdin>' , formatted : false , valid : false , warnings : [ ] , } } ; } } param fsPath returns export function getBuildifierFileType ( fsPath ) { const raw = fsPath . toLowerCase ( ) ; let parsedPath = path . parse ( raw ) ; if ( parsedPath . ext === '.oss' ) { parsedPath = path . parse ( parsedPath . name ) ; } if ( parsedPath . ext === '.bzl' || parsedPath . ext === '.sky' ) { return 'bzl' ; } if ( parsedPath . ext === '.build' || parsedPath . name === 'build' || parsedPath . name . startsWith ( 'build.' ) ) { return 'build' ; } if ( parsedPath . ext === '.workspace' || parsedPath . name === 'workspace' || parsedPath . name . startsWith ( 'workspace.' ) ) { return 'workspace' ; } return 'bzl' ; } param fileContent param args param acceptNonSevereErrors function executeBuildifier ( cfg , fileContent , args , acceptNonSevereErrors ) { return new Promise ( ( resolve , reject ) => { const execOptions = { maxBuffer : Number . MAX_SAFE_INTEGER , } ; const process = child_process . execFile ( cfg . executable ! , args , execOptions , ( error , stdout , stderr ) => { if ( ! error || ( acceptNonSevereErrors && shouldTreatBuildifierErrorAsSuccess ( error ) ) ) { resolve ( { stdout , stderr } ) ; } else { reject ( error ) ; } } ) ; process . stdin && process . stdin . write ( fileContent ) ; process . stdin && process . stdin . end ( ) ; } ) ; } param error function shouldTreatBuildifierErrorAsSuccess ( error ) { const code = ( error as any ) . code ; switch ( code ) { case 1 : case 4 : return true ; case undefined : return false ; default : return false ; } }