Skip to content

Commit

Permalink
Extract and test CLI logic (#278)
Browse files Browse the repository at this point in the history
* Extract and test CLI argument parsing
  • Loading branch information
ralfhandl authored Jan 17, 2024
1 parent de92a86 commit 028cf1a
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 99 deletions.
2 changes: 1 addition & 1 deletion examples/PingTest_V1.no-batch.openapi3.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,4 @@
}
}
}
}
}
112 changes: 14 additions & 98 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,35 @@
#!/usr/bin/env node
"use strict";

//console.dir(argv);

//TODO: what to require?
const csdl = require("odata-csdl");
const lib = require("./csdl2openapi");
const minimist = require("minimist");
const fs = require("fs");
const { parseArgs } = require("./cliParts");
const { stringifyStream } = require("@discoveryjs/json-ext");

var unknown = false;

var argv = minimist(process.argv.slice(2), {
string: [
"o",
"openapi-version",
"t",
"target",
"basePath",
"description",
"host",
"levels",
"scheme",
"title",
],
boolean: [
"d",
"diagram",
"h",
"help",
"p",
"pretty",
"u",
"used-schemas-only",
"skipBatchPath",
],
alias: {
d: "diagram",
h: "help",
o: "openapi-version",
p: "pretty",
t: "target",
u: "used-schemas-only",
},
default: {
levels: 4,
pretty: false,
skipBatchPath: false,
},
unknown: (arg) => {
if (arg.substring(0, 1) == "-") {
console.error("Unknown option: " + arg);
unknown = true;
return false;
}
},
});

if (unknown || argv._.length == 0 || argv.h) {
console.log(`Usage: odata-openapi3 <options> <source file>
Options:
--basePath base path (default: /service-root)
--description default description if none is annotated
-d, --diagram include YUML diagram
-h, --help show this info
--host host (default: localhost)
--levels maximum number of path segments
-o, --openapi-version 3.0.0 to 3.0.3 or 3.1.0 (default: 3.0.2)
-p, --pretty pretty-print JSON result
--scheme scheme (default: http)
--skipBatchPath skips the generation of the $batch path, (default: false)
-t, --target target file (default: source file basename + .openapi3.json)
--title default title if none is annotated`);
} else {
//TODO: further input parameters reserved for e.g. referenced CSDL documents
// for (var i = 0; i < argv._.length; i++) {
// convert(argv._[i]);
// }
convert(argv._[0]);
}
const args = parseArgs(process.argv.slice(2));
if (args.unknown)
args.unknown.map((arg) => console.error(`Unknown option: ${arg}`));
if (args.usage) console.log(args.usage);
else convert(args);

function convert(source) {
if (!fs.existsSync(source)) {
console.error("Source file not found: " + source);
function convert(args) {
if (!fs.existsSync(args.source)) {
console.error("Source file not found: " + args.source);
return;
}

const text = fs.readFileSync(source, "utf8");
const text = fs.readFileSync(args.source, "utf8");
const json = text.startsWith("<") ? csdl.xml2json(text) : JSON.parse(text);

const target =
argv.target ||
(source.lastIndexOf(".") <= 0
? source
: source.substring(0, source.lastIndexOf("."))) + ".openapi3.json";
console.log(target);
console.log(args.target);

const messages = [];

const openapi = lib.csdl2openapi(json, {
scheme: argv.scheme,
host: argv.host,
basePath: argv.basePath,
diagram: argv.diagram,
maxLevels: Number(argv.levels),
openapiVersion: argv.o,
messages,
skipBatchPath: argv.skipBatchPath,
defaultTitle: argv.title,
defaultDescription: argv.description,
});
const openapi = lib.csdl2openapi(json, { messages, ...args.options });

stringifyStream(openapi, null, argv.pretty ? 4 : 0).pipe(
fs.createWriteStream(target),
stringifyStream(openapi, null, args.options.pretty ? 4 : 0).pipe(
fs.createWriteStream(args.target),
);

if (messages.length > 0) console.dir(messages);
Expand Down
104 changes: 104 additions & 0 deletions lib/cliParts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Parse command-line options
*
* Latest version: https://github.com/oasis-tcs/odata-openapi/blob/main/lib/cliOptions.js
*/

const minimist = require("minimist");

module.exports = { parseArgs };

function parseArgs(argv) {
const usage = `Usage: odata-openapi3 <options> <source file>
Options:
--basePath base path (default: /service-root)
--description default description if none is annotated
-d, --diagram include YUML diagram
-h, --help show this info
--host host (default: localhost)
--levels maximum number of path segments
-o, --openapi-version 3.0.0 to 3.0.3 or 3.1.0 (default: 3.0.2)
-p, --pretty pretty-print JSON result
--scheme scheme (default: http)
--skipBatchPath skips the generation of the $batch path, (default: false)
-t, --target target file (default: source file basename + .openapi3.json)
--title default title if none is annotated`;
const unknown = [];

const args = minimist(argv, {
string: [
"basePath",
"description",
"host",
"levels",
"openapi-version",
"scheme",
"target",
"title",
],
boolean: ["diagram", "help", "pretty", "skipBatchPath"],
alias: {
d: "diagram",
h: "help",
o: "openapi-version",
p: "pretty",
t: "target",
},
default: {
pretty: false,
},
unknown: (arg) => {
if (arg.substring(0, 1) == "-") {
unknown.push(arg);
return false;
}
},
});

if (unknown.length > 0 || args.help || args._.length !== 1)
return {
unknown,
usage,
};

const source = args._[0];
const target =
args.target ||
(source.lastIndexOf(".") > 0
? source.substring(0, source.lastIndexOf("."))
: source) + ".openapi3.json";

const options = {};

for (const [name, value] of Object.entries(args)) {
if (name.length === 1) continue;
if (value === false) continue;
switch (name) {
case "description":
options.defaultDescription = value;
break;
case "levels": {
const l = Number(value);
if (!isNaN(l)) options.maxLevels = l;
break;
}
case "openapi-version":
options.openapiVersion = value;
break;
case "target":
break;
case "title":
options.defaultTitle = value;
break;
default:
options[name] = value;
break;
}
}

return {
source,
target,
options,
};
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"scripts": {
"build": "node lib/transform.js",
"pretest": "rm examples/PingTest_V1.no-batch.openapi3.json && node lib/cli.js -p --skipBatchPath -t examples/PingTest_V1.no-batch.openapi3.json examples/PingTest_V1.xml",
"test": "c8 mocha",
"watch": "mocha --watch"
},
Expand Down
Loading

0 comments on commit 028cf1a

Please sign in to comment.