Merge pull request +9885 from c9/prevalidate-packages

[Trivial] Validate package name only contains valid characters.
pull/223/head
Tim Robinson 2015-10-21 11:04:01 +02:00
commit 8f7f129a1e
2 zmienionych plików z 69 dodań i 23 usunięć

Wyświetl plik

@ -114,7 +114,7 @@ define(function(require, exports, module) {
process.exit(1);
}
else if (!dryRun) {
console.log("Succesfully published version", data.version);
console.log("Successfully published version", data.version);
process.exit(0);
}
});
@ -210,7 +210,7 @@ define(function(require, exports, module) {
process.exit(1);
}
else {
console.log("Succesfully disabled package");
console.log("Successfully disabled package");
process.exit(0);
}
});
@ -250,6 +250,37 @@ define(function(require, exports, module) {
return (verbose ? JSON.stringify(err, 4, " ") : (typeof err == "string" ? err : err.message));
}
function addMissingValues(json) {
json.permissions = json.permissions || "world";
return json;
}
function validateConfig(json) {
var cwd = process.cwd();
// Basic Validation
if (json.private)
return new Error("ERROR: Private flag in package.json prevents from publishing");
if (!json.name)
return new Error("ERROR: Missing name property in package.json");
if (!json.name.match(/^[\w\._]+$/))
return new Error("ERROR: Package name can only contain Alphanumeric characters, periods and underscores");
if (basename(cwd) != json.name) {
console.warn("WARNING: The name property in package.json is not equal to the directory name, which is " + basename(cwd));
if (!force)
return new Error("Use --force to ignore this warning.");
}
if (!json.repository)
return new Error("ERROR: Missing repository property in package.json");
if (!json.repository.url)
return new Error("ERROR: Missing repository.url property in package.json");
if (!json.categories || json.categories.length == 0)
return new Error("ERROR: At least one category is required in package.json");
if (!json.permissions || !json.permissions.match(/org|world/))
return new Error("ERROR: Permissions must be 'org' or 'world'");
}
function publish(options, callback) {
if (typeof options != "object")
options = {version: options};
@ -266,22 +297,13 @@ define(function(require, exports, module) {
return callback(new Error("ERROR: Could not parse package.json: ", e.message));
}
// Basic Validation
if (json.private)
return callback(new Error("ERROR: Private flag in package.json prevents from publishing"));
if (!json.name)
return callback(new Error("ERROR: Missing name property in package.json"));
if (basename(cwd) != json.name) {
console.warn("WARNING: The name property in package.json is not equal to the directory name, which is " + basename(cwd));
if (!force)
return callback(new Error("Use --force to ignore this warning."));
}
if (!json.repository)
return callback(new Error("ERROR: Missing repository property in package.json"));
if (!json.repository.url)
return callback(new Error("ERROR: Missing repository.url property in package.json"));
if (!json.categories || json.categories.length == 0)
return callback(new Error("ERROR: At least one category is required in package.json"));
console.log("Permissions are: ", json.permissions);
console.log("Data is: ", data);
json = addMissingValues(json);
console.log("Permissions are: ", json.permissions);
var validationError = validateConfig(json);
if (validationError) return callback(validationError);
var description = json.description;
@ -701,7 +723,7 @@ define(function(require, exports, module) {
description: description,
owner_type: "user", // @TODO implement this when adding orgs
owner_id: parseInt(user.id),
permissions: json.permissions || "world",
permissions: json.permissions,
categories: json.categories,
repository: json.repository,
longname: json.longname,
@ -710,9 +732,10 @@ define(function(require, exports, module) {
pricing: json.pricing || {}
}
}, function(err, pkg){
if (err)
if (err) {
return callback(new Error("ERROR: Failed to upload new package to API - "
+ stringifyError(err)));
}
next(pkg);
});

Wyświetl plik

@ -2,8 +2,6 @@
"use strict";
"use server";
"use blacklist";
require("c9/inline-mocha")(module);
if (typeof define === "undefined") {
@ -64,7 +62,7 @@ describe("cli.publish", function(){
"description": "",
"star_count": 0,
"star_total": 0,
"installs": 0,
"screenshots": [
// TODO Screenshots are broken
@ -95,6 +93,14 @@ describe("cli.publish", function(){
});
});
it("should be fine if json.permissions is missing as it defaults to world", function(done){
fs.writeFileSync(packagePath, packageJson.replace(/"permissions[\s\S]*?\],/, ""));
runCLI("publish", ["major"], function(err, stdout, stderr){
assert(!err, err);
done();
});
});
it("should warn if the package.json is missing", function(done){
fs.unlinkSync(packagePath);
runCLI("publish", ["major"], function(err, stdout, stderr){
@ -116,6 +122,13 @@ describe("cli.publish", function(){
done();
});
});
it("should fail if the name in the package.json contains invalid characters", function(done){
fs.writeFileSync(packagePath, packageJson.replace('c9.ide.example', 'c9-ide-example'));
runCLI("publish", ["major"], function(err, stdout, stderr){
expect(stderr).to.match(/ERROR: Package name can only contain/);
done();
});
});
it("should fail if the name in the package.json is not equal to the directory", function(done){
fs.writeFileSync(packagePath, packageJson.replace('"name": "c9.ide.example"', '"name": "wrongname"'));
runCLI("publish", ["major"], function(err, stdout, stderr){
@ -137,6 +150,16 @@ describe("cli.publish", function(){
done();
});
});
it("should fail if json.permissions is not org or world", function(done){
var parsedJson = JSON.parse(packageJson);
parsedJson.permissions = "notvalid";
fs.writeFileSync(packagePath, JSON.stringify(parsedJson));
runCLI("publish", ["major"], function(err, stdout, stderr){
console.log("stdout: ", stdout)
expect(stderr).to.match(/ERROR: Permissions must be/);
done();
});
});
it("should warn if a plugin is not listed in the package.json", function(done){
fs.writeFileSync(packagePath, packageJson.replace('"example": {}', ''));
runCLI("publish", ["major"], function(err, stdout, stderr){