-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[plugin cli] Retry folder rename on windows eperm
Backports PR #9260 **Commit 1:** [plugin cli] Retry folder rename on windows eperm * Original sha: 398662f * Authored by Jonathan Budzenski <[email protected]> on 2016-11-29T20:05:19Z
- Loading branch information
1 parent
59b31e5
commit 5eb63f3
Showing
3 changed files
with
95 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import expect from 'expect.js'; | ||
import sinon from 'sinon'; | ||
import fs from 'fs'; | ||
|
||
import { renamePlugin } from '../rename'; | ||
|
||
describe('plugin folder rename', function () { | ||
let renameStub; | ||
|
||
beforeEach(function () { | ||
renameStub = sinon.stub(); | ||
}); | ||
|
||
afterEach(function () { | ||
fs.rename.restore(); | ||
}); | ||
|
||
it('should rethrow any exceptions', function () { | ||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) { | ||
cb({ | ||
code: 'error' | ||
}); | ||
}); | ||
|
||
return renamePlugin('/foo/bar', '/bar/foo') | ||
.catch(function (err) { | ||
expect(err.code).to.be('error'); | ||
expect(renameStub.callCount).to.be(1); | ||
}); | ||
}); | ||
|
||
it('should resolve if there are no errors', function () { | ||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) { | ||
cb(); | ||
}); | ||
|
||
return renamePlugin('/foo/bar', '/bar/foo') | ||
.then(function (err) { | ||
expect(renameStub.callCount).to.be(1); | ||
}) | ||
.catch(function () { | ||
throw new Error('We shouln\'t have any errors'); | ||
}); | ||
}); | ||
|
||
describe('Windows', function () { | ||
let platform; | ||
beforeEach(function () { | ||
platform = Object.getOwnPropertyDescriptor(process, 'platform'); | ||
Object.defineProperty(process, 'platform', { | ||
value: 'win32' | ||
}); | ||
}); | ||
afterEach(function () { | ||
Object.defineProperty(process, 'platform', platform); | ||
}); | ||
|
||
it('should retry on Windows EPERM errors for up to 3 seconds', function () { | ||
this.timeout(5000); | ||
renameStub = sinon.stub(fs, 'rename', function (from, to, cb) { | ||
cb({ | ||
code: 'EPERM' | ||
}); | ||
}); | ||
return renamePlugin('/foo/bar', '/bar/foo') | ||
.catch(function (err) { | ||
expect(err.code).to.be('EPERM'); | ||
expect(renameStub.callCount).to.be.greaterThan(1); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { rename } from 'fs'; | ||
import { delay } from 'lodash'; | ||
|
||
export function renamePlugin(workingPath, finalPath) { | ||
return new Promise(function (resolve, reject) { | ||
const start = Date.now(); | ||
const retryTime = 3000; | ||
const retryDelay = 100; | ||
rename(workingPath, finalPath, function retry(err) { | ||
if (err) { | ||
// In certain cases on Windows, such as running AV, plugin folders can be locked shortly after extracting | ||
// Retry for up to retryTime seconds | ||
const windowsEPERM = process.platform === 'win32' && err.code === 'EPERM'; | ||
const retryAvailable = Date.now() - start < retryTime; | ||
if (windowsEPERM && retryAvailable) return delay(rename, retryDelay, workingPath, finalPath, retry); | ||
reject(err); | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
} |