Metalskin Metalskin - 3 months ago 15
JSON Question

How to validate bower.json?

I have an error with my bower.json file.

A google has turned up that this is quite common, often because of a non-printable character (due to using an editor that uses such characters).

Is there a way to validate the file locally from the cli?

As an FYI, my error is as follows:

bower meltingpot#* EMALFORMED Failed to read /tmp/james/bower/meltingpot-5659-xBMHsL/bower.json

Additional error details:
Unexpected token ]


The contents of my bower.json file are as follows:

{
"name": "meltingpot",
"version": "0.0.1",
"homepage": "https://github.com/jamesjenner/meltingpot",
"authors": [
"james-jenner <james.jenner@########.com>"
],
"description": "HTML based application, websockets for comms and node.js for backend",
"keywords": [
"application",
"websocket",
"node"
],
"license": "MIT",
"ignore": [
"**/.*",
"Gruntfile.js",
"application.js",
"bower_components",
"comms.js",
"node_modules",
"*.json",
"panelHandler.js",
"shared/panel.js",
"test",
"tests"
]
}


While I'm happy if someone can point out the cause of the problem, the real question is how do I validate the bower.json file to detect and identify any errors. Preference would be that the line is provided where the error occurs.

:edit:

I created a quick script to read in the bower file, parse the data via JSON and then stringify the result. From experience if the json file contained malformed json then I would have received an exception. So it looks like the problem isn't with the format of the file, but with the contents.

Code I used to test the file:

var fs = require('fs');

var data;

try {
data = fs.readFileSync('bower.json');
} catch (e) {
if (e.code === 'ENOENT') {
// ENOENT is file not found, that is okay, just means no records
} else {
// unknown error, lets throw
throw e;
}
}

var json = JSON.parse(data);
console.log(JSON.stringify(json, null, ' '));


:edit:

I've now tested using the
bower-json
package (thanks to jayeff), and still validates as okay. Code used is as follows:

var bowerJson = require('bower-json');

// Can also be used by simply calling bowerJson()
bowerJson.read('./bower.json', function (err, json) {
if (err) {
console.error('There was an error reading the file');
console.error(err.message);
return;
}

console.log('JSON: ', json);

try {
bowerJson.validate(json);
} catch (err) {
console.error('There was an error validating the object');
console.error(err.message);
}
});


:edit:

Just to be clear on the solution (provided by drorb below), the problem was that I had created a tag, noticed the extra comma and then fixed the comma just by committing the change. As far as bower was concerned, it was taking the latest release/tag, so was ignoring the fix in my commit.

In addition, while in git you can remove a version via
git -d <tag>
, bower appears to take the release, not the latest tag (there are complications with how github uses releases). In my case I deleted 0.1.0, added 0.0.1 and bower register ignored 0.0.1. I was forced to create a 0.1.1 tag (after committing the changes in the bower.json file) and then I was able to register.

I've now discovered that you can delete the releases from github, via the website interface (refer Editing and Deleting Releases). I was able to tidy up my releases, update the
package.json
and then push the release I wanted via
git tag <tag> -a -m "<desc>"
and
git push --tags
. Now
bower info <mypackage>
displays the correct information.

I've added the above, as this was not discussed when I looked through other stackoverflow posts that have this problem. I hope the above makes clear the issue of tags and commits with bower, trying to register and how to tidy up any mistakes.

I also recommend reading Creating and Maintaining your own Bower Package.

Answer

The problem is not with the bower.json you posted which I assume is the on you have in the master branch.
The issue is the version of the file found in the 0.1.0 tag - there is aמ unnecessary comma in the ignore list:

  "ignore": [
    "**/.*",
    "Gruntfile.js",
    "application.js",
    "bower_components",
    "comms.js",
    "node_modules",
    "package.json",
    "panelHandler.js",
    "shared/panel.js",
    "test",
    "tests", << issue is here
  ]

Running your test code against this file produces the correct error message:

undefined:27
  ]
  ^
SyntaxError: Unexpected token ]
    at Object.parse (native)
    at Object.<anonymous> (D:\work\js\meltingpot\test.js:16:17)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3