import * as moment from 'moment' ; import * as fs from 'fs' ; import { exec } from 'child_process' ; import { sep } from 'path' ; import { WebviewMsg } from '../util/dataStatement' ; import { RandomNumber } from '../util/util' ; import { getPanelWebview , outputLog , isProduction , getExtensionContext , } from '../util/vscodeUtil' ; import WebView from './WebView' ; interface TimeElement { value : Array < string > ; commitNumber : number ; } interface DayTime { value : string ; commitNumber : number ; } const getAllDay = ( begin , end ) => { const timeArr = [ ] ; const beginDate = moment ( begin ) . toDate ( ) ; const beginNumber = beginDate . getTime ( ) ; const endDate = moment ( end ) . toDate ( ) ; const endNumber = endDate . getTime ( ) ; for ( let k = beginNumber ; k <= endNumber ; ) { const day = new Date ( parseInt ( k ) ) ; const dayFormat = moment ( day ) . format ( 'YYYY-MM-DD' ) ; timeArr . push ( dayFormat ) ; k += 24 * 60 * 60 * 1000 ; } return timeArr ; } ; const getTodayRandomNumber = ( time ) => { const hour1 = RandomNumber ( 0 , 2 ) ; let hour2 = RandomNumber ( 0 , 9 ) ; if ( hour1 === 2 ) { hour2 = RandomNumber ( 0 , 3 ) ; } const minute = `${ RandomNumber ( 0 , 5 ) }${ RandomNumber ( 0 , 9 ) }` ; const hour = `${ hour1 }${ hour2 }` ; return `${ time } ${ hour }:${ minute }` ; } ; class CommitHandle { public paramsObj : any ; public moreObj : any ; public timeArr : Array < DayTime > ; public autoCommitView : WebView ; private userCancel : boolean ; private totalCommit : number ; constructor ( message ) { this . paramsObj = message . data . form ; this . moreObj = message . data . moreObj ; this . timeArr = [ ] ; this . totalCommit = 0 ; this . userCancel = false ; this . timeHandle ( ) ; this . autoCommitView = getPanelWebview ( ) ; } timeHandle ( ) { this . paramsObj . timeArr . forEach ( ( item ) => { const detailTimeArr = getAllDay ( item . value [ 0 ] , item . value [ 1 ] ) ; detailTimeArr . forEach ( ( ele ) => { const index = this . timeArr . findIndex ( ( element ) => element . value === ele ) ; if ( index !== - 1 ) { this . timeArr . splice ( index , 1 ) ; } const dayCommitNumber = this . getDayCommitNumber ( item . commitNumber ) ; this . totalCommit = dayCommitNumber + this . totalCommit ; this . timeArr . push ( { value : ele , commitNumber : dayCommitNumber , } ) ; } ) ; } ) ; this . sortTime ( ) ; } sortTime ( ) { this . timeArr = this . timeArr . sort ( ( item1 , item2 ) : number => { const dateArr1 = item1 . value . split ( '-' ) ; const dateArr2 = item2 . value . split ( '-' ) ; if ( dateArr1 [ 0 ] === dateArr2 [ 0 ] ) { if ( dateArr1 [ 1 ] === dateArr2 [ 1 ] ) { return dateArr1 [ 2 ] - dateArr2 [ 2 ] ; } return dateArr1 [ 1 ] - dateArr2 [ 1 ] ; } return dateArr1 [ 0 ] - dateArr2 [ 0 ] ; } ) ; this . deleteDayArrDay ( ) ; this . commitFn ( ) ; } deleteDayArrDay ( ) { const { noCommitDay } = this . moreObj ; const { scopeDay } = this . moreObj ; if ( scopeDay < 1 || noCommitDay < 1 ) return ; if ( scopeDay > this . timeArr . length ) return ; for ( let i = 0 ; i < noCommitDay ; i += 1 ) { const ranDomNum = Math . floor ( Math . random ( ) * this . timeArr . length ) ; this . timeArr . splice ( ranDomNum , 1 ) ; } } async commitFn ( ) { await outputLog ( '将要commit的日期:' , JSON . stringify ( this . timeArr ) ) ; outputLog ( '总commit天数:' , this . timeArr . length ) ; outputLog ( '总commit次数:' , this . totalCommit ) ; let totalNum = 0 ; if ( sep === '\\' ) { const reg = new RegExp ( /\\/g ) ; this . paramsObj . itemSrc = `${ this . paramsObj . itemSrc . replace ( reg , '/' ) }` ; } for ( const item of this . timeArr . values ( ) ) { if ( this . cancelCommit ( ) ) break ; const dayCommitNumber = item . commitNumber ; for ( let i = 0 ; i < dayCommitNumber ; i += 1 ) { if ( this . cancelCommit ( ) ) break ; let time = getTodayRandomNumber ( item . value ) ; time = moment ( time ) . format ( ) ; const commitContent = this . commitFileContent ( time , totalNum ) ; let commitMsg ; const isDebug = false ; if ( ! isProduction ( ) || ! isDebug ) { try { const commitCmd = 'git add .' ; commitMsg = await this . execCmd ( commitCmd ) ; const cmd = `git commit --date='${ time }' -am '${ this . paramsObj . commitMsg }'` ; commitMsg = await this . execCmd ( cmd ) ; } catch ( err ) { outputLog ( `commit出错:${ err }` ) ; continue ; } } else { await new Promise ( ( resolve ) => { setTimeout ( ( ) => { outputLog ( '延迟一秒' ) ; resolve ( '延迟一秒' ) ; } , 1000 ) ; } ) ; } totalNum += 1 ; console . log ( `${ totalNum }commit内容` , commitContent ) ; console . log ( `${ totalNum }commit信息` , commitMsg ) ; } } this . pushCommitFn ( totalNum ) ; } async pushCommitFn ( totalNum ) { const commitNumberBig = 100 ; let thinkNumber = 10000 ; if ( totalNum > commitNumberBig ) { outputLog ( `commit数量:${ totalNum }` ) ; outputLog ( 'commit数量超过100次,请考虑10秒钟是否需要取消commit' ) ; } else { thinkNumber = 2000 ; } await new Promise ( ( resolve ) => { setTimeout ( resolve , thinkNumber ) ; } ) ; if ( this . cancelCommit ( ) ) { if ( totalNum === 0 ) return ; await this . resetCommit ( totalNum ) ; this . commitEnd ( totalNum , true ) ; } else { outputLog ( '提交中...' ) ; this . autoCommitView . postMessage ( '提交中...' , '提交中' ) ; const cmd = 'git pull --rebase  && git push' ; const res = await this . execCmd ( cmd ) ; outputLog ( '提交信息:' , res ) ; this . commitEnd ( totalNum ) ; } } async resetCommit ( totalNum ) { this . autoCommitView . postMessage ( '回滚' , '回滚' ) ; outputLog ( '回滚中...' ) ; const cmd = `git reset --hard HEAD~${ totalNum }` ; const p = await this . execCmd ( cmd ) ; outputLog ( `回滚${ totalNum }次commit成功:` , p ) ; return p ; } commitEnd ( totalNum , cancel = false ) { this . userCancel = false ; if ( ! cancel ) { this . autoCommitView . postMessage ( 'commit 完成' , this . paramsObj ) ; getExtensionContext ( ) . globalState . update ( 'commit-params' , this . paramsObj ) ; outputLog ( '自动commit完成' , `总commit次数${ totalNum }` ) ; } outputLog ( '保存参数信息' ) ; } cancelCommit ( ) { if ( this . userCancel ) { outputLog ( '终止自动commit' ) ; } return this . userCancel ; } public closeCommit ( ) { this . userCancel = true ; } commitFileContent ( time , totalNum ) { const commitContent = `${ time }\n随机数:${ RandomNumber ( 1 , 100000 ) }\n提交次数:${ totalNum + 1 }` ; fs . writeFileSync ( `${ this . paramsObj . itemSrc }/${ this . paramsObj . fileName }` , commitContent , 'utf-8' ) ; return commitContent ; } execCmd ( cmd ) { return new Promise ( ( resolve , reject ) => { exec ( cmd , { cwd : this . paramsObj . itemSrc , env : process . env , } , ( error , stdout , stderr ) => { if ( error ) { outputLog ( `执行命令出错:${ cmd }` ) ; outputLog ( `错误信息:${ error }` , stderr ) ; reject ( error ) ; return ; } resolve ( stdout ) ; } ) ; } ) ; } getDayCommitNumber ( commitNumber ) { let dayCommitNumber = this . paramsObj . commitNumber ; if ( this . paramsObj . randomCommit ) { dayCommitNumber = RandomNumber ( 1 , this . paramsObj . commitNumber ) ; } if ( commitNumber !== 0 ) { dayCommitNumber = commitNumber ; } return dayCommitNumber ; } } export default CommitHandle ;