Giter VIP home page Giter VIP logo

cpx2's Introduction

cpx2

npm version Downloads/month tests

Copy file globs, watching for changes.

This module provides a CLI tool like cp, but with watching.

This is a maintained fork of mysticatea/cpx. It retains the cpx bin name, so it can act as a drop-in replacement.

Installation

npm install cpx2

Usage

Usage: cpx <source> <dest> [options]

    Copy files, watching for changes.

        <source>  The glob of target files.
        <dest>    The path of a destination directory.

Options:

    -c, --command <command>   A command text to transform each file.
    -C, --clean               Clean files that matches <source> like pattern in
                              <dest> directory before the first copying.
    -f, --force               Force the file to be copied, even if the
                              destination is readonly.   
    -i, --ignore              A comma separated list of gitignore style ignore
                              patterns.
    -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
                              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
                                the specified name via "require()".
    -u, --update              The flag to not overwrite files on destination if
                              the source file is older.
    -v, --verbose             Print copied/removed files.
    -V, --version             Print the version number.
    -w, --watch               Watch for files that matches <source>, and copy
                              the file to <dest> every changing.

Example

$ cpx "src/**/*.{html,png,jpg}" app --watch

This example will copy html/png/jpg files from src directory to app directory, keeping file tree structure. Whenever the files are changed, copy them.

Since Bash expands globs, requires to enclose it with double quotes.

You can use together Browserify.

$ cpx "src/**/*.{html,png,jpg}" app -w & watchify src/index.js -o app/index.js

You can use shell commands to convert each file.

$ cpx "src/**/*.js" app -w -c "babel --source-maps inline"

You can use the transform packages for Browserify.

$ cpx "src/**/*.js" app -w -t babelify -t uglifyify

It maybe can use to add header comment, to optimize images, or etc...

Node.js API

You can use this module as a node module.

var cpx = require("cpx2");

cpx.copy

cpx.copy(source, dest, options, callback)
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. 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.force {boolean} -- The flag to copy file to the destination, even if it is readonly.
    • 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. Default: false.
    • options.ignore {string|Array<string>} -- A gitignore style string or array of strings that make ignoring directory patterns easier. Default: []
  • callback {(err: Error|null) => void} -- A function that is called at done.

Copy files that matches with source glob to dest directory.

cpx.copySync

cpx.copySync(source, dest, options)
cpx.copySync(source, dest)

A synchronous function of cpx.copy.

Arguments is almost same as cpx.copy. But options.transform is not supported.

cpx.watch

cpx.watch(source, dest, options)
cpx.watch(source, dest)

Copy files that matches with source glob string to dest directory. After the first copy, starts observing. And copy the files when every changes.

Arguments is same as cpx.copy.

cpx.watch returns an EventEmitter.

  • .on("copy", (e) => { ... }) : Be fired after file is copied. e.srcPath is a path of original file. e.dstPath is a path of new file.
  • .on("remove", (e) => { ... }) : Be fired after file is removed. e.path is a path of removed file.
  • .on("watch-ready", () => { ... }) : Be fired when started watching files, after the first copying.
  • .on("watch-error", (err) => { ... }) : Be fired when occured errors during watching.

Changelog

GitHub Releases

Contributing

Thank you for contributions!

Bug Reports or Feature Requests

Please use GitHub Issues.

Document Corrections

Please use GitHub Pull Requests. I would especially thank for document corrections since I'm not familiar with English.

Feature Implementing

Please use GitHub Pull Requests.

There are some npm-scripts to help developments.

  • npm test - Run tests and collect coverage.
  • npm run build - Make lib directory from src directory.
  • npm run clean - Delete directories (folders) which are created by other commands.
  • npm run lint - Run ESLint.
  • npm run watch - Run tests (not collect coverage) when each file was modified.
  • npm run open-coverage - Open the coverage report of the last npm test command with web browser.

cpx2's People

Contributors

bcomnes avatar mysticatea avatar dependabot[bot] avatar k88hudson avatar igor-toporet avatar quilicicf avatar forivall avatar mhanberg avatar pdehaan avatar yassh avatar

Stargazers

Kirill Groshkov avatar  avatar Rintaro Itokawa avatar Brecht Carlier avatar Peter Szabo avatar Tiago Cunha avatar 黄小健 avatar  avatar Yavorski avatar Will Slattum avatar Guo Zhihao avatar Takeo Yoshida avatar  avatar Angelos Pikoulas avatar Matthias avatar Shuwen avatar Goncalo Tojeiro avatar Alex avatar Nikola Hristov avatar Aymeric Guillien avatar Petr Homoky avatar Nate Goldman avatar Marcel Kinzel avatar Terry Thorsen avatar  avatar 应元东 avatar Fredrik Blomqvist avatar George Spake avatar Vitaly Pinchuk avatar  avatar LocTran avatar Eric Bailey avatar  avatar Mick Lawitzke avatar liucaidong avatar Travis LaDuke avatar yqrashawn avatar Tanner Wisniewski avatar Yoshitaka Totsuka avatar Vasyl Boroviak avatar Nikolas Evers avatar David Lannoye avatar  avatar

Watchers

 avatar James Cloos avatar  avatar

cpx2's Issues

Readonly source-file can't watch

The target will get the same chmod-attributes as the source. As a result in watch-mode cpx2 isn't able to update changes, if the write-bit isn't set on source.

So either the initial chmod needs to include the write-bit explicitly or just before the pipe(write) the write-bit needs to be set.

Speed up tests

These tests take way to long to run. Some ideas for speeding up testing:

  • Switch to tap. This is probably not going to help with speed, other than writing and maintaining tests.
  • Remove sync calls wherever possible.
  • Run tests in temp dirs where they won't overlap, so we can run them in parallel.
  • Take the opportunity to improve assertion output.

Those are the main ideas I have for now.

Copying with * no longer works in Node 15.5 with node_modules cpx2

This is a bit of an odd one ; not sure where exactly the issue lies. I tested with Node 15.3 and Node 15.5, and only node 15.5 showed the issue.

To reproduce:

# Start a docker container with node 15.5
docker run -it --rm node:15.5 bash

Inside the container:

mkdir repo
cd repo
touch src/a.txt
touch src/b.txt
npm install cpx2
npx cpx "src/*" dist
# ERROR (displays usage instructions)

Note this works if I install cpx globally...? So maybe an issue with npx ?

npm install -g cpx2
cpx "src/*" dist
# WORKS

cc @iisa

Watcher ignores glob pattern when adding subdirectories

The watcher walks subdirectories based on the initial directory that is provided in the glob pattern. This can cause serious performance issues.

Take for instance the glob pattern /myproject/package.json . In order to watch this single file, cpx2's watcher will first wall all subdirectories of /myproject. Things can bog down in a hurry if your project contains node_modules.

I'm not sure if there's an easy fix. Possibly a better approach that using minimatch would be to use glob itself to return the list of directories and files.

Let me know if you have any possible workarounds.

Rename file's

I want to copy a file but rename it:

cpx.copy('assets/icon.ico', `dist/favicon.ico`)

Version 6 does not work on Windows

Running cpx command on windows does not copy files. No error messages displayed (even in verbose).

Windows 10
powershell, cmd, and bash

Glob regression pattern.

This (cpx './!(node_modules)**/*.{png,ico}' public") worked in 3.0.0, but doesn't work in 4.0.0 when run in a directory with a static/foo.png file. This glob doesn't end up copying anything (but should). Granted, using the ignore flag is more efficient and intuitive, however it should continue working as is.

RangeError: path should be a `path.relative()`d string, but got ....

Hey and thanks for this great lib! It's the best copy out there! But I faced a daring bug:

(Also related to same error message #44)

My cmd is

╭─anodynos@Giga /mnt/projects/__fake/macos/newin
╰─$ cpx "/mnt/projects/devzen-tools/packages/newin/**" "./" --ignore "node_modules/,dist/,build/" --verbose --update  

so I want to copy from a deep path, into my CWD.

It fails with a a gazzillion of these - it enumerates all my files and node_modules (despite being ignored). For each file (mine & node_modules) it throws:

RangeError: path should be a `path.relative()`d string, but got "../../../devzen-tools/packages/newin/node_modules/expect/build/types.js"
    at throwError (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:379:9)
    at checkPath (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:398:12)
    at Ignore._test (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:519:5)
    at Ignore.ignores (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:564:17)
    at Object.ignored (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/lib/utils/apply-action.js:42:41)
    at #ignored (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:54:64)
    at GlobWalker.matchFinish (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:124:26)
    at GlobWalker.match (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:148:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
RangeError: path should be a `path.relative()`d string, but got "../../../devzen-tools/packages/newin/node_modules/expect/build/toThrowMatchers.js"
    at throwError (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:379:9)
    at checkPath (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:398:12)
    at Ignore._test (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:519:5)
    at Ignore.ignores (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/ignore/index.js:564:17)
    at Object.ignored (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/lib/utils/apply-action.js:42:41)
    at #ignored (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:54:64)
    at GlobWalker.matchFinish (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:124:26)
    at GlobWalker.match (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/cpx2/node_modules/glob/dist/commonjs/walker.js:148:18)
....
RangeError: path should be a `path.relative()`d string, but got "../../../../c/dev/newin/node_modules/lws-conditional-get"
...

Then it copies all the files I wanted, witch a glitch: ALWAYS, despite having --update.

Now the interesting thing is, if I reverse the paths, everything works fine:

╭─anodynos@Giga /mnt/projects/__fake/macos/newin
╰─$ cpx "./src/**/*" "/mnt/projects/devzen-tools/packages/newin/src" --ignore "node_modules/,dist/,build/" --verbose --update

Copy: ./src/**/* --> /mnt/projects/devzen-tools/packages/newin/src

Copied: src/tsconfig.json --> ../../../devzen-tools/packages/newin/src/tsconfig.json
Copied: src/tsconfig.deploy.json --> ../../../devzen-tools/packages/newin/src/tsconfig.deploy.json
Copied: src/package.json --> ../../../devzen-tools/packages/newin/src/package.json
Copied: src/package-lock.json --> ../../../devzen-tools/packages/newin/src/package-lock.json
Copied: src/nodemon.copy.json --> ../../../devzen-tools/packages/newin/src/nodemon.copy.json
....

Something's wrong with the globbing apparently, but after some digging I think it doesnt like absolute directories.

I converted to relative paths, and boom, all good.

$ cpx "./**/*" /mnt/projects/__fake/macos/newin --verbose

UPDATE:
It's not relative paths either, it crashes the same with them as well.

But when I add --watch the problem goes away!

Works:

╭─anodynos@Giga /mnt/projects/__fake/macos/newin
╰─$ cpx "../../../newin/**/*" . --verbose --ignore "node_modules" --watch  

Fails:

╭─anodynos@Giga /mnt/projects/__fake/macos/newin
╰─$ cpx "../../../newin/**/*" . --verbose --ignore "node_modules"

Great irony, I wanted to do it in a sleep loop "while sleep 5 ; cpx ...." cause watch dosnt work on Network drives apparently...

Any ideas?

Thanks again!

watch fails when source is parent directory

$ node --version
v16.13.0
$ npm --version
7.24.2
$ touch example.txt
$ mkdir folder
$ cd folder
$ npx cpx2 "../example.txt" . --watch     
path should be a `path.relative()`d string, but got "./"

A single copy works without issue npx cpx2 "../example.txt" .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.