Initial commit (a fork of sorts from remote-code https://www.npmjs.com/package/remote-code)
Started refactoring the 4 primary classes Added ignore list generator from various default ignore files. wrote corresponding test -- passingmaster
parent
40f1e80bc4
commit
11ca82e084
|
@ -0,0 +1,37 @@
|
||||||
|
module.exports = {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"modules": true,
|
||||||
|
"spread" : true,
|
||||||
|
"restParams" : true
|
||||||
|
},
|
||||||
|
// "plugins": [
|
||||||
|
// "unicorn"
|
||||||
|
// ],
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"node": true,
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2017,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
// "unicorn/no-array-instanceof": "error",
|
||||||
|
"no-console": 0,
|
||||||
|
"semi": ["error", "never"],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"single"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
/node_modules/
|
||||||
|
/coverage/
|
|
@ -0,0 +1,5 @@
|
||||||
|
tests/
|
||||||
|
test/
|
||||||
|
*.test.js
|
||||||
|
testing/
|
||||||
|
example/
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "@uci/remote-code",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "module to copy, maintain, and launch hardware modules on other machines",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"testd": "./node_modules/.bin/mocha -r esm --watch --timeout 30000 || exit 0",
|
||||||
|
"test": "./node_modules/.bin/mocha -r esm --timeout 30000 || exit 0",
|
||||||
|
"testibc": "istanbul cover ./node_modules/.bin/_mocha test/ --report lcovonly -- -R spec --recursive && codecov || true"
|
||||||
|
},
|
||||||
|
"author": "David Kebler",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/uCOMmandIt/uci-remote-code.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"node.js",
|
||||||
|
"I2C",
|
||||||
|
"raspberryPi"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/uCOMmandIt/uci-remote-code/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/uCOMmandIt/uci-remote-code#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^2.0.4",
|
||||||
|
"p-settle": "^2.1.0",
|
||||||
|
"rsyncwrapper": "^3.0.1",
|
||||||
|
"ssh2": "^0.8.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"chai": "^4.2.0",
|
||||||
|
"codecov": "^3.1.0",
|
||||||
|
"esm": "^3.1.4",
|
||||||
|
"istanbul": "^0.4.5",
|
||||||
|
"mocha": "^5.x"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
# uCOMmandIt Template Package Repository
|
||||||
|
|
||||||
|
<!-- 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)
|
||||||
|
|
||||||
|
Clone this to get a quick start on a new uci package. It has all the testing ready to go with Travis-CI and code coverage. All the readme badges are included as well
|
||||||
|
|
||||||
|
Clone it for as a starting place for your own package!
|
||||||
|
|
||||||
|
You'll need codecov and travis-ci accounts
|
||||||
|
|
||||||
|
##Steps
|
||||||
|
|
||||||
|
1. Clone repo
|
||||||
|
2. Edit package.json
|
||||||
|
3. Edit badge urls above changing to repo path
|
||||||
|
4. Start Coding
|
|
@ -0,0 +1,39 @@
|
||||||
|
import settle from 'p-settle'
|
||||||
|
import { promisify } from 'util'
|
||||||
|
import { readFile } from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
const read = promisify(readFile)
|
||||||
|
|
||||||
|
// A helper function to return a list of paths to ignore from .npmignore, .gitignore, .rcignore
|
||||||
|
function ignore (repoPath,files) {
|
||||||
|
// console.log('additional files', files)
|
||||||
|
let ignoreList = []
|
||||||
|
let ignoreFiles = ['.npmignore','.gitignore','.rcignore']
|
||||||
|
if (Array.isArray(files)) {
|
||||||
|
ignoreFiles=[...ignoreFiles,...files]
|
||||||
|
} else {
|
||||||
|
if (files) ignoreFiles.push(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
// each set in an the array is new line delimited set of ignore patterns
|
||||||
|
return settle(ignoreFiles.map(file => {
|
||||||
|
// console.log('directory',path.dirname(file))
|
||||||
|
if (path.dirname(file)==='.') file = repoPath+'/'+file
|
||||||
|
// console.log('file', file)
|
||||||
|
return read(file)
|
||||||
|
}))
|
||||||
|
.then((sets) => {
|
||||||
|
sets.forEach( set => {
|
||||||
|
if (set.isFulfilled) ignoreList.push(...set.value.toString().match(/.+/g))
|
||||||
|
else console.log('READ ERROR=> ',set.reason.Error)
|
||||||
|
})
|
||||||
|
// console.log('built list=====================', ignoreList)
|
||||||
|
return Promise.resolve(ignoreList)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
// only returned when something horrible is wrong
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ignore
|
|
@ -0,0 +1,8 @@
|
||||||
|
import RemoteCode from './remote-code'
|
||||||
|
import Ssh from './ssh'
|
||||||
|
import Sync from './sync'
|
||||||
|
import Watcher from './watcher'
|
||||||
|
import ignore from './ignore'
|
||||||
|
|
||||||
|
export { RemoteCode, Ssh, Sync, Watcher, ignore }
|
||||||
|
export default RemoteCode
|
|
@ -0,0 +1,123 @@
|
||||||
|
import { EventEmitter as Emitter } from 'events'
|
||||||
|
import stream from 'stream'
|
||||||
|
import Watcher from './watcher'
|
||||||
|
import Ssh from './ssh'
|
||||||
|
import Sync from './lib/sync'
|
||||||
|
|
||||||
|
const devNull = new stream.Writable()
|
||||||
|
devNull._write = () => null
|
||||||
|
|
||||||
|
class RemoteCode {
|
||||||
|
constructor(opts = {}) {
|
||||||
|
// Set defaults
|
||||||
|
// a id emitted with every event emit that can identify which remote code emitted
|
||||||
|
this.id = opts.id
|
||||||
|
this.watch = opts.watch || false
|
||||||
|
this.options.ssh.keepaliveInterval = opts.ssh.keepaliveInterval || 500
|
||||||
|
this.options.ssh.readyTimeout = opts.ssh.readyTimeout || 2000
|
||||||
|
this.options.ssh.port = opts.ssh.port || 22
|
||||||
|
this.options.source = opts.source || '.'
|
||||||
|
this.options.install = opts.install || 'yarn'
|
||||||
|
this.options.install = opts.registry ? `${this.options.install} --registry ${opts.registry}` : this.options.install
|
||||||
|
this.options.start = opts.start || 'nodemon .'
|
||||||
|
if (!(opts.ssh.keyfilePath || opts.ssh.password)) {
|
||||||
|
this.options.ssh.agent = process.env[opts.ssh.agent] || process.env.SSH_AUTH_SOCK || process.env.SSH_AGENT_SOCK
|
||||||
|
if (!this.options.ssh.agent) {
|
||||||
|
return new Error('no ssh authentification method provided')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.ssh = new Ssh()
|
||||||
|
this.verbose = opts.verbose || false
|
||||||
|
this.stdout = opts.stdout instanceof stream.Writable ? opts.stdout : new stream.Writable()
|
||||||
|
this.stderr = opts.stderr instanceof stream.Writable ? opts.stderr : new stream.Writable()
|
||||||
|
this.watcher = new Watcher(this.options)
|
||||||
|
this.sync = new Sync(this.options)
|
||||||
|
.addStdOutStream(this.stdout)
|
||||||
|
.addStdErrStream(this.stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_getStdOut() {
|
||||||
|
if (this.verbose) {
|
||||||
|
return this.stdout
|
||||||
|
}
|
||||||
|
return devNull
|
||||||
|
}
|
||||||
|
|
||||||
|
_getStdErr() {
|
||||||
|
if (this.verbose) {
|
||||||
|
return this.stderr
|
||||||
|
}
|
||||||
|
return devNull
|
||||||
|
}
|
||||||
|
|
||||||
|
sync() {
|
||||||
|
this.emit('sync',{})
|
||||||
|
return this.sync.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
watch() {
|
||||||
|
this.watcher.start()
|
||||||
|
const watchEmitter = this.watcher.getEventEmitter()
|
||||||
|
watchEmitter.on('sync', () => {
|
||||||
|
this.syncCode()
|
||||||
|
})
|
||||||
|
watchEmitter.on('install', () => {
|
||||||
|
return this.install()
|
||||||
|
.then(() => {
|
||||||
|
this.ssh.liveReload.send('rs')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return this.emitter
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this.emitter.emit('start')
|
||||||
|
const sshSettings = this.options.ssh
|
||||||
|
return Promise.all([this.syncCode(), this.watch()])
|
||||||
|
.then(() => this.install())
|
||||||
|
.then(() => this.ssh.liveReload.connect(sshSettings))
|
||||||
|
.then(() => {
|
||||||
|
this.emitter.emit('nodemon', 'start')
|
||||||
|
this.ssh.liveReload.send(`cd ${this.options.target} && ${this.options.start}`)
|
||||||
|
})
|
||||||
|
.catch(this._abort.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute a single command and then resolve
|
||||||
|
execute(cmd, stdout, stderr) {
|
||||||
|
console.log('remote codes exec', cmd)
|
||||||
|
this.emitter.emit('exec', cmd)
|
||||||
|
const ssh = new Ssh()
|
||||||
|
const result = ssh.exec(this.options.ssh, cmd, stdout, stderr)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
async install() {
|
||||||
|
this.emit('install', 'triggered')
|
||||||
|
if (!this.installInProgress) {
|
||||||
|
this.emitter.emit('install', 'started')
|
||||||
|
console.log('calling execute from install')
|
||||||
|
return this.execute(`cd ${this.options.target} && ${this.options.install}`, this._getStdOut(), this._getStdErr())
|
||||||
|
.then(res => {
|
||||||
|
this.emit('install', 'done', res)
|
||||||
|
this.installInProgress = false
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.emitter.emit('close')
|
||||||
|
return Promise.all([this.watcher.close(),
|
||||||
|
this.ssh.liveReload.close()])
|
||||||
|
}
|
||||||
|
|
||||||
|
_abort(err) {
|
||||||
|
this.emitter.emit('error', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RemoteCode
|
|
@ -0,0 +1,97 @@
|
||||||
|
const fs = require('fs')
|
||||||
|
const EventEmitter = require('events').EventEmitter
|
||||||
|
const ssh = require('ssh2')
|
||||||
|
|
||||||
|
const Client = ssh.Client
|
||||||
|
|
||||||
|
class Ssh extends Client {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this._emitter = new EventEmitter()
|
||||||
|
this._ignoreStdOut = []
|
||||||
|
return this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const conn = this
|
||||||
|
conn.on('ready', () => {
|
||||||
|
conn.shell((err, stream) => {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
this.stream = stream
|
||||||
|
this._emit('connect', 'Connection established')
|
||||||
|
stream.on('close', () => {
|
||||||
|
this._emit('close', 'Connection closed')
|
||||||
|
conn.end()
|
||||||
|
})
|
||||||
|
stream.on('data', data => this._emit('data', data))
|
||||||
|
stream.stderr.on('data', data => this._emit('error', data))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(opts = {}) {
|
||||||
|
opts.privateKey = opts.keyfilePath ? fs.readFileSync(opts.keyfilePath) : null
|
||||||
|
super.connect(opts)
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.getEventEmitter().on('connect', () => resolve(this))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getEventEmitter() {
|
||||||
|
return this._emitter
|
||||||
|
}
|
||||||
|
|
||||||
|
_emit(...args) {
|
||||||
|
this._emitter.emit(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
send(line) {
|
||||||
|
this._ignoreStdOut.push(line)
|
||||||
|
if (this.stream.writable) {
|
||||||
|
this.stream.write(`${line}\n`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.end()
|
||||||
|
this.stream = null
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supercedes ssh2.exec
|
||||||
|
// execute a single command on the server and close & resolve
|
||||||
|
// uses interactive shell to get stdout/stderr back
|
||||||
|
// stdout, stderr are streams
|
||||||
|
exec(opts, command = 'uptime', stdout, stderr) {
|
||||||
|
let data = ''
|
||||||
|
console.log('executing', opts, command)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.on('ready', () => {
|
||||||
|
this.shell((err, stream) => {
|
||||||
|
stream
|
||||||
|
.on('close', () => {
|
||||||
|
this.end()
|
||||||
|
resolve(data)
|
||||||
|
})
|
||||||
|
.on('data', s => {
|
||||||
|
data += s
|
||||||
|
stdout.write(s)
|
||||||
|
})
|
||||||
|
.stderr.on('data', s => {
|
||||||
|
data += s
|
||||||
|
stderr.write(s)
|
||||||
|
})
|
||||||
|
stream.end(command + '\nexit\n')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.on('error', e => reject(e))
|
||||||
|
.connect(opts)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Ssh
|
|
@ -0,0 +1,61 @@
|
||||||
|
const path = require('path')
|
||||||
|
const Rsync = require('rsync')
|
||||||
|
|
||||||
|
class Sync {
|
||||||
|
constructor(opts) {
|
||||||
|
this.options = opts
|
||||||
|
this.rsync = new Rsync()
|
||||||
|
.archive()
|
||||||
|
.delete()
|
||||||
|
.compress()
|
||||||
|
.dirs()
|
||||||
|
.exclude('node_modules/')
|
||||||
|
.exclude('.git/')
|
||||||
|
.source(path.join(opts.source, '/'))
|
||||||
|
.destination(`${opts.ssh.username}@${opts.ssh.host}:${path.join(opts.target)}`)
|
||||||
|
// can pass array of string of addition exlcudes - from a list likely
|
||||||
|
if (opts.excludes) {
|
||||||
|
this.rsync.exclude(opts.excludes)
|
||||||
|
}
|
||||||
|
if (opts.ssh.agent) {
|
||||||
|
this.rsync.shell(`ssh -p ${opts.ssh.port}`)
|
||||||
|
}
|
||||||
|
if (opts.ssh.keyfilePath) {
|
||||||
|
// This does NOT work with keys with pass phrase, use an ssh agent!
|
||||||
|
this.rsync.shell(`ssh -i ${opts.ssh.keyfilePath} -p ${opts.ssh.port}`)
|
||||||
|
}
|
||||||
|
if (opts.ssh.password) {
|
||||||
|
this.rsync.shell(`sshpass -p ${opts.ssh.password} ssh -o StrictHostKeyChecking=no -l ${opts.ssh.username}`)
|
||||||
|
}
|
||||||
|
console.log(this.rsync.command())
|
||||||
|
this.syncInProgress = false
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addStdOutStream(stream) {
|
||||||
|
this.stdOutStream = stream
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addStdErrStream(stream) {
|
||||||
|
this.stdErrStream = stream
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
execute() {
|
||||||
|
this.syncInProgress = true
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.rsync.execute((err, resCode) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
this.syncInProgress = false
|
||||||
|
resolve(resCode)
|
||||||
|
},
|
||||||
|
this.stdOutStream,
|
||||||
|
this.stdErrStream)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Sync
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { EventEmitter as Emitter } from 'events'
|
||||||
|
import path from 'path'
|
||||||
|
import chokidar from 'chokidar'
|
||||||
|
|
||||||
|
class Watcher extends Emitter {
|
||||||
|
constructor(options) {
|
||||||
|
super()
|
||||||
|
// pass in ignores
|
||||||
|
const opts = {
|
||||||
|
ignored: '**/node_modules/**',
|
||||||
|
ignoreInitial: true
|
||||||
|
}
|
||||||
|
const watcher = chokidar.watch(options.source, opts)
|
||||||
|
this.watcher = watcher
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
const handler = (type, f) => {
|
||||||
|
const fname = path.basename(f)
|
||||||
|
if ( fname.toLowerCase() === 'package.json')
|
||||||
|
if (type !=='change') {
|
||||||
|
this.emit('error',new Error('package.json was added or removed, ignoring sync and reinstall'))
|
||||||
|
return
|
||||||
|
} else{
|
||||||
|
this.emit('install', f)
|
||||||
|
}
|
||||||
|
this.emit('sync', f)
|
||||||
|
} // end handler
|
||||||
|
this.watcher
|
||||||
|
.on('add', handler.bind(this, 'add'))
|
||||||
|
.on('change', handler.bind(this, 'change'))
|
||||||
|
.on('unlink', handler.bind(this, 'remove'))
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.watcher.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Watcher
|
|
@ -0,0 +1,49 @@
|
||||||
|
import events from 'events';
|
||||||
|
import test from 'ava';
|
||||||
|
import td from 'testdouble';
|
||||||
|
|
||||||
|
const chokidarStub = {};
|
||||||
|
|
||||||
|
td.replace('chokidar', chokidarStub);
|
||||||
|
const Fn = require('./watcher');
|
||||||
|
|
||||||
|
function setup(stubs = {}) {
|
||||||
|
chokidarStub.watch = stubs.watch || (() => new events.EventEmitter());
|
||||||
|
return new Fn({source: '.'});
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should emit "sync" if file was added/changed/deleted', t => {
|
||||||
|
t.plan(3);
|
||||||
|
const fn = setup();
|
||||||
|
fn.start();
|
||||||
|
fn.getEventEmitter().on('sync', () => t.pass('file change detected'));
|
||||||
|
fn.watcher.emit('add', 'file.txt');
|
||||||
|
fn.watcher.emit('change', 'file.txt');
|
||||||
|
fn.watcher.emit('unlink', 'file.txt');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should emit "install" if "package.json" or "yarn.lock" was added/changed/deleted', t => {
|
||||||
|
t.plan(6);
|
||||||
|
const fn = setup();
|
||||||
|
fn.start();
|
||||||
|
fn.getEventEmitter().on('install', () => t.pass('file change detected'));
|
||||||
|
fn.watcher.emit('add', 'package.json');
|
||||||
|
fn.watcher.emit('change', 'package.json');
|
||||||
|
fn.watcher.emit('unlink', 'package.json');
|
||||||
|
fn.watcher.emit('add', 'yarn.lock');
|
||||||
|
fn.watcher.emit('change', 'yarn.lock');
|
||||||
|
fn.watcher.emit('unlink', 'yarn.lock');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should emit "sync" if "package.json" or "yarn.lock" was added/changed/deleted', t => {
|
||||||
|
t.plan(6);
|
||||||
|
const fn = setup();
|
||||||
|
fn.start();
|
||||||
|
fn.getEventEmitter().on('sync', () => t.pass('file change detected'));
|
||||||
|
fn.watcher.emit('add', 'package.json');
|
||||||
|
fn.watcher.emit('change', 'package.json');
|
||||||
|
fn.watcher.emit('unlink', 'package.json');
|
||||||
|
fn.watcher.emit('add', 'yarn.lock');
|
||||||
|
fn.watcher.emit('change', 'yarn.lock');
|
||||||
|
fn.watcher.emit('unlink', 'yarn.lock');
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
wtf/
|
|
@ -0,0 +1,64 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import ignore from '../src/ignore'
|
||||||
|
import { expect } from 'chai'
|
||||||
|
import { it } from 'mocha'
|
||||||
|
// pause = require('@uci/utils').pPause
|
||||||
|
|
||||||
|
describe (
|
||||||
|
'Build Ignore Array',
|
||||||
|
function () {
|
||||||
|
// hooks()
|
||||||
|
buildIgnoreList()
|
||||||
|
// someothertests()
|
||||||
|
})
|
||||||
|
|
||||||
|
//****************** TESTS **********************
|
||||||
|
function buildIgnoreList() {
|
||||||
|
it('==> can create array for multiple files of ignore lines', async function () {
|
||||||
|
const shouldbe = [ 'tests/',
|
||||||
|
'test/',
|
||||||
|
'*.test.js',
|
||||||
|
'testing/',
|
||||||
|
'example/',
|
||||||
|
'/node_modules/',
|
||||||
|
'/coverage/',
|
||||||
|
'foo/**',
|
||||||
|
'bar/*.js' ]
|
||||||
|
let result = await ignore(__dirname+'/repo')
|
||||||
|
//console.log('returned to test',result, shouldbe)
|
||||||
|
expect(result, 'list build failed').to.deep.equal(shouldbe)
|
||||||
|
})
|
||||||
|
it('==> can create array with additional passed in file and relative repo path', async function () {
|
||||||
|
const shouldbe = [ 'tests/',
|
||||||
|
'test/',
|
||||||
|
'*.test.js',
|
||||||
|
'testing/',
|
||||||
|
'example/',
|
||||||
|
'/node_modules/',
|
||||||
|
'/coverage/',
|
||||||
|
'foo/**',
|
||||||
|
'bar/*.js',
|
||||||
|
'bah/*/*.js'
|
||||||
|
]
|
||||||
|
let result = await ignore('./test/repo','.testignore')
|
||||||
|
//console.log('returned to test',result, shouldbe)
|
||||||
|
expect(result, 'list build failed').to.deep.equal(shouldbe)
|
||||||
|
})
|
||||||
|
it('==> can handle file in other than repo path', async function () {
|
||||||
|
const shouldbe = [ 'tests/',
|
||||||
|
'test/',
|
||||||
|
'*.test.js',
|
||||||
|
'testing/',
|
||||||
|
'example/',
|
||||||
|
'/node_modules/',
|
||||||
|
'/coverage/',
|
||||||
|
'foo/**',
|
||||||
|
'bar/*.js',
|
||||||
|
'wtf/'
|
||||||
|
]
|
||||||
|
let result = await ignore(__dirname+'/repo','./test/anotherignorefile')
|
||||||
|
//console.log('returned to test',result, shouldbe)
|
||||||
|
expect(result, 'list build failed').to.deep.equal(shouldbe)
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
/node_modules/
|
||||||
|
/coverage/
|
|
@ -0,0 +1,5 @@
|
||||||
|
tests/
|
||||||
|
test/
|
||||||
|
*.test.js
|
||||||
|
testing/
|
||||||
|
example/
|
|
@ -0,0 +1,2 @@
|
||||||
|
foo/**
|
||||||
|
bar/*.js
|
|
@ -0,0 +1 @@
|
||||||
|
bah/*/*.js
|
Loading…
Reference in New Issue