file author sigmaliu
  import fs from 'fs' ; import path from 'path' ; import globby from 'globby' ; import { execSync } from 'child_process' ; export const cwd = process . cwd ( ) ; export const unknown = 'alloylint-unknown' ; export const BOM = '\uFEFF' ; param params export function occurError ( ... params ) { console . error ( '[alloylint]' , ... params ) ; process . exit ( 0 ) ; } param params export function log ( ... params ) { console . error ( '[alloylint]' , ... params ) ; } param files export function fileFilter ( files ) { const result = [ ] ; for ( const file of files ) { let contents = '' ; try { contents = fs . readFileSync ( file , 'utf8' ) ; } catch ( err ) { continue ; } const lines = contents . split ( /\r?\n/ ) ; const len = lines . length ; let isMini = false ; for ( let j = 0 ; j < len ; j ++ ) { const line = lines [ j ] ; const width = line . length ; if ( width > 1000 ) { isMini = true ; break ; } } if ( ! isMini ) { result . push ( file ) ; } } return result ; } /**
 * glob 转化成文件列表
 */ export async function globToFiles ( args ) { let extensions = [ 'js' , 'jsx' , 'ts' , 'tsx' , 'mjs' , 'vue' ] ; let files = await globby ( args , { expandDirectories : { files : [ '*' ] , extensions , } , ignore : [ '**/node_modules/**' ] , } ) ; extensions = extensions . map ( ( e ) => `.${ e }` ) ; files = files . filter ( ( file ) => extensions . includes ( path . extname ( file ) ) ) ; files = files . map ( ( file ) => path . resolve ( cwd , file ) ) ; files = fileFilter ( files ) ; const filesSet = new Set ( files ) ; files = Array . from ( filesSet ) ; files = files . map ( ( file ) => fs . realpathSync ( file ) ) ; if ( ! files . length ) { occurError ( 'No file to be fixed' ) ; } return files ; } /**
 * 501e975e36b73b8015ce73151ea67c6e4967af5f 1 1 1
 * author auth1
 * author-mail <auth1@tencent.com>
 * author-time 1578735415
 * author-tz +0800
 * committer sigmaliu
 * committer-mail <sigmaliu@tencent.com>
 * committer-time 1578735415
 * committer-tz +0800
 * summary auth1
 * filename demo/demo1.ts
 *      document.documentElement.style['position'] = 'fixed';
 */ export function getAuthAndEmailByBlame ( gitBlame ) { const lines = Array . isArray ( gitBlame ) ? gitBlame : gitBlame . split ( '\n' ) ; let auth = '' ; let email = '' ; for ( const line of lines ) { const each = line . split ( ' ' ) ; if ( each [ 0 ] === 'author' ) { auth = each . slice ( 1 ) . join ( ' ' ) . trim ( ) ; } if ( each [ 0 ] === 'author-mail' ) { email = each . slice ( 1 ) . join ( ' ' ) . trim ( ) ; } } return { auth , email , } ; } param filePath export function getAuthByEachLine ( filePath ) { const lineAuthMapping = [ ] ; const gitBlame = execSync ( `git blame ${ filePath }` ) ; const lines = gitBlame . toString ( ) . split ( '\n' ) ; const len = lines . length ; for ( let i = 0 ; i < len ; i ++ ) { const line = lines [ i ] ; const matches = line . match ( /^\w+\s+\((.*?)\s+\d+-\d+-\d+\s+.*?(\d+)\)/ ) ; if ( matches ) { const auth = matches [ 1 ] ; const codeLine = parseInt ( matches [ 2 ] , 10 ) ; lineAuthMapping [ codeLine ] = auth ; } } return lineAuthMapping ; } param filePath export function getAuthAndEmailMapping ( filePath ) { const authEmailMapping = { } ; const gitBlame = execSync ( `git blame ${ filePath } --line-porcelain` ) . toString ( ) ; const lines = gitBlame . split ( '\n' ) ; const len = lines . length ; for ( let i = 0 ; i < len ; i += 13 ) { const { auth , email } = getAuthAndEmailByBlame ( lines . slice ( i , i + 13 ) ) ; authEmailMapping [ auth ] = email ; } return authEmailMapping ; }