Skip to content

Commit

Permalink
fix: empty directory is not copied with sscaff (#703)
Browse files Browse the repository at this point in the history
Currently `sscaff` does not copy over an empty directory from source to target directory. This PR is adding that functionality.
  • Loading branch information
vinayak-kukreja authored Aug 21, 2023
1 parent 779356f commit d8abc14
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 1 deletion.
4 changes: 4 additions & 0 deletions lib/__tests__/fixture5.expected/myproject/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# this is a gitignore file we use the substitution
# in the file name in order for it not to be treated as a .gitignore
# in the parent project
*.js
1 change: 1 addition & 0 deletions lib/__tests__/fixture5.expected/myproject/foo-dir/foo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is my foo
3 changes: 3 additions & 0 deletions lib/__tests__/fixture5/.hooks.sscaff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.pre = variables => {
variables.name = 'foo'
};
1 change: 1 addition & 0 deletions lib/__tests__/fixture5/{{name}}-dir/{{name}}.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is my {{name}}
4 changes: 4 additions & 0 deletions lib/__tests__/fixture5/{{}}.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# this is a gitignore file we use the {{}} substitution
# in the file name in order for it not to be treated as a .gitignore
# in the parent project
*.js
28 changes: 27 additions & 1 deletion lib/__tests__/sscaff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,50 @@ void testWithFixture('fixture3', {

void testWithFixture('fixture4');

async function testWithFixture(fixture: string, variables?: { [key: string]: string }) {
void testWithFixture('fixture5', { name: 'foo' }, 'empty-dir');

async function testWithFixture(fixture: string, variables?: { [key: string]: string }, emptyDirName?: string) {
test(fixture, async () => {
const input = path.join(__dirname, fixture);
const expected = path.join(__dirname, `${fixture}.expected`);

const [imputEmptyDirPath, expectedEmptyDirPath] = emptyDirName ?
await createEmptyDirsForTesting(input, expected, emptyDirName): [undefined, undefined];

const actual = await fs.mkdtemp('/tmp/sscaff-test');
const outdir = path.join(actual, 'myproject');

await sscaff(input, outdir, variables);

try {
await expectDirsEqual(actual, expected, ['.hooks.sscaff.js']);
} catch (e) {
console.log(`\nto update:\n rsync --delete -av ${actual}/ ${expected}/`);
throw e;
} finally {
// Cleaning up empty dirs created for test, if any
if (imputEmptyDirPath && expectedEmptyDirPath) {
await fs.rmdir(imputEmptyDirPath, { recursive: true });
await fs.rmdir(expectedEmptyDirPath, { recursive: true });
}
}
});
}

async function createEmptyDirsForTesting(input: string, expected: string, emptyDirName: string) {
// For testing an empty directory. We create this during the test to
// avoid using .gitkeep files to retain the folder structure in git
let imputEmptyDirPath;
let expectedEmptyDirPath;

if (emptyDirName) {
imputEmptyDirPath = await fs.mkdir(path.join(input, emptyDirName), { recursive: true });
expectedEmptyDirPath = await fs.mkdir(path.join(expected, 'myproject', emptyDirName), { recursive: true });
}

return [imputEmptyDirPath, expectedEmptyDirPath];
}

async function expectDirsEqual(left: string, right: string, exclude: string[] = []) {
const leftFiles = (await fs.readdir(left)).sort().filter(x => !exclude.includes(x));
const rightFiles = (await fs.readdir(right)).sort().filter(x => !exclude.includes(x));
Expand Down
10 changes: 10 additions & 0 deletions lib/sscaff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ export async function sscaff(sourceDir: string, targetDir: string, variables: {

async function processDirectory(subdir: string) {
const subPath = path.join(sourceDir, subdir);

const contents = await fs.readdir(subPath);

// Empty directory
if ((await fs.stat(subPath)).isDirectory() && contents.length == 0) {
const targetPath = substitute(subdir, variables);
await fs.mkdir(targetPath, { recursive: true });
return;
}

for (const file of await fs.readdir(subPath)) {

if (file === hooksFile) {
Expand Down

0 comments on commit d8abc14

Please sign in to comment.