Skip to content

Instantly share code, notes, and snippets.

@rhythnic
Last active September 28, 2018 20:29
Show Gist options
  • Save rhythnic/39c285c12354693097ecbb0c056c91a4 to your computer and use it in GitHub Desktop.
Save rhythnic/39c285c12354693097ecbb0c056c91a4 to your computer and use it in GitHub Desktop.
Classes for keeping directories in sync.
const { join } = require('path')
const fs = require('fs')
const pump = require('pump')
class Directory {
constructor ({ dir = '' }) {
this.dir = dir
this.init()
}
init () {}
getFullPath (path) {
return join(this.dir, path)
}
}
class FileDirectory extends Directory {
init () {
if (!fs.existsSync(this.dir)) fs.mkdirSync(this.dir)
}
createReadStream (path) {
return fs.createReadStream(this.getFullPath(path))
}
createWriteStream (path) {
return fs.createWriteStream(this.getFullPath(path))
}
readFile (path) {
return new Promise((rsv, rej) => {
const cb = (err, x) => err ? rej(err) : rsv(x)
return fs.readFile(this.getFullPath(path), cb)
})
}
writeFile (path, data) {
return new Promise((rsv, rej) => {
const cb = (err, x) => err ? rej(err) : rsv(x)
return fs.writeFile(this.getFullPath(path), data, cb)
})
}
}
class DirectorySync {
constructor ({ local, remote } = {}) {
this.local = local
this.remote = remote
}
setLocal (x) {
this.local = x
}
setRemote (x) {
this.remote = x
}
// for large transfers, will overwrite dest on error
streamPath (path, source, dest, opts = {}) {
return new Promise((resolve, reject) => {
return pump(
source.createReadStream(path),
dest.createWriteStream(path),
err => {
if (!err || opts.failSilently) return resolve()
reject(err)
}
)
})
}
// for small files that fit into memory
// won't overwrite dest on error
async syncPath (path, source, dest, opts = {}) {
if (opts.stream)
return this.streamPath(path, source, dest, opts)
try {
const body = await source.readFile(path)
return dest.writeFile(path, body)
} catch (err) {
if (!opts.failSilently) throw err
}
}
pushFile (path, opts) {
return this.syncPath(path, this.local, this.remote, opts)
}
pullFile (path, opts) {
return this.syncPath(path, this.remote, this.local, opts)
}
pushMultipleFiles (paths, opts) {
return Promise.all(paths.map(x => this.pushFile(x, opts)))
}
pullMultipleFiles (paths, opts) {
return Promise.all(paths.map(x => this.pullFile(x, opts)))
}
}
module.exports = {
Directory,
FileDirectory,
DirectorySync
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment