Skip to content

Commit

Permalink
New: --no-initial option
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Sep 4, 2016
1 parent 6324e50 commit bae874a
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 32 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ Options:
<dest> directory before the first copying.
-L, --dereference Follow symbolic links when copying from them.
-h, --help Print usage information.
--include-empty-dirs The flag to copy empty directories which is
--include-empty-dirs The flag to copy empty directories which is
matched with the glob.
--no-initial The flag to not copy at the initial time of watch.
Use together '--watch' option.
-p, --preserve The flag to copy attributes of files.
This attributes are uid, gid, atime, and mtime.
-t, --transform <name> A module name to transform each file. cpx lookups
Expand Down Expand Up @@ -101,12 +103,13 @@ cpx.copy(source, dest, callback)
- **source** `{string}` -- A file glob of copy targets.
- **dest** `{string}` -- A file path of a destination directory.
- **options** `{object}`
- **options.clean** `{boolean}` -- The flag to remove files that copied on past before copy.
- **options.dereference** `{boolean}` -- The flag to follow symbolic links when copying from them.
- **options.includeEmptyDirs** `{boolean}` -- The flag to copy empty directories which is matched with the glob.
- **options.preserve** `{boolean}` -- The flag to copy uid, gid, atime, and mtime of files.
- **options.clean** `{boolean}` -- The flag to remove files that copied on past before copy. Default: `false`.
- **options.dereference** `{boolean}` -- The flag to follow symbolic links when copying from them. Default: `false`.
- **options.includeEmptyDirs** `{boolean}` -- The flag to copy empty directories which is matched with the glob. Default: `false`.
- **options.initialCopy** `{boolean}` -- The flag to not copy at the initial time of watch. This is for `cpx.watch()`. Default: `true`.
- **options.preserve** `{boolean}` -- The flag to copy uid, gid, atime, and mtime of files. Default: `false`.
- **options.transform** `{((filepath: string) => stream.Transform)[]}` -- Functions that creates a `stream.Transform` object to transform each copying file.
- **options.update** `{boolean}` -- The flag to not overwrite files on destination if the source file is older.
- **options.update** `{boolean}` -- The flag to not overwrite files on destination if the source file is older. Default: `false`.
- **callback** `{(err: Error|null) => void}` -- A function that is called at done.

Copy files that matches with `source` glob to `dest` directory.
Expand Down
4 changes: 3 additions & 1 deletion src/bin/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ Options:
<dest> directory before the first copying.
-L, --dereference Follow symbolic links when copying from them.
-h, --help Print usage information.
--include-empty-dirs The flag to copy empty directories which is
--include-empty-dirs The flag to copy empty directories which is
matched with the glob.
--no-initial The flag to not copy at the initial time of watch.
Use together '--watch' option.
-p, --preserve The flag to copy attributes of files.
This attributes are uid, gid, atime, and mtime.
-t, --transform <name> A module name to transform each file. cpx lookups
Expand Down
45 changes: 23 additions & 22 deletions src/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,47 @@ const subarg = require("subarg")

//------------------------------------------------------------------------------
// Parse arguments.
const OPTIONS = {
c: "command",
C: "clean",
h: "help",
includeEmptyDirs: "include-empty-dirs",
L: "dereference",
p: "preserve",
t: "transform",
u: "update",
v: "verbose",
V: "version",
w: "watch",
}
const unknowns = new Set()
const args = subarg(process.argv.slice(2), {
alias: {
c: "command",
C: "clean",
h: "help",
includeEmptyDirs: "include-empty-dirs",
L: "dereference",
p: "preserve",
t: "transform",
u: "update",
v: "verbose",
V: "version",
w: "watch",
},
boolean: [
"clean",
"dereference",
"help",
"include-empty-dirs",
"initial",
"preserve",
"update",
"verbose",
"version",
"watch",
],
alias: OPTIONS,
default: {initial: true},
unknown: (arg) => {
if (arg[0] === "-") {
unknowns.add(arg)
}
},
})
const source = args._[0]
const outDir = args._[1]

//------------------------------------------------------------------------------
// Validate Options.
const knowns = new Set(["_"])
for (const key in OPTIONS) {
knowns.add(key)
knowns.add(OPTIONS[key])
}
const unknowns = Object.keys(args).filter(key => !knowns.has(key))
if (unknowns.length > 0) {
console.error(`Unknown option(s): ${unknowns.join(", ")}`)
if (unknowns.size > 0) {
console.error(`Unknown option(s): ${Array.from(unknowns).join(", ")}`)
process.exit(1)
}

Expand Down
1 change: 1 addition & 0 deletions src/bin/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ module.exports = function main(source, outDir, args) {
transform: mergedTransformFactories,
dereference: args.dereference,
includeEmptyDirs: args.includeEmptyDirs,
initialCopy: args.initial,
preserve: args.preserve,
update: args.update,
}
Expand Down
14 changes: 13 additions & 1 deletion src/lib/cpx.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const Queue = require("./queue")
const BASE_DIR = Symbol("baseDir")
const DEREFERENCE = Symbol("dereference")
const INCLUDE_EMPTY_DIRS = Symbol("include-empty-dirs")
const INITIAL_COPY = Symbol("initialCopy")
const OUT_DIR = Symbol("outDir")
const PRESERVE = Symbol("preserve")
const SOURCE = Symbol("source")
Expand Down Expand Up @@ -145,6 +146,9 @@ module.exports = class Cpx extends EventEmitter {
this[OUT_DIR] = normalizePath(outDir)
this[DEREFERENCE] = Boolean(options.dereference)
this[INCLUDE_EMPTY_DIRS] = Boolean(options.includeEmptyDirs)
this[INITIAL_COPY] =
options.initialCopy === undefined ||
Boolean(options.initialCopy)
this[PRESERVE] = Boolean(options.preserve)
this[TRANSFORM] = [].concat(options.transform).filter(Boolean)
this[UPDATE] = Boolean(options.update)
Expand Down Expand Up @@ -189,6 +193,14 @@ module.exports = class Cpx extends EventEmitter {
return this[INCLUDE_EMPTY_DIRS]
}

/**
* The flag to copy files at the initial time of watch.
* @type {boolean}
*/
get initialCopy() {
return this[INITIAL_COPY]
}

/**
* The flag to copy file attributes.
* @type {boolean}
Expand Down Expand Up @@ -483,7 +495,7 @@ module.exports = class Cpx extends EventEmitter {
if (ready) {
this.enqueueCopy(normalizedPath)
}
else {
else if (this.initialCopy) {
firstCopyCount += 1
this.enqueueCopy(normalizedPath, () => {
firstCopyCount -= 1
Expand Down
4 changes: 2 additions & 2 deletions test/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ describe("[misc]", () => {
const result = execCommandSync("\"test-ws/a/**/*.txt\" test-ws/b --invalid")

assert(result.code === 1)
assert(result.stderr === "Unknown option(s): invalid\n")
assert(result.stderr === "Unknown option(s): --invalid\n")
})

it("should throw error if invalid options were given.", () => {
const result = execCommandSync("\"test-ws/a/**/*.txt\" test-ws/b --invalid --foo --bar")

assert(result.code === 1)
assert(result.stderr === "Unknown option(s): invalid, foo, bar\n")
assert(result.stderr === "Unknown option(s): --invalid, --foo, --bar\n")
})

it("should throw error and show help if <source> and <dest> were lacking.", () => {
Expand Down
87 changes: 87 additions & 0 deletions test/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,52 @@ describe("The watch method", () => {
})
})

describe("should not copy specified files with globs at first when `--no-initial` option was given:", () => {
beforeEach(() => {
setupTestDir({
"test-ws/untachable.txt": "untachable",
"test-ws/a/hello.txt": "Hello",
"test-ws/a/b/this-is.txt": "A pen",
"test-ws/a/b/that-is.txt": "A note",
"test-ws/a/b/no-copy.dat": "no-copy",
})
})

/**
* Verify.
* @returns {void}
*/
function verifyFiles() {
assert(content("test-ws/untachable.txt") === "untachable")
assert(content("test-ws/a/hello.txt") === "Hello")
assert(content("test-ws/a/b/this-is.txt") === "A pen")
assert(content("test-ws/a/b/that-is.txt") === "A note")
assert(content("test-ws/a/b/no-copy.dat") === "no-copy")
assert(content("test-ws/b/untachable.txt") === null)
assert(content("test-ws/b/hello.txt") === null)
assert(content("test-ws/b/b/this-is.txt") === null)
assert(content("test-ws/b/b/that-is.txt") === null)
assert(content("test-ws/b/b/no-copy.dat") === null)
}

it("lib version.", (done) => {
watcher = cpx.watch("test-ws/a/**/*.txt", "test-ws/b", {initialCopy: false})
watcher.on("watch-ready", () => {
// Done the first copies.
verifyFiles()
done()
})
})

it("command version.", (done) => {
command = execCommand("\"test-ws/a/**/*.txt\" test-ws/b --no-initial --watch --verbose")
waitForReady(() => {
verifyFiles()
done()
})
})
})

;[
{
description: "should copy on file added:",
Expand Down Expand Up @@ -509,4 +555,45 @@ describe("The watch method", () => {
})
})
})

describe("should copy it when a file is added even if '--no-initial' option was given:", () => {
beforeEach(() => {
setupTestDir({
"test-ws/a/hello.txt": "Hello",
"test-ws/a/b/hello.txt": "Hello",
})
})

/**
* Verify.
* @returns {void}
*/
function verifyFiles() {
assert(content("test-ws/b/hello.txt") === null)
assert(content("test-ws/b/b/hello.txt") === null)
assert(content("test-ws/b/added.txt") === "added")
}

it("lib version.", (done) => {
watcher = cpx.watch("test-ws/a/**", "test-ws/b", {initialCopy: false})
waitForReady(() => {
writeFile("test-ws/a/added.txt", "added")
waitForCopy(() => {
verifyFiles()
done()
})
})
})

it("command version.", (done) => {
command = execCommand("\"test-ws/a/**\" test-ws/b --no-initial --watch --verbose")
waitForReady(() => {
writeFile("test-ws/a/added.txt", "added")
waitForCopy(() => {
verifyFiles()
done()
})
})
})
})
})

0 comments on commit bae874a

Please sign in to comment.