Commit project
This commit is contained in:
parent
28471965a0
commit
3ac017a5ad
1030 changed files with 94062 additions and 0 deletions
13
node_modules/nodemon/.jscsrc
generated
vendored
Normal file
13
node_modules/nodemon/.jscsrc
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"preset": "node-style-guide",
|
||||
"requireCapitalizedComments": null,
|
||||
"requireSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningCurlyBrace": true,
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInNamedFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"excludeFiles": ["node_modules/**"],
|
||||
"disallowSpacesInFunction": null
|
||||
}
|
16
node_modules/nodemon/.jshintrc
generated
vendored
Normal file
16
node_modules/nodemon/.jshintrc
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"browser": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"devel": true,
|
||||
"eqeqeq": true,
|
||||
"forin": true,
|
||||
"indent": 2,
|
||||
"noarg": true,
|
||||
"node": true,
|
||||
"quotmark": "single",
|
||||
"undef": true,
|
||||
"strict": false,
|
||||
"unused": true
|
||||
}
|
||||
|
3
node_modules/nodemon/.npmignore
generated
vendored
Normal file
3
node_modules/nodemon/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
test/
|
||||
tmp/
|
||||
coverage/
|
21
node_modules/nodemon/.travis.yml
generated
vendored
Normal file
21
node_modules/nodemon/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
sudo: false
|
||||
language: node_js
|
||||
#cache:
|
||||
# directories:
|
||||
# - node_modules
|
||||
notifications:
|
||||
email: false
|
||||
node_js:
|
||||
- 8
|
||||
- 7
|
||||
- 6
|
||||
- 4
|
||||
before_install:
|
||||
- npm i -g npm@^2.0.0
|
||||
before_script:
|
||||
- npm prune
|
||||
- 'curl -Lo travis_after_all.py https://git.io/vLSON'
|
||||
after_success:
|
||||
- python travis_after_all.py
|
||||
- export $(cat .to_export_back)
|
||||
- npm run semantic-release
|
22
node_modules/nodemon/CODE_OF_CONDUCT.md
generated
vendored
Normal file
22
node_modules/nodemon/CODE_OF_CONDUCT.md
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
35
node_modules/nodemon/CONTRIBUTING.md
generated
vendored
Normal file
35
node_modules/nodemon/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Contributing
|
||||
|
||||
## Commit messages
|
||||
|
||||
Commit messages must follow the [Angular-style](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format) commit format (but excluding the scope).
|
||||
|
||||
i.e:
|
||||
|
||||
```text
|
||||
fix: minified scripts being removed
|
||||
|
||||
Also includes tests
|
||||
```
|
||||
|
||||
This will allow for the automatic changelog to generate correctly.
|
||||
|
||||
## Code standards
|
||||
|
||||
Ensure that your code adheres to the included `.jshintrc` and `.jscsrc` configs.
|
||||
|
||||
## Sending pull requests
|
||||
|
||||
- new command line options are generally discouraged unless there's a *really* good reason
|
||||
- add tests for newly added code (and try to mirror directory and file structure if possible)
|
||||
- spell check
|
||||
- PRs will not be code reviewed unless all tests are passing
|
||||
|
||||
*Important:* when fixing a bug, please commit a **failing test** first so that Travis CI (or I can) can show the code failing. Once that commit is in place, then commit the bug fix, so that we can test *before* and *after*.
|
||||
|
||||
Remember that you're developing for multiple platforms and versions of node, so if the tests pass on your Mac or Linux or Windows machine, it *may* not pass elsewhere. I personally have Mac and Linux coverage, I need help with Windows tests.
|
||||
|
||||
## Issues
|
||||
|
||||
- Please include the output from `nodemon --dump` for diagnosis
|
||||
- If there's a script that nodemon is having trouble with or is causing nodemon to throw exceptions, please include it in your filed issue to allow me to replicate the issue.
|
19
node_modules/nodemon/Dockerfile
generated
vendored
Normal file
19
node_modules/nodemon/Dockerfile
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
FROM ubuntu:12.04
|
||||
MAINTAINER Remy Sharp <remy@leftlogic.com>
|
||||
|
||||
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
|
||||
RUN apt-get update && apt-get install curl npm -y
|
||||
|
||||
ENV NVM_DIR /usr/local/nvm
|
||||
ENV NODE_VERSION 4
|
||||
ENV NVM_VERSION 0.26.1
|
||||
ENV TRAVIS TRUE
|
||||
|
||||
# # Install nvm with node and npm
|
||||
RUN curl https://raw.githubusercontent.com/creationix/nvm/v$NVM_VERSION/install.sh | bash \
|
||||
&& source $NVM_DIR/nvm.sh \
|
||||
&& nvm install 0.10 \
|
||||
&& nvm install 0.12 \
|
||||
&& nvm install 4 \
|
||||
&& nvm alias default $NODE_VERSION \
|
||||
&& nvm use default
|
293
node_modules/nodemon/README.md
generated
vendored
Normal file
293
node_modules/nodemon/README.md
generated
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||

|
||||
|
||||
# nodemon
|
||||
|
||||
<a href="https://app.codesponsor.io/link/wnz2te8CdfKZ8wMjGUpi8EZG/remy/nodemon" rel="nofollow"><img src="https://app.codesponsor.io/embed/wnz2te8CdfKZ8wMjGUpi8EZG/remy/nodemon.svg" style="width: 888px; height: 68px;" alt="Sponsor" /></a>
|
||||
|
||||
For use during development of a node.js based application.
|
||||
|
||||
nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.
|
||||
|
||||
nodemon does **not** require *any* changes to your code or method of development. nodemon simply wraps your node application and keeps an eye on any files that have changed. Remember that nodemon is a replacement wrapper for `node`, think of it as replacing the word "node" on the command line when you run your script.
|
||||
|
||||
[](https://npmjs.org/package/nodemon)
|
||||
[](https://travis-ci.org/remy/nodemon)
|
||||
|
||||
# Installation
|
||||
|
||||
Either through cloning with git or by using [npm](http://npmjs.org) (the recommended way):
|
||||
|
||||
npm install -g nodemon
|
||||
|
||||
And nodemon will be installed globally to your system path.
|
||||
|
||||
It is also possible to install locally:
|
||||
|
||||
npm install --save-dev nodemon
|
||||
|
||||
With a local installation, nodemon will not be available in your system path. Instead, the local installation of nodemon can be run by calling it from within an npm script (such as `npm start`) or using `npx nodemon`.
|
||||
|
||||
# Usage
|
||||
|
||||
nodemon wraps your application, so you can pass all the arguments you would normally pass to your app:
|
||||
|
||||
nodemon [your node app]
|
||||
|
||||
For CLI options, use the `-h` (or `--help`) argument:
|
||||
|
||||
nodemon -h
|
||||
|
||||
Using nodemon is simple, if my application accepted a host and port as the arguments, I would start it as so:
|
||||
|
||||
nodemon ./server.js localhost 8080
|
||||
|
||||
Any output from this script is prefixed with `[nodemon]`, otherwise all output from your application, errors included, will be echoed out as expected.
|
||||
|
||||
nodemon also supports running and monitoring [coffee-script](http://coffeescript.org/) apps:
|
||||
|
||||
nodemon server.coffee
|
||||
|
||||
If no script is given, nodemon will test for a `package.json` file and if found, will run the file associated with the *main* property ([ref](https://github.com/remy/nodemon/issues/14)).
|
||||
|
||||
You can also pass the debug flag to node through the command line as you would normally:
|
||||
|
||||
nodemon --debug ./server.js 80
|
||||
|
||||
If you have a `package.json` file for your app, you can omit the main script entirely and nodemon will read the `package.json` for the `main` property and use that value as the app.
|
||||
|
||||
nodemon will also search for the `scripts.start` property in `package.json` (as of nodemon 1.1.x).
|
||||
|
||||
Also check out the [FAQ](https://github.com/remy/nodemon/blob/master/faq.md) or [issues](https://github.com/remy/nodemon/issues) for nodemon.
|
||||
|
||||
## Automatic re-running
|
||||
|
||||
nodemon was originally written to restart hanging processes such as web servers, but now supports apps that cleanly exit. If your script exits cleanly, nodemon will continue to monitor the directory (or directories) and restart the script if there are any changes.
|
||||
|
||||
## Manual restarting
|
||||
|
||||
Whilst nodemon is running, if you need to manually restart your application, instead of stopping and restart nodemon, you can simply type `rs` with a carriage return, and nodemon will restart your process.
|
||||
|
||||
## Config files
|
||||
|
||||
nodemon supports local and global configuration files. These are usually named `nodemon.json` and can be located in the current working directory or in your home directory. An alternative local configuration file can be specified with the `--config <file>` option.
|
||||
|
||||
The specificity is as follows, so that a command line argument will always override the config file settings:
|
||||
|
||||
- command line arguments
|
||||
- local config
|
||||
- global config
|
||||
|
||||
A config file can take any of the command line arguments as JSON key values, for example:
|
||||
|
||||
{
|
||||
"verbose": true,
|
||||
"ignore": ["*.test.js", "fixtures/*"],
|
||||
"execMap": {
|
||||
"rb": "ruby",
|
||||
"pde": "processing --sketch={{pwd}} --run"
|
||||
}
|
||||
}
|
||||
|
||||
The above `nodemon.json` file might be my global config so that I have support for ruby files and processing files, and I can simply run `nodemon demo.pde` and nodemon will automatically know how to run the script even though out of the box support for processing scripts.
|
||||
|
||||
A further example of options can be seen in [sample-nodemon.md](https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md)
|
||||
|
||||
### package.json
|
||||
|
||||
If you want to keep all your package configurations in one place, nodemon supports using `package.json` for configuration.
|
||||
Simply specify the config in the same format as you would for a config file but under `nodemonConfig` in the `package.json` file, for example, take the following `package.json`:
|
||||
|
||||
{
|
||||
"name": "nodemon",
|
||||
"homepage": "http://nodemon.io",
|
||||
...
|
||||
... other standard package.json values
|
||||
...
|
||||
"nodemonConfig": {
|
||||
"ignore": ["test/*", "docs/*"],
|
||||
"delay": "2500"
|
||||
}
|
||||
}
|
||||
|
||||
Note that if you specify a `--config` file or provide a local `nodemon.json` any `package.json` config is ignored.
|
||||
|
||||
*This section needs better documentation, but for now you can also see `nodemon --help config` ([also here](https://github.com/remy/nodemon/blob/master/doc/cli/config.txt))*.
|
||||
|
||||
## Using nodemon as a module
|
||||
|
||||
Please see [doc/requireable.md](doc/requireable.md)
|
||||
|
||||
## Running non-node scripts
|
||||
|
||||
nodemon can also be used to execute and monitor other programs. nodemon will read the file extension of the script being run and monitor that extension instead of .js if there's no .nodemonignore:
|
||||
|
||||
nodemon --exec "python -v" ./app.py
|
||||
|
||||
Now nodemon will run `app.py` with python in verbose mode (note that if you're not passing args to the exec program, you don't need the quotes), and look for new or modified files with the `.py` extension.
|
||||
|
||||
### Default executables
|
||||
|
||||
Using the `nodemon.json` config file, you can define your own default executables using the `execMap` property. This is particularly useful if you're working with a language that isn't supported by default by nodemon.
|
||||
|
||||
To add support for nodemon to know about the .pl extension (for Perl), the nodemon.json file would add:
|
||||
|
||||
{
|
||||
"execMap": {
|
||||
"pl": "perl"
|
||||
}
|
||||
}
|
||||
|
||||
Now running the following, nodemon will know to use `perl` as the executable:
|
||||
|
||||
nodemon script.pl
|
||||
|
||||
It's generally recommended to use the global `nodemon.json` to add your own `execMap` options. However, if there's a common default that's missing, this can be merged in to the project so that nodemon supports it by default, by changing [default.js](https://github.com/remy/nodemon/blob/master/lib/config/defaults.js) and sending a pull request.
|
||||
|
||||
## Monitoring multiple directories
|
||||
|
||||
By default nodemon monitors the current working directory. If you want to take control of that option, use the `--watch` option to add specific paths:
|
||||
|
||||
nodemon --watch app --watch libs app/server.js
|
||||
|
||||
Now nodemon will only restart if there are changes in the `./app` or `./libs` directory. By default nodemon will traverse sub-directories, so there's no need in explicitly including sub-directories.
|
||||
|
||||
Don't use unix globbing to pass multiple directories, e.g `--watch ./lib/*`, it won't work. You need a `--watch` flag per directory watched.
|
||||
|
||||
## Specifying extension watch list
|
||||
|
||||
By default, nodemon looks for files with the `.js`, `.coffee`, `.litcoffee`, and `.json` extensions. If you use the `--exec` option and monitor `app.py` nodemon will monitor files with the extension of `.py`. However, you can specify your own list with the `-e` (or `--ext`) switch like so:
|
||||
|
||||
nodemon -e js,jade
|
||||
|
||||
Now nodemon will restart on any changes to files in the directory (or subdirectories) with the extensions .js, .jade.
|
||||
|
||||
## Ignoring files
|
||||
|
||||
By default, nodemon will only restart when a `.js` JavaScript file changes. In some cases you will want to ignore some specific files, directories or file patterns, to prevent nodemon from prematurely restarting your application.
|
||||
|
||||
This can be done via the command line:
|
||||
|
||||
nodemon --ignore lib/ --ignore tests/
|
||||
|
||||
Or specific files can be ignored:
|
||||
|
||||
nodemon --ignore lib/app.js
|
||||
|
||||
Patterns can also be ignored (but be sure to quote the arguments):
|
||||
|
||||
nodemon --ignore 'lib/*.js'
|
||||
|
||||
Note that by default, nodemon will ignore the `.git`, `node_modules`, `bower_components`, `.nyc_output`, `coverage` and `.sass-cache` directories and *add* your ignored patterns to the list. If you want to indeed watch a directory like `node_modules`, you need to [override the underlying default ignore rules](https://github.com/remy/nodemon/blob/master/faq.md#overriding-the-underlying-default-ignore-rules).
|
||||
|
||||
## Application isn't restarting
|
||||
|
||||
In some networked environments (such as a container running nodemon reading across a mounted drive), you will need to use the `legacyWatch: true` which enables Chokidar's polling.
|
||||
|
||||
Via the CLI, use either `--legacy-watch` or `-L` for short:
|
||||
|
||||
nodemon -L
|
||||
|
||||
Though this should be a last resort as it will poll every file it can find.
|
||||
|
||||
## Delaying restarting
|
||||
|
||||
In some situations, you may want to wait until a number of files have changed. The timeout before checking for new file changes is 1 second. If you're uploading a number of files and it's taking some number of seconds, this could cause your app to restart multiple times unnecessarily.
|
||||
|
||||
To add an extra throttle, or delay restarting, use the `--delay` command:
|
||||
|
||||
nodemon --delay 10 server.js
|
||||
|
||||
For more precision, milliseconds can be specified. Either as a float:
|
||||
|
||||
nodemon --delay 2.5 server.js
|
||||
|
||||
Or using the time specifier (ms):
|
||||
|
||||
nodemon --delay 2500ms server.js
|
||||
|
||||
The delay figure is number of seconds (or milliseconds, if specified) to delay before restarting. So nodemon will only restart your app the given number of seconds after the *last* file change.
|
||||
|
||||
If you are setting this value in `nodemon.json`, the value will always be interpretted in milliseconds. E.g., the following are equivalent:
|
||||
|
||||
nodemon --delay 2.5
|
||||
|
||||
{
|
||||
"delay": "2500"
|
||||
}
|
||||
|
||||
## Controlling shutdown of your script
|
||||
|
||||
nodemon sends a kill signal to your application when it sees a file update. If you need to clean up on shutdown inside your script you can capture the kill signal and handle it yourself.
|
||||
|
||||
The following example will listen once for the `SIGUSR2` signal (used by nodemon to restart), run the clean up process and then kill itself for nodemon to continue control:
|
||||
|
||||
process.once('SIGUSR2', function () {
|
||||
gracefulShutdown(function () {
|
||||
process.kill(process.pid, 'SIGUSR2');
|
||||
});
|
||||
});
|
||||
|
||||
Note that the `process.kill` is *only* called once your shutdown jobs are complete. Hat tip to [Benjie Gillam](http://www.benjiegillam.com/2011/08/node-js-clean-restart-and-faster-development-with-nodemon/) for writing this technique up.
|
||||
|
||||
## Triggering events when nodemon state changes
|
||||
|
||||
If you want growl like notifications when nodemon restarts or to trigger an action when an event happens, then you can either `require` nodemon or simply add event actions to your `nodemon.json` file.
|
||||
|
||||
For example, to trigger a notification on a Mac when nodemon restarts, `nodemon.json` looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"events": {
|
||||
"restart": "osascript -e 'display notification \"app restarted\" with title \"nodemon\"'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A full list of available events is listed on the [event states wiki](https://github.com/remy/nodemon/wiki/Events#states). Note that you can bind to both states and messages.
|
||||
|
||||
## Pipe output to somewhere else
|
||||
|
||||
```js
|
||||
nodemon({
|
||||
script: ...,
|
||||
stdout: false // important: this tells nodemon not to output to console
|
||||
}).on('readable', function() { // the `readable` event indicates that data is ready to pick up
|
||||
this.stdout.pipe(fs.createWriteStream('output.txt'));
|
||||
this.stderr.pipe(fs.createWriteStream('err.txt'));
|
||||
});
|
||||
```
|
||||
|
||||
## Using nodemon in your gulp workflow
|
||||
|
||||
Check out the [gulp-nodemon](https://github.com/JacksonGariety/gulp-nodemon) plugin to integrate nodemon with the rest of your project's gulp workflow.
|
||||
|
||||
## Using nodemon in your Grunt workflow
|
||||
|
||||
Check out the [grunt-nodemon](https://github.com/ChrisWren/grunt-nodemon) plugin to integrate nodemon with the rest of your project's grunt workflow.
|
||||
|
||||
## Pronunciation
|
||||
|
||||
> nodemon, is it pronounced: node-mon, no-demon or node-e-mon (like pokémon)?
|
||||
|
||||
Well...I've been asked this many times before. I like that I've been asked this before. There's been bets as to which one it actually is.
|
||||
|
||||
The answer is simple, but possibly frustrating. I'm not saying (how I pronounce it). It's up to you to call it as you like. All answers are correct :)
|
||||
|
||||
## Design principles
|
||||
|
||||
- Less flags is better
|
||||
- Works across all platforms
|
||||
- Less features
|
||||
- Let individuals build on top of nodemon
|
||||
- Offer all CLI functionality as an API
|
||||
- Contributions must have and pass tests
|
||||
|
||||
Nodemon is not perfect, and CLI arguments has sprawled beyond where I'm completely happy, but perhaps it can be pulled back a little.
|
||||
|
||||
## FAQ
|
||||
|
||||
See the [FAQ](https://github.com/remy/nodemon/blob/master/faq.md) and please add your own questions if you think they would help others.
|
||||
|
||||
# License
|
||||
|
||||
MIT [http://rem.mit-license.org](http://rem.mit-license.org)
|
17
node_modules/nodemon/bin/nodemon.js
generated
vendored
Executable file
17
node_modules/nodemon/bin/nodemon.js
generated
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
var cli = require('../lib/cli');
|
||||
var nodemon = require('../lib/');
|
||||
var options = cli.parse(process.argv);
|
||||
|
||||
nodemon(options);
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
// checks for available update and returns an instance
|
||||
var defaults = require('lodash.defaults');
|
||||
var pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json'));
|
||||
|
||||
require('update-notifier')({
|
||||
pkg: defaults(pkg, { version: '0.0.0' }),
|
||||
}).notify();
|
7
node_modules/nodemon/commitlint.config.js
generated
vendored
Normal file
7
node_modules/nodemon/commitlint.config.js
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
rules: {
|
||||
'body-tense': [0, 'never', 0],
|
||||
lang: 'eng',
|
||||
},
|
||||
extends: ['@commitlint/config-angular'],
|
||||
};
|
41
node_modules/nodemon/doc/arch.md
generated
vendored
Normal file
41
node_modules/nodemon/doc/arch.md
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
# nodemon code arch
|
||||
|
||||
```
|
||||
CLI -> parser -> nodemon options -> rules
|
||||
|
||||
rules -> configure -> watch -> start process
|
||||
```
|
||||
|
||||
## CLI examples
|
||||
|
||||
Watch src but only *.js and *.coffee
|
||||
|
||||
nodemon --watch src/ -e js,coffee app.js
|
||||
|
||||
Parsed to:
|
||||
|
||||
{
|
||||
watch: ['src/'],
|
||||
ignore: [],
|
||||
script: 'app.js'
|
||||
options: {
|
||||
extensions: ['js', 'coffee'],
|
||||
exec: 'node'
|
||||
}
|
||||
}
|
||||
|
||||
Watch with no args:
|
||||
|
||||
nodemon
|
||||
|
||||
Parsed to (assuming a package.json or index.js is found):
|
||||
|
||||
{
|
||||
watch: [], // meaning all subdirectories
|
||||
ignore: [],
|
||||
script: 'index.js',
|
||||
options: {
|
||||
extensions: ['js'],
|
||||
exec: 'node'
|
||||
}
|
||||
}
|
8
node_modules/nodemon/doc/cli/authors.txt
generated
vendored
Normal file
8
node_modules/nodemon/doc/cli/authors.txt
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
Remy Sharp - author and maintainer
|
||||
http://github.com/remy
|
||||
http://twitter.com/rem
|
||||
|
||||
Contributors: https://github.com/remy/nodemon/graphs/contributors ❤︎
|
||||
|
||||
Please help make nodemon better: https://github.com/remy/nodemon/
|
44
node_modules/nodemon/doc/cli/config.txt
generated
vendored
Normal file
44
node_modules/nodemon/doc/cli/config.txt
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
Typically the options to control nodemon are passed in via the CLI and are
|
||||
listed under the default nodemon --help command.
|
||||
|
||||
nodemon can also be configured via a local and global config file:
|
||||
|
||||
* $HOME/nodemon.json
|
||||
* $PWD/nodemon.json OR --config <file>
|
||||
* nodemonConfig in package.json
|
||||
|
||||
All config options in the .json file map 1-to-1 with the CLI options, so a
|
||||
config could read as:
|
||||
|
||||
{
|
||||
"ext": "*.pde",
|
||||
"verbose": true,
|
||||
"exec": "processing --sketch=game --run"
|
||||
}
|
||||
|
||||
There are a limited number of variables available in the config (since you
|
||||
could use backticks on the CLI to use a variable, backticks won't work in
|
||||
the .json config).
|
||||
|
||||
* {{pwd}} - the current directory
|
||||
* {{filename}} - the filename you pass to nodemon
|
||||
|
||||
For example:
|
||||
|
||||
{
|
||||
"ext": "*.pde",
|
||||
"verbose": true,
|
||||
"exec": "processing --sketch={{pwd}} --run"
|
||||
}
|
||||
|
||||
The global config file is useful for setting up default executables
|
||||
instead of repeating the same option in each of your local configs:
|
||||
|
||||
{
|
||||
"verbose": true,
|
||||
"execMap": {
|
||||
"rb": "ruby",
|
||||
"pde": "processing --sketch={{pwd}} --run"
|
||||
}
|
||||
}
|
41
node_modules/nodemon/doc/cli/help.txt
generated
vendored
Normal file
41
node_modules/nodemon/doc/cli/help.txt
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
Usage: nodemon [options] [script.js] [args]
|
||||
|
||||
Options:
|
||||
|
||||
--config file ............ alternate nodemon.json config file to use
|
||||
-e, --ext ................ extensions to look for, ie. js,jade,hbs.
|
||||
-x, --exec app ........... execute script with "app", ie. -x "python -v".
|
||||
-w, --watch dir........... watch directory "dir" or files. use once for
|
||||
each directory or file to watch.
|
||||
-i, --ignore ............. ignore specific files or directories.
|
||||
-q, --quiet .............. minimise nodemon messages to start/stop only.
|
||||
-V, --verbose ............ show detail on what is causing restarts.
|
||||
-I, --no-stdin ........... don't try to read from stdin.
|
||||
-C, --on-change-only ..... execute script on change only, not startup
|
||||
--no-colors .............. disable color output
|
||||
-d, --delay n ............ debounce restart for "n" seconds.
|
||||
--exitcrash .............. exit on crash, allows use of nodemon with daemon
|
||||
tools like forever.js.
|
||||
-v, --version ............ current nodemon version.
|
||||
-h, --help ............... you're looking at it.
|
||||
--help <topic> ........... help on a specific feature. Try "--help topics".
|
||||
-- <your args> ........... to tell nodemon stop slurping arguments.
|
||||
|
||||
Note: if the script is omitted, nodemon will try to read "main" from
|
||||
package.json and without a nodemon.json, nodemon will monitor .js, .coffee,
|
||||
and .litcoffee by default.
|
||||
|
||||
To learn more about nodemon.json config: nodemon --help config
|
||||
See also the sample: https://github.com/remy/nodemon/wiki/Sample-nodemon.json
|
||||
|
||||
Examples:
|
||||
|
||||
$ nodemon server.js
|
||||
$ nodemon --config my/custom/nodemon.json server.js
|
||||
$ nodemon -w ../foo server.js apparg1 apparg2
|
||||
$ PORT=8000 nodemon --debug-brk server.js
|
||||
$ nodemon --exec python app.py
|
||||
$ nodemon --exec "make build" -e "styl hbs"
|
||||
$ nodemon app.js -- -v
|
||||
|
||||
For more details see http://github.com/remy/nodemon/
|
20
node_modules/nodemon/doc/cli/logo.txt
generated
vendored
Normal file
20
node_modules/nodemon/doc/cli/logo.txt
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
; ;
|
||||
kO. x0
|
||||
KMX, .:x0kc. 'KMN
|
||||
0MMM0: 'oKMMMMMMMXd, ;OMMMX
|
||||
oMMMMMWKOONMMMMMMMMMMMMMWOOKWMMMMMx
|
||||
OMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMK.
|
||||
.oWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd.
|
||||
KMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN
|
||||
KMMMMMMMMMMMMMMW0k0WMMMMMMMMMMMMMMW
|
||||
KMMMMMMMMMMMNk:. :xNMMMMMMMMMMMW
|
||||
KMMMMMMMMMMK OMMMMMMMMMMW
|
||||
KMMMMMMMMMMO xMMMMMMMMMMN
|
||||
KMMMMMMMMMMO xMMMMMMMMMMN
|
||||
KMMMMMMMMMMO xMMMMMMMMMMN
|
||||
KMMMMMMMMMMO xMMMMMMMMMMN
|
||||
KMMMMMMMMMMO xMMMMMMMMMMN
|
||||
KMMMMMMMMMNc ;NMMMMMMMMMN
|
||||
KMMMMMW0o' .lOWMMMMMN
|
||||
KMMKd; ,oKMMN
|
||||
kX: ,K0
|
6
node_modules/nodemon/doc/cli/topics.txt
generated
vendored
Normal file
6
node_modules/nodemon/doc/cli/topics.txt
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
config ................... default config options using nodemon.json
|
||||
authors .................. contributors to this project
|
||||
whoami ................... I, AM, NODEMON \o/
|
||||
|
||||
Please contribute http://github.com/remy/nodemon/
|
3
node_modules/nodemon/doc/cli/usage.txt
generated
vendored
Normal file
3
node_modules/nodemon/doc/cli/usage.txt
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
Usage: nodemon [nodemon options] [script.js] [args]
|
||||
|
||||
See "nodemon --help" for more.
|
9
node_modules/nodemon/doc/cli/whoami.txt
generated
vendored
Normal file
9
node_modules/nodemon/doc/cli/whoami.txt
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
__/\\\\\_____/\\\_______/\\\\\_______/\\\\\\\\\\\\_____/\\\\\\\\\\\\\\\__/\\\\____________/\\\\_______/\\\\\_______/\\\\\_____/\\\_
|
||||
_\/\\\\\\___\/\\\_____/\\\///\\\____\/\\\////////\\\__\/\\\///////////__\/\\\\\\________/\\\\\\_____/\\\///\\\____\/\\\\\\___\/\\\_
|
||||
_\/\\\/\\\__\/\\\___/\\\/__\///\\\__\/\\\______\//\\\_\/\\\_____________\/\\\//\\\____/\\\//\\\___/\\\/__\///\\\__\/\\\/\\\__\/\\\_
|
||||
_\/\\\//\\\_\/\\\__/\\\______\//\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\_____\/\\\\///\\\/\\\/_\/\\\__/\\\______\//\\\_\/\\\//\\\_\/\\\_
|
||||
_\/\\\\//\\\\/\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/\\\///////______\/\\\__\///\\\/___\/\\\_\/\\\_______\/\\\_\/\\\\//\\\\/\\\_
|
||||
_\/\\\_\//\\\/\\\_\//\\\______/\\\__\/\\\_______\/\\\_\/\\\_____________\/\\\____\///_____\/\\\_\//\\\______/\\\__\/\\\_\//\\\/\\\_
|
||||
_\/\\\__\//\\\\\\__\///\\\__/\\\____\/\\\_______/\\\__\/\\\_____________\/\\\_____________\/\\\__\///\\\__/\\\____\/\\\__\//\\\\\\_
|
||||
_\/\\\___\//\\\\\____\///\\\\\/_____\/\\\\\\\\\\\\/___\/\\\\\\\\\\\\\\\_\/\\\_____________\/\\\____\///\\\\\/_____\/\\\___\//\\\\\_
|
||||
_\///_____\/////_______\/////_______\////////////_____\///////////////__\///______________\///_______\/////_______\///_____\/////__
|
79
node_modules/nodemon/doc/events.md
generated
vendored
Normal file
79
node_modules/nodemon/doc/events.md
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Events
|
||||
|
||||
nodemon will emit events based on the child process.
|
||||
|
||||
## Commands
|
||||
|
||||
- restart
|
||||
- config:update
|
||||
- quit
|
||||
|
||||
## States
|
||||
|
||||
- start - child process has started
|
||||
- crash - child process has crashed (nodemon will not emit exit)
|
||||
- exit - child process has cleanly exited (ie. no crash)
|
||||
- restart([ array of files triggering the restart ]) - child process has restarted
|
||||
- config:update - nodemon's config has changed
|
||||
|
||||
## Messages
|
||||
|
||||
- log({ type, message (plain text log), colour (colour coded log) }) - logging from nodemon (not the child process)
|
||||
- stdout - the stdout stream from the child process
|
||||
- stderr - the stderr stream from the child process
|
||||
- readable - stdout and stderr streams are ready ([example](https://github.com/remy/nodemon#pipe-output-to-somewhere-else))
|
||||
|
||||
Note that if you want to supress the normal stdout & stderr of the child, in favour
|
||||
of processing the stream manually using the stdout/stderr nodemon events, pass
|
||||
nodemon the option of `stdout: false`.
|
||||
|
||||
## Using nodemon events
|
||||
|
||||
If nodemon is required, events can be bound and emitted on the nodemon object:
|
||||
|
||||
```js
|
||||
var nodemon = require('nodemon');
|
||||
|
||||
nodemon({ script: 'app.js' }).on('start', function () {
|
||||
console.log('nodemon started');
|
||||
}).on('crash', function () {
|
||||
console.log('script crashed for some reason');
|
||||
});
|
||||
|
||||
// force a restart
|
||||
nodemon.emit('restart');
|
||||
|
||||
// force a quit
|
||||
nodemon.emit('quit');
|
||||
```
|
||||
|
||||
If nodemon is a spawned process, then the child (nodemon) will emit message
|
||||
events whereby the event argument contains the event type, and instead of
|
||||
emitting events, you `send` the command:
|
||||
|
||||
```js
|
||||
var app = spawnNodemon();
|
||||
|
||||
app.on('message', function (event) {
|
||||
if (event.type === 'start') {
|
||||
console.log('nodemon started');
|
||||
} else if (event.type === 'crash') {
|
||||
console.log('script crashed for some reason');
|
||||
}
|
||||
});
|
||||
|
||||
// force a restart
|
||||
app.send('restart');
|
||||
|
||||
// force a quit
|
||||
app.send('quit');
|
||||
```
|
||||
|
||||
Note that even though the child will still emit a `message` event whose type is
|
||||
`exit`, it makes more sense to listen to the actual `exit` event on the child:
|
||||
|
||||
```js
|
||||
app.on('exit', function () {
|
||||
console.log('nodemon quit');
|
||||
});
|
||||
```
|
8
node_modules/nodemon/doc/option-parsing-logic.md
generated
vendored
Normal file
8
node_modules/nodemon/doc/option-parsing-logic.md
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Option parsing logic
|
||||
|
||||
1. Read all CLI arguments
|
||||
2. Load local config
|
||||
3. Load global config
|
||||
4. Try backup: package.main
|
||||
5. Try backup: package.start
|
||||
6. Try index.js
|
56
node_modules/nodemon/doc/requireable.md
generated
vendored
Normal file
56
node_modules/nodemon/doc/requireable.md
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Nodemon as a required module
|
||||
|
||||
Nodemon (as of 1.0.0) also works as a required module. At present, you can only require nodemon in to your project once (as there are static config variables), but you can re-run with new settings for a different application to monitor.
|
||||
|
||||
By requiring nodemon, you can extend it's functionality. Below is a simple example of using nodemon in your project:
|
||||
|
||||
```js
|
||||
var nodemon = require('nodemon');
|
||||
|
||||
nodemon({
|
||||
script: 'app.js',
|
||||
ext: 'js json'
|
||||
});
|
||||
|
||||
nodemon.on('start', function () {
|
||||
console.log('App has started');
|
||||
}).on('quit', function () {
|
||||
console.log('App has quit');
|
||||
process.exit();
|
||||
}).on('restart', function (files) {
|
||||
console.log('App restarted due to: ', files);
|
||||
});
|
||||
```
|
||||
|
||||
Nodemon will emit a number of [events](https://github.com/remy/nodemon/blob/master/doc/events.md) by default, and when in verbose mode will also emit a `log` event (which matches what the nodemon cli tool echos).
|
||||
|
||||
## Arguments
|
||||
|
||||
The `nodemon` function takes either an object (that matches the [nodemon config](https://github.com/remy/nodemon#config-files)) or can take a string that matches the arguments that would be used on the command line:
|
||||
|
||||
```js
|
||||
var nodemon = require('nodemon');
|
||||
|
||||
nodemon('-e "js json" app.js');
|
||||
```
|
||||
|
||||
## Methods & Properties
|
||||
|
||||
The `nodemon` object also has a few methods and properties. Some are exposed to help with tests, but have been listed here for completeness:
|
||||
|
||||
### Event handling
|
||||
|
||||
This is simply the event emitter bus that exists inside nodemon exposed at the top level module (ie. it's the `events` api):
|
||||
|
||||
- `nodemon.on(event, fn)`
|
||||
- `nodemon.addListener(event, fn)`
|
||||
- `nodemon.once(event, fn)`
|
||||
- `nodemon.emit(event)`
|
||||
- `nodemon.removeAllListeners([event])`
|
||||
|
||||
Note: there's no `removeListener` (happy to take a pull request if it's needed).
|
||||
|
||||
### Test utilities
|
||||
|
||||
- `nodemon.reset()` - reverts nodemon's internal state to a clean slate
|
||||
- `nodemon.config` - a reference to the internal config nodemon uses
|
34
node_modules/nodemon/doc/rules.md
generated
vendored
Normal file
34
node_modules/nodemon/doc/rules.md
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Rules
|
||||
|
||||
Given a nodemon.json file that contains:
|
||||
|
||||
```json
|
||||
{
|
||||
"ignore": ["*.coffee"],
|
||||
"watch": ["server/*.coffee", "test/"]
|
||||
}
|
||||
```
|
||||
|
||||
Then nodemon detects changes, but what causes nodemon to restart? The ignored files or the watched files? Which wins?
|
||||
|
||||
```js
|
||||
var files = ['server/foo.coffee', 'server/app.js'];
|
||||
|
||||
// afterIgnore = ['server/app.js'] now since foo.coffee matches *.coffee
|
||||
var afterIgnore = files.filter(applyIgnore);
|
||||
|
||||
// watch = ['server/foo.coffee'] as it's under the watch
|
||||
var watched = files.filter(applyWatch);
|
||||
```
|
||||
|
||||
What about:
|
||||
|
||||
```js
|
||||
var files = ['test/app.js', 'test/app.coffee'];
|
||||
|
||||
// afterIgnore = ['test/app.js'] now since test/app.coffee matches *.coffee
|
||||
var afterIgnore = files.filter(applyIgnore);
|
||||
|
||||
// watch.length = 2 as watch implies test/*.*
|
||||
var watched = files.filter(applyWatch);
|
||||
```
|
28
node_modules/nodemon/doc/sample-nodemon.md
generated
vendored
Normal file
28
node_modules/nodemon/doc/sample-nodemon.md
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Sample nodemon.json
|
||||
|
||||
Here is an example (of a contrived) `nodemon.json` file:
|
||||
|
||||
{
|
||||
"restartable": "rs",
|
||||
"ignore": [
|
||||
".git",
|
||||
"node_modules/**/node_modules"
|
||||
],
|
||||
"verbose": true,
|
||||
"execMap": {
|
||||
"js": "node --harmony"
|
||||
},
|
||||
"events": {
|
||||
"restart": "osascript -e 'display notification \"App restarted due to:\n'$FILENAME'\" with title \"nodemon\"'"
|
||||
},
|
||||
"watch": [
|
||||
"test/fixtures/",
|
||||
"test/samples/"
|
||||
],
|
||||
"env": {
|
||||
"NODE_ENV": "development"
|
||||
},
|
||||
"ext": "js json"
|
||||
}
|
||||
|
||||
Note that the `ignore` used is nodemon's default ignore rule. The complete defaults can be seen here: [defaults.js](https://github.com/remy/nodemon/blob/master/lib/config/defaults.js).
|
188
node_modules/nodemon/docs/index.html
generated
vendored
Normal file
188
node_modules/nodemon/docs/index.html
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>nodemon</title>
|
||||
<style id="jsbin-css">
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
src: local('Roboto Thin'), local('Roboto-Thin'), url(https://themes.googleusercontent.com/static/fonts/roboto/v9/vzIUHo9z-oJ4WgkpPOtg13YhjbSpvc47ee6xR_80Hnw.woff) format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Roboto Light'), local('Roboto-Light'), url(https://themes.googleusercontent.com/static/fonts/roboto/v9/Hgo13k-tfSpn0qi1SFdUfbO3LdcAZYWl9Si6vvxL-qU.woff) format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(https://themes.googleusercontent.com/static/fonts/roboto/v9/RxZJdnzeo3R5zSexge8UUbO3LdcAZYWl9Si6vvxL-qU.woff) format('woff');
|
||||
}
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
min-height: 100%;
|
||||
background: #2B2922;
|
||||
color: #eee;
|
||||
font-family: 'Roboto', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 100;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
html {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
header, footer {
|
||||
background: #76d04b;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
/* background: white; */
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 0 auto;
|
||||
padding: 80px 0 0;
|
||||
border: 1px solid #77d04b;
|
||||
display: block;
|
||||
fill: #4F4D3F;
|
||||
}
|
||||
|
||||
header, footer a, footer p {
|
||||
color: #4F4D3F;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 40px 0 0 0;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
header strong {
|
||||
font-weight: 500;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
header h1, header h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body > p, h2, ul {
|
||||
margin: 20px 48px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 23px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-weight: 100;
|
||||
font-size: 22px;
|
||||
font-family: 'courier new';
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: courier;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
background: #000;
|
||||
border-radius: 3px;
|
||||
padding: 20px 48px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 40px;
|
||||
padding: 10px 28px;
|
||||
}
|
||||
|
||||
footer p {
|
||||
font-size: 80%;
|
||||
margin: 5px 10px;
|
||||
}
|
||||
|
||||
footer a {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
body > p, h2, ul {
|
||||
margin: 20px 10px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 20px 12px;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
pre, pre code {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<svg version="1.1" id="template" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" x="0px" y="0px" width="160" height="180"
|
||||
viewBox="0 0 160 185" xml:space="preserve">
|
||||
<path d="M158.156,60.461l-5.326-3.066
|
||||
c8.189-12.08,13.084-30.242,6.947-57.395c0,0-13.82,38.733-41.602,37.449L85.645,18.73c-1.227-0.728-2.602-1.103-3.992-1.159
|
||||
c-0.125,0-0.648,0-0.75,0c-1.387,0.057-2.76,0.432-4.004,1.159L44.367,37.449C16.586,38.738,2.762,0,2.762,0
|
||||
c-6.141,27.152-1.238,45.314,6.949,57.395l-5.324,3.066C1.682,62.018,0,64.914,0,68.072l0.16,112.363
|
||||
c0,1.568,0.812,3.021,2.188,3.783c1.344,0.812,3.008,0.812,4.35,0l43.094-24.676c2.727-1.619,4.385-4.477,4.385-7.6V99.449
|
||||
c0-3.129,1.658-6.031,4.373-7.582l18.35-10.568c1.367-0.795,2.863-1.182,4.391-1.182c1.492,0,3.027,0.387,4.356,1.182
|
||||
l18.344,10.568c2.715,1.551,4.379,4.453,4.379,7.582v52.494c0,3.123,1.68,6.002,4.391,7.6l43.082,24.676
|
||||
c1.352,0.812,3.039,0.812,4.379,0c1.336-0.762,2.176-2.215,2.176-3.783l0.141-112.363
|
||||
C162.535,64.914,160.879,62.018,158.156,60.461z"/>
|
||||
</svg>
|
||||
<h1><strong>nodemon</strong> reload, automatically.</h1>
|
||||
|
||||
</header>
|
||||
|
||||
<p>Nodemon is a utility that will monitor for any changes in your source and automatically restart your server. Perfect for development. Install it using <a href="https://npmjs.org/package/nodemon">npm</a>.</p>
|
||||
|
||||
<p>Just use <code>nodemon</code> instead of <code>node</code> to run your code, and now your process will automatically restart when your code changes. To install, get <a href="https://nodejs.org" target="_blank">node.js</a>, then from your terminal run:</p>
|
||||
|
||||
<pre><code>npm install -g nodemon</code></pre>
|
||||
|
||||
|
||||
<h2>Features</h2>
|
||||
|
||||
<ul>
|
||||
<li>Automatic restarting of application.</li>
|
||||
<li>Detects default file extension to monitor.</li>
|
||||
<li>Default support for node & coffeescript, but easy to run any executable (such as python, make, etc).</li>
|
||||
<li>Ignoring specific files or directories.</li>
|
||||
<li>Watch specific directories.</li>
|
||||
<li>Works with server applications or one time run utilities and REPLs.</li>
|
||||
<li>Requirable in node apps.</li>
|
||||
<li>Open source and available on <a href="https://github.com/remy/nodemon/">github</a>.</li>
|
||||
</ul>
|
||||
|
||||
<p>Read the full <a href="https://github.com/remy/nodemon#nodemon">documentation</a>.</p>
|
||||
|
||||
<footer>
|
||||
<p><a href="https://github.com/remy/nodemon/issues">issues</a> • <a href="https://github.com/remy/nodemon/">source code</a> • <a href="https://twitter.com/rem">built by @rem</a></p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
12
node_modules/nodemon/docs/index.js
generated
vendored
Normal file
12
node_modules/nodemon/docs/index.js
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
var http = require('http'),
|
||||
fs = require('fs');
|
||||
|
||||
var page = fs.readFileSync(__dirname + '/index.html', 'utf8');
|
||||
|
||||
var server = http.createServer(function (req, res) {
|
||||
res.writeHead(200, { 'content-type': 'text/html' });
|
||||
res.end(page);
|
||||
}).listen(process.env.PORT || 0, function () {
|
||||
console.log('Listening on http://localhost:' + server.address().port);
|
||||
});
|
1
node_modules/nodemon/docs/nodemon.svg
generated
vendored
Normal file
1
node_modules/nodemon/docs/nodemon.svg
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="268" height="306" viewBox="0 0 268 306" xmlns="http://www.w3.org/2000/svg"><title>nodemon</title><g fill="none"><path d="M126.616 303.746c4.458 2.577 9.957 2.577 14.415 0L260.46 234.83c4.466-2.575 7.215-7.336 7.215-12.494V84.398c0-5.154-2.75-9.912-7.208-12.493L141.04 2.933c-4.467-2.577-9.966-2.577-14.432 0L7.212 71.905C2.75 74.485 0 79.245 0 84.398v137.946c0 5.15 2.75 9.91 7.215 12.485l119.4 68.916" fill="#76D04B"/><path d="M211.156 120.46l-5.326-3.065c8.19-12.08 13.084-30.242 6.947-57.395 0 0-13.82 38.733-41.602 37.45l-32.53-18.72c-1.227-.728-2.602-1.103-3.992-1.16h-.75c-1.387.058-2.76.433-4.004 1.16L97.366 97.45C69.587 98.737 55.762 60 55.762 60c-6.14 27.152-1.238 45.314 6.95 57.395l-5.325 3.066C54.682 122.02 53 124.915 53 128.073l.16 112.363c0 1.568.812 3.02 2.188 3.783 1.344.812 3.008.812 4.35 0l43.094-24.676c2.727-1.62 4.385-4.477 4.385-7.6V159.45c0-3.13 1.658-6.032 4.373-7.583L129.9 141.3c1.367-.796 2.863-1.183 4.39-1.183 1.493 0 3.028.387 4.357 1.182l18.344 10.567c2.716 1.55 4.38 4.453 4.38 7.582v52.493c0 3.123 1.68 6.002 4.39 7.6l43.083 24.676c1.352.81 3.04.81 4.38 0 1.335-.763 2.175-2.216 2.175-3.784l.14-112.363c-.003-3.16-1.66-6.055-4.382-7.612z" fill="#4F4D3F"/></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
206
node_modules/nodemon/faq.md
generated
vendored
Normal file
206
node_modules/nodemon/faq.md
generated
vendored
Normal file
|
@ -0,0 +1,206 @@
|
|||
# FAQ
|
||||
|
||||
This is being added to as common issues occur on the [issues](http://github.com/remy/nodemon/issues), and where appropriate the answers will be added here.
|
||||
|
||||
This is a working document, and if it makes sense, I'll take pull requests to help make it better.
|
||||
|
||||
## nodemon doesn't work with my REPL
|
||||
|
||||
Create an nodemon.json file with the setting:
|
||||
|
||||
```js
|
||||
{
|
||||
"restartable": false
|
||||
}
|
||||
```
|
||||
|
||||
This will leave the STDIN to your application rather than listening for the `rs` command to restart.
|
||||
|
||||
# My script arguments are being taken by nodemon
|
||||
|
||||
Use the `--` switch to tell nodemon to ignore all arguments after this point. So to pass `-L` to your script instead of nodemon, use:
|
||||
|
||||
```
|
||||
$ nodemon app.js -- -L -opt2 -opt3
|
||||
```
|
||||
|
||||
nodemon will ignore all script arguments after `--` and pass them to your script.
|
||||
|
||||
# Can't install nodemon: permission issue
|
||||
|
||||
You may need to install nodemon using `sudo` (which isn't recommended, but I understand it's unavoidable in some environemnts). If the install fails with this appearing in the npm error log, then you need the following workaround.
|
||||
|
||||
```
|
||||
gyp WARN EACCES user "root" does not have permission to access the dev dir "<some-local-dir>"
|
||||
```
|
||||
|
||||
Try to re-install adding `--unsafe-perm` to the arguments:
|
||||
|
||||
```
|
||||
sudo npm install -g nodemon --unsafe-perm
|
||||
```
|
||||
|
||||
Ref [#713](https://github.com/remy/nodemon/issues/713)
|
||||
|
||||
# Help! My changes aren't being detected!
|
||||
|
||||
nodemon (from 1.4.2 onwards) uses [Chokidar](https://www.npmjs.com/package/chokidar) as its underlying watch system.
|
||||
|
||||
If you find your files aren't being monitored, either nodemon isn't restarting, or it reports that zero files are being watched, then you may need the polling mode.
|
||||
|
||||
To enable polling use the the legacy flag either via the terminal:
|
||||
|
||||
```shell
|
||||
$ nodemon --legacy-watch
|
||||
$ nodemon -L # short alias
|
||||
```
|
||||
|
||||
Or via the `nodemon.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"legacyWatch": true
|
||||
}
|
||||
```
|
||||
|
||||
## nodemon tries to run two scripts
|
||||
|
||||
If you see nodemon trying to run two scripts, like:
|
||||
|
||||
```
|
||||
9 Dec 23:52:58 - [nodemon] starting `node ./app.js fixtures/sigint.js`
|
||||
```
|
||||
|
||||
This is because the main script argument (`fixtures/sigint.js` in this case) wasn't found, and a `package.json`'s main file *was* found. ie. to solve, double check the path to your script is correct.
|
||||
|
||||
## What has precedence, ignore or watch?
|
||||
|
||||
Everything under the ignore rule has the final word. So if you ignore the `node_modules` directory, but watch `node_modules/*.js`, then all changed files will be ignored, because any changed .js file in the `node_modules` are ignored.
|
||||
|
||||
However, there are defaults in the ignore rules that your rules will be merged with, and not override. To override the ignore rules see [overriding the underlying default ignore rules](#overriding-the-underlying-default-ignore-rules).
|
||||
|
||||
## Overriding the underlying default ignore rules
|
||||
|
||||
The way the ignore rules work is that your rules are merged with the `ignoreRoot` rules, which contain `['.git', 'node_modules', ...]`. So if you ignore `public`, the ignore rule results in `['.git', 'node_modules', ..., 'public']`.
|
||||
|
||||
Say you did want to watch the `node_modules` directory. You have to override the `ignoreRoot`. If you wanted this on a per project basis, add the config to you local `nodemon.json`. If you want it for all projects, add it to `$HOME/nodemon.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"ignoreRoot": [".git"]
|
||||
}
|
||||
```
|
||||
|
||||
Now when ignoring `public`, the ignore rule results in `['.git', 'public']`, and nodemon will restart on `node_modules` changes.
|
||||
|
||||
## nodemon doesn't work with fedora
|
||||
|
||||
Fedora is looking for `nodejs` rather than `node` which is the binary that nodemon kicks off.
|
||||
|
||||
The solution is a simple workaround, Linux 101:
|
||||
|
||||
```bash
|
||||
sudo ln -s /usr/bin/nodejs /usr/local/bin/node
|
||||
```
|
||||
|
||||
Fedora and Ubuntu pakage node as nodejs, because node.dpkg is
|
||||
|
||||
> Description-en: Amateur Packet Radio Node program
|
||||
The node program accepts TCP/IP and packet radio network connections and
|
||||
presents users with an interface that allows them to make gateway connections
|
||||
to remote hosts using a variety of amateur radio protocols.
|
||||
They make the binary is nodejs, rather than node. So long as you're not using that Packet Radio Node Program mentioned above the workaround will work.
|
||||
|
||||
Thank you [@EvanCarroll](https://github.com/remy/nodemon/issues/68#issuecomment-13672509)
|
||||
|
||||
## Using nodemon with forever
|
||||
|
||||
If you're using nodemon with [forever](https://github.com/foreverjs/forever) (perhaps in a production environment), you can combine the two together. This way if the script crashes, forever restarts the script, and if there are file changes, nodemon restarts your script. For more detail, see [issue 30](https://github.com/remy/nodemon/issues/30).
|
||||
|
||||
To achieve this you need to add the following on the call to `forever`:
|
||||
|
||||
* Use forever's `-c nodemon` option to tell forever to run `nodemon` instead of `node`.
|
||||
* Include the nodemon `--exitcrash` flag to ensure nodemon exits if the script crashes (or exits unexpectedly).
|
||||
* Tell forever to use `SIGTERM` instead of `SIGKILL` when requesting nodemon to stop. This ensures that nodemon can stop the watched node process cleanly.
|
||||
* Optionally add the `--uid` parameter, adding a unique name for your process. In the example, the uid is set to `foo`.
|
||||
|
||||
```bash
|
||||
forever start --uid foo --killSignal=SIGTERM -c nodemon --exitcrash server.js
|
||||
```
|
||||
|
||||
To test this, you can kill the server.js process and forever will restart it. If you `touch server.js` nodemon will restart it.
|
||||
|
||||
To stop the process monitored by forever and nodemon, simply call the following, using the `uid` we assigned above (`foo`):
|
||||
|
||||
```bash
|
||||
forever stop foo
|
||||
```
|
||||
|
||||
This will stop both nodemon and the node process it was monitoring.
|
||||
|
||||
Note that I *would not* recommend using nodemon in a production environment - but that's because I wouldn't want it restart without my explicit instruction.
|
||||
|
||||
## What does "verbose" give me?
|
||||
|
||||
The `--verbose` (or `-V`) puts nodemon in verbose mode which adds some detail to starting and restarting.
|
||||
|
||||
Additional restart information:
|
||||
|
||||
- Which nodemon configs are loaded (local and global if found)
|
||||
- Which ignore rules are being applied
|
||||
- Which file extensions are being watch
|
||||
- The process ID of your application (the `child pid`)
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
14 Apr 15:24:58 - [nodemon] v1.0.17
|
||||
14 Apr 15:24:58 - [nodemon] reading config /Users/remy/Sites/jsbin-private/nodemon.json
|
||||
14 Apr 15:24:58 - [nodemon] to restart at any time, enter `rs`
|
||||
14 Apr 15:24:58 - [nodemon] ignoring: /Users/remy/Sites/jsbin-private/.git/**/* node_modules/**/node_modules
|
||||
14 Apr 15:24:58 - [nodemon] watching: /Users/remy/Sites/jsbin/views/**/* /Users/remy/Sites/jsbin/lib/**/* ../json/*.json config.dev.json
|
||||
14 Apr 15:24:58 - [nodemon] watching extensions: json,js,html
|
||||
14 Apr 15:24:58 - [nodemon] starting `node run.js`
|
||||
14 Apr 15:24:58 - [nodemon] child pid: 9292
|
||||
```
|
||||
|
||||
When nodemon detects a change, the following addition information is shown:
|
||||
|
||||
- Which file(s) triggered the check
|
||||
- Which (if any) rules the file matched to cause a subsequent restart
|
||||
- How many rules were matched and out of those rules, how many cause a restart
|
||||
- A list of all the files that *successfully* caused a restart
|
||||
|
||||
For example, on `lib/app.js` being changed:
|
||||
|
||||
```text
|
||||
14 Apr 15:25:56 - [nodemon] files triggering change check: ../jsbin/lib/app.js
|
||||
14 Apr 15:25:56 - [nodemon] matched rule: **/Users/remy/Sites/jsbin/lib/**/*
|
||||
14 Apr 15:25:56 - [nodemon] changes after filters (before/after): 1/1
|
||||
14 Apr 15:25:56 - [nodemon] restarting due to changes...
|
||||
14 Apr 15:25:56 - [nodemon] ../jsbin/lib/app.js
|
||||
|
||||
14 Apr 15:25:56 - [nodemon] starting `node run.js`
|
||||
14 Apr 15:25:56 - [nodemon] child pid: 9556
|
||||
```
|
||||
|
||||
## My .nodemonignore is being ignored
|
||||
|
||||
The new `nodemon.json` superceeds the `.nodemonignore` file, so if you have both, the `.nodemonignore` is not used at all.
|
||||
|
||||
Note that if you have a `nodemon.json` in your `$HOME` path, then this will also supersede the old ignore file.
|
||||
|
||||
## nodemon does nothing
|
||||
|
||||
On Ubuntu globally installed node applications have been found to have no output when they're run. This *seems* to be an issue with node not being correctly installed (possibly linked to the binary having to be called `nodejs`).
|
||||
|
||||
The solution (that's worked in the past) is to install [nvm](https://github.com/creationix/nvm) first and using it to install node, *rather* than using `apt-get` (or similar tools) to install node directly.
|
||||
|
||||
## If nodemon is facing the watch errors (mac)
|
||||
|
||||
Try the following command on terminal:
|
||||
|
||||
```bash
|
||||
echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
```
|
||||
|
49
node_modules/nodemon/lib/cli/index.js
generated
vendored
Normal file
49
node_modules/nodemon/lib/cli/index.js
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
var parse = require('./parse');
|
||||
|
||||
/**
|
||||
* Converts a string to command line args, in particular
|
||||
* groups together quoted values.
|
||||
* This is a utility function to allow calling nodemon as a required
|
||||
* library, but with the CLI args passed in (instead of an object).
|
||||
*
|
||||
* @param {String} string
|
||||
* @return {Array}
|
||||
*/
|
||||
function stringToArgs(string) {
|
||||
var args = [];
|
||||
|
||||
var parts = string.split(' ');
|
||||
var length = parts.length;
|
||||
var i = 0;
|
||||
var open = false;
|
||||
var grouped = '';
|
||||
var lead = '';
|
||||
|
||||
for (; i < length; i++) {
|
||||
lead = parts[i].substring(0, 1);
|
||||
if (lead === '"' || lead === '\'') {
|
||||
open = lead;
|
||||
grouped = parts[i].substring(1);
|
||||
} else if (open && parts[i].slice(-1) === open) {
|
||||
open = false;
|
||||
grouped += ' ' + parts[i].slice(0, -1);
|
||||
args.push(grouped);
|
||||
} else if (open) {
|
||||
grouped += ' ' + parts[i];
|
||||
} else {
|
||||
args.push(parts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parse: function (argv) {
|
||||
if (typeof argv === 'string') {
|
||||
argv = stringToArgs(argv);
|
||||
}
|
||||
|
||||
return parse(argv);
|
||||
},
|
||||
};
|
246
node_modules/nodemon/lib/cli/parse.js
generated
vendored
Normal file
246
node_modules/nodemon/lib/cli/parse.js
generated
vendored
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
|
||||
nodemon is a utility for node, and replaces the use of the executable
|
||||
node. So the user calls `nodemon foo.js` instead.
|
||||
|
||||
nodemon can be run in a number of ways:
|
||||
|
||||
`nodemon` - tries to use package.json#main property to run
|
||||
`nodemon` - if no package, looks for index.js
|
||||
`nodemon app.js` - runs app.js
|
||||
`nodemon --arg app.js --apparg` - eats arg1, and runs app.js with apparg
|
||||
`nodemon --apparg` - as above, but passes apparg to package.json#main (or
|
||||
index.js)
|
||||
`nodemon --debug app.js
|
||||
|
||||
*/
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var existsSync = fs.existsSync || path.existsSync;
|
||||
|
||||
module.exports = parse;
|
||||
|
||||
/**
|
||||
* Parses the command line arguments `process.argv` and returns the
|
||||
* nodemon options, the user script and the executable script.
|
||||
*
|
||||
* @param {Array} full process arguments, including `node` leading arg
|
||||
* @return {Object} { options, script, args }
|
||||
*/
|
||||
function parse(argv) {
|
||||
if (typeof argv === 'string') {
|
||||
argv = argv.split(' ');
|
||||
}
|
||||
|
||||
var eat = function (i, args) {
|
||||
if (i <= args.length) {
|
||||
return args.splice(i + 1, 1).pop();
|
||||
}
|
||||
};
|
||||
|
||||
var args = argv.slice(2);
|
||||
var script = null;
|
||||
var nodemonOptions = { scriptPosition: null };
|
||||
|
||||
var nodemonOpt = nodemonOption.bind(null, nodemonOptions);
|
||||
var lookForArgs = true;
|
||||
|
||||
// move forward through the arguments
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
// if the argument looks like a file, then stop eating
|
||||
if (!script) {
|
||||
if (args[i] === '.' || existsSync(args[i])) {
|
||||
script = args.splice(i, 1).pop();
|
||||
|
||||
// we capture the position of the script because we'll reinsert it in
|
||||
// the right place in run.js:command (though I'm not sure we should even
|
||||
// take it out of the array in the first place, but this solves passing
|
||||
// arguments to the exec process for now).
|
||||
nodemonOptions.scriptPosition = i;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (lookForArgs) {
|
||||
// respect the standard way of saying: hereafter belongs to my script
|
||||
if (args[i] === '--') {
|
||||
args.splice(i, 1);
|
||||
// cycle back one argument, as we just ate this one up
|
||||
i--;
|
||||
|
||||
// ignore all further nodemon arguments
|
||||
lookForArgs = false;
|
||||
|
||||
// move to the next iteration
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nodemonOpt(args[i], eat.bind(null, i, args)) !== false) {
|
||||
args.splice(i, 1);
|
||||
// cycle back one argument, as we just ate this one up
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (script === null && !nodemonOptions.exec) {
|
||||
var found = findAppScript();
|
||||
if (found !== null) {
|
||||
if (found.exec) {
|
||||
nodemonOptions.exec = found.exec;
|
||||
}
|
||||
script = found.script;
|
||||
nodemonOptions.scriptPosition = args.length;
|
||||
}
|
||||
}
|
||||
|
||||
nodemonOptions.script = script;
|
||||
nodemonOptions.args = args;
|
||||
|
||||
return nodemonOptions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an argument (ie. from process.argv), sets nodemon
|
||||
* options and can eat up the argument value
|
||||
*
|
||||
* @param {Object} options object that will be updated
|
||||
* @param {Sting} current argument from argv
|
||||
* @param {Function} the callback to eat up the next argument in argv
|
||||
* @return {Boolean} false if argument was not a nodemon arg
|
||||
*/
|
||||
function nodemonOption(options, arg, eatNext) {
|
||||
// line seperation on purpose to help legibility
|
||||
if (arg === '--help' || arg === '-h' || arg === '-?') {
|
||||
var help = eatNext();
|
||||
options.help = help ? help : true;
|
||||
} else
|
||||
|
||||
if (arg === '--version' || arg === '-v') {
|
||||
options.version = true;
|
||||
} else
|
||||
|
||||
if (arg === '--dump') {
|
||||
options.dump = true;
|
||||
} else
|
||||
|
||||
if (arg === '--verbose' || arg === '-V') {
|
||||
options.verbose = true;
|
||||
} else
|
||||
|
||||
if (arg === '--legacy-watch' || arg === '-L') {
|
||||
options.legacyWatch = true;
|
||||
} else
|
||||
|
||||
if (arg === '--polling-interval' || arg === '-P') {
|
||||
options.pollingInterval = parseInt(eatNext(), 10);
|
||||
} else
|
||||
|
||||
// Depricated as this is "on" by default
|
||||
if (arg === '--js') {
|
||||
options.js = true;
|
||||
} else
|
||||
|
||||
if (arg === '--quiet' || arg === '-q') {
|
||||
options.quiet = true;
|
||||
} else
|
||||
|
||||
if (arg === '--hidden') { // TODO document this flag?
|
||||
options.hidden = true;
|
||||
} else
|
||||
|
||||
if (arg === '--config') {
|
||||
options.configFile = eatNext();
|
||||
} else
|
||||
|
||||
if (arg === '--watch' || arg === '-w') {
|
||||
if (!options.watch) { options.watch = []; }
|
||||
options.watch.push(eatNext());
|
||||
} else
|
||||
|
||||
if (arg === '--ignore' || arg === '-i') {
|
||||
if (!options.ignore) { options.ignore = []; }
|
||||
options.ignore.push(eatNext());
|
||||
} else
|
||||
|
||||
if (arg === '--exitcrash') {
|
||||
options.exitcrash = true;
|
||||
} else
|
||||
|
||||
if (arg === '--delay' || arg === '-d') {
|
||||
options.delay = parseDelay(eatNext());
|
||||
} else
|
||||
|
||||
if (arg === '--exec' || arg === '-x') {
|
||||
options.exec = eatNext();
|
||||
} else
|
||||
|
||||
if (arg === '--no-stdin' || arg === '-I') {
|
||||
options.stdin = false;
|
||||
} else
|
||||
|
||||
if (arg === '--on-change-only' || arg === '-C') {
|
||||
options.runOnChangeOnly = true;
|
||||
} else
|
||||
|
||||
if (arg === '--ext' || arg === '-e') {
|
||||
options.ext = eatNext();
|
||||
} else
|
||||
|
||||
if (arg === '--no-colours' || arg === '--no-colors') {
|
||||
options.colours = false;
|
||||
} else
|
||||
|
||||
if (arg === '--signal' || arg === '-s') {
|
||||
options.signal = eatNext();
|
||||
} else
|
||||
|
||||
if (arg === '--cwd') {
|
||||
options.cwd = eatNext();
|
||||
|
||||
// go ahead and change directory. This is primarily for nodemon tools like
|
||||
// grunt-nodemon - we're doing this early because it will affect where the
|
||||
// user script is searched for.
|
||||
process.chdir(path.resolve(options.cwd));
|
||||
} else {
|
||||
|
||||
// this means we didn't match
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function findAppScript() {
|
||||
// nodemon has been run alone, so try to read the package file
|
||||
// or try to read the index.js file
|
||||
if (existsSync('./index.js')) {
|
||||
return { exec: null, script: 'index.js' };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an argument (ie. from nodemonOption()), will parse and return the
|
||||
* equivalent millisecond value or 0 if the argument cannot be parsed
|
||||
*
|
||||
* @param {String} argument value given to the --delay option
|
||||
* @return {Number} millisecond equivalent of the argument
|
||||
*/
|
||||
function parseDelay(value) {
|
||||
var millisPerSecond = 1000;
|
||||
var millis = 0;
|
||||
|
||||
if (value.match(/^\d*ms$/)) {
|
||||
// Explicitly parse for milliseconds when using ms time specifier
|
||||
millis = parseInt(value, 10);
|
||||
} else {
|
||||
// Otherwise, parse for seconds, with or without time specifier then convert
|
||||
millis = parseFloat(value) * millisPerSecond;
|
||||
}
|
||||
|
||||
return isNaN(millis) ? 0 : millis;
|
||||
}
|
||||
|
43
node_modules/nodemon/lib/config/command.js
generated
vendored
Normal file
43
node_modules/nodemon/lib/config/command.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
module.exports = command;
|
||||
|
||||
/**
|
||||
* command constructs the executable command to run in a shell including the
|
||||
* user script, the command arguments.
|
||||
*
|
||||
* @param {Object} settings Object as:
|
||||
* { execOptions: {
|
||||
* exec: String,
|
||||
* [script: String],
|
||||
* [scriptPosition: Number],
|
||||
* [execArgs: Array<string>]
|
||||
* }
|
||||
* }
|
||||
* @return {Object} an object with the node executable and the
|
||||
* arguments to the command
|
||||
*/
|
||||
function command(settings) {
|
||||
var options = settings.execOptions;
|
||||
var executable = options.exec;
|
||||
var args = [];
|
||||
|
||||
// after "executable" go the exec args (like --debug, etc)
|
||||
if (options.execArgs) {
|
||||
[].push.apply(args, options.execArgs);
|
||||
}
|
||||
|
||||
// then goes the user's script arguments
|
||||
if (options.args) {
|
||||
[].push.apply(args, options.args);
|
||||
}
|
||||
|
||||
// after the "executable" goes the user's script
|
||||
if (options.script) {
|
||||
args.splice((options.scriptPosition || 0) +
|
||||
options.execArgs.length, 0, options.script);
|
||||
}
|
||||
|
||||
return {
|
||||
executable: executable,
|
||||
args: args,
|
||||
};
|
||||
}
|
24
node_modules/nodemon/lib/config/defaults.js
generated
vendored
Normal file
24
node_modules/nodemon/lib/config/defaults.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
var ignoreRoot = require('ignore-by-default').directories()
|
||||
|
||||
// default options for config.options
|
||||
module.exports = {
|
||||
restartable: 'rs',
|
||||
colours: true,
|
||||
execMap: {
|
||||
py: 'python',
|
||||
rb: 'ruby',
|
||||
// more can be added here such as ls: lsc - but please ensure it's cross
|
||||
// compatible with linux, mac and windows, or make the default.js
|
||||
// dynamically append the `.cmd` for node based utilities
|
||||
},
|
||||
ignoreRoot: ignoreRoot,
|
||||
watch: ['*.*'],
|
||||
stdin: true,
|
||||
runOnChangeOnly: false,
|
||||
verbose: false,
|
||||
// 'stdout' refers to the default behaviour of a required nodemon's child,
|
||||
// but also includes stderr. If this is false, data is still dispatched via
|
||||
// nodemon.on('stdout/stderr')
|
||||
stdout: true,
|
||||
|
||||
};
|
171
node_modules/nodemon/lib/config/exec.js
generated
vendored
Normal file
171
node_modules/nodemon/lib/config/exec.js
generated
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
var path = require('path');
|
||||
var utils = require('../utils');
|
||||
|
||||
module.exports = exec;
|
||||
|
||||
/**
|
||||
* Reads the cwd/package.json file and looks to see if it can load a script
|
||||
* and possibly an exec first from package.main, then package.start.
|
||||
*
|
||||
* @return {Object} exec & script if found
|
||||
*/
|
||||
function execFromPackage() {
|
||||
// doing a try/catch because we can't use the path.exist callback pattern
|
||||
// or we could, but the code would get messy, so this will do exactly
|
||||
// what we're after - if the file doesn't exist, it'll throw.
|
||||
try {
|
||||
// note: this isn't nodemon's package, it's the user's cwd package
|
||||
var pkg = require(path.join(process.cwd(), 'package.json'));
|
||||
if (pkg.main !== undefined) {
|
||||
// no app found to run - so give them a tip and get the feck out
|
||||
return { exec: null, script: pkg.main };
|
||||
} else if (pkg.scripts && pkg.scripts.start) {
|
||||
return { exec: pkg.scripts.start };
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function replace(map, str) {
|
||||
var re = new RegExp('{{(' + Object.keys(map).join('|') + ')}}');
|
||||
return str.replace(re, function (all, m) {
|
||||
return map[m] || all || '';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Discovers all the options required to run the script
|
||||
* and if a custom exec has been passed in, then it will
|
||||
* also try to work out what extensions to monitor and
|
||||
* whether there's a special way of running that script.
|
||||
*
|
||||
* @param {Object} nodemonOptions
|
||||
* @param {Object} execMap
|
||||
* @return {Object} new and updated version of nodemonOptions
|
||||
*/
|
||||
function exec(nodemonOptions, execMap) {
|
||||
if (!execMap) {
|
||||
execMap = {};
|
||||
}
|
||||
|
||||
// if there's no exec found yet, then try to read it from the local
|
||||
// package.json this logic used to sit in the cli/parse, but actually the cli
|
||||
// should be parsed first, then the user options (via nodemon.json) then
|
||||
// finally default down to pot shots at the directory via package.json
|
||||
if (!nodemonOptions.exec && !nodemonOptions.script) {
|
||||
var found = execFromPackage();
|
||||
if (found !== null) {
|
||||
if (found.exec) {
|
||||
nodemonOptions.exec = found.exec;
|
||||
}
|
||||
if (!nodemonOptions.script) {
|
||||
nodemonOptions.script = found.script;
|
||||
}
|
||||
if (Array.isArray(nodemonOptions.args) &&
|
||||
nodemonOptions.scriptPosition === null) {
|
||||
nodemonOptions.scriptPosition = nodemonOptions.args.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var options = utils.clone(nodemonOptions || {});
|
||||
var script = path.basename(options.script || '');
|
||||
var scriptExt = path.extname(script).slice(1);
|
||||
var extension = options.ext || (scriptExt ? scriptExt + ',json' : 'js,json');
|
||||
var execDefined = !!options.exec;
|
||||
|
||||
// allows the user to simplify cli usage:
|
||||
// https://github.com/remy/nodemon/issues/195
|
||||
// but always give preference to the user defined argument
|
||||
if (!options.exec && execMap[scriptExt] !== undefined) {
|
||||
options.exec = execMap[scriptExt];
|
||||
execDefined = true;
|
||||
}
|
||||
|
||||
options.execArgs = [];
|
||||
|
||||
if (Array.isArray(options.exec)) {
|
||||
options.execArgs = options.exec;
|
||||
options.exec = options.execArgs.shift();
|
||||
}
|
||||
|
||||
if (options.exec === undefined) {
|
||||
options.exec = 'node';
|
||||
} else {
|
||||
// allow variable substitution for {{filename}} and {{pwd}}
|
||||
var substitution = replace.bind(null, {
|
||||
filename: options.script,
|
||||
pwd: process.cwd(),
|
||||
});
|
||||
|
||||
var newExec = substitution(options.exec);
|
||||
if (newExec !== options.exec &&
|
||||
options.exec.indexOf('{{filename}}') !== -1) {
|
||||
options.script = null;
|
||||
}
|
||||
options.exec = newExec;
|
||||
|
||||
var newExecArgs = options.execArgs.map(substitution);
|
||||
if (newExecArgs.join('') !== options.execArgs.join('')) {
|
||||
options.execArgs = newExecArgs;
|
||||
delete options.script;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (options.exec === 'node' && options.nodeArgs && options.nodeArgs.length) {
|
||||
options.execArgs = options.execArgs.concat(options.nodeArgs);
|
||||
}
|
||||
|
||||
// note: indexOf('coffee') handles both .coffee and .litcoffee
|
||||
if (!execDefined && options.exec === 'node' &&
|
||||
scriptExt.indexOf('coffee') !== -1) {
|
||||
options.exec = 'coffee';
|
||||
|
||||
// we need to get execArgs set before the script
|
||||
// for example, in `nodemon --debug my-script.coffee --my-flag`, debug is an
|
||||
// execArg, while my-flag is a script arg
|
||||
var leadingArgs = (options.args || []).splice(0, options.scriptPosition);
|
||||
options.execArgs = options.execArgs.concat(leadingArgs);
|
||||
options.scriptPosition = 0;
|
||||
|
||||
if (options.execArgs.length > 0) {
|
||||
// because this is the coffee executable, we need to combine the exec args
|
||||
// into a single argument after the nodejs flag
|
||||
options.execArgs = ['--nodejs', options.execArgs.join(' ')];
|
||||
}
|
||||
}
|
||||
|
||||
if (options.exec === 'coffee') {
|
||||
// don't override user specified extension tracking
|
||||
if (!options.ext) {
|
||||
extension = 'coffee,litcoffee,js,json';
|
||||
}
|
||||
|
||||
// because windows can't find 'coffee', it needs the real file 'coffee.cmd'
|
||||
if (utils.isWindows) {
|
||||
options.exec += '.cmd';
|
||||
}
|
||||
}
|
||||
|
||||
// allow users to make a mistake on the extension to monitor
|
||||
// converts .js, jade => js,jade
|
||||
// BIG NOTE: user can't do this: nodemon -e *.js
|
||||
// because the terminal will automatically expand the glob against
|
||||
// the file system :(
|
||||
extension = (extension.match(/[^,.\s]+/g) || []).join(',');
|
||||
|
||||
options.ext = extension;
|
||||
|
||||
options.env = {};
|
||||
// make sure it's an object (and since we don't have )
|
||||
if (({}).toString.apply(nodemonOptions.env) === '[object Object]') {
|
||||
options.env = utils.clone(nodemonOptions.env);
|
||||
} else if (nodemonOptions.env !== undefined) {
|
||||
throw new Error('nodemon env values must be an object: { PORT: 8000 }');
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
90
node_modules/nodemon/lib/config/index.js
generated
vendored
Normal file
90
node_modules/nodemon/lib/config/index.js
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Manages the internal config of nodemon, checking for the state of support
|
||||
* with fs.watch, how nodemon can watch files (using find or fs methods).
|
||||
*
|
||||
* This is *not* the user's config.
|
||||
*/
|
||||
var debug = require('debug')('nodemon');
|
||||
var load = require('./load');
|
||||
var rules = require('../rules');
|
||||
var utils = require('../utils');
|
||||
var pinVersion = require('../version').pin;
|
||||
var command = require('./command');
|
||||
var rulesToMonitor = require('../monitor/match').rulesToMonitor;
|
||||
var bus = utils.bus;
|
||||
|
||||
function reset() {
|
||||
rules.reset();
|
||||
|
||||
config.dirs = [];
|
||||
config.options = { ignore: [], watch: [] };
|
||||
config.lastStarted = 0;
|
||||
config.loaded = [];
|
||||
}
|
||||
|
||||
var config = {
|
||||
run: false,
|
||||
system: {
|
||||
cwd: process.cwd(),
|
||||
},
|
||||
required: false,
|
||||
dirs: [],
|
||||
timeout: 1000,
|
||||
options: {},
|
||||
signal: 'SIGUSR2',
|
||||
};
|
||||
|
||||
/**
|
||||
* Take user defined settings, then detect the local machine capability, then
|
||||
* look for local and global nodemon.json files and merge together the final
|
||||
* settings with the config for nodemon.
|
||||
*
|
||||
* @param {Object} settings user defined settings for nodemon (typically on
|
||||
* the cli)
|
||||
* @param {Function} ready callback fired once the config is loaded
|
||||
*/
|
||||
config.load = function (settings, ready) {
|
||||
reset();
|
||||
var config = this;
|
||||
load(settings, config.options, config, function (options) {
|
||||
config.options = options;
|
||||
|
||||
if (options.watch.length === 0) {
|
||||
// this is to catch when the watch is left blank
|
||||
options.watch.push('*.*');
|
||||
}
|
||||
|
||||
if (options['watch_interval']) { // jshint ignore:line
|
||||
options.watchInterval = options['watch_interval']; // jshint ignore:line
|
||||
}
|
||||
|
||||
config.watchInterval = options.watchInterval || null;
|
||||
if (options['signal']) { // jshint ignore:line
|
||||
config.signal = options.signal;
|
||||
}
|
||||
|
||||
var cmd = command(config.options);
|
||||
config.command = {
|
||||
raw: cmd,
|
||||
string: utils.stringify(cmd.executable, cmd.args),
|
||||
};
|
||||
|
||||
// now run automatic checks on system adding to the config object
|
||||
options.monitor = rulesToMonitor(options.watch, options.ignore, config);
|
||||
|
||||
var cwd = process.cwd();
|
||||
debug('config: dirs', config.dirs);
|
||||
if (config.dirs.length === 0) {
|
||||
config.dirs.unshift(cwd);
|
||||
}
|
||||
|
||||
bus.emit('config:update', config);
|
||||
pinVersion().then(function () {
|
||||
ready(config);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
config.reset = reset;
|
||||
|
||||
module.exports = config;
|
213
node_modules/nodemon/lib/config/load.js
generated
vendored
Normal file
213
node_modules/nodemon/lib/config/load.js
generated
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
var debug = require('debug')('nodemon');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exists = fs.exists || path.exists;
|
||||
var utils = require('../utils');
|
||||
var rules = require('../rules');
|
||||
var parse = require('../rules/parse');
|
||||
var exec = require('./exec');
|
||||
var defaults = require('./defaults');
|
||||
|
||||
module.exports = load;
|
||||
|
||||
/**
|
||||
* Load the nodemon config, first reading the global root/nodemon.json, then
|
||||
* the local nodemon.json to the exec and then overwritting using any user
|
||||
* specified settings (i.e. from the cli)
|
||||
*
|
||||
* @param {Object} settings user defined settings
|
||||
* @param {Function} ready callback that recieves complete config
|
||||
*/
|
||||
function load(settings, options, config, callback) {
|
||||
config.loaded = [];
|
||||
// first load the root nodemon.json
|
||||
loadFile(options, config, utils.home, function (options) {
|
||||
// then load the user's local configuration file
|
||||
if (settings.configFile) {
|
||||
options.configFile = path.resolve(settings.configFile);
|
||||
}
|
||||
loadFile(options, config, process.cwd(), function (options) {
|
||||
// Then merge over with the user settings (parsed from the cli).
|
||||
// Note that merge protects and favours existing values over new values,
|
||||
// and thus command line arguments get priority
|
||||
options = utils.merge(settings, options);
|
||||
|
||||
// legacy support
|
||||
if (!Array.isArray(options.ignore)) {
|
||||
options.ignore = [options.ignore];
|
||||
}
|
||||
|
||||
if (!options.ignoreRoot) {
|
||||
options.ignoreRoot = defaults.ignoreRoot;
|
||||
}
|
||||
|
||||
// blend the user ignore and the default ignore together
|
||||
if (options.ignoreRoot && options.ignore) {
|
||||
if (!Array.isArray(options.ignoreRoot)) {
|
||||
options.ignoreRoot = [options.ignoreRoot];
|
||||
}
|
||||
options.ignore = options.ignoreRoot.concat(options.ignore);
|
||||
} else {
|
||||
options.ignore = defaults.ignore.concat(options.ignore);
|
||||
}
|
||||
|
||||
|
||||
// add in any missing defaults
|
||||
options = utils.merge(options, defaults);
|
||||
|
||||
// work out the execOptions based on the final config we have
|
||||
options.execOptions = exec({
|
||||
script: options.script,
|
||||
exec: options.exec,
|
||||
args: options.args,
|
||||
scriptPosition: options.scriptPosition,
|
||||
nodeArgs: options.nodeArgs,
|
||||
ext: options.ext,
|
||||
env: options.env,
|
||||
}, options.execMap);
|
||||
|
||||
// clean up values that we don't need at the top level
|
||||
delete options.scriptPosition;
|
||||
delete options.script;
|
||||
delete options.args;
|
||||
delete options.ext;
|
||||
|
||||
if (options.quiet) {
|
||||
utils.quiet();
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
utils.debug = true;
|
||||
}
|
||||
|
||||
// simplify the ready callback to be called after the rules are normalised
|
||||
// from strings to regexp through the rules lib. Note that this gets
|
||||
// created *after* options is overwritten twice in the lines above.
|
||||
var ready = function (options) {
|
||||
normaliseRules(options, callback);
|
||||
};
|
||||
|
||||
// if we didn't pick up a nodemon.json file & there's no cli ignores
|
||||
// then try loading an old style .nodemonignore file
|
||||
if (config.loaded.length === 0) {
|
||||
// TODO decide whether this is just confusing...
|
||||
var legacy = loadLegacyIgnore.bind(null, options, ready);
|
||||
|
||||
// first try .nodemonignore, if that doesn't exist, try nodemon-ignore
|
||||
return legacy('.nodemonignore', function () {
|
||||
legacy('nodemon-ignore', function (options) {
|
||||
ready(options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ready(options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the old style nodemonignore files which are simply a list of patterns
|
||||
* in a file to ignore
|
||||
*
|
||||
* @param {Object} options nodemon user options
|
||||
* @param {Function} success
|
||||
* @param {String} filename ignore file (.nodemonignore or nodemon-ignore)
|
||||
* @param {Function} fail (optional) failure callback
|
||||
*/
|
||||
function loadLegacyIgnore(options, success, filename, fail) {
|
||||
var ignoreFile = path.join(process.cwd(), filename);
|
||||
|
||||
exists(ignoreFile, function (exists) {
|
||||
if (exists) {
|
||||
return parse(ignoreFile, function (error, rules) {
|
||||
options.ignore = rules.raw;
|
||||
success(options);
|
||||
});
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
fail(options);
|
||||
} else {
|
||||
success(options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function normaliseRules(options, ready) {
|
||||
// convert ignore and watch options to rules/regexp
|
||||
rules.watch.add(options.watch);
|
||||
rules.ignore.add(options.ignore);
|
||||
|
||||
// normalise the watch and ignore arrays
|
||||
options.watch = options.watch === false ? false : rules.rules.watch;
|
||||
options.ignore = rules.rules.ignore;
|
||||
|
||||
ready(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a config in the current working directory, and a config in the
|
||||
* user's home directory, merging the two together, giving priority to local
|
||||
* config. This can then be overwritten later by command line arguments
|
||||
*
|
||||
* @param {Function} ready callback to pass loaded settings to
|
||||
*/
|
||||
function loadFile(options, config, dir, ready) {
|
||||
if (!ready) {
|
||||
ready = function () {};
|
||||
}
|
||||
|
||||
var callback = function (settings) {
|
||||
// prefer the local nodemon.json and fill in missing items using
|
||||
// the global options
|
||||
ready(utils.merge(settings, options));
|
||||
};
|
||||
|
||||
if (!dir) {
|
||||
return callback({});
|
||||
}
|
||||
|
||||
var filename = options.configFile || path.join(dir, 'nodemon.json');
|
||||
fs.readFile(filename, 'utf8', function (err, data) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
if (!options.configFile && dir !== utils.home) {
|
||||
// if no specified local config file and local nodemon.json
|
||||
// doesn't exist, try the package.json
|
||||
return loadPackageJSON(config, callback);
|
||||
}
|
||||
}
|
||||
return callback({});
|
||||
}
|
||||
|
||||
var settings = {};
|
||||
|
||||
try {
|
||||
settings = JSON.parse(data.toString('utf8').replace(/^\uFEFF/, ''));
|
||||
config.loaded.push(filename);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
utils.log.fail('Failed to parse config ' + filename);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// options values will overwrite settings
|
||||
callback(settings);
|
||||
});
|
||||
}
|
||||
|
||||
function loadPackageJSON(config, ready) {
|
||||
if (!ready) {
|
||||
ready = function () {};
|
||||
}
|
||||
|
||||
utils.log.detail('Looking in package.json for nodemonConfig');
|
||||
|
||||
var dir = process.cwd();
|
||||
var filename = path.join(dir, 'package.json');
|
||||
var packageLoadOptions = { configFile: filename };
|
||||
return loadFile(packageLoadOptions, config, dir, function (settings) {
|
||||
ready(settings.nodemonConfig || {});
|
||||
});
|
||||
}
|
24
node_modules/nodemon/lib/help/index.js
generated
vendored
Normal file
24
node_modules/nodemon/lib/help/index.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = help;
|
||||
|
||||
function help(item) {
|
||||
if (!item) {
|
||||
item = 'help';
|
||||
} else if (item === true) { // if used with -h or --help and no args
|
||||
item = 'help';
|
||||
}
|
||||
|
||||
// cleanse the filename to only contain letters
|
||||
// aka: /\W/g but figured this was eaiser to read
|
||||
item = item.replace(/[^a-z]/gi, '');
|
||||
|
||||
try {
|
||||
var dir = path.join(__dirname, '..', '..', 'doc', 'cli', item + '.txt');
|
||||
var body = fs.readFileSync(dir, 'utf8');
|
||||
return body;
|
||||
} catch (e) {
|
||||
return '"' + item + '" help can\'t be found';
|
||||
}
|
||||
}
|
1
node_modules/nodemon/lib/index.js
generated
vendored
Normal file
1
node_modules/nodemon/lib/index.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('./nodemon');
|
4
node_modules/nodemon/lib/monitor/index.js
generated
vendored
Normal file
4
node_modules/nodemon/lib/monitor/index.js
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
run: require('./run'),
|
||||
watch: require('./watch').watch,
|
||||
};
|
244
node_modules/nodemon/lib/monitor/match.js
generated
vendored
Normal file
244
node_modules/nodemon/lib/monitor/match.js
generated
vendored
Normal file
|
@ -0,0 +1,244 @@
|
|||
var minimatch = require('minimatch');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var utils = require('../utils');
|
||||
|
||||
module.exports = match;
|
||||
module.exports.rulesToMonitor = rulesToMonitor;
|
||||
|
||||
function rulesToMonitor(watch, ignore, config) {
|
||||
var monitor = [];
|
||||
|
||||
if (!Array.isArray(ignore)) {
|
||||
if (ignore) {
|
||||
ignore = [ignore];
|
||||
} else {
|
||||
ignore = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray(watch)) {
|
||||
if (watch) {
|
||||
watch = [watch];
|
||||
} else {
|
||||
watch = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (watch && watch.length) {
|
||||
monitor = utils.clone(watch);
|
||||
}
|
||||
|
||||
if (ignore) {
|
||||
[].push.apply(monitor, (ignore || []).map(function (rule) {
|
||||
return '!' + rule;
|
||||
}));
|
||||
}
|
||||
|
||||
var cwd = process.cwd();
|
||||
|
||||
// next check if the monitored paths are actual directories
|
||||
// or just patterns - and expand the rule to include *.*
|
||||
monitor = monitor.map(function (rule) {
|
||||
var not = rule.slice(0, 1) === '!';
|
||||
|
||||
if (not) {
|
||||
rule = rule.slice(1);
|
||||
}
|
||||
|
||||
if (rule === '.' || rule === '.*') {
|
||||
rule = '*.*';
|
||||
}
|
||||
|
||||
var dir = path.resolve(cwd, rule);
|
||||
|
||||
try {
|
||||
var stat = fs.statSync(dir);
|
||||
if (stat.isDirectory()) {
|
||||
rule = dir;
|
||||
if (rule.slice(-1) !== '/') {
|
||||
rule += '/';
|
||||
}
|
||||
rule += '**/*';
|
||||
|
||||
// `!not` ... sorry.
|
||||
if (!not) {
|
||||
config.dirs.push(dir);
|
||||
}
|
||||
} else {
|
||||
// ensures we end up in the check that tries to get a base directory
|
||||
// and then adds it to the watch list
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
var base = tryBaseDir(dir);
|
||||
if (!not && base) {
|
||||
if (config.dirs.indexOf(base) === -1) {
|
||||
config.dirs.push(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rule.slice(-1) === '/') {
|
||||
// just slap on a * anyway
|
||||
rule += '*';
|
||||
}
|
||||
|
||||
// if the url ends with * but not **/* and not *.*
|
||||
// then convert to **/* - somehow it was missed :-\
|
||||
if (rule.slice(-4) !== '**/*' &&
|
||||
rule.slice(-1) === '*' &&
|
||||
rule.indexOf('*.') === -1) {
|
||||
rule += '*/*';
|
||||
}
|
||||
|
||||
|
||||
return (not ? '!' : '') + rule;
|
||||
});
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
function tryBaseDir(dir) {
|
||||
var stat;
|
||||
if (/[?*\{\[]+/.test(dir)) { // if this is pattern, then try to find the base
|
||||
try {
|
||||
var base = path.dirname(dir.replace(/([?*\{\[]+.*$)/, 'foo'));
|
||||
stat = fs.statSync(base);
|
||||
if (stat.isDirectory()) {
|
||||
return base;
|
||||
}
|
||||
} catch (error) {
|
||||
// console.log(error);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
stat = fs.statSync(dir);
|
||||
// if this path is actually a single file that exists, then just monitor
|
||||
// that, *specifically*.
|
||||
if (stat.isFile() || stat.isDirectory()) {
|
||||
return dir;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function match(files, monitor, ext) {
|
||||
// sort the rules by highest specificity (based on number of slashes)
|
||||
// ignore rules (!) get sorted highest as they take precedent
|
||||
// TODO actually check separator rules work on windows
|
||||
var rules = monitor.sort(function (a, b) {
|
||||
var r = b.split(path.sep).length - a.split(path.sep).length;
|
||||
var aIsIgnore = a.slice(0, 1) === '!';
|
||||
var bIsIgnore = b.slice(0, 1) === '!';
|
||||
|
||||
if (aIsIgnore || bIsIgnore) {
|
||||
if (aIsIgnore) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (r === 0) {
|
||||
return b.length - a.length;
|
||||
}
|
||||
return r;
|
||||
}).map(function (s) {
|
||||
var prefix = s.slice(0, 1);
|
||||
|
||||
if (prefix === '!') {
|
||||
return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1);
|
||||
} else if (s.slice(0, 2) === '..') {
|
||||
return path.resolve(process.cwd(), s);
|
||||
}
|
||||
return '**' + (prefix !== path.sep ? path.sep : '') + s;
|
||||
});
|
||||
|
||||
var good = [];
|
||||
var whitelist = []; // files that we won't check against the extension
|
||||
var ignored = 0;
|
||||
var watched = 0;
|
||||
var usedRules = [];
|
||||
var minimatchOpts = {};
|
||||
|
||||
// enable case-insensitivity on Windows
|
||||
if (utils.isWindows) {
|
||||
minimatchOpts.nocase = true;
|
||||
}
|
||||
|
||||
files.forEach(function (file) {
|
||||
var matched = false;
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
if (rules[i].slice(0, 1) === '!') {
|
||||
if (!minimatch(file, rules[i], minimatchOpts)) {
|
||||
ignored++;
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (minimatch(file, rules[i], minimatchOpts)) {
|
||||
watched++;
|
||||
|
||||
// don't repeat the output if a rule is matched
|
||||
if (usedRules.indexOf(rules[i]) === -1) {
|
||||
usedRules.push(rules[i]);
|
||||
utils.log.detail('matched rule: ' + rules[i]);
|
||||
}
|
||||
|
||||
// if the rule doesn't match the WATCH EVERYTHING
|
||||
// but *does* match a rule that ends with *.*, then
|
||||
// white list it - in that we don't run it through
|
||||
// the extension check too.
|
||||
if (rules[i] !== '**' + path.sep + '*.*' &&
|
||||
rules[i].slice(-3) === '*.*') {
|
||||
whitelist.push(file);
|
||||
} else if (path.basename(file) === path.basename(rules[i])) {
|
||||
// if the file matches the actual rule, then it's put on whitelist
|
||||
whitelist.push(file);
|
||||
} else {
|
||||
good.push(file);
|
||||
}
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
ignored++;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// finally check the good files against the extensions that we're monitoring
|
||||
if (ext) {
|
||||
if (ext.indexOf(',') === -1) {
|
||||
ext = '**/*.' + ext;
|
||||
} else {
|
||||
ext = '**/*.{' + ext + '}';
|
||||
}
|
||||
|
||||
good = good.filter(function (file) {
|
||||
// only compare the filename to the extension test
|
||||
return minimatch(path.basename(file), ext, minimatchOpts);
|
||||
});
|
||||
} // else assume *.*
|
||||
|
||||
var result = good.concat(whitelist);
|
||||
|
||||
if (utils.isWindows) {
|
||||
// fix for windows testing - I *think* this is okay to do
|
||||
result = result.map(function (file) {
|
||||
return file.slice(0, 1).toLowerCase() + file.slice(1);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
result: result,
|
||||
ignored: ignored,
|
||||
watched: watched,
|
||||
total: files.length,
|
||||
};
|
||||
}
|
370
node_modules/nodemon/lib/monitor/run.js
generated
vendored
Normal file
370
node_modules/nodemon/lib/monitor/run.js
generated
vendored
Normal file
|
@ -0,0 +1,370 @@
|
|||
var debug = require('debug')('nodemon');
|
||||
var utils = require('../utils');
|
||||
var bus = utils.bus;
|
||||
var childProcess = require('child_process');
|
||||
var spawn = childProcess.spawn;
|
||||
var exec = childProcess.exec;
|
||||
var watch = require('./watch').watch;
|
||||
var config = require('../config');
|
||||
var child = null; // the actual child process we spawn
|
||||
var killedAfterChange = false;
|
||||
var noop = function () {};
|
||||
var restart = null;
|
||||
var psTree = require('ps-tree');
|
||||
var hasPS = true;
|
||||
var path = require('path');
|
||||
|
||||
// discover if the OS has `ps`, and therefore can use psTree
|
||||
exec('ps', function (error) {
|
||||
if (error) {
|
||||
hasPS = false;
|
||||
}
|
||||
});
|
||||
|
||||
function run(options) {
|
||||
var cmd = config.command.raw;
|
||||
|
||||
var runCmd = !options.runOnChangeOnly || config.lastStarted !== 0;
|
||||
if (runCmd) {
|
||||
utils.log.status('starting `' + config.command.string + '`');
|
||||
}
|
||||
|
||||
/*jshint validthis:true*/
|
||||
restart = run.bind(this, options);
|
||||
run.restart = restart;
|
||||
|
||||
config.lastStarted = Date.now();
|
||||
|
||||
var stdio = ['pipe', 'pipe', 'pipe'];
|
||||
|
||||
if (config.options.stdout) {
|
||||
stdio = ['pipe',
|
||||
process.stdout,
|
||||
process.stderr,];
|
||||
}
|
||||
|
||||
var sh = 'sh';
|
||||
var shFlag = '-c';
|
||||
|
||||
if (utils.isWindows) {
|
||||
sh = 'cmd';
|
||||
shFlag = '/c';
|
||||
}
|
||||
|
||||
var executable = cmd.executable;
|
||||
|
||||
if (utils.isWindows) {
|
||||
// under windows if the executable path contains a forward slash, that will
|
||||
// fail with cmd.exe, so we need to normalize it
|
||||
if (executable.indexOf('/') !== -1) {
|
||||
executable = path.normalize(executable);
|
||||
}
|
||||
|
||||
// if the executable path contains a space the whole string must be quoted
|
||||
// to get windows treat it as 1 argument for cmd.exe
|
||||
if (executable.indexOf(' ') !== -1 && executable[0] !== '\"'
|
||||
&& executable[executable.length - 1] !== '\"') {
|
||||
// remove all quotes from executable (possible backward compat hacks)
|
||||
executable = executable.replace (/\"/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
var args = runCmd ? utils.stringify(executable, cmd.args) : ':';
|
||||
var spawnArgs = [sh, [shFlag, args]];
|
||||
debug('spawning', args);
|
||||
|
||||
if (utils.version.major === 0 && utils.version.minor < 8) {
|
||||
// use the old spawn args :-\
|
||||
} else {
|
||||
spawnArgs.push({
|
||||
env: utils.merge(options.execOptions.env, process.env),
|
||||
stdio: stdio,
|
||||
});
|
||||
}
|
||||
|
||||
child = spawn.apply(null, spawnArgs);
|
||||
|
||||
if (config.required) {
|
||||
var emit = {
|
||||
stdout: function (data) {
|
||||
bus.emit('stdout', data);
|
||||
},
|
||||
stderr: function (data) {
|
||||
bus.emit('stderr', data);
|
||||
},
|
||||
};
|
||||
|
||||
// now work out what to bind to...
|
||||
if (config.options.stdout) {
|
||||
child.on('stdout', emit.stdout).on('stderr', emit.stderr);
|
||||
} else {
|
||||
child.stdout.on('data', emit.stdout);
|
||||
child.stderr.on('data', emit.stderr);
|
||||
|
||||
bus.stdout = child.stdout;
|
||||
bus.stderr = child.stderr;
|
||||
}
|
||||
}
|
||||
|
||||
bus.emit('start');
|
||||
|
||||
utils.log.detail('child pid: ' + child.pid);
|
||||
|
||||
child.on('error', function (error) {
|
||||
bus.emit('error', error);
|
||||
if (error.code === 'ENOENT') {
|
||||
utils.log.error('unable to run executable: "' + cmd.executable + '"');
|
||||
process.exit(1);
|
||||
} else {
|
||||
utils.log.error('failed to start child process: ' + error.code);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
child.on('exit', function (code, signal) {
|
||||
if (code === 127) {
|
||||
utils.log.error('failed to start process, "' + cmd.executable +
|
||||
'" exec not found');
|
||||
bus.emit('error', code);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
if (code === 2) {
|
||||
// something wrong with parsed command
|
||||
utils.log.error('failed to start process, possible issue with exec ' +
|
||||
'arguments');
|
||||
bus.emit('error', code);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
// In case we killed the app ourselves, set the signal thusly
|
||||
if (killedAfterChange) {
|
||||
killedAfterChange = false;
|
||||
signal = config.signal;
|
||||
}
|
||||
// this is nasty, but it gives it windows support
|
||||
if (utils.isWindows && signal === 'SIGTERM') {
|
||||
signal = config.signal;
|
||||
}
|
||||
|
||||
if (signal === config.signal || code === 0) {
|
||||
// this was a clean exit, so emit exit, rather than crash
|
||||
debug('bus.emit(exit) via ' + config.signal);
|
||||
bus.emit('exit');
|
||||
|
||||
// exit the monitor, but do it gracefully
|
||||
if (signal === config.signal) {
|
||||
return restart();
|
||||
} else if (code === 0) { // clean exit - wait until file change to restart
|
||||
if (runCmd) {
|
||||
utils.log.status('clean exit - waiting for changes before restart');
|
||||
}
|
||||
child = null;
|
||||
}
|
||||
} else {
|
||||
bus.emit('crash');
|
||||
if (options.exitcrash) {
|
||||
utils.log.fail('app crashed');
|
||||
if (!config.required) {
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
utils.log.fail('app crashed - waiting for file changes before' +
|
||||
' starting...');
|
||||
child = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.options.restartable) {
|
||||
// stdin needs to kick in again to be able to listen to the
|
||||
// restart command
|
||||
process.stdin.resume();
|
||||
}
|
||||
});
|
||||
|
||||
run.kill = function (noRestart, callback) {
|
||||
// I hate code like this :( - Remy (author of said code)
|
||||
if (typeof noRestart === 'function') {
|
||||
callback = noRestart;
|
||||
noRestart = false;
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
callback = noop;
|
||||
}
|
||||
|
||||
if (child !== null) {
|
||||
// if the stdin piping is on, we need to unpipe, but also close stdin on
|
||||
// the child, otherwise linux can throw EPIPE or ECONNRESET errors.
|
||||
if (options.stdin) {
|
||||
if (process.stdin.unpipe) { // node > 0.8
|
||||
process.stdin.unpipe(child.stdin);
|
||||
}
|
||||
}
|
||||
|
||||
if (utils.isWindows) {
|
||||
// For the on('exit', ...) handler above the following looks like a
|
||||
// crash, so we set the killedAfterChange flag
|
||||
killedAfterChange = true;
|
||||
}
|
||||
|
||||
/* Now kill the entire subtree of processes belonging to nodemon */
|
||||
var oldPid = child.pid;
|
||||
if (child) {
|
||||
kill(child, config.signal, function () {
|
||||
// this seems to fix the 0.11.x issue with the "rs" restart command,
|
||||
// though I'm unsure why. it seems like more data is streamed in to
|
||||
// stdin after we close.
|
||||
if (child && options.stdin && oldPid === child.pid) {
|
||||
// this is stupid and horrible, but node 0.12 on windows blows up
|
||||
// with this line, so we'll skip it entirely.
|
||||
if (!utils.isWindows) {
|
||||
child.stdin.end();
|
||||
}
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
} else if (!noRestart) {
|
||||
// if there's no child, then we need to manually start the process
|
||||
// this is because as there was no child, the child.on('exit') event
|
||||
// handler doesn't exist which would normally trigger the restart.
|
||||
bus.once('start', callback);
|
||||
restart();
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
// connect stdin to the child process (options.stdin is on by default)
|
||||
if (options.stdin) {
|
||||
process.stdin.resume();
|
||||
// FIXME decide whether or not we need to decide the encoding
|
||||
// process.stdin.setEncoding('utf8');
|
||||
process.stdin.pipe(child.stdin);
|
||||
|
||||
bus.once('exit', function () {
|
||||
if (child && process.stdin.unpipe) { // node > 0.8
|
||||
process.stdin.unpipe(child.stdin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
debug('start watch on: %s', config.options.watch);
|
||||
if (config.options.watch !== false) {
|
||||
watch();
|
||||
}
|
||||
}
|
||||
|
||||
function kill(child, signal, callback) {
|
||||
if (!callback) {
|
||||
callback = function () {};
|
||||
}
|
||||
|
||||
if (utils.isWindows) {
|
||||
// When using CoffeeScript under Windows, child's process is not node.exe
|
||||
// Instead coffee.cmd is launched, which launches cmd.exe, which starts
|
||||
// node.exe as a child process child.kill() would only kill cmd.exe, not
|
||||
// node.exe
|
||||
// Therefore we use the Windows taskkill utility to kill the process and all
|
||||
// its children (/T for tree).
|
||||
// Force kill (/F) the whole child tree (/T) by PID (/PID 123)
|
||||
exec('taskkill /pid ' + child.pid + ' /T /F');
|
||||
callback();
|
||||
} else {
|
||||
if (hasPS) {
|
||||
// we use psTree to kill the full subtree of nodemon, because when
|
||||
// spawning processes like `coffee` under the `--debug` flag, it'll spawn
|
||||
// it's own child, and that can't be killed by nodemon, so psTree gives us
|
||||
// an array of PIDs that have spawned under nodemon, and we send each the
|
||||
// configured signal (defaul: SIGUSR2) signal, which fixes #335
|
||||
psTree(child.pid, function (err, kids) {
|
||||
spawn('kill', ['-s', signal, child.pid].concat(kids.map(function (p) {
|
||||
return p.PID;
|
||||
}))).on('close', callback);
|
||||
});
|
||||
} else {
|
||||
exec('kill -s ' + signal + ' ' + child.pid, function () {
|
||||
// ignore if the process has been killed already
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stubbed out for now, filled in during run
|
||||
run.kill = function (flag, callback) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
run.restart = noop;
|
||||
|
||||
bus.on('quit', function onQuit() {
|
||||
// remove event listener
|
||||
var exitTimer = null;
|
||||
var exit = function () {
|
||||
clearTimeout(exitTimer);
|
||||
exit = noop; // null out in case of race condition
|
||||
child = null;
|
||||
if (!config.required) {
|
||||
// Execute all other quit listeners.
|
||||
bus.listeners('quit').forEach(function (listener) {
|
||||
if (listener !== onQuit) {
|
||||
listener();
|
||||
}
|
||||
});
|
||||
process.exit(0);
|
||||
} else {
|
||||
bus.emit('exit');
|
||||
}
|
||||
};
|
||||
|
||||
// if we're not running already, don't bother with trying to kill
|
||||
if (config.run === false) {
|
||||
return exit();
|
||||
}
|
||||
|
||||
// immediately try to stop any polling
|
||||
config.run = false;
|
||||
|
||||
if (child) {
|
||||
// give up waiting for the kids after 10 seconds
|
||||
exitTimer = setTimeout(exit, 10 * 1000);
|
||||
child.removeAllListeners('exit');
|
||||
child.once('exit', exit);
|
||||
|
||||
kill(child, 'SIGINT');
|
||||
} else {
|
||||
exit();
|
||||
}
|
||||
});
|
||||
|
||||
bus.on('restart', function () {
|
||||
// run.kill will send a SIGINT to the child process, which will cause it
|
||||
// to terminate, which in turn uses the 'exit' event handler to restart
|
||||
run.kill();
|
||||
});
|
||||
|
||||
// remove the flag file on exit
|
||||
process.on('exit', function () {
|
||||
utils.log.detail('exiting');
|
||||
if (child) { child.kill(); }
|
||||
});
|
||||
|
||||
// because windows borks when listening for the SIG* events
|
||||
if (!utils.isWindows) {
|
||||
// usual suspect: ctrl+c exit
|
||||
process.once('SIGINT', function () {
|
||||
bus.emit('quit');
|
||||
});
|
||||
|
||||
process.once('SIGTERM', function () {
|
||||
bus.emit('quit');
|
||||
if (child) { child.kill('SIGTERM'); }
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = run;
|
175
node_modules/nodemon/lib/monitor/watch.js
generated
vendored
Normal file
175
node_modules/nodemon/lib/monitor/watch.js
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
module.exports.watch = watch;
|
||||
module.exports.resetWatchers = resetWatchers;
|
||||
|
||||
var debug = require('debug')('nodemon:watch');
|
||||
var debugRoot = require('debug')('nodemon');
|
||||
var Promise = require('es6-promise').Promise; // jshint ignore:line
|
||||
var chokidar = require('chokidar');
|
||||
var undefsafe = require('undefsafe');
|
||||
var config = require('../config');
|
||||
var path = require('path');
|
||||
var utils = require('../utils');
|
||||
var bus = utils.bus;
|
||||
var match = require('./match');
|
||||
var watchers = [];
|
||||
var debouncedBus;
|
||||
|
||||
bus.on('reset', resetWatchers);
|
||||
|
||||
function resetWatchers() {
|
||||
debug('resetting watchers');
|
||||
watchers.forEach(function (watcher) {
|
||||
watcher.close();
|
||||
});
|
||||
watchers = [];
|
||||
}
|
||||
|
||||
|
||||
function watch() {
|
||||
if (watchers.length) {
|
||||
debug('early exit on watch, still watching (%s)', watchers.length);
|
||||
return;
|
||||
}
|
||||
|
||||
var dirs = [].slice.call(config.dirs);
|
||||
|
||||
debugRoot('start watch on: %s', dirs.join(', '));
|
||||
debugRoot('ignore dirs regex(%s)', config.options.ignore.re);
|
||||
|
||||
var promises = [];
|
||||
var watchedFiles = [];
|
||||
|
||||
dirs.forEach(function (dir) {
|
||||
var promise = new Promise(function (resolve) {
|
||||
var ignored = config.options.ignore.re;
|
||||
var dotFilePattern = /[\/\\]\./;
|
||||
|
||||
// don't ignore dotfiles if explicitly watched.
|
||||
if (!dir.match(dotFilePattern)) {
|
||||
ignored = [ignored, dotFilePattern];
|
||||
}
|
||||
|
||||
var watcher = chokidar.watch(dir, {
|
||||
ignored: ignored,
|
||||
persistent: true,
|
||||
usePolling: config.options.legacyWatch || false,
|
||||
interval: config.options.pollingInterval,
|
||||
});
|
||||
|
||||
watcher.ready = false;
|
||||
|
||||
var total = 0;
|
||||
|
||||
watcher.on('change', filterAndRestart);
|
||||
watcher.on('add', function (file) {
|
||||
if (watcher.ready) {
|
||||
return filterAndRestart(file);
|
||||
}
|
||||
|
||||
watchedFiles.push(file);
|
||||
total++;
|
||||
debug('watching dir: %s', file);
|
||||
});
|
||||
watcher.on('ready', function () {
|
||||
watcher.ready = true;
|
||||
resolve(total);
|
||||
debugRoot('watch is complete');
|
||||
});
|
||||
|
||||
watcher.on('error', function (error) {
|
||||
if (error.code === 'EINVAL') {
|
||||
utils.log.error('Internal watch failed. Likely cause: too many ' +
|
||||
'files being watched (perhaps from the root of a drive?\n' +
|
||||
'See https://github.com/paulmillr/chokidar/issues/229 for details');
|
||||
} else {
|
||||
utils.log.error('Internal watch failed: ' + error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
watchers.push(watcher);
|
||||
});
|
||||
promises.push(promise);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(function (res) {
|
||||
var total = res.reduce(function (acc, curr) {
|
||||
acc += curr;
|
||||
return acc;
|
||||
}, 0);
|
||||
|
||||
var count = total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
utils.log.detail('watching ' + count + ' files');
|
||||
return watchedFiles;
|
||||
});
|
||||
}
|
||||
|
||||
function filterAndRestart(files) {
|
||||
if (!Array.isArray(files)) {
|
||||
files = [files];
|
||||
}
|
||||
if (files.length) {
|
||||
if (utils.isWindows) {
|
||||
// ensure the drive letter is in uppercase (c:\foo -> C:\foo)
|
||||
files = files.map(function (f) {
|
||||
return f[0].toUpperCase() + f.slice(1);
|
||||
});
|
||||
}
|
||||
|
||||
var cwd = process.cwd();
|
||||
utils.log.detail('files triggering change check: ' +
|
||||
files.map(function (file) {
|
||||
return path.relative(cwd, file);
|
||||
}).join(', '));
|
||||
|
||||
var matched = match(
|
||||
files,
|
||||
config.options.monitor,
|
||||
undefsafe(config, 'options.execOptions.ext')
|
||||
);
|
||||
|
||||
utils.log.detail('changes after filters (before/after): ' +
|
||||
[files.length, matched.result.length].join('/'));
|
||||
|
||||
// reset the last check so we're only looking at recently modified files
|
||||
config.lastStarted = Date.now();
|
||||
|
||||
if (matched.result.length) {
|
||||
if (config.options.delay > 0) {
|
||||
utils.log.detail('delaying restart for ' + config.options.delay + 'ms');
|
||||
if (debouncedBus === undefined) {
|
||||
debouncedBus = debounce(restartBus, config.options.delay);
|
||||
}
|
||||
debouncedBus(matched);
|
||||
} else {
|
||||
return restartBus(matched);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function restartBus(matched) {
|
||||
utils.log.status('restarting due to changes...');
|
||||
matched.result.map(function (file) {
|
||||
utils.log.detail(path.relative(process.cwd(), file));
|
||||
});
|
||||
|
||||
if (config.options.verbose) {
|
||||
utils.log._log('');
|
||||
}
|
||||
|
||||
bus.emit('restart', matched.result);
|
||||
}
|
||||
|
||||
function debounce(fn, delay) {
|
||||
var timer = null;
|
||||
return function () {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
263
node_modules/nodemon/lib/nodemon.js
generated
vendored
Normal file
263
node_modules/nodemon/lib/nodemon.js
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
|||
var debug = require('debug')('nodemon');
|
||||
var path = require('path');
|
||||
var monitor = require('./monitor');
|
||||
var cli = require('./cli');
|
||||
var version = require('./version');
|
||||
var util = require('util');
|
||||
var utils = require('./utils');
|
||||
var bus = utils.bus;
|
||||
var help = require('./help');
|
||||
var config = require('./config');
|
||||
var spawn = require('./spawn');
|
||||
var eventHandlers = {};
|
||||
|
||||
// this is fairly dirty, but theoretically sound since it's part of the
|
||||
// stable module API
|
||||
config.required = utils.isRequired;
|
||||
|
||||
function nodemon(settings) {
|
||||
nodemon.reset();
|
||||
|
||||
// allow the cli string as the argument to nodemon, and allow for
|
||||
// `node nodemon -V app.js` or just `-V app.js`
|
||||
if (typeof settings === 'string') {
|
||||
settings = settings.trim();
|
||||
if (settings.indexOf('node') !== 0) {
|
||||
if (settings.indexOf('nodemon') !== 0) {
|
||||
settings = 'nodemon ' + settings;
|
||||
}
|
||||
settings = 'node ' + settings;
|
||||
}
|
||||
settings = cli.parse(settings);
|
||||
}
|
||||
|
||||
// set the debug flag as early as possible to get all the detailed logging
|
||||
if (settings.verbose) {
|
||||
utils.debug = true;
|
||||
}
|
||||
|
||||
if (settings.help) {
|
||||
process.stdout._handle.setBlocking(true); // nodejs/node#6456
|
||||
console.log(help(settings.help));
|
||||
if (!config.required) {
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.version) {
|
||||
version().then(function (v) {
|
||||
console.log(v);
|
||||
if (!config.required) {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// nodemon tools like grunt-nodemon. This affects where
|
||||
// the script is being run from, and will affect where
|
||||
// nodemon looks for the nodemon.json files
|
||||
if (settings.cwd) {
|
||||
// this is protection to make sure we haven't dont the chdir already...
|
||||
// say like in cli/parse.js (which is where we do this once already!)
|
||||
if (process.cwd() !== path.resolve(config.system.cwd, settings.cwd)) {
|
||||
process.chdir(settings.cwd);
|
||||
}
|
||||
}
|
||||
|
||||
config.load(settings, function (config) {
|
||||
if (!config.options.dump && !config.options.execOptions.script &&
|
||||
config.options.execOptions.exec === 'node') {
|
||||
if (!config.required) {
|
||||
console.log(help('usage'));
|
||||
process.exit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// before we print anything, update the colour setting on logging
|
||||
utils.colours = config.options.colours;
|
||||
|
||||
// always echo out the current version
|
||||
utils.log.info(version.pinned);
|
||||
|
||||
if (config.options.cwd) {
|
||||
utils.log.detail('process root: ' + process.cwd());
|
||||
}
|
||||
|
||||
config.loaded.forEach(function (filename) {
|
||||
utils.log.detail('reading config ' + filename);
|
||||
});
|
||||
|
||||
// echo out notices about running state
|
||||
if (config.options.stdin && config.options.restartable) {
|
||||
// allow nodemon to restart when the use types 'rs\n'
|
||||
process.stdin.resume();
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function (data) {
|
||||
data = (data + '').trim().toLowerCase();
|
||||
|
||||
// if the keys entered match the restartable value, then restart!
|
||||
if (data === config.options.restartable) {
|
||||
bus.emit('restart');
|
||||
}
|
||||
});
|
||||
} else if (config.options.stdin) {
|
||||
// if 'restartable' is disabled (via a nodemon.json)
|
||||
// then it's possible we're being used with a REPL
|
||||
// so let's make sure we don't eat the key presses
|
||||
// but also, since we're wrapping, watch out for
|
||||
// special keys, like ctrl+c x 2 or '.exit' or ctrl+d
|
||||
var ctrlC = false;
|
||||
var buffer = '';
|
||||
|
||||
process.stdin.on('data', function (data) {
|
||||
buffer += data;
|
||||
data = data.toString();
|
||||
var chr = data.charCodeAt(0);
|
||||
if (chr === 3) {
|
||||
if (ctrlC) {
|
||||
process.exit();
|
||||
}
|
||||
ctrlC = true;
|
||||
} else if (buffer === '.exit' || chr === 4) {
|
||||
process.exit();
|
||||
} else if (ctrlC || chr === 10) {
|
||||
ctrlC = false;
|
||||
buffer = '';
|
||||
}
|
||||
});
|
||||
process.stdin.setRawMode(true);
|
||||
}
|
||||
|
||||
if (config.options.restartable) {
|
||||
utils.log.info('to restart at any time, enter `' +
|
||||
config.options.restartable + '`');
|
||||
}
|
||||
|
||||
var none = function (v) {
|
||||
return v;
|
||||
};
|
||||
|
||||
utils.log.detail('ignoring: ' + config.options.monitor.map(function (rule) {
|
||||
return rule.slice(0, 1) === '!' ? rule.slice(1) : false;
|
||||
}).filter(none).join(' '));
|
||||
|
||||
utils.log.info('watching: ' + config.options.monitor.map(function (rule) {
|
||||
return rule.slice(0, 1) !== '!' ? rule : false;
|
||||
}).filter(none).join(' '));
|
||||
|
||||
utils.log.detail('watching extensions: ' + config.options.execOptions.ext);
|
||||
|
||||
|
||||
if (config.options.dump) {
|
||||
utils.log._log('log', '--------------');
|
||||
utils.log._log('log', 'node: ' + process.version);
|
||||
utils.log._log('log', 'nodemon: ' + version.pinned);
|
||||
utils.log._log('log', 'command: ' + process.argv.join(' '));
|
||||
utils.log._log('log', 'cwd: ' + process.cwd());
|
||||
utils.log._log('log', ['OS:', process.platform, process.arch].join(' '));
|
||||
utils.log._log('log', '--------------');
|
||||
utils.log._log('log', util.inspect(config, { depth: null }));
|
||||
utils.log._log('log', '--------------');
|
||||
if (!config.required) {
|
||||
process.exit();
|
||||
}
|
||||
|
||||
} else {
|
||||
config.run = true;
|
||||
|
||||
if (config.options.stdout === false) {
|
||||
nodemon.on('start', function () {
|
||||
nodemon.stdout = bus.stdout;
|
||||
nodemon.stderr = bus.stderr;
|
||||
|
||||
bus.emit('readable');
|
||||
});
|
||||
}
|
||||
|
||||
if (config.options.events && Object.keys(config.options.events).length) {
|
||||
Object.keys(config.options.events).forEach(function (key) {
|
||||
utils.log.detail('bind ' + key + ' -> `' +
|
||||
config.options.events[key] + '`');
|
||||
nodemon.on(key, function () {
|
||||
if (config.options && config.options.events) {
|
||||
spawn(config.options.events[key], config,
|
||||
[].slice.apply(arguments));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
monitor.run(config.options);
|
||||
}
|
||||
});
|
||||
|
||||
return nodemon;
|
||||
}
|
||||
|
||||
nodemon.restart = function () {
|
||||
utils.log.status('restarting child process');
|
||||
bus.emit('restart');
|
||||
return nodemon;
|
||||
};
|
||||
|
||||
nodemon.addListener = nodemon.on = function (event, handler) {
|
||||
if (!eventHandlers[event]) { eventHandlers[event] = []; }
|
||||
eventHandlers[event].push(handler);
|
||||
bus.on(event, handler);
|
||||
return nodemon;
|
||||
};
|
||||
|
||||
nodemon.once = function (event, handler) {
|
||||
if (!eventHandlers[event]) { eventHandlers[event] = []; }
|
||||
eventHandlers[event].push(handler);
|
||||
bus.once(event, function () {
|
||||
debug('bus.once(%s)', event);
|
||||
eventHandlers[event].splice(eventHandlers[event].indexOf(handler), 1);
|
||||
handler.apply(this, arguments);
|
||||
});
|
||||
return nodemon;
|
||||
};
|
||||
|
||||
nodemon.emit = function () {
|
||||
bus.emit.apply(bus, [].slice.call(arguments));
|
||||
return nodemon;
|
||||
};
|
||||
|
||||
nodemon.removeAllListeners = function (event) {
|
||||
// unbind only the `nodemon.on` event handlers
|
||||
Object.keys(eventHandlers).filter(function (e) {
|
||||
return event ? e === event : true;
|
||||
}).forEach(function (event) {
|
||||
eventHandlers[event].forEach(function (handler) {
|
||||
bus.removeListener(event, handler);
|
||||
eventHandlers[event].splice(eventHandlers[event].indexOf(handler), 1);
|
||||
});
|
||||
});
|
||||
|
||||
return nodemon;
|
||||
};
|
||||
|
||||
nodemon.reset = function (done) {
|
||||
bus.emit('reset', done);
|
||||
};
|
||||
|
||||
bus.on('reset', function (done) {
|
||||
debug('reset');
|
||||
nodemon.removeAllListeners();
|
||||
monitor.run.kill(true, function () {
|
||||
utils.reset();
|
||||
config.reset();
|
||||
config.run = false;
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// expose the full config
|
||||
nodemon.config = config;
|
||||
|
||||
module.exports = nodemon;
|
||||
|
89
node_modules/nodemon/lib/rules/add.js
generated
vendored
Normal file
89
node_modules/nodemon/lib/rules/add.js
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
// internal
|
||||
var reEscComments = /\\#/g;
|
||||
// note that '^^' is used in place of escaped comments
|
||||
var reUnescapeComments = /\^\^/g;
|
||||
var reComments = /#.*$/;
|
||||
var reEscapeChars = /[.|\-[\]()\\]/g;
|
||||
var reAsterisk = /\*/g;
|
||||
|
||||
module.exports = add;
|
||||
|
||||
/**
|
||||
* Coverts file patterns or regular expressions to nodemon
|
||||
* compatible RegExp matching rules. Note: the `rules` argument
|
||||
* object is modified to include the new rule and new RegExp
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* var rules = { watch: [], ignore: [] };
|
||||
* add(rules, 'watch', '*.js');
|
||||
* add(rules, 'ignore', '/public/');
|
||||
* add(rules, 'watch', ':(\d)*\.js'); // note: string based regexp
|
||||
* add(rules, 'watch', /\d*\.js/);
|
||||
*
|
||||
* @param {Object} rules containing `watch` and `ignore`. Also updated during
|
||||
* execution
|
||||
* @param {String} which must be either "watch" or "ignore"
|
||||
* @param {String|RegExp} the actual rule.
|
||||
*/
|
||||
function add(rules, which, rule) {
|
||||
if (!{ ignore: 1, watch: 1}[which]) {
|
||||
throw new Error('rules/index.js#add requires "ignore" or "watch" as the ' +
|
||||
'first argument');
|
||||
}
|
||||
|
||||
if (Array.isArray(rule)) {
|
||||
rule.forEach(function (rule) {
|
||||
add(rules, which, rule);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// support the rule being a RegExp, but reformat it to
|
||||
// the custom :<regexp> format that we're working with.
|
||||
if (rule instanceof RegExp) {
|
||||
// rule = ':' + rule.toString().replace(/^\/(.*?)\/$/g, '$1');
|
||||
utils.log.error('RegExp format no longer supported, but globs are.');
|
||||
return;
|
||||
}
|
||||
|
||||
// remove comments and trim lines
|
||||
// this mess of replace methods is escaping "\#" to allow for emacs temp files
|
||||
|
||||
// first up strip comments and remove blank head or tails
|
||||
rule = (rule || '').replace(reEscComments, '^^')
|
||||
.replace(reComments, '')
|
||||
.replace(reUnescapeComments, '#').trim();
|
||||
|
||||
var regexp = false;
|
||||
|
||||
if (typeof rule === 'string' && rule.substring(0, 1) === ':') {
|
||||
rule = rule.substring(1);
|
||||
utils.log.error('RegExp no longer supported: ' + rule);
|
||||
regexp = true;
|
||||
} else if (rule.length === 0) {
|
||||
// blank line (or it was a comment)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regexp) {
|
||||
// rules[which].push(rule);
|
||||
} else {
|
||||
// rule = rule.replace(reEscapeChars, '\\$&')
|
||||
// .replace(reAsterisk, '.*');
|
||||
|
||||
rules[which].push(rule);
|
||||
// compile a regexp of all the rules for this ignore or watch
|
||||
var re = rules[which].map(function (rule) {
|
||||
return rule.replace(reEscapeChars, '\\$&')
|
||||
.replace(reAsterisk, '.*');
|
||||
}).join('|');
|
||||
|
||||
// used for the directory matching
|
||||
rules[which].re = new RegExp(re);
|
||||
}
|
||||
}
|
53
node_modules/nodemon/lib/rules/index.js
generated
vendored
Normal file
53
node_modules/nodemon/lib/rules/index.js
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
'use strict';
|
||||
var utils = require('../utils');
|
||||
var add = require('./add');
|
||||
var parse = require('./parse');
|
||||
|
||||
// exported
|
||||
var rules = { ignore: [], watch: [] };
|
||||
|
||||
/**
|
||||
* Loads a nodemon config file and populates the ignore
|
||||
* and watch rules with it's contents, and calls callback
|
||||
* with the new rules
|
||||
*
|
||||
* @param {String} filename
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function load(filename, callback) {
|
||||
parse(filename, function (err, result) {
|
||||
if (err) {
|
||||
// we should have bombed already, but
|
||||
utils.log.error(err);
|
||||
callback(err);
|
||||
}
|
||||
|
||||
if (result.raw) {
|
||||
result.raw.forEach(add.bind(null, rules, 'ignore'));
|
||||
} else {
|
||||
result.ignore.forEach(add.bind(null, rules, 'ignore'));
|
||||
result.watch.forEach(add.bind(null, rules, 'watch'));
|
||||
}
|
||||
|
||||
callback(null, rules);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
reset: function () { // just used for testing
|
||||
rules.ignore.length = rules.watch.length = 0;
|
||||
delete rules.ignore.re;
|
||||
delete rules.watch.re;
|
||||
},
|
||||
load: load,
|
||||
ignore: {
|
||||
test: add.bind(null, rules, 'ignore'),
|
||||
add: add.bind(null, rules, 'ignore'),
|
||||
},
|
||||
watch: {
|
||||
test: add.bind(null, rules, 'watch'),
|
||||
add: add.bind(null, rules, 'watch'),
|
||||
},
|
||||
add: add.bind(null, rules),
|
||||
rules: rules,
|
||||
};
|
43
node_modules/nodemon/lib/rules/parse.js
generated
vendored
Normal file
43
node_modules/nodemon/lib/rules/parse.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
var fs = require('fs');
|
||||
|
||||
/**
|
||||
* Parse the nodemon config file, supporting both old style
|
||||
* plain text config file, and JSON version of the config
|
||||
*
|
||||
* @param {String} filename
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function parse(filename, callback) {
|
||||
var rules = {
|
||||
ignore: [],
|
||||
watch: [],
|
||||
};
|
||||
|
||||
fs.readFile(filename, 'utf8', function (err, content) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var json = null;
|
||||
try {
|
||||
json = JSON.parse(content);
|
||||
} catch (e) {}
|
||||
|
||||
if (json !== null) {
|
||||
rules = {
|
||||
ignore: json.ignore || [],
|
||||
watch: json.watch || [],
|
||||
};
|
||||
|
||||
return callback(null, rules);
|
||||
}
|
||||
|
||||
// otherwise return the raw file
|
||||
return callback(null, { raw: content.split(/\n/) });
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parse;
|
||||
|
62
node_modules/nodemon/lib/spawn.js
generated
vendored
Normal file
62
node_modules/nodemon/lib/spawn.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
var utils = require('./utils');
|
||||
var merge = utils.merge;
|
||||
var bus = utils.bus;
|
||||
var childProcess = require('child_process');
|
||||
var _spawn = childProcess.spawn;
|
||||
|
||||
module.exports = function spawn(command, config, eventArgs) {
|
||||
var stdio = ['pipe', 'pipe', 'pipe'];
|
||||
var child = null;
|
||||
|
||||
if (config.options.stdout) {
|
||||
stdio = ['pipe', process.stdout, process.stderr];
|
||||
}
|
||||
|
||||
var sh = 'sh';
|
||||
var shFlag = '-c';
|
||||
|
||||
if (utils.isWindows) {
|
||||
sh = 'cmd';
|
||||
shFlag = '/c';
|
||||
}
|
||||
|
||||
var args = '';
|
||||
|
||||
if (!Array.isArray(command)) {
|
||||
command = [command];
|
||||
}
|
||||
|
||||
args = command.join(' ');
|
||||
|
||||
if (utils.version.major >= 1 || utils.version.minor >= 8) {
|
||||
var env = merge(process.env, { FILENAME: eventArgs[0] });
|
||||
child = _spawn(sh, [shFlag, args], {
|
||||
env: merge(config.options.execOptions.env, env),
|
||||
stdio: stdio,
|
||||
});
|
||||
} else {
|
||||
child = spawn(sh, args);
|
||||
}
|
||||
|
||||
if (config.required) {
|
||||
var emit = {
|
||||
stdout: function (data) {
|
||||
bus.emit('stdout', data);
|
||||
},
|
||||
stderr: function (data) {
|
||||
bus.emit('stderr', data);
|
||||
},
|
||||
};
|
||||
|
||||
// now work out what to bind to...
|
||||
if (config.options.stdout) {
|
||||
child.on('stdout', emit.stdout).on('stderr', emit.stderr);
|
||||
} else {
|
||||
child.stdout.on('data', emit.stdout);
|
||||
child.stderr.on('data', emit.stderr);
|
||||
|
||||
bus.stdout = child.stdout;
|
||||
bus.stderr = child.stderr;
|
||||
}
|
||||
}
|
||||
};
|
44
node_modules/nodemon/lib/utils/bus.js
generated
vendored
Normal file
44
node_modules/nodemon/lib/utils/bus.js
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
var events = require('events');
|
||||
var debug = require('debug')('nodemon');
|
||||
var util = require('util');
|
||||
|
||||
var Bus = function () {
|
||||
events.EventEmitter.call(this);
|
||||
};
|
||||
|
||||
util.inherits(Bus, events.EventEmitter);
|
||||
|
||||
var bus = new Bus();
|
||||
|
||||
// /*
|
||||
var collected = {};
|
||||
bus.on('newListener', function (event) {
|
||||
debug('bus new listener: %s (%s)', event, bus.listeners(event).length);
|
||||
if (!collected[event]) {
|
||||
collected[event] = true;
|
||||
bus.on(event, function () {
|
||||
debug('bus emit: %s', event);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// */
|
||||
|
||||
// proxy process messages (if forked) to the bus
|
||||
process.on('message', function (event) {
|
||||
debug('process.message(%s)', event);
|
||||
bus.emit(event);
|
||||
});
|
||||
|
||||
var emit = bus.emit;
|
||||
|
||||
// if nodemon was spawned via a fork, allow upstream communication
|
||||
// via process.send
|
||||
if (process.send) {
|
||||
bus.emit = function (event, data) {
|
||||
process.send({ type: event, data: data });
|
||||
emit.apply(bus, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = bus;
|
40
node_modules/nodemon/lib/utils/clone.js
generated
vendored
Normal file
40
node_modules/nodemon/lib/utils/clone.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
module.exports = clone;
|
||||
|
||||
// via http://stackoverflow.com/a/728694/22617
|
||||
function clone(obj) {
|
||||
// Handle the 3 simple types, and null or undefined
|
||||
if (null === obj || 'object' !== typeof obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var copy;
|
||||
|
||||
// Handle Date
|
||||
if (obj instanceof Date) {
|
||||
copy = new Date();
|
||||
copy.setTime(obj.getTime());
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Array
|
||||
if (obj instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = obj.length; i < len; i++) {
|
||||
copy[i] = clone(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Object
|
||||
if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (var attr in obj) {
|
||||
if (obj.hasOwnProperty && obj.hasOwnProperty(attr)) {
|
||||
copy[attr] = clone(obj[attr]);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
throw new Error('Unable to copy obj! Its type isn\'t supported.');
|
||||
}
|
30
node_modules/nodemon/lib/utils/colour.js
generated
vendored
Normal file
30
node_modules/nodemon/lib/utils/colour.js
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Encodes a string in a colour: red, yellow or green
|
||||
* @param {String} c colour to highlight in
|
||||
* @param {String} str the string to encode
|
||||
* @return {String} coloured string for terminal printing
|
||||
*/
|
||||
function colour(c, str) {
|
||||
return (colour[c] || colour.black) + str + colour.black;
|
||||
}
|
||||
|
||||
function strip(str) {
|
||||
re.lastIndex = 0; // reset position
|
||||
return str.replace(re, '');
|
||||
}
|
||||
|
||||
colour.red = '\x1B[31m';
|
||||
colour.yellow = '\x1B[33m';
|
||||
colour.green = '\x1B[32m';
|
||||
colour.black = '\x1B[39m';
|
||||
|
||||
var reStr = Object.keys(colour).map(function (key) {
|
||||
return colour[key];
|
||||
}).join('|');
|
||||
|
||||
var re = new RegExp(('(' + reStr + ')').replace(/\[/g, '\\['), 'g');
|
||||
|
||||
colour.strip = strip;
|
||||
|
||||
|
||||
module.exports = colour;
|
100
node_modules/nodemon/lib/utils/index.js
generated
vendored
Normal file
100
node_modules/nodemon/lib/utils/index.js
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
var noop = function () { };
|
||||
var path = require('path');
|
||||
var version = process.versions.node.split('.') || [null, null, null];
|
||||
|
||||
var utils = (module.exports = {
|
||||
version: {
|
||||
major: parseInt(version[0] || 0, 10),
|
||||
minor: parseInt(version[1] || 0, 10),
|
||||
patch: parseInt(version[2] || 0, 10),
|
||||
},
|
||||
clone: require('./clone'),
|
||||
merge: require('./merge'),
|
||||
bus: require('./bus'),
|
||||
isWindows: process.platform === 'win32',
|
||||
isMac: process.platform === 'darwin',
|
||||
isLinux: process.platform === 'linux',
|
||||
isRequired: (function () {
|
||||
var p = module.parent;
|
||||
while (p) {
|
||||
// in electron.js engine it happens
|
||||
if (p.filename === undefined) {
|
||||
return true;
|
||||
}
|
||||
if (p.filename.indexOf('bin' + path.sep + 'nodemon.js') !== -1) {
|
||||
return false;
|
||||
}
|
||||
p = p.parent;
|
||||
}
|
||||
|
||||
return true;
|
||||
})(),
|
||||
home: process.env.HOME || process.env.HOMEPATH,
|
||||
quiet: function () {
|
||||
// nukes the logging
|
||||
if (!this.debug) {
|
||||
for (var method in utils.log) {
|
||||
if (typeof utils.log[method] === 'function') {
|
||||
utils.log[method] = noop;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
reset: function () {
|
||||
if (!this.debug) {
|
||||
for (var method in utils.log) {
|
||||
if (typeof utils.log[method] === 'function') {
|
||||
delete utils.log[method];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.debug = false;
|
||||
},
|
||||
regexpToText: function (t) {
|
||||
return t
|
||||
.replace(/\.\*\\./g, '*.')
|
||||
.replace(/\\{2}/g, '^^')
|
||||
.replace(/\\/g, '')
|
||||
.replace(/\^\^/g, '\\');
|
||||
},
|
||||
stringify: function (exec, args) {
|
||||
// serializes an executable string and array of arguments into a string
|
||||
args = args || [];
|
||||
|
||||
return [exec]
|
||||
.concat(
|
||||
args.map(function (arg) {
|
||||
// if an argument contains a space, we want to show it with quotes
|
||||
// around it to indicate that it is a single argument
|
||||
if (arg.indexOf(' ') === -1) {
|
||||
return arg;
|
||||
} else {
|
||||
// this should correctly escape nested quotes
|
||||
return JSON.stringify(arg);
|
||||
}
|
||||
})
|
||||
)
|
||||
.join(' ')
|
||||
.trim();
|
||||
},
|
||||
});
|
||||
|
||||
utils.log = require('./log')(utils.isRequired);
|
||||
|
||||
Object.defineProperty(utils, 'debug', {
|
||||
set: function (value) {
|
||||
this.log.debug = value;
|
||||
},
|
||||
get: function () {
|
||||
return this.log.debug;
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(utils, 'colours', {
|
||||
set: function (value) {
|
||||
this.log.useColours = value;
|
||||
},
|
||||
get: function () {
|
||||
return this.log.useColours;
|
||||
},
|
||||
});
|
79
node_modules/nodemon/lib/utils/log.js
generated
vendored
Normal file
79
node_modules/nodemon/lib/utils/log.js
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
var colour = require('./colour');
|
||||
var bus = require('./bus');
|
||||
var required = false;
|
||||
var useColours = true;
|
||||
|
||||
var coding = {
|
||||
log: 'black',
|
||||
info: 'yellow',
|
||||
status: 'green',
|
||||
detail: 'yellow',
|
||||
fail: 'red',
|
||||
error: 'red',
|
||||
};
|
||||
|
||||
function log(type, text) {
|
||||
var msg = '[nodemon] ' + (text || '');
|
||||
|
||||
if (useColours) {
|
||||
msg = colour(coding[type], msg);
|
||||
}
|
||||
|
||||
// always push the message through our bus
|
||||
bus.emit('log', { type: type, message: text, colour: msg });
|
||||
|
||||
// but if we're running on the command line, also echo out
|
||||
// question: should we actually just consume our own events?
|
||||
if (!required) {
|
||||
if (type === 'error') {
|
||||
console.error(msg);
|
||||
} else {
|
||||
console.log(msg || '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Logger = function (r) {
|
||||
if (!(this instanceof Logger)) {
|
||||
return new Logger(r);
|
||||
}
|
||||
this.required(r);
|
||||
return this;
|
||||
};
|
||||
|
||||
Object.keys(coding).forEach(function (type) {
|
||||
Logger.prototype[type] = log.bind(null, type);
|
||||
});
|
||||
|
||||
// detail is for messages that are turned on during debug
|
||||
Logger.prototype.detail = function (msg) {
|
||||
if (this.debug) {
|
||||
log('detail', msg);
|
||||
}
|
||||
};
|
||||
|
||||
Logger.prototype.required = function (val) {
|
||||
required = val;
|
||||
};
|
||||
|
||||
Logger.prototype.debug = false;
|
||||
Logger.prototype._log = function (type, msg) {
|
||||
if (required) {
|
||||
bus.emit('log', { type: type, message: msg || '', colour: msg || '' });
|
||||
} else if (type === 'error') {
|
||||
console.error(msg);
|
||||
} else {
|
||||
console.log(msg || '');
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(Logger.prototype, 'useColours', {
|
||||
set: function (val) {
|
||||
useColours = val;
|
||||
},
|
||||
get: function () {
|
||||
return useColours;
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Logger;
|
47
node_modules/nodemon/lib/utils/merge.js
generated
vendored
Normal file
47
node_modules/nodemon/lib/utils/merge.js
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
var clone = require('./clone');
|
||||
|
||||
module.exports = merge;
|
||||
|
||||
function typesMatch(a, b) {
|
||||
return (typeof a === typeof b) && (Array.isArray(a) === Array.isArray(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* A deep merge of the source based on the target.
|
||||
* @param {Object} source [description]
|
||||
* @param {Object} target [description]
|
||||
* @return {Object} [description]
|
||||
*/
|
||||
function merge(source, target, result) {
|
||||
if (result === undefined) {
|
||||
result = clone(source);
|
||||
}
|
||||
|
||||
// merge missing values from the target to the source
|
||||
Object.getOwnPropertyNames(target).forEach(function (key) {
|
||||
if (source[key] === undefined) {
|
||||
result[key] = target[key];
|
||||
}
|
||||
});
|
||||
|
||||
Object.getOwnPropertyNames(source).forEach(function (key) {
|
||||
var value = source[key];
|
||||
|
||||
if (target[key] && typesMatch(value, target[key])) {
|
||||
// merge empty values
|
||||
if (value === '') {
|
||||
result[key] = target[key];
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0 && target[key].length) {
|
||||
result[key] = target[key].slice(0);
|
||||
}
|
||||
} else if (typeof value === 'object') {
|
||||
result[key] = merge(value, target[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
101
node_modules/nodemon/lib/version.js
generated
vendored
Normal file
101
node_modules/nodemon/lib/version.js
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
module.exports = version;
|
||||
module.exports.pin = pin;
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var Promise = require('es6-promise').Promise; // jshint ignore:line
|
||||
var root = null;
|
||||
|
||||
function pin() {
|
||||
return version().then(function (v) {
|
||||
version.pinned = v;
|
||||
});
|
||||
}
|
||||
|
||||
function version(callback) {
|
||||
// first find the package.json as this will be our root
|
||||
var promise = findPackage(path.dirname(module.parent.filename))
|
||||
.then(function (dir) {
|
||||
// now try to load the package
|
||||
var v = require(path.resolve(dir, 'package.json')).version;
|
||||
|
||||
if (v && v !== '0.0.0') {
|
||||
return v;
|
||||
}
|
||||
|
||||
root = dir;
|
||||
|
||||
// else we're in development, give the commit out
|
||||
// get the last commit and whether the working dir is dirty
|
||||
var promises = [
|
||||
branch().catch(function () { return 'master'; }),
|
||||
commit().catch(function () { return '<none>'; }),
|
||||
dirty().catch(function () { return 0; }),
|
||||
];
|
||||
|
||||
// use the cached result as the export
|
||||
return Promise.all(promises).then(function (res) {
|
||||
var branch = res[0];
|
||||
var commit = res[1];
|
||||
var dirtyCount = parseInt(res[2], 10);
|
||||
var curr = branch + ': ' + commit;
|
||||
if (dirtyCount !== 0) {
|
||||
curr += ' (' + dirtyCount + ' dirty files)';
|
||||
}
|
||||
|
||||
return curr;
|
||||
});
|
||||
}).catch(function (error) {
|
||||
console.log(error.stack);
|
||||
throw error;
|
||||
});
|
||||
|
||||
if (callback) {
|
||||
promise.then(function (res) {
|
||||
callback(null, res);
|
||||
}, callback);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function findPackage(dir) {
|
||||
if (dir === '/') {
|
||||
return Promise.reject(new Error('package not found'));
|
||||
}
|
||||
return new Promise(function (resolve) {
|
||||
fs.stat(path.resolve(dir, 'package.json'), function (error, exists) {
|
||||
if (error || !exists) {
|
||||
return resolve(findPackage(path.resolve(dir, '..')));
|
||||
}
|
||||
|
||||
resolve(dir);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function command(cmd) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exec(cmd, { cwd: root }, function (err, stdout, stderr) {
|
||||
var error = stderr.trim();
|
||||
if (error) {
|
||||
return reject(new Error(error));
|
||||
}
|
||||
resolve(stdout.split('\n').join(''));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function commit() {
|
||||
return command('git rev-parse HEAD');
|
||||
}
|
||||
|
||||
function branch() {
|
||||
return command('git rev-parse --abbrev-ref HEAD');
|
||||
}
|
||||
|
||||
function dirty() {
|
||||
return command('expr $(git status --porcelain 2>/dev/null| ' +
|
||||
'egrep "^(M| M)" | wc -l)');
|
||||
}
|
8252
node_modules/nodemon/package-lock.json
generated
vendored
Normal file
8252
node_modules/nodemon/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
97
node_modules/nodemon/package.json
generated
vendored
Normal file
97
node_modules/nodemon/package.json
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"_args": [
|
||||
[
|
||||
"nodemon@1.12.1",
|
||||
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
|
||||
]
|
||||
],
|
||||
"_development": true,
|
||||
"_from": "nodemon@1.12.1",
|
||||
"_id": "nodemon@1.12.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-mWpW3EnZ8Wu/G3ik3gjxNjSzh40=",
|
||||
"_location": "/nodemon",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "nodemon@1.12.1",
|
||||
"name": "nodemon",
|
||||
"escapedName": "nodemon",
|
||||
"rawSpec": "1.12.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "1.12.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#DEV:/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.12.1.tgz",
|
||||
"_spec": "1.12.1",
|
||||
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
|
||||
"author": {
|
||||
"name": "Remy Sharp",
|
||||
"url": "http://github.com/remy"
|
||||
},
|
||||
"bin": {
|
||||
"nodemon": "./bin/nodemon.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/remy/nodemon/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"chokidar": "^1.7.0",
|
||||
"debug": "^2.6.8",
|
||||
"es6-promise": "^3.3.1",
|
||||
"ignore-by-default": "^1.0.1",
|
||||
"lodash.defaults": "^3.1.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"ps-tree": "^1.1.0",
|
||||
"touch": "^3.1.0",
|
||||
"undefsafe": "0.0.3",
|
||||
"update-notifier": "^2.2.0"
|
||||
},
|
||||
"description": "Simple monitor script for use during development of a node.js app.",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^3.1.3",
|
||||
"@commitlint/config-angular": "^3.1.1",
|
||||
"async": "1.4.2",
|
||||
"coffee-script": "~1.7.1",
|
||||
"connect": "~2.19.1",
|
||||
"husky": "^0.14.3",
|
||||
"istanbul": "~0.2.10",
|
||||
"jscs": "2.1.1",
|
||||
"mocha": "2.3.3",
|
||||
"semantic-release": "4.3.5",
|
||||
"should": "~4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
},
|
||||
"homepage": "http://nodemon.io",
|
||||
"keywords": [
|
||||
"monitor",
|
||||
"development",
|
||||
"restart",
|
||||
"autoload",
|
||||
"reload",
|
||||
"terminal"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./lib/nodemon",
|
||||
"name": "nodemon",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/remy/nodemon.git"
|
||||
},
|
||||
"scripts": {
|
||||
":spec": "mocha --timeout 30000 --ui bdd test/**/*.test.js",
|
||||
"commitmsg": "commitlint -e",
|
||||
"coverage": "istanbul cover _mocha -- --timeout 30000 --ui bdd --reporter list test/**/*.test.js",
|
||||
"lint": "jscs lib/**/*.js -v",
|
||||
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
|
||||
"spec": "for FILE in test/**/*.test.js; do echo $FILE; ./node_modules/.bin/mocha --timeout 30000 $FILE; if [ $? -ne 0 ]; then exit 1; fi; sleep 1; done",
|
||||
"test": "npm run lint && npm run spec",
|
||||
"web": "node web"
|
||||
},
|
||||
"version": "1.12.1"
|
||||
}
|
132
node_modules/nodemon/travis_after_all.py
generated
vendored
Normal file
132
node_modules/nodemon/travis_after_all.py
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import logging
|
||||
|
||||
try:
|
||||
from functools import reduce
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import urllib.request as urllib2
|
||||
except ImportError:
|
||||
import urllib2
|
||||
|
||||
log = logging.getLogger("travis.leader")
|
||||
log.addHandler(logging.StreamHandler())
|
||||
log.setLevel(logging.INFO)
|
||||
|
||||
TRAVIS_JOB_NUMBER = 'TRAVIS_JOB_NUMBER'
|
||||
TRAVIS_BUILD_ID = 'TRAVIS_BUILD_ID'
|
||||
POLLING_INTERVAL = 'LEADER_POLLING_INTERVAL'
|
||||
GITHUB_TOKEN = 'GITHUB_TOKEN'
|
||||
|
||||
|
||||
# Travis API entry point, there are at least https://api.travis-ci.com and https://api.travis-ci.org
|
||||
travis_entry = sys.argv[1] if len(sys.argv) > 1 else 'https://api.travis-ci.org'
|
||||
|
||||
build_id = os.getenv(TRAVIS_BUILD_ID)
|
||||
polling_interval = int(os.getenv(POLLING_INTERVAL, '5'))
|
||||
gh_token = os.getenv(GITHUB_TOKEN)
|
||||
|
||||
# assume, first job is the leader
|
||||
|
||||
|
||||
def is_leader(job_number):
|
||||
return job_number.endswith('.1')
|
||||
|
||||
|
||||
job_number = os.getenv(TRAVIS_JOB_NUMBER)
|
||||
|
||||
if not job_number:
|
||||
# seems even for builds with only one job, this won't get here
|
||||
log.fatal("Don't use defining leader for build without matrix")
|
||||
exit(1)
|
||||
elif is_leader(job_number):
|
||||
log.info("This is a leader")
|
||||
else:
|
||||
# since python is subprocess, env variables are exported back via file
|
||||
with open(".to_export_back", "w") as export_var:
|
||||
export_var.write("BUILD_MINION=YES")
|
||||
log.info("This is a minion")
|
||||
exit(0)
|
||||
|
||||
|
||||
class MatrixElement(object):
|
||||
|
||||
def __init__(self, json_raw):
|
||||
self.is_finished = json_raw['finished_at'] is not None
|
||||
self.is_succeeded = json_raw['result'] == 0
|
||||
self.number = json_raw['number']
|
||||
self.is_leader = is_leader(self.number)
|
||||
|
||||
|
||||
def matrix_snapshot(travis_token):
|
||||
"""
|
||||
:return: Matrix List
|
||||
"""
|
||||
headers = {'content-type': 'application/json', 'Authorization': 'token {}'.format(travis_token)}
|
||||
req = urllib2.Request("{0}/builds/{1}".format(travis_entry, build_id), headers=headers)
|
||||
response = urllib2.urlopen(req).read()
|
||||
raw_json = json.loads(response.decode('utf-8'))
|
||||
matrix_without_leader = [MatrixElement(job) for job in raw_json["matrix"] if not is_leader(job['number'])]
|
||||
return matrix_without_leader
|
||||
|
||||
|
||||
def wait_others_to_finish(travis_token):
|
||||
def others_finished():
|
||||
"""
|
||||
Dumps others to finish
|
||||
Leader cannot finish, it is working now
|
||||
:return: tuple(True or False, List of not finished jobs)
|
||||
"""
|
||||
snapshot = matrix_snapshot(travis_token)
|
||||
finished = [job.is_finished for job in snapshot if not job.is_leader]
|
||||
return reduce(lambda a, b: a and b, finished), [job.number for job in snapshot if
|
||||
not job.is_leader and not job.is_finished]
|
||||
|
||||
while True:
|
||||
finished, waiting_list = others_finished()
|
||||
if finished:
|
||||
break
|
||||
log.info("Leader waits for minions {0}...".format(waiting_list)) # just in case do not get "silence timeout"
|
||||
time.sleep(polling_interval)
|
||||
|
||||
|
||||
def get_token():
|
||||
assert gh_token, 'GITHUB_TOKEN is not set'
|
||||
data = {"github_token": gh_token}
|
||||
headers = {'content-type': 'application/json', 'User-Agent': 'Travis/1.0'}
|
||||
|
||||
req = urllib2.Request("{0}/auth/github".format(travis_entry), json.dumps(data).encode('utf-8'), headers)
|
||||
response = urllib2.urlopen(req).read()
|
||||
travis_token = json.loads(response.decode('utf-8')).get('access_token')
|
||||
|
||||
return travis_token
|
||||
|
||||
|
||||
try:
|
||||
token = get_token()
|
||||
wait_others_to_finish(token)
|
||||
|
||||
final_snapshot = matrix_snapshot(token)
|
||||
log.info("Final Results: {0}".format([(e.number, e.is_succeeded) for e in final_snapshot]))
|
||||
|
||||
BUILD_AGGREGATE_STATUS = 'BUILD_AGGREGATE_STATUS'
|
||||
others_snapshot = [el for el in final_snapshot if not el.is_leader]
|
||||
if reduce(lambda a, b: a and b, [e.is_succeeded for e in others_snapshot]):
|
||||
os.environ[BUILD_AGGREGATE_STATUS] = "others_succeeded"
|
||||
elif reduce(lambda a, b: a and b, [not e.is_succeeded for e in others_snapshot]):
|
||||
log.error("Others Failed")
|
||||
os.environ[BUILD_AGGREGATE_STATUS] = "others_failed"
|
||||
else:
|
||||
log.warn("Others Unknown")
|
||||
os.environ[BUILD_AGGREGATE_STATUS] = "unknown"
|
||||
# since python is subprocess, env variables are exported back via file
|
||||
with open(".to_export_back", "w") as export_var:
|
||||
export_var.write("BUILD_LEADER=YES {0}={1}".format(BUILD_AGGREGATE_STATUS, os.environ[BUILD_AGGREGATE_STATUS]))
|
||||
|
||||
except Exception as e:
|
||||
log.fatal(e)
|
Loading…
Add table
Add a link
Reference in a new issue