import Path from 'path' ; import execa from 'execa' ; import { ToolingLog } from '@kbn/dev-utils' ; export class RepoInfo { constructor ( private readonly log , private readonly dir , private readonly upstreamUrl ) { } async getRecentShasFrom ( sha , size ) { return ( await this . git ( [ 'log' , '--pretty=%P' , `-n` , `${ size }` , sha ] ) ) . split ( '\n' ) . map ( ( l ) => l . trim ( ) ) . filter ( Boolean ) ; } async getMergeBase ( ref , upstreamBranch ) { this . log . info ( 'ensuring we have the latest changelog from upstream' , upstreamBranch ) ; await this . git ( [ 'fetch' , this . upstreamUrl , upstreamBranch ] ) ; this . log . info ( 'determining merge base with upstream' ) ; const mergeBase = await this . git ( [ 'merge-base' , ref , 'FETCH_HEAD' ] ) ; this . log . info ( 'merge base with' , upstreamBranch , 'is' , mergeBase ) ; return mergeBase ; } async getHeadSha ( ) { return await this . git ( [ 'rev-parse' , 'HEAD' ] ) ; } getRelative ( path ) { return Path . relative ( this . dir , path ) ; } private async git ( args ) { const proc = await execa ( 'git' , args , { cwd : this . dir , } ) ; return proc . stdout . trim ( ) ; } async getFilesChangesSinceSha ( sha ) { this . log . debug ( 'determining files changes since sha' , sha ) ; const proc = await execa ( 'git' , [ 'diff' , '--name-only' , sha ] , { cwd : this . dir , } ) ; const files = proc . stdout . trim ( ) . split ( '\n' ) . map ( ( p ) => Path . resolve ( this . dir , p ) ) ; this . log . verbose ( 'found the following changes compared to' , sha , `\n - ${ files . join ( '\n - ' ) }` ) ; return files ; } }