@berun/sparky
Version:
Sparky task runner for @berun
133 lines (114 loc) • 3.2 kB
text/typescript
import * as fs from 'fs-extra'
import * as path from 'path'
import { replaceExt, ensureUserPath, ensureDir } from './Utils'
import { Config } from './Config'
import { Plugin } from './FuseBox'
export class SparkyFile {
public homePath: string
public name: string
public contents: Buffer | string
public extension: string
public filepath: string
public root: string
private savingRequired = false
constructor(filepath: string, root: string) {
this.filepath = path.normalize(filepath)
this.root = path.normalize(root)
const hp = path.relative(this.root, this.filepath)
this.homePath = path.isAbsolute(hp) ? hp.slice(1) : hp
this.name = path.basename(this.filepath)
}
public read(): SparkyFile {
this.contents = fs.readFileSync(this.filepath)
return this
}
public write(contents: string | Buffer): SparkyFile {
this.contents = contents
fs.writeFileSync(this.filepath, contents)
return this
}
public save(): SparkyFile {
this.savingRequired = false
if (this.contents) {
const { contents } = this
if (typeof this.contents === 'object') {
this.contents = JSON.stringify(contents, null, 2)
}
ensureDir(path.dirname(this.filepath))
fs.writeFileSync(this.filepath, this.contents)
}
return this
}
public ext(ext: string): SparkyFile {
this.extension = ext
return this
}
public json(fn: any): SparkyFile {
if (!this.contents) {
this.read()
}
if (typeof fn === 'function') {
try {
const contents = this.contents.toString()
? JSON.parse(this.contents.toString())
: {}
const response = fn(contents)
this.contents = response || contents
this.savingRequired = true
} catch (ex) {
console.error(`SparkyFile Error parsing ${this.filepath} ${ex.message}`)
process.exit(1)
}
}
return this
}
public plugin(plugin: Plugin) {
if (!this.contents) {
this.read()
}
}
public setContent(cnt: string): SparkyFile {
this.contents = cnt
this.savingRequired = true
return this
}
public rename(name: string): SparkyFile {
this.name = name
return this
}
public copy(dest: string) {
return new Promise((resolve, reject) => {
const isDirectory = fs.statSync(this.filepath).isDirectory()
if (isDirectory) {
resolve()
return
}
const isTemplate = dest.indexOf('$') > -1
if (isTemplate) {
if (!path.isAbsolute(dest)) {
dest = path.join(Config.PROJECT_ROOT, dest)
}
dest = dest.replace('$name', this.name).replace('$path', this.filepath)
} else {
dest = path.join(dest, this.homePath)
dest = ensureUserPath(dest)
}
if (this.extension) {
dest = replaceExt(dest, `.${this.extension}`)
delete this.extension
}
fs.copy(this.filepath, dest, err => {
if (err) {
reject(err)
return
}
this.filepath = dest
// save is required
if (this.savingRequired) {
this.save()
}
resolve()
})
})
}
}