Skip to content

Commit

Permalink
Merge branch 'feature/#259-debug-method' into release/2.5.x
Browse files Browse the repository at this point in the history
  • Loading branch information
webketje committed May 29, 2022
2 parents 5d75539 + 7d39a76 commit 91e2f46
Show file tree
Hide file tree
Showing 9 changed files with 365 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ coverage.info
.DS_Store
examples/package-lock.json
*.tgz
*.log
.eslintcache
109 changes: 109 additions & 0 deletions lib/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const debug = require('debug')
const utf8 = require('is-utf8')
const { isString } = require('./helpers')

const streamLogHandler =
(stream) =>
(...args) =>
stream.write(require('util').format(...args) + '\n')
debug.log = streamLogHandler(process.stderr)

const options = {}
Object.defineProperties(options, {
colors: {
get() {
return debug.inspectOpts.colors
},
set(v) {
debug.inspectOpts.colors = v
}
},
handle: {
get() {
return debug.log
},
set(v) {
debug.log = v
}
}
})

// add a %b buffer formatter to print buffer contents.
// useful for checking whether the contents match rendering expectations
debug.formatters.b = function (buffer) {
if (buffer instanceof Buffer && utf8(buffer)) {
return `${buffer.toString().slice(0, 200)}...`
}
return buffer
}

/**
* @typedef {import('debug').Debugger} Debugger
* @property {import('debug').Debugger} info
* @property {import('debug').Debugger} warn
* @property {import('debug').Debugger} error
*/

/**
* Create a new [debug](https://github.com/debug-js/debug#readme) debugger
* @param {string} namespace Debugger namespace
* @returns {Debugger}
* @example
* ```js
* const debug = metalsmith.debug('metalsmith-myplugin')
* debug('a debug log') // logs 'metalsmith-myplugin a debug log'
* debug.warn('A warning') // logs 'metalsmith-myplugin:warn A warning'
* ```
*/
function Debugger(namespace) {
if (!isString(namespace)) {
const err = new Error(`invalid debugger namespace "${namespace}"`)
err.code = 'invalid_debugger_namespace'
throw err
}
// ANSI colors, see https://tintin.mudhalla.net/info/256color/
// the colors have been chosen to best integrate with dark & light bg
// and provide consistent coloring of debug/error/warn/info channel messages
// debug only supports these colors if an extra module is installed, but these are already available in most terminals
// to be tested on Windows Batch

const namespacedDebug = debug(namespace)

namespacedDebug.log = (...args) => options.handle(...args)
namespacedDebug.color = 247

const warn = namespacedDebug.extend('warn')
warn.color = 178

const info = namespacedDebug.extend('info')
info.color = 51

const error = namespacedDebug.extend('error')
error.color = 196

const dbugger = Object.assign(namespacedDebug, { warn, info, error })
return dbugger
}

// We need to proxy some properties through Debugger to get access to them through metalsmith.debug.<option>
function proxy(host, target, option) {
Object.defineProperty(host, option, {
get() {
return target[option]
},
set(v) {
target[option] = v
}
})
}

proxy(Debugger, options, 'handle')
proxy(Debugger, options, 'colors')
proxy(Debugger, debug, 'enabled')
proxy(Debugger, debug, 'enable')
proxy(Debugger, debug, 'disable')

module.exports = {
Debugger,
fileLogHandler: streamLogHandler
}
7 changes: 6 additions & 1 deletion lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ function match(input, patterns, options) {
})
return micromatch(input, patterns, options).sort()
}

function writeStream(path) {
return fs.createWriteStream(path, 'utf-8')
}
/**
* Recursively remove a directory
* @param {string} p
Expand Down Expand Up @@ -181,7 +185,8 @@ const helpers = {
outputFile,
stat,
readFile,
batchAsync
batchAsync,
writeStream
}

module.exports = helpers
73 changes: 67 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@ const assert = require('assert')
const matter = require('gray-matter')
const Mode = require('stat-mode')
const path = require('path')
const { readdir, batchAsync, isFunction, outputFile, stat, readFile } = require('./helpers')
const { rm, isString, isBoolean, isObject, isNumber, isUndefined, match } = require('./helpers')
const {
readdir,
batchAsync,
isFunction,
outputFile,
stat,
readFile,
writeStream,
rm,
isString,
isBoolean,
isObject,
isNumber,
isUndefined,
match
} = require('./helpers')
const utf8 = require('is-utf8')
const Ware = require('ware')
const { Debugger, fileLogHandler } = require('./debug')

const symbol = {
env: Symbol('env')
env: Symbol('env'),
log: Symbol('log')
}

/**
Expand Down Expand Up @@ -109,6 +125,11 @@ function Metalsmith(directory) {
value: Object.create(null),
enumerable: false
})
Object.defineProperty(this, symbol.log, {
value: null,
enumerable: false,
writable: true
})
}

/**
Expand Down Expand Up @@ -342,6 +363,8 @@ Metalsmith.prototype.env = function (vars, value) {
if (isUndefined(vars)) return Object.assign(Object.create(null), this[symbol.env])
}

Metalsmith.prototype.debug = Debugger

/**
* Build with the current settings to the destination directory.
*
Expand All @@ -361,9 +384,39 @@ Metalsmith.prototype.build = function (callback) {
const clean = this.clean()
const dest = this.destination()

const result = (clean ? rm(dest) : Promise.resolve()).then(this.process.bind(this)).then((files) => {
return this.write(files).then(() => files)
})
const result = (clean ? rm(dest) : Promise.resolve())
.then(() => {
if (this.debug.enabled && this.env('DEBUG_LOG')) {
this[symbol.log] = writeStream(this.path(this.env('DEBUG_LOG')))
this.debug.handle = fileLogHandler(this[symbol.log])
this.debug.colors = false

return new Promise((resolve, reject) => {
this[symbol.log].on('error', (err) => {
let error = err
if (error.code === 'ENOENT') {
error = new Error(
`Inexistant directory path "${path.dirname(this.env('DEBUG_LOG'))}" given for DEBUG_LOG`
)
error.code = 'invalid_logpath'
reject(error)
}
})
if (this[symbol.log].pending) {
this[symbol.log].on('ready', () => resolve())
} else {
resolve()
}
})
}
})
.then(this.process.bind(this))
.then((files) => {
return this.write(files).then(() => {
if (this[symbol.log]) this[symbol.log].end()
return files
})
})

/** block required for Metalsmith 2.x callback-flow compat */
if (isFunction(callback)) {
Expand Down Expand Up @@ -412,6 +465,14 @@ Metalsmith.prototype.process = function (callback) {
*/

Metalsmith.prototype.run = function (files, plugins, callback) {
let debugValue = this.env('DEBUG')
if (debugValue === false) {
this.debug.disable()
} else {
if (debugValue === true) debugValue = '*'
this.debug.enable(debugValue)
}

/** block required for Metalsmith 2.x callback-flow compat */
const last = arguments[arguments.length - 1]
callback = isFunction(last) ? last : undefined
Expand Down
4 changes: 1 addition & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
},
"files": [
"index.js",
"lib/**",
"lib/index.js",
"lib/debug.js",
"lib/helpers.js",
"bin/**",
"CHANGELOG.md",
"snapcraft.yaml"
Expand All @@ -54,6 +56,7 @@
"dependencies": {
"commander": "^6.2.1",
"cross-spawn": "^7.0.3",
"debug": "^4.3.3",
"gray-matter": "^4.0.3",
"is-utf8": "~0.2.0",
"micromatch": "^4.0.5",
Expand Down
Empty file.
Empty file.

0 comments on commit 91e2f46

Please sign in to comment.