2020-03-27 17:12:15 +00:00
import * as assert from 'assert'
2020-03-02 16:33:30 +00:00
import * as core from '@actions/core'
import * as fs from 'fs'
import * as fsHelper from './fs-helper'
import * as io from '@actions/io'
import * as path from 'path'
import { IGitCommandManager } from './git-command-manager'
2020-03-27 17:12:15 +00:00
import { IGitSourceSettings } from './git-source-settings'
2020-03-02 16:33:30 +00:00
export async function prepareExistingDirectory (
git : IGitCommandManager | undefined ,
repositoryPath : string ,
repositoryUrl : string ,
clean : boolean
) : Promise < void > {
2020-03-27 17:12:15 +00:00
assert . ok ( repositoryPath , 'Expected repositoryPath to be defined' )
assert . ok ( repositoryUrl , 'Expected repositoryUrl to be defined' )
// Indicates whether to delete the directory contents
2020-03-02 16:33:30 +00:00
let remove = false
// Check whether using git or REST API
if ( ! git ) {
remove = true
}
// Fetch URL does not match
else if (
! fsHelper . directoryExistsSync ( path . join ( repositoryPath , '.git' ) ) ||
repositoryUrl !== ( await git . tryGetFetchUrl ( ) )
) {
remove = true
} else {
// Delete any index.lock and shallow.lock left by a previously canceled run or crashed git process
const lockPaths = [
path . join ( repositoryPath , '.git' , 'index.lock' ) ,
path . join ( repositoryPath , '.git' , 'shallow.lock' )
]
for ( const lockPath of lockPaths ) {
try {
await io . rmRF ( lockPath )
} catch ( error ) {
core . debug ( ` Unable to delete ' ${ lockPath } '. ${ error . message } ` )
}
}
try {
2020-03-27 17:12:15 +00:00
core . startGroup ( 'Removing previously created refs, to avoid conflicts' )
2020-03-02 16:33:30 +00:00
// Checkout detached HEAD
if ( ! ( await git . isDetached ( ) ) ) {
await git . checkoutDetach ( )
}
// Remove all refs/heads/*
let branches = await git . branchList ( false )
for ( const branch of branches ) {
await git . branchDelete ( false , branch )
}
// Remove all refs/remotes/origin/* to avoid conflicts
branches = await git . branchList ( true )
for ( const branch of branches ) {
await git . branchDelete ( true , branch )
}
2020-03-27 17:12:15 +00:00
core . endGroup ( )
2020-03-02 16:33:30 +00:00
// Clean
if ( clean ) {
2020-03-27 17:12:15 +00:00
core . startGroup ( 'Cleaning the repository' )
2020-03-02 16:33:30 +00:00
if ( ! ( await git . tryClean ( ) ) ) {
core . debug (
` The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For futher investigation, manually run 'git clean -ffdx' on the directory ' ${ repositoryPath } '. `
)
remove = true
} else if ( ! ( await git . tryReset ( ) ) ) {
remove = true
}
2020-03-27 17:12:15 +00:00
core . endGroup ( )
2020-03-02 16:33:30 +00:00
if ( remove ) {
core . warning (
` Unable to clean or reset the repository. The repository will be recreated instead. `
)
}
}
} catch ( error ) {
core . warning (
` Unable to prepare the existing repository. The repository will be recreated instead. `
)
remove = true
}
}
if ( remove ) {
// Delete the contents of the directory. Don't delete the directory itself
// since it might be the current working directory.
core . info ( ` Deleting the contents of ' ${ repositoryPath } ' ` )
for ( const file of await fs . promises . readdir ( repositoryPath ) ) {
await io . rmRF ( path . join ( repositoryPath , file ) )
}
}
}