Skip to content

Commit 9681854

Browse files
committed
CLI: Added customizable linter configuration to pbjs; CLI: Added stdin support to pbjs and pbts
1 parent fde56c0 commit 9681854

17 files changed

+193
-116
lines changed

cli/pbjs.js

+70-34
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ var protobuf = require(".."),
1717
* @returns {number|undefined} Exit code, if known
1818
*/
1919
exports.main = function(args, callback) {
20+
var lintDefault = "eslint-disable block-scoped-var, no-redeclare, no-control-regex";
2021
var argv = minimist(args, {
2122
alias: {
2223
target : "t",
2324
out : "o",
2425
path : "p",
2526
wrap : "w",
26-
root : "r"
27+
root : "r",
28+
lint : "l"
2729
},
28-
string: [ "target", "out", "path", "wrap", "root" ],
30+
string: [ "target", "out", "path", "wrap", "root", "lint" ],
2931
boolean: [ "keep-case", "create", "encode", "decode", "verify", "convert", "delimited", "beautify", "comments" ],
3032
default: {
3133
target : "json",
@@ -36,7 +38,8 @@ exports.main = function(args, callback) {
3638
convert : true,
3739
delimited : true,
3840
beautify : true,
39-
comments : true
41+
comments : true,
42+
lint : lintDefault
4043
}
4144
});
4245

@@ -52,9 +55,9 @@ exports.main = function(args, callback) {
5255
callback(Error("usage"));
5356
else
5457
console.error([
55-
"protobuf.js v" + pkg.version + " cli",
58+
"protobuf.js v" + pkg.version + " CLI for JavaScript",
5659
"",
57-
"Consolidates imports and converts between file formats.",
60+
chalk.bold.white("Consolidates imports and converts between file formats."),
5861
"",
5962
" -t, --target Specifies the target format. Also accepts a path to require a custom target.",
6063
"",
@@ -64,21 +67,26 @@ exports.main = function(args, callback) {
6467
"",
6568
" -o, --out Saves to a file instead of writing to stdout.",
6669
"",
67-
" Module targets only:",
70+
chalk.bold.gray(" Module targets only:"),
6871
"",
6972
" -w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper.",
7073
"",
7174
" default Default wrapper supporting both CommonJS and AMD",
72-
" commonjs CommonJS only wrapper",
73-
" amd AMD only wrapper",
75+
" commonjs CommonJS wrapper",
76+
" amd AMD wrapper",
77+
" es6 ES6 wrapper",
7478
"",
7579
" -r, --root Specifies an alternative protobuf.roots name.",
7680
"",
77-
" Proto sources only:",
81+
" -l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:",
82+
"",
83+
" " + lintDefault,
84+
"",
85+
chalk.bold.gray(" Proto sources only:"),
7886
"",
7987
" --keep-case Keeps field casing instead of converting to camel case (not recommended).",
8088
"",
81-
" Static targets only:",
89+
chalk.bold.gray(" Static targets only:"),
8290
"",
8391
" --no-create Does not generate create functions used for runtime compatibility.",
8492
" --no-encode Does not generate encode functions.",
@@ -89,7 +97,7 @@ exports.main = function(args, callback) {
8997
" --no-beautify Does not beautify generated code.",
9098
" --no-comments Does not output any JSDoc comments.",
9199
"",
92-
"usage: " + chalk.bold.green("pbjs") + " [options] file1.proto file2.json ..."
100+
"usage: " + chalk.bold.green("pbjs") + " [options] file1.proto file2.json ..." + chalk.gray(" (or) ") + "other | " + chalk.bold.green("pbjs") + " [options] -"
93101
].join("\n"));
94102
return 1;
95103
}
@@ -127,30 +135,58 @@ exports.main = function(args, callback) {
127135
"keepCase": argv["keep-case"] || false
128136
};
129137

130-
try {
131-
root.loadSync(files, parseOptions); // sync is deterministic while async is not
132-
} catch (err) {
133-
if (callback) {
134-
callback(err);
135-
return undefined;
136-
}
137-
throw err;
138-
}
138+
// Read from stdin
139+
if (files.length === 1 && files[0] === "-") {
140+
var data = [];
141+
process.stdin.on("data", function(chunk) {
142+
data.push(chunk);
143+
});
144+
process.stdin.on("end", function() {
145+
var source = Buffer.concat(data).toString("utf8");
146+
if (source.charAt(0) !== "{") {
147+
protobuf.parse(source, root, parseOptions);
148+
} else {
149+
var json = JSON.parse(source);
150+
root.setOptions(json.options).addJSON(json);
151+
}
152+
callTarget();
153+
});
139154

140-
target(root, argv, function targetCallback(err, output) {
141-
if (err) {
142-
if (callback)
143-
return callback(err);
155+
// Load from disk
156+
} else {
157+
try {
158+
root.loadSync(files, parseOptions); // sync is deterministic while async is not
159+
callTarget();
160+
} catch (err) {
161+
if (callback) {
162+
callback(err);
163+
return undefined;
164+
}
144165
throw err;
145166
}
146-
if (output !== "") {
147-
if (argv.out)
148-
fs.writeFileSync(argv.out, output, { encoding: "utf8" });
149-
else
150-
process.stdout.write(output, "utf8");
151-
}
152-
return callback
153-
? callback(null)
154-
: undefined;
155-
});
167+
}
168+
169+
function callTarget() {
170+
target(root, argv, function targetCallback(err, output) {
171+
if (err) {
172+
if (callback)
173+
return callback(err);
174+
throw err;
175+
}
176+
if (output !== "") {
177+
output = [
178+
"// $> pbjs " + args.join(" "),
179+
"// Generated " + (new Date()).toUTCString().replace(/GMT/, "UTC"),
180+
""
181+
].join("\n") + "\n" + output;
182+
if (argv.out)
183+
fs.writeFileSync(argv.out, output, { encoding: "utf8" });
184+
else
185+
process.stdout.write(output, "utf8");
186+
}
187+
return callback
188+
? callback(null)
189+
: undefined;
190+
});
191+
}
156192
};

cli/pbts.js

+87-59
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ var child_process = require("child_process");
66

77
var minimist = util.require("minimist", pkg.devDependencies.minimist),
88
chalk = util.require("chalk", pkg.devDependencies.chalk),
9-
glob = util.require("glob", pkg.devDependencies.glob);
9+
glob = util.require("glob", pkg.devDependencies.glob),
10+
tmp = util.require("tmp", pkg.devDependencies.glob);
1011

1112
var jsdoc = util.require("jsdoc/package.json", pkg.devDependencies.jsdoc);
1213

@@ -41,9 +42,9 @@ exports.main = function(args, callback) {
4142
callback(Error("usage"));
4243
else
4344
console.error([
44-
"protobuf.js v" + pkg.version + " cli for TypeScript",
45+
"protobuf.js v" + pkg.version + " CLI for TypeScript",
4546
"",
46-
"Generates TypeScript definitions from annotated JavaScript files.",
47+
chalk.bold.white("Generates TypeScript definitions from annotated JavaScript files."),
4748
"",
4849
" -n, --name Wraps everything in a module of the specified name.",
4950
"",
@@ -55,7 +56,7 @@ exports.main = function(args, callback) {
5556
"",
5657
" --no-comments Does not output any JSDoc comments.",
5758
"",
58-
"usage: " + chalk.bold.green("pbts") + " [options] file1.js file2.js ..."
59+
"usage: " + chalk.bold.green("pbts") + " [options] file1.js file2.js ..." + chalk.bold.gray(" (or) ") + "other | " + chalk.bold.green("pbts") + " [options] -"
5960
].join("\n"));
6061
if (callback)
6162
callback(Error("usage"));
@@ -72,63 +73,90 @@ exports.main = function(args, callback) {
7273
++i;
7374
}
7475

75-
// There is no proper API for jsdoc, so this executes the CLI and pipes the output
76-
var basedir = path.join(__dirname, "..");
77-
var moduleName = argv.name || "null";
78-
var child = child_process.exec("node \"" + basedir + "/node_modules/jsdoc/jsdoc.js\" -c \"" + basedir + "/jsdoc.types.json\" -q \"module=" + encodeURIComponent(moduleName) + "&comments=" + Boolean(argv.comments) + "\" " + files.map(function(file) { return '"' + file + '"'; }).join(' '), {
79-
cwd: process.cwd(),
80-
argv0: "node",
81-
stdio: "pipe",
82-
maxBuffer: 1 << 24 // 16mb
83-
});
84-
var out = [];
85-
child.stdout.on("data", function(data) {
86-
out.push(data);
87-
});
88-
child.stderr.pipe(process.stderr);
89-
child.on("close", function(code) {
90-
if (code) {
91-
out = out.join('').replace(/\s*JSDoc \d+\.\d+\.\d+ [^$]+/, "");
92-
process.stderr.write(out);
93-
var err = Error("code " + code);
94-
if (callback)
95-
callback(err);
96-
else
97-
throw err;
98-
return;
99-
}
76+
var cleanup = [];
10077

101-
var output = [
102-
"// $> pbts " + args.join(" "),
103-
"// Generated " + (new Date()).toUTCString().replace(/GMT/, "UTC"),
104-
""
105-
];
106-
if (argv.global)
107-
output.push(
108-
"export as namespace " + argv.global + ";",
109-
""
110-
);
111-
if (!argv.main)
112-
output.push(
113-
"import * as $protobuf from \"protobufjs\";",
78+
// Read from stdin (to a temporary file)
79+
if (files.length === 1 && files[0] === "-") {
80+
var data = [];
81+
process.stdin.on("data", function(chunk) {
82+
data.push(chunk);
83+
});
84+
process.stdin.on("end", function() {
85+
files[0] = tmp.tmpNameSync() + ".js";
86+
fs.writeFileSync(files[0], Buffer.concat(data));
87+
cleanup.push(files[0]);
88+
callJsdoc();
89+
});
90+
91+
// Load from disk
92+
} else {
93+
callJsdoc();
94+
}
95+
96+
function callJsdoc() {
97+
98+
// There is no proper API for jsdoc, so this executes the CLI and pipes the output
99+
var basedir = path.join(__dirname, "..");
100+
var moduleName = argv.name || "null";
101+
var cmd = "node \"" + basedir + "/node_modules/jsdoc/jsdoc.js\" -c \"" + basedir + "/jsdoc.types.json\" -q \"module=" + encodeURIComponent(moduleName) + "&comments=" + Boolean(argv.comments) + "\" " + files.map(function(file) { return '"' + file + '"'; }).join(' ');
102+
var child = child_process.exec(cmd, {
103+
cwd: process.cwd(),
104+
argv0: "node",
105+
stdio: "pipe",
106+
maxBuffer: 1 << 24 // 16mb
107+
});
108+
var out = [];
109+
child.stdout.on("data", function(data) {
110+
out.push(data);
111+
});
112+
child.stderr.pipe(process.stderr);
113+
child.on("close", function(code) {
114+
// clean up temporary files, no matter what
115+
try { cleanup.forEach(fs.unlinkSync); } catch(e) {} cleanup = [];
116+
117+
if (code) {
118+
out = out.join('').replace(/\s*JSDoc \d+\.\d+\.\d+ [^$]+/, "");
119+
process.stderr.write(out);
120+
var err = Error("code " + code);
121+
if (callback)
122+
callback(err);
123+
else
124+
throw err;
125+
return;
126+
}
127+
128+
var output = [
129+
"// $> pbts " + args.join(" "),
130+
"// Generated " + (new Date()).toUTCString().replace(/GMT/, "UTC"),
114131
""
115-
);
116-
output = output.join('\n') + "\n" + out.join('');
117-
118-
try {
119-
if (argv.out)
120-
fs.writeFileSync(argv.out, output);
121-
else
122-
process.stdout.write(output, "utf8");
123-
if (callback)
124-
callback(null);
125-
} catch (err) {
126-
if (callback)
127-
callback(err);
128-
else
129-
throw err;
130-
}
131-
});
132+
];
133+
if (argv.global)
134+
output.push(
135+
"export as namespace " + argv.global + ";",
136+
""
137+
);
138+
if (!argv.main)
139+
output.push(
140+
"import * as $protobuf from \"protobufjs\";",
141+
""
142+
);
143+
output = output.join('\n') + "\n" + out.join('');
144+
145+
try {
146+
if (argv.out)
147+
fs.writeFileSync(argv.out, output);
148+
else
149+
process.stdout.write(output, "utf8");
150+
if (callback)
151+
callback(null);
152+
} catch (err) {
153+
if (callback)
154+
callback(err);
155+
else
156+
throw err;
157+
}
158+
});
159+
}
132160

133161
return undefined;
134162
};

cli/targets/json-module.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ json_module.description = "JSON representation as a module"
88
function json_module(root, options, callback) {
99
try {
1010
var output = "var $root = protobuf.Root.fromJSON(" + JSON.stringify(root, null, 2).replace(/^(?!$)/mg, " ").trim() + ").resolveAll();";
11-
output = util.wrap(options.wrap || "default", output, options.root);
11+
output = util.wrap(output, options);
1212
process.nextTick(function() {
1313
callback(null, output);
1414
});

cli/targets/static-module.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function static_module_target(root, options, callback) {
1919
if (err)
2020
return callback(err);
2121
try {
22-
output = util.wrap(options.wrap || "default", output, options.root);
22+
output = util.wrap(output, options);
2323
} catch (e) {
2424
callback(e);
2525
return;

cli/targets/static.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ function buildService(ref, service) {
537537
]);
538538
push("this.responseDelimited = Boolean(responseDelimited);");
539539
--indent;
540-
push("};");
540+
push("}");
541541

542542
service.methodsArray.forEach(function(method) {
543543
method.resolve();
@@ -567,7 +567,7 @@ function buildService(ref, service) {
567567
--indent;
568568
push("} catch (err) {");
569569
++indent;
570-
push("(typeof setImmediate === 'function' ? setImmediate : setTimeout)(function() { callback(err); });");
570+
push("(typeof setImmediate === \"function\" ? setImmediate : setTimeout)(function() { callback(err); });");
571571
push("return;");
572572
--indent;
573573
push("}");

0 commit comments

Comments
 (0)