0.0.4
separated out watcher and read-lines started work on cli add testing moved to @uci-utils/sync
This commit is contained in:
parent
ff6efd0b88
commit
bed36111ff
27 changed files with 1536 additions and 333 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
**/node_modules/**
|
||||
/coverage/
|
||||
package-lock.json
|
||||
|
|
3
bin/sync-cli.js
Normal file
3
bin/sync-cli.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Set options as a parameter, environment variable, or rc file.
|
||||
require = require('esm')(module)
|
||||
module.exports = require('./sync.js')
|
61
bin/sync.js
Normal file
61
bin/sync.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env node
|
||||
import Sync from '../src/sync'
|
||||
import to from 'await-to-js'
|
||||
// import logger from '@uci-utils/logger'
|
||||
import yargs from 'yargs'
|
||||
|
||||
import readlines from '@uci-utils/read-lines'
|
||||
|
||||
let jobname; let command
|
||||
console.log(process.argv)
|
||||
let args = yargs
|
||||
.boolean('w')
|
||||
.alias('w','watch')
|
||||
.boolean('v')
|
||||
.alias('v','verbose')
|
||||
.argv
|
||||
console.log('yargs',args)
|
||||
const cmds=['view','run','list','default','ddir','dir']
|
||||
if (args._.length ===1) {
|
||||
if (cmds.indexOf(args._[0])<0) jobname = args._[0]
|
||||
else command = args._[0]
|
||||
} else {
|
||||
jobname = args._[0]
|
||||
command = args._[1]
|
||||
}
|
||||
console.log(jobname, command)
|
||||
|
||||
;
|
||||
(async () => {
|
||||
// const log = logger({ repo: '', package:'@uci/sync', bin:'./bin/sync.js', id: 'sync-binary' })
|
||||
|
||||
const sync = new Sync()
|
||||
|
||||
if(command==='dir') { console.log(`Current Jobs Directory: ${sync.jobsDir}`)}
|
||||
if(command==='dir' && jobname ) {
|
||||
sync.jobsDir = jobname
|
||||
console.log(`Jobs Directory set to: ${sync.jobsDir}`)
|
||||
}
|
||||
if(command==='ddir') { console.log(`Current Default Jobs Directory: ${sync.defaultJobsDir}`)}
|
||||
if(command==='ddir' && jobname ) {
|
||||
sync.defaultJobsDir = jobname=== 'reset'? null : jobname
|
||||
console.log(`Setting Default Jobs Directory to: ${sync.defaultJobsDir}`)
|
||||
}
|
||||
if(command==='view') {
|
||||
(await readlines(`${sync.JobsDir}/${jobname}`)).forEach(line=>{console.log(line)})
|
||||
}
|
||||
|
||||
// if(!jobname) jobname = sync.getConfig('defaultJob')
|
||||
// if(!jobname) {
|
||||
// console.log('must specify a job or have a default job')
|
||||
// return
|
||||
// }
|
||||
|
||||
// await sync.loadJob(arg.j)
|
||||
// console.log(sync.command())
|
||||
|
||||
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: Failed to Connecct to Remote!\n',err)
|
||||
})
|
4
bin/sync.sh
Executable file
4
bin/sync.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
LINK=`readlink -f $0`
|
||||
DEV_BIN=`dirname $LINK`
|
||||
UCI_ENV=dev /usr/bin/node $DEV_BIN/sync-cli "$@"
|
|
@ -1,9 +1,8 @@
|
|||
import Sync from '../src/sync'
|
||||
import onDeath from 'ondeath'
|
||||
|
||||
|
||||
(async () => {
|
||||
const sync = new Sync({jobsDir:'./example/jobs'})
|
||||
const sync = new Sync({jobsDir:'./example/jobs'}) // look for job files here
|
||||
|
||||
await sync.loadJob('example')
|
||||
sync.live()
|
||||
|
|
21
package.json
21
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@uci/sync",
|
||||
"version": "0.0.2",
|
||||
"name": "@uci-utils/sync",
|
||||
"version": "0.0.4",
|
||||
"description": "module to copy, maintain, and launch hardware modules on other machines",
|
||||
"main": "src/index.js",
|
||||
"bin": {
|
||||
|
@ -13,8 +13,7 @@
|
|||
"testd": "UCI_ENV=dev ./node_modules/.bin/nodemon --exec './node_modules/.bin/mocha -r esm --timeout 30000'",
|
||||
"testdd": "UCI_LOG_LEVEL='trace' npm run testd",
|
||||
"testde": "UCI_LOG_LEVEL='warn' npm run testd",
|
||||
"testl": "UCI_ENV=pro UCI_LOG_PATH=./test/test.log 0 npm run test || exit 0",
|
||||
"testibc": "istanbul cover ./node_modules/.bin/_mocha test/ --report lcovonly -- -R spec --recursive && codecov || true"
|
||||
"testl": "UCI_ENV=pro UCI_LOG_PATH=./test/test.log 0 npm run test || exit 0"
|
||||
},
|
||||
"author": "David Kebler",
|
||||
"license": "MIT",
|
||||
|
@ -32,24 +31,20 @@
|
|||
},
|
||||
"homepage": "https://github.com/uCOMmandIt/uci-remote-code#readme",
|
||||
"dependencies": {
|
||||
"@uci/logger": "0.0.10",
|
||||
"@uci-utils/logger": "0.0.13",
|
||||
"@uci-utils/read-lines": "^0.2.1",
|
||||
"@uci-utils/watcher": "^0.2.1",
|
||||
"aggregation": "^1.2.5",
|
||||
"await-to-js": "^2.1.1",
|
||||
"chokidar": "^2.0.4",
|
||||
"conf": "^2.2.0",
|
||||
"debounce-fn": "^1.0.0",
|
||||
"esm": "^3.1.4",
|
||||
"esm": "^3.2.4",
|
||||
"fs-read-data": "^1.0.4",
|
||||
"globby": "^9.0.0",
|
||||
"p-settle": "^2.1.0",
|
||||
"path-exists": "^3.0.0",
|
||||
"yargs": "^12.0.5"
|
||||
"yargs": "^13.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"chai-arrays": "^2.0.0",
|
||||
"codecov": "^3.1.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"mocha": "^5.x",
|
||||
"nodemon": "^1.18.9",
|
||||
"ondeath": "^1.0.0"
|
||||
|
|
9
readme.md
Normal file
9
readme.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# UCommandIt ile Synchronization Class
|
||||
## based on rsync and as an extension to the rsync wrapper class
|
||||
|
||||
<!-- find and replace the package name to match -->
|
||||
[![Build Status](https://img.shields.io/travis/uCOMmandIt/uci-pkg-template.svg?branch=master)](https://travis-ci.org/uCOMmandIt/uci-pkg-template)
|
||||
[![Inline docs](http://inch-ci.org/github/uCOMmandIt/uci-pkg-template.svg?branch=master)](http://inch-ci.org/github/uCOMmandIt/uci-pkg-template)
|
||||
[![Dependencies](https://img.shields.io/david/uCOMmandIt/uci-pkg-template.svg)](https://david-dm.org/uCOMmandIt/uci-pkg-template)
|
||||
[![devDependencies](https://img.shields.io/david/dev/uCOMmandIt/uci-pkg-template.svg)](https://david-dm.org/uCOMmandIt/uci-pkg-template?type=dev)
|
||||
[![codecov](https://img.shields.io/codecov/c/github/uCOMmandIt/uci-pkg-template/master.svg)](https://codecov.io/gh/uCOMmandIt/uci-pkg-template)
|
464
rsync.readme.md
Normal file
464
rsync.readme.md
Normal file
|
@ -0,0 +1,464 @@
|
|||
|
||||
|
||||
|
||||
# Rsync ![build status](https://travis-ci.org/mattijs/node-rsync.svg?branch=master)
|
||||
|
||||
[![NPM](https://nodei.co/npm/rsync.png?downloads=true)](https://nodei.co/npm/rsync/)
|
||||
|
||||
## Credits
|
||||
|
||||
This is a fork of [node-rsync](https://github.com/mattijs/node-rsync) with some additional features and bug fixes as noted
|
||||
|
||||
It's primary use purpose is as the core to the extended @uci-utils/sync Class
|
||||
|
||||
`Rsync` is a class for building and executing `rsync` commands with Node.js.
|
||||
|
||||
## Installation
|
||||
|
||||
Installation goes through NPM:
|
||||
|
||||
```
|
||||
$ npm install rsync
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This module is licensed under the MIT License. See the `LICENSE` file for more details.
|
||||
|
||||
## Simple usage
|
||||
|
||||
```javascript
|
||||
var Rsync = require('rsync');
|
||||
|
||||
// Build the command
|
||||
var rsync = new Rsync()
|
||||
.shell('ssh')
|
||||
.flags('az')
|
||||
.source('/path/to/source')
|
||||
.destination('server:/path/to/destination');
|
||||
|
||||
// Execute the command
|
||||
rsync.execute(function(error, code, cmd) {
|
||||
// we're done
|
||||
});
|
||||
```
|
||||
|
||||
For more examples see the `examples` directory.
|
||||
|
||||
# API
|
||||
|
||||
* [constructor](#constructor)
|
||||
* [instance methods](#instance-methods)
|
||||
* [accessor methods](#accessor-methods)
|
||||
* [static methods](#static-methods)
|
||||
|
||||
## constructor
|
||||
|
||||
Construct a new Rsync command instance. The constructor takes no arguments.
|
||||
|
||||
```javascript
|
||||
var rsync = new Rsync();
|
||||
```
|
||||
|
||||
## instance methods
|
||||
|
||||
### set(option, value)
|
||||
|
||||
Set an option. This can be any option from the rsync manual. The value is optional and only applies to options that take a value. This is not checked however. Supplying a value for an option that does not take a value will append the value regardless. This may cause errors when the command is executed.
|
||||
|
||||
```javascript
|
||||
rsync.set('a')
|
||||
.set('progress')
|
||||
.set('list-only')
|
||||
.set('exclude-from', '/path/to/exclude-file');
|
||||
```
|
||||
|
||||
Options must be unique and setting the same option twice will override any existing value. For options that can be set multiple times special methods exist (see accessor methods). Any leading dashes (-) are stripped when setting the option.
|
||||
|
||||
The `set` method is chainable.
|
||||
|
||||
### unset(option)
|
||||
|
||||
Unset an option. Any leading dashes (-) are stripped when unsetting an option.
|
||||
|
||||
```javascript
|
||||
rsync.unset('progress')
|
||||
.unset('quiet');
|
||||
```
|
||||
|
||||
The `unset` method is chainable.
|
||||
|
||||
### flags(flags, set)
|
||||
|
||||
Set one or more flags. Flags are single letter options without a value, for example _compress_ (`-z`) or _archive_ (`-a`).
|
||||
|
||||
The `flags` method is a polymorphic function: it can take different arguments to set flags.
|
||||
Flags can be presented as a single string with multiple flags, multiple strings as arguments, an array containing strings or an object with the flags as keys.
|
||||
|
||||
Whether the presented flags need to be set or unset is determined based on the last argument, if this is a Boolean. When presenting the flags as an Object the value for each key (flag) determines if the flag is set or unset. This version can be used to mix setting and unsetting of flags in one statement.
|
||||
|
||||
```javascript
|
||||
// As String
|
||||
rsync.flags('avz'); // set
|
||||
rsync.flags('avz', false); // unset
|
||||
|
||||
// As String arguments
|
||||
rsync.flags('a', 'v', 'z'); // set
|
||||
rsync.flags('a', 'v', 'z', false); // unset
|
||||
|
||||
// As Array
|
||||
rsync.flags(['a', 'v', 'z']); // set
|
||||
rsync.flags(['a', 'z'], false); // unset
|
||||
|
||||
// As Object
|
||||
rsync.flags({
|
||||
'a': true, // set
|
||||
'z': true, // set
|
||||
'v': false // unset
|
||||
});
|
||||
```
|
||||
|
||||
The `flags` method is chainable.
|
||||
|
||||
### isSet(option)
|
||||
|
||||
Check if an option is set.
|
||||
|
||||
This method does not check alternate versions for an option. When an option is set as the short version this method will still return `false` when checking for the long version, event though they are the same option.
|
||||
|
||||
```javascript
|
||||
rsync.set('quiet');
|
||||
rsync.isSet('quiet'); // is TRUE
|
||||
rsync.isSet('q'); // is FALSE
|
||||
```
|
||||
|
||||
### option(option)
|
||||
|
||||
Get the value for an option by name. If a valueless option is requested null will be returned.
|
||||
|
||||
```javascript
|
||||
rsync.option('rsh'); // returns String value
|
||||
rsync.option('progress'); // returns NULL
|
||||
```
|
||||
|
||||
### args()
|
||||
|
||||
Get the arguments list for the command that is going to be executed. Returns an Array with the complete options that will be passed to the command.
|
||||
|
||||
### command()
|
||||
|
||||
Get the complete command that is going to be executed.
|
||||
|
||||
```javascript
|
||||
var rsync = new Rsync()
|
||||
.shell('ssh')
|
||||
.flags('az')
|
||||
.source('/p/t/source')
|
||||
.destination('server:/p/t/dest');
|
||||
|
||||
var c = rsync.command();
|
||||
// c is "rsync -az --rsh="ssh" /p/t/source server:/p/t/dest
|
||||
```
|
||||
|
||||
### cwd(path)
|
||||
|
||||
Set or get the value for rsync process cwd.
|
||||
|
||||
```javascript
|
||||
rsync.cwd(__dirname); // Set cwd to __dirname
|
||||
rsync.cwd(); // Get cwd value
|
||||
```
|
||||
|
||||
### env(envObj)
|
||||
|
||||
Set or get the value for rsync process environment variables.
|
||||
|
||||
Default: process.env
|
||||
|
||||
```javascript
|
||||
rsync.env(process.env); // Set env to process.env
|
||||
rsync.env(); // Get env values
|
||||
```
|
||||
|
||||
### output(stdoutHandler, stderrHandler)
|
||||
|
||||
Register output handler functions for the commands stdout and stderr output. The handlers will be
|
||||
called with streaming data from the commands output when it is executed.
|
||||
|
||||
```javascript
|
||||
rsync.output(
|
||||
function(data){
|
||||
// do things like parse progress
|
||||
}, function(data) {
|
||||
// do things like parse error output
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
This method can be called with an array containing one or two functions. These functions will
|
||||
be treated as the stdoutHandler and stderrHandler arguments. This makes it possible to register
|
||||
handlers through the `Rsync.build` method by specifying the functions as an array.
|
||||
|
||||
```javascript
|
||||
var rsync = Rsync.build({
|
||||
// ...
|
||||
output: [stdoutFunc, stderrFunc] // these are references to functions defined elsewhere
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### execute(callback, stdoutHandler, stderrHandler)
|
||||
|
||||
Execute the command. The callback function is called with an Error object (or null when there
|
||||
was none), the exit code from the executed command and the executed command as a String.
|
||||
|
||||
When `stdoutHandler` and `stderrHandler` functions are provided they will be used to stream
|
||||
data from stdout and stderr directly without buffering. Any output handlers that were
|
||||
defined previously will be overwritten.
|
||||
|
||||
The function returns the child process object, which can be used to kill the
|
||||
rsync process or clean up if the main program exits early.
|
||||
|
||||
```javascript
|
||||
// signal handler function
|
||||
var quitting = function() {
|
||||
if (rsyncPid) {
|
||||
rsyncPid.kill();
|
||||
}
|
||||
process.exit();
|
||||
}
|
||||
process.on("SIGINT", quitting); // run signal handler on CTRL-C
|
||||
process.on("SIGTERM", quitting); // run signal handler on SIGTERM
|
||||
process.on("exit", quitting); // run signal handler when main process exits
|
||||
|
||||
// simple execute
|
||||
var rsyncPid = rsync.execute(function(error, code, cmd) {
|
||||
// we're done
|
||||
});
|
||||
|
||||
// execute with stream callbacks
|
||||
var rsyncPid = rsync.execute(
|
||||
function(error, code, cmd) {
|
||||
// we're done
|
||||
}, function(data){
|
||||
// do things like parse progress
|
||||
}, function(data) {
|
||||
// do things like parse error output
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## option shorthands
|
||||
|
||||
The following option shorthand methods are available:
|
||||
|
||||
- **shell(value)**: `--rsh=SHELL`
|
||||
- **delete()**: `--delete`
|
||||
- **progress()**: `--progress`
|
||||
- **archive()**: `-a`
|
||||
- **compress()**: `-z`
|
||||
- **recursive()**: `-r`
|
||||
- **update()**: `-u`
|
||||
- **quiet()**: `-q`
|
||||
- **dirs()**: `-d`
|
||||
- **links()**: `-l`
|
||||
- **dry()**: `-n`
|
||||
- **chmod(value)**: `--chmod=VALUE` (accumulative)
|
||||
- **hardLinks()**: `-H`
|
||||
- **perms()**: `-p`
|
||||
- **executability()**: `-E`
|
||||
- **owner()**: `-o`
|
||||
- **group()**: `-g`
|
||||
- **acls()**: `-A`
|
||||
- **xattrs()**: `-X`
|
||||
- **devices()**: `--devices`
|
||||
- **specials**: `--specials`
|
||||
- **times()**: `-t`
|
||||
|
||||
|
||||
All shorthand methods are chainable as long as options that require a value are provided with one.
|
||||
|
||||
## accessor methods
|
||||
|
||||
These methods can be used to get or set values in a chainable way. When the methods are called without arguments the current value is returned. When the methods are called with a value this will override the current value and the Rsync instance is returned to provide the chainability.
|
||||
|
||||
### executable(executable)
|
||||
|
||||
Get or set the executable to use as the rsync command.
|
||||
|
||||
### executableShell(shell)
|
||||
|
||||
Get or set the shell to use to launch the rsync command on non-Windows (Unix and Mac OS X) systems. The default shell is /bin/sh.
|
||||
|
||||
On some systems (Debian, for example) /bin/sh links to /bin/dash, which does not do proper process control. If you have problems with leftover processes, try a different shell such as /bin/bash.
|
||||
|
||||
### destination(destination)
|
||||
|
||||
Get or set the destination for the rsync command.
|
||||
|
||||
### source(source)
|
||||
|
||||
Get or set the source or sources for the rsync command. When this method is called multiple times with a value it is appended to the list of sources. It is also possible to present the list of source as an array where each value will be appended to the list of sources
|
||||
|
||||
```javascript
|
||||
// chained
|
||||
rsync.source('/a/path')
|
||||
.source('/b/path');
|
||||
|
||||
// as Array
|
||||
rsync.source(['/a/path', '/b/path']);
|
||||
```
|
||||
|
||||
In both cases the list of sources will contain two paths.
|
||||
|
||||
### patterns(patterns)
|
||||
|
||||
Register a list of file patterns to include/exclude in the transfer. Patterns can be registered as
|
||||
an array of Strings or Objects.
|
||||
|
||||
When registering a pattern as a String it be prefixed with a `+` or `-` sign to
|
||||
signal include or exclude for the pattern. The sign will be stripped of and the
|
||||
pattern will be added to the ordered pattern list.
|
||||
|
||||
When registering the pattern as an Object it must contain the `action` and
|
||||
`pattern` keys where `action` contains the `+` or `-` sign and the `pattern`
|
||||
key contains the file pattern, without the `+` or `-` sign.
|
||||
|
||||
The order of patterns is important for some rsync commands. The patterns are stored in the order
|
||||
they are added either through the `patterns` method or the `include` and `exclude` methods. The
|
||||
`patterns` method can be used with `Rsync.build` to provide an ordered list for the command.
|
||||
|
||||
```javascript
|
||||
// on an existing Rsync object
|
||||
rsync.patterns([ '-.git', { action: '+', pattern: '/some_dir' });
|
||||
|
||||
// through Rsync.build
|
||||
var command = Rsync.build({
|
||||
// ...
|
||||
patterns: [ '-.git', { action: '+', pattern: '/some_dir' } ]
|
||||
// ...
|
||||
});
|
||||
```
|
||||
### exclude(pattern)
|
||||
|
||||
Exclude a pattern from transfer. When this method is called multiple times with a value it is
|
||||
appended to the list of patterns. It is also possible to present the list of excluded
|
||||
patterns as an array where each pattern will be appended to the list.
|
||||
|
||||
```javascript
|
||||
// chained
|
||||
rsync.exclude('.git')
|
||||
.exclude('.DS_Store');
|
||||
|
||||
// as Array
|
||||
rsync.exclude(['.git', '.DS_Store']);
|
||||
```
|
||||
|
||||
### include(pattern)
|
||||
|
||||
Include a pattern for transfer. When this method is called multiple times with a value it is
|
||||
appended to the list of patterns. It is also possible to present the list of included patterns as
|
||||
an array where each pattern will be appended to the list.
|
||||
|
||||
```javascript
|
||||
// chained
|
||||
rsync.include('/a/file')
|
||||
.include('/b/file');
|
||||
|
||||
// as Array
|
||||
rsync.include(['/a/file', '/b/file']);
|
||||
```
|
||||
|
||||
### debug(flag)
|
||||
|
||||
Get or set the debug flag. This is only used internally and must be a Boolean to set or unset.
|
||||
|
||||
## static methods
|
||||
|
||||
### build
|
||||
|
||||
For convenience there is the `build` function on the Rsync contructor. This function can be
|
||||
used to create a new Rsync command instance from an options object.
|
||||
|
||||
For each key in the options object the corresponding method on the Rsync instance will be
|
||||
called. When a function for the key does not exist it is ignored. An existing Rsync instance
|
||||
can optionally be provided.
|
||||
|
||||
```javascript
|
||||
var rsync = Rsync.build({
|
||||
source: '/path/to/source',
|
||||
destination: 'server:/path/to/destination',
|
||||
exclude: ['.git'],
|
||||
flags: 'avz',
|
||||
shell: 'ssh'
|
||||
});
|
||||
|
||||
rsync.execute(function(error, stdout, stderr) {
|
||||
// we're done
|
||||
});
|
||||
```
|
||||
|
||||
# Development
|
||||
|
||||
If there is something missing (which there probably is) just fork, patch and send a pull request.
|
||||
|
||||
For adding a new shorthand method there are a few simple steps to take:
|
||||
- Fork
|
||||
- Add the option through the `exposeShortOption`, `exposeLongOption` or `exposeMultiOption` functions. For examples see the source file.
|
||||
- Update this README file to list the new shorthand method
|
||||
- Make a pull request
|
||||
|
||||
When adding a shorthand make sure it does not already exist, it is a sane name and a shorthand is necessary.
|
||||
|
||||
If there is something broken (which there probably is), the same applies: fork, patch, pull request. Opening an issue is also possible.
|
||||
|
||||
# Changelog
|
||||
|
||||
v0.6.1
|
||||
|
||||
- Add support for windows file paths under cygwin (#53)
|
||||
|
||||
v0.6.0
|
||||
|
||||
- Escape dollar signs in filenames (#40)
|
||||
- Add permission shorthands (#46)
|
||||
- Added env() option to set the process environment variables (#51)
|
||||
|
||||
v0.5.0
|
||||
|
||||
- Properly treat flags as String
|
||||
- Differentiate between shell and file arguments (escaping)
|
||||
- Added a bunch of unit tests
|
||||
- Added TravisCI setup to run tests on branches and PRs
|
||||
- Added cwd() option to set the process CWD (#36)
|
||||
|
||||
v0.4.0
|
||||
|
||||
- Child process pid is returned from `execute` (#27)
|
||||
- Command execution shell is configurable for Unix systems (#27)
|
||||
- Better escaping for filenames with spaces (#24)
|
||||
|
||||
v0.3.0
|
||||
|
||||
- Launch the command under a shell (#15)
|
||||
- Typo fix isaArray -> isArray for issue (#14)
|
||||
- Error: rsync exited with code 14 (#11)
|
||||
|
||||
v0.2.0
|
||||
|
||||
- use spawn instead of exec (#6)
|
||||
|
||||
v0.1.0
|
||||
|
||||
- better support for include/exclude filters
|
||||
- better support for output handlers
|
||||
- removed output buffering (#6)
|
||||
|
||||
v0.0.2
|
||||
|
||||
- swapped exclude and include order
|
||||
- better shell escaping
|
||||
|
||||
v0.0.1
|
||||
|
||||
- initial version (actually the second)
|
|
@ -1,5 +1,5 @@
|
|||
import Sync from './sync'
|
||||
import Watcher from './watcher'
|
||||
import Rsync from './rsync'
|
||||
|
||||
export { Sync, Watcher}
|
||||
export { Sync, Rsync }
|
||||
export default Sync
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
import { promisify } from 'util'
|
||||
import { readFile, writeFile } from 'fs'
|
||||
const read = promisify(readFile)
|
||||
const write = promisify(writeFile)
|
||||
// alternative with new promise experimental fs
|
||||
// import fs from 'fs'
|
||||
// const read = fs.promises.readFile
|
||||
import settle from 'p-settle'
|
||||
import path from 'path'
|
||||
import logger from '@uci/logger'
|
||||
let log = logger({ package:'@cui/sync', file:'src/read-lines.js'})
|
||||
|
||||
// A promise helper function to return a list of paths to ignore from .npmignore, .gitignore, .rcignore
|
||||
function readLines (files=[],dir) {
|
||||
// console.log('additional files', files)
|
||||
let list = []
|
||||
if (!Array.isArray(files)) files=[files]
|
||||
|
||||
// each set in an the array is new line delimited set of ignore patterns
|
||||
// settle returns array of error,value pairs
|
||||
return settle(files.map(file => {
|
||||
// console.log('directory',path.dirname(file))
|
||||
if (path.dirname(file)==='.') file = dir+'/'+file
|
||||
log.debug({function:'readLines',file:file,msg:'reading a file of lines into array'})
|
||||
return read(file)
|
||||
}))
|
||||
.then((sets) => {
|
||||
sets.forEach( set => {
|
||||
if (set.isFulfilled) list.push(...set.value.toString().match(/.+/g))
|
||||
else log.warn({function:'readLines', error:set.reason, msg:' was unable to read file'})
|
||||
})
|
||||
return Promise.resolve(list)
|
||||
})
|
||||
.catch((err) => {
|
||||
// only returned when something horrible is wrong
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
// an ignore list should not be huge so can serailize at once
|
||||
function writeLines (filePath,list) {
|
||||
|
||||
return write(filePath,list.join('\n'))
|
||||
.then(() => {
|
||||
log.info({function:'writeLines', file:filePath, msg:'wrote array to file of lines'})
|
||||
})
|
||||
.catch( err => {
|
||||
log.fatal({function:'writeLines', error:err, msg:'unable to write array to file of lines'})
|
||||
})
|
||||
}
|
||||
|
||||
export default readLines
|
||||
export { readLines, writeLines }
|
11
src/sync.js
11
src/sync.js
|
@ -1,6 +1,5 @@
|
|||
// local imports
|
||||
import Rsync from './rsync'
|
||||
import Watcher from './watcher'
|
||||
// native imports
|
||||
import { EventEmitter as Emitter } from 'events'
|
||||
import { dirname } from 'path'
|
||||
|
@ -9,11 +8,11 @@ import merge from 'aggregation/es6'
|
|||
import { readFile } from 'fs-read-data'
|
||||
import Conf from 'conf'
|
||||
import debounce from 'debounce-fn'
|
||||
// import getFiles from 'globby'
|
||||
import pathExists from 'path-exists'
|
||||
import to from 'await-to-js'
|
||||
// uci imports
|
||||
import logger from '@uci/logger'
|
||||
import logger from '@uci-utils/logger'
|
||||
import Watcher from '@uci-utils/watcher'
|
||||
let log = {} // declare module wide log to be set during construction
|
||||
|
||||
class Sync extends merge(Rsync, Emitter) {
|
||||
|
@ -24,7 +23,6 @@ class Sync extends merge(Rsync, Emitter) {
|
|||
this._debounce = opts.debounce || null
|
||||
this.syncHandler = opts.syncHandler || (()=>{})
|
||||
// TODO if opts include source and destination then call loadJob with them
|
||||
// this._debounce = opts.debounce
|
||||
this.config = new Conf({projectName:'sync'})
|
||||
this.jobsDir = process.env.SYNC_JOBS_DIR || opts.jobsDir || this.config.get('jobsDir') || dirname(this.config.path)
|
||||
this.sshDir = opts.sshDir || this.config.get('sshDir') || `${this.jobsDir}/ssh`
|
||||
|
@ -37,7 +35,10 @@ class Sync extends merge(Rsync, Emitter) {
|
|||
get watcher() { return this._watcher} // in case one need set a listerner for other purposes
|
||||
|
||||
get defaultJobsDir() { return this.config.get('jobsDir', this.jobsDir) }
|
||||
set defaultJobsDir(jobsDir) { this.config.set('jobsDir', jobsDir || this.jobsDir)}
|
||||
set defaultJobsDir(jobsDir) {
|
||||
if (jobsDir==null) this.config.delete('jobsDir')
|
||||
else this.config.set('jobsDir', jobsDir)
|
||||
}
|
||||
|
||||
setConfig(name,val) { this.config.set(name,val)}
|
||||
getConfig(name) { return this.config.get(name)}
|
||||
|
|
133
src/watcher.js
133
src/watcher.js
|
@ -1,133 +0,0 @@
|
|||
// native imports
|
||||
import { EventEmitter as Emitter } from 'events'
|
||||
import path from 'path'
|
||||
// third party imports
|
||||
import { watch } from 'chokidar'
|
||||
// local imports
|
||||
import ignores from './read-lines'
|
||||
// UCI imports
|
||||
import logger from '@uci/logger'
|
||||
let log = {}
|
||||
|
||||
|
||||
const READY_TIMEOUT = 2000
|
||||
|
||||
class Watcher extends Emitter {
|
||||
constructor(opts={}) {
|
||||
super()
|
||||
log = logger({ package:'@uci/sync', class:'Watcher', file:'src/watcher.js'})
|
||||
opts.unlinkDir = Object.hasOwnProperty(opts.unlinkDir) ? opts.unlinkDir : true
|
||||
this.opts = opts
|
||||
this._ignored = []
|
||||
this._ready=false
|
||||
this.watching=false
|
||||
return this
|
||||
}
|
||||
|
||||
async init(opts) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
opts = opts || this.opts
|
||||
if (opts.excludeFrom) await this.getIgnoreLists(opts.excludeFrom)
|
||||
if (opts.ignoreList) await this.getIgnoreLists(opts.ignoreList)
|
||||
if (opts.source) {
|
||||
opts.ignored = opts.ignored ? [...this._ignored,...opts.ignored] : this._ignored
|
||||
log.debug({ignored:opts.ignored, msg:'all ignores'})
|
||||
this._watcher = watch(opts.source,opts)
|
||||
this._watcher.on('error', error => {
|
||||
log.error({error:error, msg:'Watcher error'})
|
||||
})
|
||||
this._watcher.on('ready', () => {
|
||||
clearTimeout(readyTimeout)
|
||||
log.info('initial scan sucessful, ready to start')
|
||||
this._ready=true
|
||||
this.opts = opts // save options
|
||||
resolve()
|
||||
})
|
||||
let readyTimeout = setTimeout(() =>{
|
||||
log.fatal({options:opts, timeout:READY_TIMEOUT, msg:'Timeout: unabled to complete initial scan'})
|
||||
reject('timeout during intial scan')
|
||||
},READY_TIMEOUT)
|
||||
}
|
||||
else {
|
||||
log.fatal('MUST provide a source directory(s) option to watch')
|
||||
reject('no source provided')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async start(opts) {
|
||||
if(this.watching) {
|
||||
log.warn(`watching aleady running for ${this.opts.source}`)
|
||||
return false
|
||||
}
|
||||
if (!this._watcher) await this.init(opts)
|
||||
if (this._ready) {
|
||||
log.info(`now watching ${this.opts.source}`)
|
||||
this._watcher.removeAllListeners() // just in case
|
||||
this.watching = true
|
||||
// define command listen handler
|
||||
const handler =
|
||||
(type, f) => {
|
||||
log.debug(`file ${f} was ${type}`)
|
||||
// convert this to a plugin/hook so it's not specific
|
||||
const fname = path.basename(f)
|
||||
if ( fname.toLowerCase() === 'package.json')
|
||||
if (type !=='modified') {
|
||||
this.emit('error',new Error('package.json was added or removed, ignoring sync and reinstall'))
|
||||
return
|
||||
} else{
|
||||
this.emit('install', f)
|
||||
}
|
||||
// user might want to run debounce on the listener for this event
|
||||
this.emit('changed', {file:f, type:type})
|
||||
} // end handler
|
||||
|
||||
this._watcher
|
||||
.on('add', handler.bind(this, 'added'))
|
||||
.on('change', handler.bind(this, 'modified'))
|
||||
.on('unlink', handler.bind(this, 'removed'))
|
||||
if(this.opts.unlinkDir) this._watcher.on('unlinkDir', handler.bind(this, 'dir-deleted'))
|
||||
if(this.opts.addDir) this._watcher.on('addDir', handler.bind(this, 'dir-added'))
|
||||
} else {
|
||||
log.warn('watcher is not ready to start, check options and try again')
|
||||
return new Error('not ready to start check configuration')
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
if(this.watching) {
|
||||
this.watching = false
|
||||
this._watcher.close()
|
||||
}
|
||||
else log.warn('not watching, nothing to close')
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.stop()
|
||||
delete(this._watcher)
|
||||
this._ready=false
|
||||
}
|
||||
|
||||
async restart(opts) {
|
||||
this.remove()
|
||||
await this.start(opts)
|
||||
}
|
||||
|
||||
async getIgnoreLists(lists) {
|
||||
// console.log('ignore lists', lists)
|
||||
if (typeof lists === 'string') lists=[lists]
|
||||
let ignored = await ignores(lists)
|
||||
// console.log('==ignores from lists', ignored)
|
||||
this._ignored = [...this._ignored,...ignored]
|
||||
// console.log(this._ignored)
|
||||
}
|
||||
|
||||
addIgnore(ignore) {
|
||||
Array.isArray(ignore) ? this._ignored.push(...ignore) : this._ignored.push(ignore)
|
||||
}
|
||||
clearAllIgnore() { this._ignored = [] }
|
||||
|
||||
}
|
||||
|
||||
export default Watcher
|
|
@ -1,54 +0,0 @@
|
|||
// let ignoreFiles = ['.npmignore','.gitignore']
|
||||
|
||||
import { readLines, writeLines } from '../src/read-lines'
|
||||
import chai from 'chai'
|
||||
import assertArrays from 'chai-arrays'
|
||||
import { it } from 'mocha'
|
||||
|
||||
chai.use(assertArrays)
|
||||
const expect = chai.expect
|
||||
|
||||
describe (
|
||||
'Read a File of Lines to Array and vice versa',
|
||||
function () {
|
||||
readList()
|
||||
writeList()
|
||||
})
|
||||
|
||||
//****************** TESTS **********************
|
||||
function readList() {
|
||||
it('==> can read one or more files (no order) each line as element in an array with common directory', async function () {
|
||||
const shouldbe = [ 'tests/',
|
||||
'test/',
|
||||
'*.test.js',
|
||||
'testing/',
|
||||
'example/',
|
||||
'/node_modules/',
|
||||
'/coverage/' ]
|
||||
let result = await readLines(['.gitignore','.npmignore'],__dirname+'/repo')
|
||||
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
|
||||
})
|
||||
|
||||
it('==> can read two files one relative the other absolute', async function () {
|
||||
const shouldbe = [ 'tests/',
|
||||
'test/',
|
||||
'*.test.js',
|
||||
'testing/',
|
||||
'example/',
|
||||
'/node_modules/',
|
||||
'/coverage/' ]
|
||||
let result = await readLines(['./test/repo/.gitignore',__dirname+'/repo/.npmignore'])
|
||||
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function writeList() {
|
||||
|
||||
it('==> can write an array items as lines in a file', async function () {
|
||||
const shouldbe = await readLines(['.gitignore','.npmignore'],__dirname+'/repo')
|
||||
await writeLines(__dirname+'/repo/combined.list',shouldbe)
|
||||
const result = await readLines(['combined.list'],__dirname+'/repo')
|
||||
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
|
||||
})
|
||||
}
|
68
test/rsync/accessors.test.js
Normal file
68
test/rsync/accessors.test.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*global describe,it*/
|
||||
'use strict';
|
||||
var Rsync = require('../rsync');
|
||||
var assert = require('chai').assert;
|
||||
var assertOutput = require('./helpers/output').assertOutput;
|
||||
var path = require('path');
|
||||
|
||||
|
||||
describe('accessors', function () {
|
||||
|
||||
describe('#executable', function () {
|
||||
|
||||
it('should set the executable to use', function () {
|
||||
var rsync = Rsync.build({
|
||||
'source': 'a.txt',
|
||||
'destination': 'b.txt',
|
||||
'executable': '/usr/local/bin/rsync'
|
||||
});
|
||||
|
||||
assert.equal('/usr/local/bin/rsync', rsync.executable(), 'executable was set');
|
||||
assertOutput(rsync, '/usr/local/bin/rsync a.txt b.txt');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#executableShell', function () {
|
||||
|
||||
it('should set the the executable shell to use', function () {
|
||||
var rsync = Rsync.build({
|
||||
'source': 'a.txt',
|
||||
'destination': 'b.txt',
|
||||
'executableShell': '/bin/zsh'
|
||||
});
|
||||
|
||||
assert.equal('/bin/zsh', rsync.executableShell(), 'executableShell was set');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#cwd', function () {
|
||||
|
||||
it('should set the the cwd to use', function () {
|
||||
var rsync = Rsync.build({
|
||||
'source': 'a.txt',
|
||||
'destination': 'b.txt',
|
||||
'cwd': __dirname + '/..'
|
||||
});
|
||||
|
||||
assert.equal(path.resolve(__dirname, '..'), rsync.cwd(), 'cwd was set');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#env', function () {
|
||||
|
||||
it('should set the the env variables to use', function () {
|
||||
var rsync = Rsync.build({
|
||||
'source': 'a.txt',
|
||||
'destination': 'b.txt',
|
||||
'env': {'red': 'blue'}
|
||||
});
|
||||
|
||||
assert.equal('blue', rsync.env().red, 'env was set');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
98
test/rsync/filters.test.js
Normal file
98
test/rsync/filters.test.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*global describe,it,beforeEach,xdescribe,xit*/
|
||||
'use strict';
|
||||
var assert = require('chai').assert;
|
||||
var assertOutput = require('./helpers/output').assertOutput;
|
||||
|
||||
var Rsync = require('../rsync');
|
||||
|
||||
describe('filters', function () {
|
||||
var command;
|
||||
|
||||
beforeEach(function () {
|
||||
command = Rsync.build({
|
||||
'source': 'SOURCE',
|
||||
'destination': 'DESTINATION'
|
||||
});
|
||||
});
|
||||
|
||||
describe('#patterns', function () {
|
||||
|
||||
it('should interpret the first character', function () {
|
||||
command.patterns(['-.git', '+/tests/*.test.js']);
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it('should be able to be set as an Object', function () {
|
||||
command.patterns([
|
||||
{ 'action': '+', 'pattern': '.git' },
|
||||
{ 'action': '-', 'pattern': '/tests/*.test' }
|
||||
]);
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it('should throw an error for invalid patterns', function () {
|
||||
assert.throw(function () {
|
||||
command.patterns(['*invalid']);
|
||||
}, /^invalid pattern:/i);
|
||||
});
|
||||
|
||||
it('should add patterns to output in order added', function () {
|
||||
command.patterns([
|
||||
{ 'action': '-', 'pattern': '.git' },
|
||||
{ 'action': '+', 'pattern': '/tests/*.test.js' },
|
||||
'-build/*'
|
||||
]);
|
||||
assertOutput(command, 'rsync --exclude=.git --include=/tests/*.test.js --exclude=build/* SOURCE DESTINATION');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#exclude', function () {
|
||||
|
||||
it('should accept patterns as arguments', function () {
|
||||
command.exclude('.git', '.out');
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it ('should accept patterns as an Array', function () {
|
||||
command.exclude(['.build', 'docs']);
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it('should add patterns to output in order added', function () {
|
||||
command.exclude('.git', 'docs', '/tests/*.test.js');
|
||||
assertOutput(command, 'rsync --exclude=.git --exclude=docs --exclude=/tests/*.test.js SOURCE DESTINATION');
|
||||
});
|
||||
|
||||
it('should escape filenames', function () {
|
||||
command.exclude('with space', 'tests/* test.js');
|
||||
assertOutput(command, 'rsync --exclude=with\\ space --exclude=tests/*\\ test.js SOURCE DESTINATION');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#include', function () {
|
||||
|
||||
it('should accept patterns as arguments', function () {
|
||||
command.include('.git', '.out');
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it ('should accept patterns as an Array', function () {
|
||||
command.include(['.build', 'docs']);
|
||||
assert.lengthOf(command._patterns, 2);
|
||||
});
|
||||
|
||||
it('should add patterns to output in order added', function () {
|
||||
command.include('LICENSE', 'README.md', 'rsync.js');
|
||||
assertOutput(command, 'rsync --include=LICENSE --include=README.md --include=rsync.js SOURCE DESTINATION');
|
||||
});
|
||||
|
||||
it('should escape filenames', function () {
|
||||
command.include('LICENSE FILE', '/tests/* test.js');
|
||||
assertOutput(command, 'rsync --include=LICENSE\\ FILE --include=/tests/*\\ test.js SOURCE DESTINATION');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
41
test/rsync/helpers/output.js
Normal file
41
test/rsync/helpers/output.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
/* jshint strict: true */
|
||||
var assert = require('chai').assert;
|
||||
|
||||
var output = module.exports;
|
||||
|
||||
/**
|
||||
* Assert the exact output of a command against an expectation.
|
||||
*
|
||||
* @param {Rsync|Function} command
|
||||
* @param {String|Function} expectation
|
||||
* @param {String} message
|
||||
*/
|
||||
output.assertOutput = function (command, expectation, message) {
|
||||
command = isFunction(command) ? command() : command;
|
||||
expectation = isFunction(expectation) ? expectation() : expectation;
|
||||
message = message || 'expected |' + command.command() + '| to equal |' + expectation + '|';
|
||||
|
||||
return assert.strictEqual(command.command(), expectation, message);
|
||||
};
|
||||
output.assertExactOutput = output.assertOutput;
|
||||
|
||||
/**
|
||||
* Assert the exact output of a command against an expectation.
|
||||
*
|
||||
* @param {Rsync|Function} command
|
||||
* @param {RegExp|Function} expectation
|
||||
* @param {String} message
|
||||
*/
|
||||
output.assertOutputPattern = function (command, expectation, message) {
|
||||
command = isFunction(command) ? command() : command;
|
||||
expectation = isFunction(expectation) ? expectation() : expectation;
|
||||
message = message || 'expected |' + command.command() + '| to match |' + String(expectation) + '|';
|
||||
|
||||
return assert(expectation.test(command.command()), message);
|
||||
};
|
||||
|
||||
|
||||
function isFunction(input) {
|
||||
return typeof input === 'function';
|
||||
}
|
111
test/rsync/input.test.js
Normal file
111
test/rsync/input.test.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* global describe,it */
|
||||
"use strict";
|
||||
|
||||
var assertOutputPattern = require('./helpers/output').assertOutputPattern;
|
||||
var Rsync = require('../rsync');
|
||||
|
||||
describe('input', function () {
|
||||
|
||||
//# sources
|
||||
describe('#source', function () {
|
||||
var rsync;
|
||||
|
||||
it('should be able to be set as a single String', function () {
|
||||
rsync = Rsync.build({
|
||||
source: 'afile.txt',
|
||||
destination: 'some_location.txt'
|
||||
});
|
||||
assertOutputPattern(rsync, /\safile.txt\s/g);
|
||||
});
|
||||
|
||||
it('should be able to be set as an Array', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'afile.txt', 'bfile.txt' ],
|
||||
destination: 'some_location.txt'
|
||||
});
|
||||
assertOutputPattern(rsync, /\safile.txt bfile.txt\s/g);
|
||||
});
|
||||
|
||||
it('should not escape regular filenames', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'some_file.txt' ],
|
||||
destination: 'wherever_we_want.txt'
|
||||
});
|
||||
assertOutputPattern(rsync, /\ssome_file.txt\s/g);
|
||||
});
|
||||
|
||||
it('should escape spaced filenames', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'some file.txt' ],
|
||||
destination: 'wherever_we_want.txt'
|
||||
});
|
||||
assertOutputPattern(rsync, /\ssome\\ file.txt\s/g);
|
||||
});
|
||||
|
||||
it('should have quote characters escaped',function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'a_quoted\'filename\".txt' ],
|
||||
destination: 'themoon'
|
||||
});
|
||||
assertOutputPattern(rsync, / a_quoted\\'filename\\".txt /);
|
||||
});
|
||||
|
||||
it('should have parentheses escaped', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'a (file) with parantheses.txt' ],
|
||||
destination: 'themoon'
|
||||
});
|
||||
assertOutputPattern(rsync, /a\\ \\\(file\\\)\\ with\\ parantheses.txt/);
|
||||
});
|
||||
|
||||
it('should allow mixed filenames', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [
|
||||
'example file.txt', 'manual.pdf', '\'special_case 1\'.rtf'
|
||||
],
|
||||
destination: 'somewhere_else/'
|
||||
});
|
||||
assertOutputPattern(rsync, / example\\ file.txt manual.pdf \\'special_case\\ 1\\'.rtf/);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# destination
|
||||
describe('#destination', function () {
|
||||
var rsync;
|
||||
|
||||
it('should not have regular filenames escaped', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'file1.txt' ],
|
||||
destination: 'the_destination/'
|
||||
});
|
||||
assertOutputPattern(rsync, /the_destination\/$/);
|
||||
});
|
||||
|
||||
it('should have spaced filenames escaped', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'file2.txt' ],
|
||||
destination: 'whereever we want.txt'
|
||||
});
|
||||
assertOutputPattern(rsync, /whereever\\ we\\ want.txt$/);
|
||||
});
|
||||
|
||||
it('should have quote characters escaped', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'space.txt' ],
|
||||
destination: '\'to infinity and beyond\"/'
|
||||
});
|
||||
assertOutputPattern(rsync, /\\'to\\ infinity\\ and\\ beyond\\"\/$/);
|
||||
});
|
||||
it('should have dollar sign characters escaped', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'file3.txt' ],
|
||||
destination: '$some_destination/'
|
||||
});
|
||||
assertOutputPattern(rsync, /\$some_destination\/$/);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
47
test/rsync/inputwin32.test.js
Normal file
47
test/rsync/inputwin32.test.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* global describe,it */
|
||||
"use strict";
|
||||
|
||||
var assertOutputPattern = require('./helpers/output').assertOutputPattern;
|
||||
var Rsync = require('../rsync');
|
||||
|
||||
describe('inputwin32', function () {
|
||||
before(function(){
|
||||
this.originalPlatform = process.platform;
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: 'win32'
|
||||
});
|
||||
});
|
||||
|
||||
//# sources under windows
|
||||
describe('#sourcewin32', function () {
|
||||
var rsync;
|
||||
|
||||
it('should convert windows path under windows',function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'C:\\home\\username\\develop\\readme.txt' ],
|
||||
destination: 'themoon'
|
||||
});
|
||||
assertOutputPattern(rsync, / \/home\/username\/develop\/readme\.txt /);
|
||||
});
|
||||
});
|
||||
|
||||
//# destination under win32
|
||||
describe('#destinationwin32', function () {
|
||||
var rsync;
|
||||
|
||||
it('should convert widows path for destination', function () {
|
||||
rsync = Rsync.build({
|
||||
source: [ 'reame.txt' ],
|
||||
destination: 'C:\\home\\username\\develop\\'
|
||||
});
|
||||
assertOutputPattern(rsync, /\/home\/username\/develop\//);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
after(function(){
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: this.originalPlatform
|
||||
});
|
||||
});
|
||||
});
|
179
test/rsync/options.test.js
Normal file
179
test/rsync/options.test.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* global describe,it,beforeEach,xdescribe,xit */
|
||||
'use strict';
|
||||
var assert = require('chai').assert;
|
||||
var Rsync = require('../rsync');
|
||||
|
||||
describe('options', function () {
|
||||
var command;
|
||||
beforeEach(function () {
|
||||
command = new Rsync();
|
||||
});
|
||||
|
||||
//# set ///////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#set', function () {
|
||||
it('should set a an option with a value', function () {
|
||||
command.set('rsh', 'ssh');
|
||||
assert.propertyVal(command._options, 'rsh', 'ssh');
|
||||
});
|
||||
|
||||
it('should enable an option without a value', function () {
|
||||
command.set('dir');
|
||||
assert.property(command._options, 'dir');
|
||||
});
|
||||
|
||||
it('should strip leading dashes', function () {
|
||||
command.set('--progress');
|
||||
command.set('--rsh', 'ssh');
|
||||
assert.property(command._options, 'progress');
|
||||
assert.propertyVal(command._options, 'rsh', 'ssh');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# unset /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#unset', function () {
|
||||
|
||||
it('should unset an option that has a value', function () {
|
||||
command.set('rsh', 'ssh');
|
||||
assert.propertyVal(command._options, 'rsh', 'ssh');
|
||||
|
||||
command.unset('rsh');
|
||||
assert.lengthOf(Object.keys(command._options), 0);
|
||||
assert.notProperty(command._options, 'rsh');
|
||||
});
|
||||
|
||||
it('should unset an enabled options', function () {
|
||||
command.set('progress');
|
||||
assert.property(command._options, 'progress');
|
||||
|
||||
command.unset('progress');
|
||||
assert.notProperty(command._options, 'progress');
|
||||
});
|
||||
|
||||
it('should unset an option that was not set', function () {
|
||||
assert.notProperty(command._options, 'dirs');
|
||||
command.unset('dirs');
|
||||
assert.notProperty(command._options, 'dirs');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# isSet /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#isSet', function () {
|
||||
|
||||
it('should return if an option is set', function () {
|
||||
command.set('inplace');
|
||||
assert.isTrue(command.isSet('inplace'));
|
||||
|
||||
command.set('b');
|
||||
assert.isTrue(command.isSet('b'));
|
||||
|
||||
command.set('max-size', '1009');
|
||||
assert.isTrue(command.isSet('max-size'));
|
||||
});
|
||||
|
||||
it('should strip leading dashes from option name', function () {
|
||||
command.set('inplace');
|
||||
assert.isTrue(command.isSet('--inplace'));
|
||||
|
||||
command.set('b');
|
||||
assert.isTrue(command.isSet('-b'));
|
||||
|
||||
command.set('max-size', '1009');
|
||||
assert.isTrue(command.isSet('--max-size'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# option ////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#option', function () {
|
||||
|
||||
it('should return the value for an option', function () {
|
||||
command.set('max-size', '1009');
|
||||
assert.equal(command.option('max-size'), '1009');
|
||||
});
|
||||
|
||||
|
||||
it('should return null for a valueless options', function () {
|
||||
command.set('progress');
|
||||
assert.isNull(command.option('progress'));
|
||||
});
|
||||
|
||||
it('should return undefined for an option that is not set', function () {
|
||||
assert.isUndefined(command.option('random'));
|
||||
});
|
||||
|
||||
it('should strip leading dashes from option names', function () {
|
||||
command.set('progress');
|
||||
assert.isNull(command.option('--progress'));
|
||||
|
||||
command.set('g');
|
||||
assert.isNull(command.option('-g'));
|
||||
|
||||
command.set('max-size', '2009');
|
||||
assert.equal(command.option('--max-size'), '2009');
|
||||
|
||||
assert.isUndefined(command.option('--random'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# flags /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#flags', function () {
|
||||
|
||||
it('it should set multiple flags from a String', function () {
|
||||
command.flags('avz');
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
});
|
||||
|
||||
it('should set multiple flags from arguments', function () {
|
||||
command.flags('v', 'z', 'a');
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
});
|
||||
|
||||
it('should set multiple flags from an array', function () {
|
||||
command.flags(['z', 'a', 'v']);
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
});
|
||||
|
||||
it('should unset multiple flags from a string', function () {
|
||||
command.flags('avz');
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
|
||||
command.flags('az', false);
|
||||
assert.sameMembers(Object.keys(command._options), ['v']);
|
||||
});
|
||||
|
||||
it('should set multiple flags from arguments', function () {
|
||||
command.flags('avz');
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
|
||||
command.flags('z', 'v', false);
|
||||
assert.sameMembers(Object.keys(command._options), ['a']);
|
||||
});
|
||||
|
||||
it('should set multiple flags from an array', function () {
|
||||
command.flags('avz');
|
||||
assert.sameMembers(Object.keys(command._options), ['a', 'v', 'z']);
|
||||
|
||||
command.flags(['a', 'v'], false);
|
||||
assert.sameMembers(Object.keys(command._options), ['z']);
|
||||
});
|
||||
|
||||
it('should set/unset flags from an Object', function () {
|
||||
command.flags('flag');
|
||||
assert.sameMembers(Object.keys(command._options), ['f', 'l', 'a', 'g']);
|
||||
|
||||
command.flags({
|
||||
'l': false,
|
||||
's': false,
|
||||
'u': true,
|
||||
'w': true,
|
||||
'b': true
|
||||
});
|
||||
assert.sameMembers(Object.keys(command._options), ['f', 'u', 'w', 'g', 'a', 'b']);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
387
test/rsync/shorthands.test.js
Normal file
387
test/rsync/shorthands.test.js
Normal file
|
@ -0,0 +1,387 @@
|
|||
"use strict";
|
||||
/* global describe, it */
|
||||
var assert = require('chai').assert;
|
||||
var Rsync = require('../rsync');
|
||||
var assertOutput = require('./helpers/output').assertOutput;
|
||||
var assertOutputPattern = require('./helpers/output').assertOutputPattern;
|
||||
|
||||
describe('shorthands', function () {
|
||||
var command, output;
|
||||
|
||||
beforeEach(function() {
|
||||
command = Rsync.build({
|
||||
'source': 'SOURCE',
|
||||
'destination': 'DESTINATION'
|
||||
});
|
||||
output = 'rsync SOURCE DESTINATION';
|
||||
});
|
||||
|
||||
//# shell /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#shell', function () {
|
||||
var rsync;
|
||||
it('should add rsh option', function () {
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination',
|
||||
'shell': 'ssh'
|
||||
});
|
||||
assertOutput(rsync, 'rsync --rsh=ssh source destination');
|
||||
});
|
||||
|
||||
it('should escape options with spaces', function () {
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination',
|
||||
'shell': 'ssh -i /home/user/.ssh/rsync.key'
|
||||
});
|
||||
assertOutput(rsync, 'rsync --rsh="ssh -i /home/user/.ssh/rsync.key" source destination');
|
||||
});
|
||||
});
|
||||
|
||||
//# chmod /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#chmod', function () {
|
||||
var rsync;
|
||||
|
||||
it('should allow a simple value through build', function () {
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination',
|
||||
'chmod': 'ug=rwx'
|
||||
});
|
||||
assertOutputPattern(rsync, /chmod=ug=rwx/i);
|
||||
});
|
||||
|
||||
it('should allow multiple values through build', function () {
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination',
|
||||
'chmod': [ 'og=uwx', 'rx=ogw' ]
|
||||
});
|
||||
assertOutputPattern(rsync, /chmod=og=uwx --chmod=rx=ogw/);
|
||||
});
|
||||
|
||||
it('should allow multiple values through setter', function () {
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination'
|
||||
});
|
||||
rsync.chmod('o=rx');
|
||||
rsync.chmod('ug=rwx');
|
||||
assertOutputPattern(rsync, /--chmod=o=rx --chmod=ug=rwx/);
|
||||
});
|
||||
|
||||
it('should return all the chmod values', function () {
|
||||
var inputValues = [ 'og=uwx', 'rx=ogw' ];
|
||||
rsync = Rsync.build({
|
||||
'source': 'source',
|
||||
'destination': 'destination',
|
||||
'chmod': inputValues
|
||||
});
|
||||
|
||||
var values = rsync.chmod();
|
||||
assert.deepEqual(values, inputValues);
|
||||
});
|
||||
});
|
||||
|
||||
//# delete ////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#delete', function () {
|
||||
var testSet = function () {
|
||||
command.delete();
|
||||
assertOutputPattern(command, /^rsync --delete/);
|
||||
return command;
|
||||
};
|
||||
it('should add the delete option', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
testSet().delete(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# progress //////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#progress', function () {
|
||||
var testSet = function () {
|
||||
command.progress();
|
||||
assertOutputPattern(command, /^rsync --progress/);
|
||||
return command;
|
||||
};
|
||||
it('should add the progress option', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
testSet().progress(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# archive ///////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#archive', function () {
|
||||
var testSet = function () {
|
||||
command.archive();
|
||||
assertOutputPattern(command, /^rsync -a/);
|
||||
return command;
|
||||
};
|
||||
it('should add the archive flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
testSet().archive(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# compress //////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#compress', function () {
|
||||
var testSet = function () {
|
||||
command.compress();
|
||||
assertOutputPattern(command, /^rsync -z/);
|
||||
return command;
|
||||
};
|
||||
it('should add the compress flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().compress(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# recursive /////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#recursive', function () {
|
||||
var testSet = function () {
|
||||
command.recursive();
|
||||
assertOutputPattern(command, /^rsync -r/);
|
||||
return command;
|
||||
};
|
||||
it('should add the recursive flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().recursive(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# update ////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#update', function () {
|
||||
var testSet = function () {
|
||||
command.update();
|
||||
assertOutputPattern(command, /^rsync -u/);
|
||||
return command;
|
||||
};
|
||||
it('should add the update flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().update(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# quiet /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#quiet', function () {
|
||||
var testSet = function () {
|
||||
command.quiet();
|
||||
assertOutputPattern(command, /^rsync -q/);
|
||||
return command;
|
||||
};
|
||||
it('should add the quiet flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().quiet(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# dirs //////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#dirs', function () {
|
||||
var testSet = function () {
|
||||
command.dirs();
|
||||
assertOutputPattern(command, /^rsync -d/);
|
||||
return command;
|
||||
};
|
||||
it('should add the dirs flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().dirs(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# links /////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#links', function () {
|
||||
var testSet = function () {
|
||||
command.links();
|
||||
assertOutputPattern(command, /^rsync -l/);
|
||||
return command;
|
||||
};
|
||||
it('should add the links flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().links(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# dry ///////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#dry', function () {
|
||||
var testSet = function () {
|
||||
command.dry();
|
||||
assertOutputPattern(command, /rsync -n/);
|
||||
return command;
|
||||
};
|
||||
it('should add the dry flag', testSet);
|
||||
it('should be able to be unset', function () {
|
||||
command = testSet().dry(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
//# hardLinks/////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#hardLinks', function () {
|
||||
|
||||
it('should add the hard links flag', function () {
|
||||
command.hardLinks();
|
||||
assertOutputPattern(command, /rsync -H/);
|
||||
});
|
||||
|
||||
it('should unset the hard links flag', function () {
|
||||
command.hardLinks();
|
||||
assertOutputPattern(command, /rsync -H/);
|
||||
command.hardLinks(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//# perms ////////////////////////////////////////////////////////////////////////////////////////
|
||||
describe('#perms', function () {
|
||||
|
||||
it('should add the perms flag', function () {
|
||||
command.perms();
|
||||
assertOutputPattern(command, /rsync -p/);
|
||||
});
|
||||
|
||||
it('should unset the perms flag', function () {
|
||||
command.perms();
|
||||
assertOutputPattern(command, /rsync -p/);
|
||||
command.perms(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#executability', function () {
|
||||
|
||||
it('should add the executability flag', function () {
|
||||
command.executability();
|
||||
assertOutputPattern(command, /rsync -E/);
|
||||
});
|
||||
|
||||
it('should unset the executability flag', function () {
|
||||
command.executability();
|
||||
assertOutputPattern(command, /rsync -E/);
|
||||
command.executability(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#owner', function () {
|
||||
|
||||
it('should add the owner flag', function () {
|
||||
command.owner();
|
||||
assertOutputPattern(command, /rsync -o/);
|
||||
});
|
||||
|
||||
it('should unset the owner flag', function () {
|
||||
command.owner();
|
||||
assertOutputPattern(command, /rsync -o/);
|
||||
command.owner(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#group', function () {
|
||||
|
||||
it('should add the group flag', function () {
|
||||
command.group();
|
||||
assertOutputPattern(command, /rsync -g/);
|
||||
});
|
||||
|
||||
it('should unset the group flag', function () {
|
||||
command.group();
|
||||
assertOutputPattern(command, /rsync -g/);
|
||||
command.group(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#acls', function () {
|
||||
|
||||
it('should set the acls flag', function () {
|
||||
command.acls();
|
||||
assertOutputPattern(command, /rsync -A/);
|
||||
});
|
||||
|
||||
it('should unset the acls flag', function () {
|
||||
command.acls();
|
||||
assertOutputPattern(command, /rsync -A/);
|
||||
command.acls(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#xattrs', function () {
|
||||
|
||||
it('should set the xattrs flag', function () {
|
||||
command.xattrs();
|
||||
assertOutputPattern(command, /rsync -X/);
|
||||
});
|
||||
|
||||
it('should unset the xattrs flag', function () {
|
||||
command.xattrs();
|
||||
assertOutputPattern(command, /rsync -X/);
|
||||
command.xattrs(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#devices', function () {
|
||||
|
||||
it('should set the the devices option', function () {
|
||||
command.devices();
|
||||
assertOutputPattern(command, /rsync --devices/);
|
||||
});
|
||||
|
||||
it('should unset the devices option', function () {
|
||||
command.devices();
|
||||
assertOutputPattern(command, /rsync --devices/);
|
||||
command.devices(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#specials', function () {
|
||||
|
||||
it('should set the the specials option', function () {
|
||||
command.specials();
|
||||
assertOutputPattern(command, /rsync --specials/);
|
||||
});
|
||||
|
||||
it('should unset the specials option', function () {
|
||||
command.specials();
|
||||
assertOutputPattern(command, /rsync --specials/);
|
||||
command.specials(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#times', function () {
|
||||
|
||||
it('should set the the times option', function () {
|
||||
command.times();
|
||||
assertOutputPattern(command, /rsync -t/);
|
||||
});
|
||||
|
||||
it('should unset the times option', function () {
|
||||
command.times();
|
||||
assertOutputPattern(command, /rsync -t/);
|
||||
command.times(false);
|
||||
assertOutput(command, output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
43
test/rsync/z_output.test.js
Normal file
43
test/rsync/z_output.test.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*global describe,it*/
|
||||
"use strict";
|
||||
var Rsync = require('../rsync');
|
||||
var assertOutput = require('./helpers/output').assertOutput;
|
||||
|
||||
/**
|
||||
* Some general and weird test cases for command output.
|
||||
*
|
||||
* These tests are meant as a general safeguard to complement
|
||||
* unit tests.
|
||||
*/
|
||||
var testCases = [
|
||||
{ expect: 'rsync -avz --exclude=no-go.txt --exclude=with\\ space --exclude=.git --exclude=*.tiff path_a/ path_b',
|
||||
build: function() {
|
||||
return new Rsync()
|
||||
.flags('avz')
|
||||
.source('path_a/')
|
||||
.exclude('no-go.txt')
|
||||
.exclude('with space')
|
||||
.exclude('.git')
|
||||
.exclude('*.tiff')
|
||||
.destination('path_b');
|
||||
}},
|
||||
{ expect: 'rsync -rav -f "- .git" test-dir/ test-dir-copy',
|
||||
build: function() {
|
||||
return new Rsync()
|
||||
.flags('rav')
|
||||
.set('f', '- .git')
|
||||
.source('test-dir/')
|
||||
.destination('test-dir-copy');
|
||||
}}
|
||||
];
|
||||
|
||||
describe('output tests', function () {
|
||||
|
||||
testCases.forEach(function buildTestCase(testCase, index) {
|
||||
var message = 'passes case ' + (index + 1);
|
||||
it(message, function() {
|
||||
assertOutput(testCase.build(), testCase.expect);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
2
test/source/.rcignore
Normal file
2
test/source/.rcignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
foo/**
|
||||
bar/*.js
|
1
test/source/.testignore
Normal file
1
test/source/.testignore
Normal file
|
@ -0,0 +1 @@
|
|||
bah/*/*.js
|
|
@ -1,71 +0,0 @@
|
|||
import Sync from '../src/sync'
|
||||
import Watcher from '../src/watcher'
|
||||
import to from 'await-to-js'
|
||||
import { expect } from 'chai'
|
||||
import { it } from 'mocha'
|
||||
import debounce from 'debounce-fn'
|
||||
import logger from '@uci/logger'
|
||||
// pause = require('@uci/utils').pPause
|
||||
|
||||
describe('Watcher Class Testing ',async ()=> {
|
||||
|
||||
// let log = logger({})
|
||||
before(async () => {
|
||||
// log = logger({ package:'@uci/sync', id: 'sync-test' })
|
||||
let sync = new Sync()
|
||||
// await sync.loadJob('local')
|
||||
// console.log('command to be run',sync.command())
|
||||
// console.log('===',sync.cwd())
|
||||
// // sync.execute({cli:true})
|
||||
await sync.loadJob('local')
|
||||
sync.live()
|
||||
let options = await sync.readOptionsFile('local')
|
||||
let watcher = new Watcher(options)
|
||||
await watcher.start()
|
||||
watcher.on('changed',
|
||||
// debounce(
|
||||
(change) => {
|
||||
console.log(`======= file ${change.file} was ${change.type} ==========`)
|
||||
sync.execute({cli:true})
|
||||
}
|
||||
// ,{wait:100, immediate:true})
|
||||
)
|
||||
|
||||
// console.log('command to be run',sync.command())
|
||||
// sync.live()
|
||||
// sync.execute({cli:true})
|
||||
|
||||
// await sync.configure('./test/config/sync')
|
||||
// log.info({cmd:sync.command(), msg:'Rsync Command that will Run'})
|
||||
// log.info(`making connection to ${remote.opts.host}`)
|
||||
// log.info('ready for testing')
|
||||
})
|
||||
|
||||
// after(async () => {
|
||||
// remote.close()
|
||||
// })
|
||||
|
||||
it('can sync a directory' , async function () {
|
||||
// let [err,res] = await to(remote.exec('cd /opt && pwd'))
|
||||
// if (err) {
|
||||
// log.info('error running command aborting test', err)
|
||||
// return
|
||||
// }
|
||||
// log.info(`result of remote command ${res.command} => ${res.reply.toString().trim()}`)
|
||||
expect('test', 'test failed').to.equal('/opt')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// function hooks(remote) {
|
||||
//
|
||||
|
||||
// // beforeEach(async() => {
|
||||
// // await someasyncfunctiontodobeforeeachtest()
|
||||
// // })
|
||||
//
|
||||
// // after(async() => {
|
||||
// // await someasyncfunctiontodoaftereeachtest()
|
||||
// // })
|
||||
//
|
||||
// }
|
Loading…
Reference in a new issue