Skip to content

Commit

Permalink
Resolves #355: proper path resolution for edge-cases using CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
webketje committed May 23, 2022
1 parent 1dae1cb commit 5d75539
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
17 changes: 12 additions & 5 deletions bin/_metalsmith
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
const exists = require('fs').existsSync
const Metalsmith = require('..')
const program = require('commander')
const resolve = require('path').resolve
const { resolve, isAbsolute, dirname } = require('path')
const { isString, isObject } = require('../lib/helpers')

const color = {
Expand Down Expand Up @@ -51,11 +51,18 @@ program.parse(process.argv)

const dir = process.cwd()
const config = program.config
const path = resolve(dir, config)
const path = isAbsolute(config) ? config : resolve(dir, config)

// Important addition of 2.5.x. Given local plugins with a relative path are written with __dirname in mind,
// having a config-relative dir path makes sure the CLI runs properly
// when the command is executed from a subfolder or outside of the ms directory
const confRelativeDir = dirname(path)
if (!exists(path)) fatal(`could not find a ${config} configuration file.`)

let json
try {
// requiring json is incompatible with ESM, however given the metalsmith CLI is not meant to be "imported" or used in an ESM flow,
// it is ok to keep it here for now
json = require(path)
} catch (e) {
fatal(`it seems like ${config} is malformed.`)
Expand All @@ -65,7 +72,7 @@ try {
* Metalsmith.
*/

const metalsmith = new Metalsmith(dir)
const metalsmith = new Metalsmith(confRelativeDir)
if (json.source) metalsmith.source(json.source)
if (json.destination) metalsmith.destination(json.destination)
if (json.concurrency) metalsmith.concurrency(json.concurrency)
Expand All @@ -88,8 +95,8 @@ normalize(json.plugins).forEach(function (plugin) {
let mod

try {
const local = resolve(dir, name)
const npm = resolve(dir, 'node_modules', name)
const local = resolve(confRelativeDir, name)
const npm = resolve(confRelativeDir, 'node_modules', name)

if (exists(local) || exists(`${local}.js`)) {
mod = require(local)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"result":"success"}
5 changes: 5 additions & 0 deletions test/fixtures/cli-from-unexpected-folder/metalsmith.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"plugins": {
"./plugin": true
}
}
5 changes: 5 additions & 0 deletions test/fixtures/cli-from-unexpected-folder/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(){
return function(files){
files['empty.json'].contents = Buffer.from(JSON.stringify({"result":"success"}));
};
};
Empty file.
10 changes: 9 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1134,12 +1134,20 @@ describe('CLI', function () {

it('should support the env method', function (done) {
exec(bin, { cwd: fixture('cli-env'), env: { NODE_ENV: 'development' } }, function (err, stdout, stderr) {
console.log(stderr)
equal(fixture('cli-env/build'), fixture('cli-env/expected'))
assert(~stdout.indexOf('successfully built to '))
assert(~stdout.indexOf(fixture('cli-env/build')))
done()
})
})

it('should work when run from a directory that is not Metalsmith#directory', function (done) {
exec(bin, { cwd: fixture('cli-from-unexpected-folder') }, function (err, stdout, stderr) {
equal(fixture('cli-from-unexpected-folder/build'), fixture('cli-from-unexpected-folder/expected'))
assert(~stdout.indexOf('successfully built to '))
assert(~stdout.indexOf(fixture('cli-from-unexpected-folder/build')))
done()
})
})
})
})

0 comments on commit 5d75539

Please sign in to comment.