Skip to content

Commit 2438dca

Browse files
authored
Merge pull request #965 from bertdeblock/use-system-temp-for-backing-up-package-manager-files
Use the system temp's folder for backing up package-manager files
2 parents f68085c + 01c179e commit 2438dca

17 files changed

Lines changed: 198 additions & 217 deletions

File tree

.eslintignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,3 @@
1414
/coverage/
1515
!.*
1616
.eslintrc.js
17-
18-
# ember-try
19-
/bower.json.ember-try
20-
/package.json.ember-try

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717
/testem.log
1818
/yarn-error.log
1919

20-
# ember-try
21-
/bower.json.ember-try
22-
/package.json.ember-try
23-
2420
/.nyc_output
2521
*.tgz
2622
.scratch

.npmignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@
3030
/yarn.lock
3131
.gitkeep
3232

33-
# ember-try
34-
/bower.json.ember-try
35-
/package.json.ember-try
36-
3733
# custom
3834
/.codeclimate.yml
3935
/test

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ In order to use an alternate config path or to group various scenarios, you can
6161

6262
#### `ember try:reset`
6363

64-
This command restores the original `package.json` from `package.json.ember-try`, `rm -rf`s `node_modules` and runs `npm install`. For use if any of the other commands fail to clean up after (they run this by default on completion).
64+
This command restores all original files, and installs the original node modules again. For use if any of the other commands fail to clean up after (they run this by default on completion) or after running with ‘—skip-cleanup’.
6565

6666
#### `ember try:ember <semver-string>`
6767

lib/dependency-manager-adapters/npm.js

Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,23 @@
22

33
const CoreObject = require('core-object');
44
const fs = require('fs-extra');
5-
const util = require('util');
6-
const copy = util.promisify(fs.copy);
75
const path = require('path');
86
const debug = require('debug')('ember-try:dependency-manager-adapter:npm');
9-
const rimraf = util.promisify(require('rimraf'));
107
const chalk = require('chalk');
118
const semver = require('semver');
9+
const Backup = require('../utils/backup');
1210

1311
module.exports = CoreObject.extend({
1412
init() {
1513
this._super.apply(this, arguments);
14+
this.backup = new Backup({ cwd: this.cwd });
1615
this.run = this.run || require('../utils/run');
1716
},
1817
useYarnCommand: false,
1918
yarnLock: 'yarn.lock',
20-
yarnLockBackupFileName: 'yarn.lock.ember-try',
2119
configKey: 'npm',
2220
packageJSON: 'package.json',
23-
packageJSONBackupFileName: 'package.json.ember-try',
2421
packageLock: 'package-lock.json',
25-
packageLockBackupFileName: 'package-lock.json.ember-try',
2622

2723
async setup(options) {
2824
if (!options) {
@@ -57,20 +53,6 @@ module.exports = CoreObject.extend({
5753
async cleanup() {
5854
try {
5955
await this._restoreOriginalDependencies();
60-
61-
debug('Remove backup package.json and node_modules');
62-
63-
let cleanupTasks = [rimraf(path.join(this.cwd, this.packageJSONBackupFileName))];
64-
65-
if (fs.existsSync(path.join(this.cwd, this.yarnLockBackupFileName))) {
66-
cleanupTasks.push(rimraf(path.join(this.cwd, this.yarnLockBackupFileName)));
67-
}
68-
69-
if (fs.existsSync(path.join(this.cwd, this.packageLockBackupFileName))) {
70-
cleanupTasks.push(rimraf(path.join(this.cwd, this.packageLockBackupFileName)));
71-
}
72-
73-
return await Promise.all(cleanupTasks);
7456
} catch (e) {
7557
console.log('Error cleaning up npm scenario:', e); // eslint-disable-line no-console
7658
}
@@ -139,7 +121,7 @@ module.exports = CoreObject.extend({
139121
return;
140122
}
141123

142-
let backupPackageJSON = path.join(this.cwd, this.packageJSONBackupFileName);
124+
let backupPackageJSON = this.backup.pathForFile(this.packageJSON);
143125
let packageJSONFile = path.join(this.cwd, this.packageJSON);
144126
let packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON));
145127
let newPackageJSON = this._packageJSONForDependencySet(packageJSON, depSet);
@@ -197,49 +179,13 @@ module.exports = CoreObject.extend({
197179
});
198180
},
199181

200-
_restoreOriginalDependencies() {
201-
debug('Restoring original package.json and node_modules');
202-
203-
let restoreTasks = [
204-
copy(
205-
path.join(this.cwd, this.packageJSONBackupFileName),
206-
path.join(this.cwd, this.packageJSON)
207-
),
208-
];
209-
210-
let yarnLockBackupFileName = path.join(this.cwd, this.yarnLockBackupFileName);
211-
if (fs.existsSync(yarnLockBackupFileName)) {
212-
restoreTasks.push(copy(yarnLockBackupFileName, path.join(this.cwd, this.yarnLock)));
213-
}
214-
215-
let packageLockBackupFileName = path.join(this.cwd, this.packageLockBackupFileName);
216-
if (fs.existsSync(packageLockBackupFileName)) {
217-
restoreTasks.push(copy(packageLockBackupFileName, path.join(this.cwd, this.packageLock)));
218-
}
219-
220-
return Promise.all(restoreTasks).then(() => this._install());
182+
async _restoreOriginalDependencies() {
183+
await this.backup.restoreFiles([this.packageJSON, this.packageLock, this.yarnLock]);
184+
await this.backup.cleanUp();
185+
await this._install();
221186
},
222187

223-
_backupOriginalDependencies() {
224-
debug('Backing up package.json and node_modules');
225-
226-
let backupTasks = [
227-
copy(
228-
path.join(this.cwd, this.packageJSON),
229-
path.join(this.cwd, this.packageJSONBackupFileName)
230-
),
231-
];
232-
233-
let yarnLockPath = path.join(this.cwd, this.yarnLock);
234-
if (fs.existsSync(yarnLockPath)) {
235-
backupTasks.push(copy(yarnLockPath, path.join(this.cwd, this.yarnLockBackupFileName)));
236-
}
237-
238-
let packageLockPath = path.join(this.cwd, this.packageLock);
239-
if (fs.existsSync(packageLockPath)) {
240-
backupTasks.push(copy(packageLockPath, path.join(this.cwd, this.packageLockBackupFileName)));
241-
}
242-
243-
return Promise.all(backupTasks);
188+
async _backupOriginalDependencies() {
189+
await this.backup.addFiles([this.packageJSON, this.packageLock, this.yarnLock]);
244190
},
245191
});

lib/dependency-manager-adapters/pnpm.js

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,24 @@ const CoreObject = require('core-object');
44
const fs = require('fs-extra');
55
const path = require('path');
66
const debug = require('debug')('ember-try:dependency-manager-adapter:pnpm');
7+
const Backup = require('../utils/backup');
78

89
const PACKAGE_JSON = 'package.json';
9-
const PACKAGE_JSON_BACKUP = 'package.json.ember-try';
1010
const PNPM_LOCKFILE = 'pnpm-lock.yaml';
1111

12-
// Note: the upstream convention is to append `.ember-try` _after_ the file
13-
// extension, however this breaks syntax highlighting, so I've chosen to
14-
// insert it right before the file extension.
15-
const PNPM_LOCKFILE_BACKUP = 'pnpm-lock.ember-try.yaml';
16-
1712
module.exports = CoreObject.extend({
1813
// This still needs to be `npm` because we're still reading the dependencies
1914
// from the `npm` key of the ember-try config.
2015
configKey: 'npm',
2116

2217
init() {
2318
this._super.apply(this, arguments);
19+
this.backup = new Backup({ cwd: this.cwd });
2420
this.run = this.run || require('../utils/run');
2521
},
2622

2723
async setup() {
28-
let pkg = path.join(this.cwd, PACKAGE_JSON);
29-
let pkgBackup = path.join(this.cwd, PACKAGE_JSON_BACKUP);
30-
debug(`Copying ${PACKAGE_JSON}`);
31-
await fs.copy(pkg, pkgBackup);
32-
33-
let lockFile = path.join(this.cwd, PNPM_LOCKFILE);
34-
let lockFileBackup = path.join(this.cwd, PNPM_LOCKFILE_BACKUP);
35-
if (fs.existsSync(lockFile)) {
36-
debug(`Copying ${PNPM_LOCKFILE}`);
37-
await fs.copy(lockFile, lockFileBackup);
38-
}
24+
await this.backup.addFiles([PACKAGE_JSON, PNPM_LOCKFILE]);
3925
},
4026

4127
async changeToDependencySet(depSet) {
@@ -60,18 +46,8 @@ module.exports = CoreObject.extend({
6046

6147
async cleanup() {
6248
try {
63-
debug(`Restoring original ${PACKAGE_JSON}`);
64-
let pkg = path.join(this.cwd, PACKAGE_JSON);
65-
let pkgBackup = path.join(this.cwd, PACKAGE_JSON_BACKUP);
66-
await fs.copy(pkgBackup, pkg);
67-
await fs.remove(pkgBackup);
68-
69-
debug(`Restoring original ${PNPM_LOCKFILE}`);
70-
let lockFile = path.join(this.cwd, PNPM_LOCKFILE);
71-
let lockFileBackup = path.join(this.cwd, PNPM_LOCKFILE_BACKUP);
72-
await fs.copy(lockFileBackup, lockFile);
73-
await fs.remove(lockFileBackup);
74-
49+
await this.backup.restoreFiles([PACKAGE_JSON, PNPM_LOCKFILE]);
50+
await this.backup.cleanUp();
7551
await this._install();
7652
} catch (e) {
7753
console.log('Error cleaning up scenario:', e); // eslint-disable-line no-console
@@ -118,7 +94,7 @@ module.exports = CoreObject.extend({
11894
return;
11995
}
12096

121-
let backupPackageJSON = path.join(this.cwd, PACKAGE_JSON_BACKUP);
97+
let backupPackageJSON = this.backup.pathForFile(PACKAGE_JSON);
12298
let packageJSONFile = path.join(this.cwd, PACKAGE_JSON);
12399
let packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON));
124100
let newPackageJSON = this._packageJSONForDependencySet(packageJSON, depSet);
@@ -129,12 +105,7 @@ module.exports = CoreObject.extend({
129105
// We restore the original lockfile here, so that we always create a minimal
130106
// diff compared to the original locked dependency set.
131107

132-
let lockFile = path.join(this.cwd, PNPM_LOCKFILE);
133-
let lockFileBackup = path.join(this.cwd, PNPM_LOCKFILE_BACKUP);
134-
if (fs.existsSync(lockFileBackup)) {
135-
debug(`Restoring original ${PNPM_LOCKFILE}`);
136-
await fs.copy(lockFileBackup, lockFile);
137-
}
108+
await this.backup.restoreFile(PNPM_LOCKFILE);
138109
},
139110

140111
_packageJSONForDependencySet(packageJSON, depSet) {

lib/utils/backup.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'use strict';
2+
3+
const debug = require('debug')('ember-try:backup');
4+
const { copy, existsSync } = require('fs-extra');
5+
const { createHash } = require('node:crypto');
6+
const { join } = require('node:path');
7+
const { promisify } = require('node:util');
8+
const remove = promisify(require('rimraf'));
9+
const tempDir = require('temp-dir');
10+
11+
module.exports = class Backup {
12+
constructor({ cwd }) {
13+
this.cwd = cwd;
14+
this.dir = join(tempDir, 'ember-try', createHash('sha256').update(cwd).digest('hex'));
15+
16+
debug(`Created backup directory ${this.dir}`);
17+
}
18+
19+
/**
20+
* Adds a file to the backup directory.
21+
*
22+
* @param {String} filename Filename relative to the current working directory.
23+
* @returns {Promise<void>}
24+
*/
25+
addFile(filename) {
26+
let originalFile = join(this.cwd, filename);
27+
28+
if (existsSync(originalFile)) {
29+
debug(`Adding ${originalFile} to backup directory`);
30+
31+
return copy(originalFile, this.pathForFile(filename));
32+
}
33+
34+
return Promise.resolve();
35+
}
36+
37+
/**
38+
* Adds multiple files to the backup directory.
39+
*
40+
* @param {Array<String>} filenames Filenames relative to the current working directory.
41+
* @returns {Promise<void>}
42+
*/
43+
addFiles(filenames) {
44+
return Promise.all(filenames.map((filename) => this.addFile(filename)));
45+
}
46+
47+
/**
48+
* Cleans up the backup directory.
49+
*
50+
* @returns {Promise<void>}
51+
*/
52+
cleanUp() {
53+
debug(`Cleaning up backup directory ${this.dir}`);
54+
55+
return remove(this.dir);
56+
}
57+
58+
/**
59+
* Returns the absolute path for a file in the backup directory.
60+
*
61+
* @param {String} filename Filename relative to the current working directory.
62+
* @returns {String}
63+
*/
64+
pathForFile(filename) {
65+
return join(this.dir, filename);
66+
}
67+
68+
/**
69+
* Restores a file from the backup directory.
70+
*
71+
* @param {String} filename Filename relative to the current working directory.
72+
* @returns {Promise<void>}
73+
*/
74+
restoreFile(filename) {
75+
let backupFile = this.pathForFile(filename);
76+
77+
if (existsSync(backupFile)) {
78+
debug(`Restoring ${backupFile} from backup directory`);
79+
80+
return copy(backupFile, join(this.cwd, filename));
81+
}
82+
83+
return Promise.resolve();
84+
}
85+
86+
/**
87+
* Restores multiple files from the backup directory.
88+
*
89+
* @param {Array<String>} filenames Filenames relative to the current working directory.
90+
* @returns {Promise<void>}
91+
*/
92+
restoreFiles(filenames) {
93+
return Promise.all(filenames.map((filename) => this.restoreFile(filename)));
94+
}
95+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"resolve": "^1.20.0",
4040
"rimraf": "^3.0.2",
4141
"semver": "^7.5.4",
42+
"temp-dir": "^2.0.0",
4243
"walk-sync": "^2.2.0"
4344
},
4445
"devDependencies": {

smoke-test-app/.eslintignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,3 @@
1515
!.*
1616
.*/
1717
.eslintcache
18-
19-
# ember-try
20-
/bower.json.ember-try
21-
/package.json.ember-try
22-
/package-lock.json.ember-try
23-
/yarn.lock.ember-try

smoke-test-app/.gitignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,5 @@
2020
/testem.log
2121
/yarn-error.log
2222

23-
# ember-try
24-
/bower.json.ember-try
25-
/package.json.ember-try
26-
/package-lock.json.ember-try
27-
/yarn.lock.ember-try
28-
2923
# broccoli-debug
3024
/DEBUG/

0 commit comments

Comments
 (0)