Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jandockx committed Apr 2, 2024
1 parent 0556cef commit bc51ddb
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions lib/Remote.js
Expand Up @@ -9,7 +9,7 @@ const { gitCreate } = require('./git/create/gitCreate')
const { gitEnsureOrigin } = require('./git/origin/gitEnsureOrigin')
const { gitUpdate } = require('./git/update/gitUpdate')
const { ensureOrigin, symLink } = require('./PerformedAction')
const { ensureDir, ensureSymlink, remove } = require('fs-extra')
const { ensureDir, ensureSymlink, remove, lstat } = require('fs-extra')
const { RepositoryRunReport } = require('./RepositoryRunReport')
const { utcNow } = require('./util/time')
const { ServiceRun } = require('./ServiceRun')
Expand Down Expand Up @@ -209,6 +209,26 @@ class Remote {
* @throws {TGitSymLinkFailure}
*/
async ensureGitSymLink() {
/* NOTE: Introduced to work around https://github.com/jprichardson/node-fs-extra/issues/1038 */
const symLinkExists = async absoluteGitSymLinkPath => {
try {
const stats = await lstat(absoluteGitSymLinkPath)
if (!stats.isSymbolicLink()) {
this.logInfo(`${this.gitSymLinkPath} exists, but is not a symbolic link`)
} else {
this.logInfo(`${this.gitSymLinkPath} exists, and is a symbolic link`)
}
return true
} catch (err) {
if (err.code === 'ENOENT') {
this.logInfo(`${this.gitSymLinkPath} does not exist`)
return false
}

throw err
}
}

this.logInfo(`ensuring symbolic link to ${this.mirrorClonePath} at ${this.gitSymLinkPath} …`)
/** @type {TGitSymLinkSuccess} */
const progress = {
Expand All @@ -219,20 +239,22 @@ class Remote {
}
const absoluteGitSymLinkPath = this.serviceRun.absolutePath(this.gitSymLinkPath)
try {
/* NOTE: We remove the symbolic link, if it exists, before we do anything else, to work around
https://github.com/jprichardson/node-fs-extra/issues/1038
We only do this when the target exists. Otherwise we leave it alone. */
const [gitSymLinkExists] = await Promise.all([
symLinkExists(absoluteGitSymLinkPath),
// `lstat` will throw `ENOENT` when it does not exist, which is what we want; we are not interested in the result
lstat(this.serviceRun.absolutePath(this.mirrorClonePath))
])
if (gitSymLinkExists) {
await remove(absoluteGitSymLinkPath)
progress.overwritten = true
}
await ensureSymlink(this.gitSymLinkReference, absoluteGitSymLinkPath, 'dir')
this.logInfo(`created symbolic link to ${this.mirrorClonePath} at ${this.gitSymLinkPath}`)
return progress
} catch (err) {
if (err.code === 'EEXIST') {
await remove(absoluteGitSymLinkPath)
await ensureSymlink(this.gitSymLinkReference, absoluteGitSymLinkPath, 'dir')
this.logInfo(
`created symbolic link to ${this.mirrorClonePath} at ${this.gitSymLinkPath} (overwritten what was there)`
)
progress.overwritten = true
return progress
}

const errorMessage = singleLineTrimmed(err.message)
this.logWarning(
`could not create symbolic link to ${this.mirrorClonePath} at ${this.gitSymLinkPath}: "${errorMessage}"`
Expand Down

0 comments on commit bc51ddb

Please sign in to comment.