1import { Task } from './Task'; 2import fs from 'fs-extra'; 3import chalk from 'chalk'; 4import spawnAsync from '@expo/spawn-async'; 5 6type CloneSettings = 7 | { 8 branch: string; 9 } 10 | { 11 tag: string; 12 } 13 | { 14 commit: string; 15 } 16 | {}; 17 18export type CloneRepoSettings = { 19 url: string; 20 destination?: string; 21} & CloneSettings; 22 23/** 24 * A task which will clone repository into the provided destination or into the working directory. 25 */ 26export class Clone extends Task { 27 private readonly url: string; 28 private readonly options: CloneSettings; 29 private destination?: string; 30 31 constructor({ url, destination, ...options }: CloneRepoSettings) { 32 super(); 33 this.url = url; 34 this.destination = destination; 35 this.options = options; 36 } 37 38 protected overrideWorkingDirectory(): string | undefined { 39 return this.destination; 40 } 41 42 async execute() { 43 const workDirectory = this.getWorkingDirectory(); 44 45 this.logSubStep( 46 ` remove ${chalk.yellow(this.overrideWorkingDirectory() || '<workingDirectory>')}` 47 ); 48 await fs.remove(workDirectory); 49 50 this.logSubStep( 51 ` clone repo ${chalk.green(this.url)} into ${chalk.yellow( 52 this.overrideWorkingDirectory() || '<workingDirectory>' 53 )}` 54 ); 55 56 const cloneArguments = this.cloneArguments(); 57 this.logDebugInfo(`run git clone ${cloneArguments.join(' ')}`); 58 await spawnAsync('git', ['clone', ...cloneArguments, this.url, workDirectory]); 59 60 if ('commit' in this.options) { 61 this.logDebugInfo(`run git checkout ${this.options.commit}`); 62 await spawnAsync('git', ['checkout', this.options.commit], { cwd: workDirectory }); 63 } 64 } 65 66 cloneArguments(): string[] { 67 // if a branch or tag was provided, we don't need to clone the whole repo. 68 const args = ['--depth', '1']; 69 if ('branch' in this.options) { 70 args.push('--branch', this.options.branch); 71 } else if ('tag' in this.options) { 72 args.push('--branch', this.options.tag); 73 } else if ('commit' in this.options) { 74 return []; 75 } 76 return args; 77 } 78} 79