Skip to content

Commit

Permalink
destroy deletes empty folders
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly Selden committed Sep 18, 2016
1 parent f5b98e5 commit 69c01d1
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/models/blueprint.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var printableProperties = require('../utilities/printable-properties').blueprint
var sequence = require('../utilities/sequence');
var printCommand = require('../utilities/print-command');
var insertIntoFile = require('../utilities/insert-into-file');
var cleanRemove = require('../utilities/clean-remove');
var fs = require('fs-extra');
var existsSync = require('exists-sync');
var inflector = require('inflection');
Expand All @@ -28,7 +29,6 @@ var normalizeEntityName = require('ember-cli-normalize-entity-name');

var stat = Promise.denodeify(fs.stat);
var writeFile = Promise.denodeify(fs.outputFile);
var removeFile = Promise.denodeify(fs.remove);

/**
A blueprint is a bundle of template files with optional install
Expand Down Expand Up @@ -328,7 +328,7 @@ var Blueprint = CoreObject.extend({
remove: function(info) {
this._writeStatusToUI(chalk.red, 'remove', info.displayPath);
if (!this.dryRun) {
return removeFile(info.outputPath);
return cleanRemove(info);
}
}
},
Expand Down
37 changes: 37 additions & 0 deletions lib/utilities/clean-remove.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

var fs = require('fs-extra');
var Promise = require('../ext/promise');
var walkUp = require('./walk-up-path');
var remove = Promise.denodeify(fs.remove);
var readdir = Promise.denodeify(fs.readdir);

function cleanRemove(fileInfo) {
return remove(fileInfo.outputPath).then(function() {
var paths = walkUp(fileInfo.displayPath);

var linkedPromise = paths.reduce(function(linkedPromise, thePath) {
return linkedPromise.then(function(wasShortCircuited) {
if (wasShortCircuited) {
// optimization that says since my child dir wasn't empty,
// I can't be empty, so keep skipping
return true;
}

return readdir(thePath).then(function(paths) {
if (paths.length) {
// don't check parent dirs since this one isn't empty
return true;
}
return remove(thePath).then(function() {
return false;
});
});
});
}, Promise.resolve());

return linkedPromise;
});
}

module.exports = cleanRemove;
16 changes: 16 additions & 0 deletions lib/utilities/walk-up-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

var path = require('path');

function walkUp(thePath) {
return (function _walkUp(currentPath, paths) {
currentPath = path.dirname(currentPath);
if (currentPath === '.') {
return paths;
}
paths.push(currentPath);
return _walkUp(currentPath, paths);
})(thePath, []);
}

module.exports = walkUp;
78 changes: 78 additions & 0 deletions tests/unit/utilities/clean-remove-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict';

var expect = require('chai').expect;
var cleanRemove = require('../../../lib/utilities/clean-remove');
var temp = require('temp');
var path = require('path');
var Promise = require('../../../lib/ext/promise');
var fs = require('fs-extra');

var outputFile = Promise.denodeify(fs.outputFile);
var stat = Promise.denodeify(fs.stat);

describe('clean-remove', function() {
var tempDir;
var originalCwd = process.cwd();
var nestedPath = 'nested1/nested2';

beforeEach(function() {
tempDir = temp.mkdirSync('clean-remove');
process.chdir(tempDir);
});

afterEach(function() {
process.chdir(originalCwd);
fs.removeSync(tempDir);
});

it('removes empty folders', function() {
var displayPath = path.join(nestedPath, 'file.txt');
var fileInfo = {
outputPath: path.join(tempDir, displayPath),
displayPath: displayPath
};

return outputFile(displayPath, '').then(function() {
return stat(displayPath).then(function(stats) {
expect(stats).to.be.ok;
});
}).then(function() {
return cleanRemove(fileInfo);
}).then(function() {
return stat('nested1').then(function() {
expect(false).to.be.ok;
}).catch(function(err) {
expect(err).to.be.ok;
});
});
});

it('preserves filled folders', function() {
var removedDisplayPath = path.join(nestedPath, 'file.txt');
var preservedDisplayPath = path.join(nestedPath, 'file2.txt');
var fileInfo = {
outputPath: path.join(tempDir, removedDisplayPath),
displayPath: removedDisplayPath
};

return outputFile(removedDisplayPath, '').then(function() {
return outputFile(preservedDisplayPath, '');
}).then(function() {
return stat(preservedDisplayPath).then(function(stats) {
expect(stats).to.be.ok;
});
}).then(function() {
return cleanRemove(fileInfo);
}).then(function() {
return stat(removedDisplayPath).then(function() {
expect(false).to.be.ok;
}).catch(function(err) {
expect(err).to.be.ok;
});
}).then(function() {
return stat(preservedDisplayPath).then(function(stats) {
expect(stats).to.be.ok;
});
});
});
});
16 changes: 16 additions & 0 deletions tests/unit/utilities/walk-up-path-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

var expect = require('chai').expect;
var walkUp = require('../../../lib/utilities/walk-up-path');

describe('walk-up-path', function() {
it('walks up paths', function() {
var paths = walkUp('app/templates/my/test.hbs');

expect(paths).to.deep.equal([
'app/templates/my',
'app/templates',
'app',
]);
});
});

0 comments on commit 69c01d1

Please sign in to comment.