New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Rewrite lib/copy/ncp.js #374
Changes from 14 commits
2dbc3b3
84681ed
8175d0d
364a114
6e0cc40
10a5d11
d139e4f
0d81c2c
469d55c
436a587
7d1857d
b9834f9
70f2c7c
6271e98
cecd184
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
'use strict' | ||
|
||
const fs = require('fs') | ||
const os = require('os') | ||
const fse = require(process.cwd()) | ||
const path = require('path') | ||
const assert = require('assert') | ||
const copy = require('../copy') | ||
|
||
/* global afterEach, beforeEach, describe, it */ | ||
|
||
describe('copy() - broken symlink', () => { | ||
const TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'copy-broken-symlinks') | ||
const src = path.join(TEST_DIR, 'src') | ||
const out = path.join(TEST_DIR, 'out') | ||
|
||
beforeEach(done => { | ||
fse.emptyDir(TEST_DIR, err => { | ||
assert.ifError(err) | ||
createFixtures(src, done) | ||
}) | ||
}) | ||
|
||
afterEach(done => fse.remove(TEST_DIR, done)) | ||
|
||
it('should copy broken symlinks by default', done => { | ||
copy(src, out, err => { | ||
assert.ifError(err) | ||
assert.equal(fs.readlinkSync(path.join(out, 'broken-symlink')), path.join(src, 'does-not-exist')) | ||
done() | ||
}) | ||
}) | ||
|
||
it('should throw an error when dereference=true', done => { | ||
copy(src, out, {dereference: true}, err => { | ||
assert.strictEqual(err.code, 'ENOENT') | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
function createFixtures (srcDir, callback) { | ||
fs.mkdir(srcDir, err => { | ||
let brokenFile | ||
let brokenFileLink | ||
|
||
if (err) return callback(err) | ||
|
||
try { | ||
brokenFile = path.join(srcDir, 'does-not-exist') | ||
brokenFileLink = path.join(srcDir, 'broken-symlink') | ||
fs.writeFileSync(brokenFile, 'does not matter') | ||
fs.symlinkSync(brokenFile, brokenFileLink, 'file') | ||
} catch (err) { | ||
callback(err) | ||
} | ||
|
||
// break the symlink now | ||
fse.remove(brokenFile, callback) | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
'use strict' | ||
|
||
const assert = require('assert') | ||
const os = require('os') | ||
const path = require('path') | ||
const fs = require(process.cwd()) | ||
const klawSync = require('klaw-sync') | ||
|
||
/* global beforeEach, afterEach, describe, it */ | ||
|
||
describe('+ copySync() - prevent copying identical files and dirs', () => { | ||
let TEST_DIR = '' | ||
let src = '' | ||
let dest = '' | ||
|
||
beforeEach(done => { | ||
TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'copy-sync-prevent-copying-identical') | ||
fs.emptyDir(TEST_DIR, done) | ||
}) | ||
|
||
afterEach(done => fs.remove(TEST_DIR, done)) | ||
|
||
it('should return an error if src and dest are the same', done => { | ||
const fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_copy_sync') | ||
const fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy_sync') | ||
|
||
fs.copy(fileSrc, fileDest, err => { | ||
assert.equal(err.message, 'Source and destination must not be the same.') | ||
done() | ||
}) | ||
}) | ||
|
||
// src is directory: | ||
// src is regular, dest is symlink | ||
// src is symlink, dest is regular | ||
// src is symlink, dest is symlink | ||
|
||
describe('> when the source is a directory', () => { | ||
describe(`>> when src is regular and dest is a symlink that points to src`, () => { | ||
it('should not copy and return', done => { | ||
src = path.join(TEST_DIR, 'src') | ||
fs.mkdirsSync(src) | ||
const subdir = path.join(TEST_DIR, 'src', 'subdir') | ||
fs.mkdirsSync(subdir) | ||
fs.writeFileSync(path.join(subdir, 'file.txt'), 'some data') | ||
|
||
const destLink = path.join(TEST_DIR, 'dest-symlink') | ||
fs.symlinkSync(src, destLink, 'dir') | ||
|
||
const oldlen = klawSync(src).length | ||
|
||
fs.copy(src, destLink, err => { | ||
assert.ifError(err) | ||
|
||
const newlen = klawSync(src).length | ||
assert.strictEqual(newlen, oldlen) | ||
const link = fs.readlinkSync(destLink) | ||
assert.strictEqual(link, src) | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe(`>> when src is a symlink that points to a regular dest`, () => { | ||
it('should not copy and return', done => { | ||
dest = path.join(TEST_DIR, 'dest') | ||
fs.mkdirsSync(dest) | ||
const subdir = path.join(TEST_DIR, 'dest', 'subdir') | ||
fs.mkdirsSync(subdir) | ||
fs.writeFileSync(path.join(subdir, 'file.txt'), 'some data') | ||
|
||
const srcLink = path.join(TEST_DIR, 'src-symlink') | ||
fs.symlinkSync(dest, srcLink, 'dir') | ||
|
||
const oldlen = klawSync(dest).length | ||
|
||
fs.copy(srcLink, dest, err => { | ||
assert.ifError(err) | ||
|
||
// assert nothing copied | ||
const newlen = klawSync(dest).length | ||
assert.strictEqual(newlen, oldlen) | ||
const link = fs.readlinkSync(srcLink) | ||
assert.strictEqual(link, dest) | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe('>> when src and dest are symlinks that point to the exact same path', () => { | ||
it('should not copy and return', done => { | ||
src = path.join(TEST_DIR, 'src') | ||
fs.mkdirsSync(src) | ||
const srcLink = path.join(TEST_DIR, 'src_symlink') | ||
fs.symlinkSync(src, srcLink, 'dir') | ||
const destLink = path.join(TEST_DIR, 'dest_symlink') | ||
fs.symlinkSync(src, destLink, 'dir') | ||
|
||
const srclenBefore = klawSync(srcLink).length | ||
const destlenBefore = klawSync(destLink).length | ||
|
||
fs.copy(srcLink, destLink, err => { | ||
assert.ifError(err) | ||
|
||
const srclenAfter = klawSync(srcLink).length | ||
assert.strictEqual(srclenAfter, srclenBefore, 'src length should not change') | ||
const destlenAfter = klawSync(destLink).length | ||
assert.strictEqual(destlenAfter, destlenBefore, 'dest length should not change') | ||
|
||
const srcln = fs.readlinkSync(srcLink) | ||
assert.strictEqual(srcln, src) | ||
const destln = fs.readlinkSync(destLink) | ||
assert.strictEqual(destln, src) | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
|
||
// src is file: | ||
// src is regular, dest is symlink | ||
// src is symlink, dest is regular | ||
// src is symlink, dest is symlink | ||
|
||
describe('> when the source is a file', () => { | ||
describe(`>> when src is regular and dest is a symlink that points to src`, () => { | ||
it('should not copy and return', done => { | ||
src = path.join(TEST_DIR, 'src', 'somefile.txt') | ||
fs.ensureFileSync(src) | ||
fs.writeFileSync(src, 'some data') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. It will be changed to use |
||
|
||
const destLink = path.join(TEST_DIR, 'dest-symlink') | ||
fs.symlinkSync(src, destLink, 'file') | ||
|
||
fs.copy(src, destLink, err => { | ||
assert.ifError(err) | ||
|
||
const link = fs.readlinkSync(destLink) | ||
assert.strictEqual(link, src) | ||
assert(fs.readFileSync(link, 'utf8'), 'some data') | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe(`>> when src is a symlink that points to a regular dest`, () => { | ||
it('should not copy and return', done => { | ||
dest = path.join(TEST_DIR, 'dest', 'somefile.txt') | ||
fs.ensureFileSync(dest) | ||
fs.writeFileSync(dest, 'some data') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
|
||
const srcLink = path.join(TEST_DIR, 'src-symlink') | ||
fs.symlinkSync(dest, srcLink, 'file') | ||
|
||
fs.copy(srcLink, dest, err => { | ||
assert.ifError(err) | ||
|
||
const link = fs.readlinkSync(srcLink) | ||
assert.strictEqual(link, dest) | ||
assert(fs.readFileSync(link, 'utf8'), 'some data') | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe('>> when src and dest are symlinks that point to the exact same path', () => { | ||
it('should not copy and return', done => { | ||
src = path.join(TEST_DIR, 'src', 'srcfile.txt') | ||
fs.ensureFileSync(src) | ||
fs.writeFileSync(src, 'src data') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
|
||
const srcLink = path.join(TEST_DIR, 'src_symlink') | ||
fs.symlinkSync(src, srcLink, 'file') | ||
|
||
const destLink = path.join(TEST_DIR, 'dest_symlink') | ||
fs.symlinkSync(src, destLink, 'file') | ||
|
||
fs.copy(srcLink, destLink, err => { | ||
assert.ifError(err) | ||
|
||
const srcln = fs.readlinkSync(srcLink) | ||
assert.strictEqual(srcln, src) | ||
const destln = fs.readlinkSync(destLink) | ||
assert.strictEqual(destln, src) | ||
assert(fs.readFileSync(srcln, 'utf8'), 'src data') | ||
assert(fs.readFileSync(destln, 'utf8'), 'src data') | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be changed to use
fs.outputFileSync()
.