* Add finding missing SDKs command * Remove getCommandLineParameterValue function * Add draft of generating TS readme * Promisify gulp tasks * Skip non directories * Add Logger * Add generating new TypeScript readme * Fix typo * Fix package.json * Address code review comments
This commit is contained in:
Родитель
28d7e6894a
Коммит
04bd3f4f70
|
@ -4,19 +4,33 @@
|
|||
* license information.
|
||||
*/
|
||||
|
||||
import * as colors from "colors";
|
||||
import * as fssync from "fs";
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import * as minimist from "minimist";
|
||||
import * as yaml from "js-yaml";
|
||||
import { CommandLineOptions, SdkType } from "./commandLineOptions";
|
||||
import { Logger } from "./logger";
|
||||
|
||||
interface readmeSettings {
|
||||
"nodejs": {
|
||||
"azure-arm": boolean;
|
||||
"license-header": string;
|
||||
"payload-flattening-threshold": number;
|
||||
"package-name": string;
|
||||
"output-folder": string;
|
||||
"generate-license-txt": boolean | undefined;
|
||||
"generate-package-json": boolean | undefined;
|
||||
"generate-readme-md": boolean | undefined;
|
||||
"generate-metadata": boolean | undefined;
|
||||
} | undefined;
|
||||
}
|
||||
|
||||
const repositoryName = "azure-rest-api-specs";
|
||||
const specificationsSegment = "specification";
|
||||
|
||||
const args = minimist(process.argv.slice(2), {
|
||||
string: [ "package", "type" ],
|
||||
string: ["package", "type"],
|
||||
boolean: ["debug", "verbose"],
|
||||
alias: {
|
||||
d: "debug",
|
||||
|
@ -28,7 +42,11 @@ const args = minimist(process.argv.slice(2), {
|
|||
}
|
||||
}) as CommandLineOptions;
|
||||
|
||||
const logger = new Logger(args);
|
||||
const _logger = new Logger(args);
|
||||
|
||||
if (!fs) {
|
||||
throw new Error("This script has to be run on Node.js 10.0+");
|
||||
}
|
||||
|
||||
function contains<T>(array: T[], el: T): boolean {
|
||||
return array.indexOf(el) != -1
|
||||
|
@ -47,9 +65,9 @@ async function exists(path: string): Promise<boolean> {
|
|||
});
|
||||
}
|
||||
|
||||
args.getSdkType = function() {
|
||||
const resourceManagerStrings = [ "arm", "rm", "resourcemanager" ]
|
||||
const dataPlaneStrings = [ "dp", "data", "dataplane" ]
|
||||
args.getSdkType = function () {
|
||||
const resourceManagerStrings = ["arm", "rm", "resourcemanager"]
|
||||
const dataPlaneStrings = ["dp", "data", "dataplane"]
|
||||
|
||||
const type = this.type.toLowerCase().replace("-", "");
|
||||
if (contains(resourceManagerStrings, type)) {
|
||||
|
@ -57,7 +75,7 @@ args.getSdkType = function() {
|
|||
} else if (contains(dataPlaneStrings, type)) {
|
||||
return SdkType.DataPlane;
|
||||
} else {
|
||||
throw new Error("Uknown SDK type");
|
||||
throw new Error("Unknown SDK type");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +119,7 @@ export async function findMissingSdks(azureRestApiSpecsRepository: string): Prom
|
|||
|
||||
for (const serviceDirectory of serviceSpecs) {
|
||||
const fullServicePath = path.resolve(specsDirectory, serviceDirectory);
|
||||
if (!(await !isDirectory(fullServicePath))) {
|
||||
if (!(await isDirectory(fullServicePath))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -122,16 +140,17 @@ export async function findMissingSdks(azureRestApiSpecsRepository: string): Prom
|
|||
} else if (readmeFiles.length == 1) {
|
||||
const readmeMdPath = readmeFiles[0];
|
||||
if (await doesReadmeMdFileSpecifiesTypescriptSdk(readmeMdPath)) {
|
||||
console.log(colors.red(fullSpecName))
|
||||
} else {
|
||||
console.log(colors.green(fullSpecName))
|
||||
missingSdks.push(fullSdkPath);
|
||||
_logger.logRed(`${fullSpecName}`);
|
||||
} else if (args.debug) {
|
||||
_logger.logGreen(fullSpecName);
|
||||
}
|
||||
} else if (contains(readmeFiles, "readme.nodejs.md")) {
|
||||
if (!contains(readmeFiles, "readme.typescript.md")) {
|
||||
missingSdks.push(fullSdkPath);
|
||||
console.log(colors.red(fullSpecName))
|
||||
_logger.logRed(`${fullSpecName}`);
|
||||
} else if (args.debug) {
|
||||
console.log(colors.green(fullSpecName))
|
||||
_logger.logGreen(fullSpecName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,16 +159,19 @@ export async function findMissingSdks(azureRestApiSpecsRepository: string): Prom
|
|||
return missingSdks;
|
||||
}
|
||||
|
||||
async function getYamlSection(buffer: Buffer, sectionBeginning: string, sectionEnd: string): Promise<Buffer> {
|
||||
const beginningIndex = buffer.indexOf(sectionBeginning);
|
||||
const trimmedBuffer = buffer.slice(beginningIndex + (sectionBeginning.length));
|
||||
|
||||
const endIndex = trimmedBuffer.indexOf(sectionEnd, 3);
|
||||
const sectionBuffer = trimmedBuffer.slice(0, endIndex);
|
||||
|
||||
return sectionBuffer;
|
||||
}
|
||||
|
||||
async function doesReadmeMdFileSpecifiesTypescriptSdk(readmeMdPath: string): Promise<boolean> {
|
||||
const readmeMdBuffer = await fs.readFile(readmeMdPath);
|
||||
const sectionBeginning = "``` yaml $(swagger-to-sdk)"
|
||||
const sectionEnd = "```"
|
||||
|
||||
const beginningIndex = readmeMdBuffer.indexOf(sectionBeginning);
|
||||
const trimmedBuffer = readmeMdBuffer.slice(beginningIndex);
|
||||
|
||||
const endIndex = trimmedBuffer.indexOf(sectionEnd);
|
||||
const sectionBuffer = trimmedBuffer.slice(0, endIndex);
|
||||
const sectionBuffer = await getYamlSection(readmeMdBuffer, "``` yaml $(swagger-to-sdk)", "```");
|
||||
|
||||
if (sectionBuffer.includes("azure-sdk-for-js")) {
|
||||
return true;
|
||||
|
@ -158,12 +180,12 @@ async function doesReadmeMdFileSpecifiesTypescriptSdk(readmeMdPath: string): Pro
|
|||
return false;
|
||||
}
|
||||
|
||||
export async function copyExistingNodeJsReadme(sdkPath: string): Promise<void> {
|
||||
export async function copyExistingNodeJsReadme(sdkPath: string): Promise<string> {
|
||||
const nodeJsReadmePath = path.resolve(sdkPath, "readme.nodejs.md");
|
||||
const typescriptReadmePath = path.resolve(sdkPath, "readme.typescript.md");
|
||||
|
||||
if (args.verbose) {
|
||||
console.log(`Copying ${nodeJsReadmePath} to ${typescriptReadmePath}`)
|
||||
_logger.log(`Copying ${nodeJsReadmePath} to ${typescriptReadmePath}`)
|
||||
}
|
||||
|
||||
if (await exists(typescriptReadmePath)) {
|
||||
|
@ -171,4 +193,64 @@ export async function copyExistingNodeJsReadme(sdkPath: string): Promise<void> {
|
|||
}
|
||||
|
||||
await fs.copyFile(nodeJsReadmePath, typescriptReadmePath);
|
||||
return typescriptReadmePath;
|
||||
}
|
||||
|
||||
async function updatePackageName(settings: readmeSettings): Promise<readmeSettings> {
|
||||
const packageName = settings.nodejs["package-name"]
|
||||
if (packageName.startsWith("arm") || !packageName.startsWith("azure-")) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
settings.nodejs["package-name"] = packageName.replace("azure-", "");
|
||||
return settings;
|
||||
}
|
||||
|
||||
async function updateMetadataFields(settings: readmeSettings): Promise<readmeSettings> {
|
||||
settings.nodejs["generate-metadata"] = true;
|
||||
delete settings.nodejs["generate-license-txt"]
|
||||
delete settings.nodejs["generate-package-json"]
|
||||
delete settings.nodejs["generate-readme-md"];
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
async function updateOutputFolder(settings: readmeSettings): Promise<readmeSettings> {
|
||||
settings.nodejs["output-folder"] = `$(typescript-sdks-folder)/packages/${settings.nodejs["package-name"]}`;
|
||||
return settings;
|
||||
}
|
||||
|
||||
async function updateYamlSection(sectionText: string): Promise<string> {
|
||||
const section = yaml.safeLoad(sectionText);
|
||||
await updatePackageName(section);
|
||||
await updateMetadataFields(section);
|
||||
await updateOutputFolder(section);
|
||||
section["typescript"] = section.nodejs;
|
||||
delete section.nodejs;
|
||||
|
||||
return yaml.safeDump(section).trim();
|
||||
}
|
||||
|
||||
export async function updateTypeScriptReadmeFile(typescriptReadmePath: string): Promise<string> {
|
||||
const readmeBuffer: Buffer = await fs.readFile(typescriptReadmePath);
|
||||
const readme: string = readmeBuffer.toString();
|
||||
let outputReadme = readme;
|
||||
|
||||
const yamlSection = await getYamlSection(readmeBuffer, "``` yaml $(nodejs)", "```");
|
||||
const sectionText = yamlSection.toString().trim();
|
||||
const updatedYamlSection = await updateYamlSection(sectionText);
|
||||
|
||||
outputReadme = outputReadme.replace(sectionText, updatedYamlSection);
|
||||
outputReadme = outputReadme.replace("azure-sdk-for-node", "azure-sdk-for-js");
|
||||
outputReadme = outputReadme.replace("Node.js", "TypeScript");
|
||||
outputReadme = outputReadme.replace("$(nodejs)", "$(typescript)");
|
||||
outputReadme = outputReadme.replace("nodejs", "typescript");
|
||||
outputReadme = outputReadme.replace("Node", "TypeScript");
|
||||
outputReadme = outputReadme.replace("node", "typescript");
|
||||
|
||||
return outputReadme;
|
||||
}
|
||||
|
||||
export async function saveContentToFile(filePath: string, content: string): Promise<void> {
|
||||
await fs.writeFile(filePath, content);
|
||||
}
|
|
@ -4,25 +4,49 @@
|
|||
* license information.
|
||||
*/
|
||||
|
||||
import * as colors from "colors";
|
||||
import { CommandLineOptions } from "./commandLineOptions";
|
||||
|
||||
export enum Color {
|
||||
Red,
|
||||
Green
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
private _colorsMap = {
|
||||
[Color.Red]: colors.red,
|
||||
[Color.Green]: colors.green
|
||||
}
|
||||
|
||||
constructor(private _options: CommandLineOptions) {
|
||||
}
|
||||
|
||||
log(text: string): void {
|
||||
console.log(text);
|
||||
log(text: string, color?: Color): void {
|
||||
if (color !== undefined) {
|
||||
const coloredText = this._colorsMap[color](text);
|
||||
console.log(coloredText);
|
||||
} else {
|
||||
console.log(text);
|
||||
}
|
||||
}
|
||||
|
||||
logVerbose(text: string): void {
|
||||
logRed(text: string): void {
|
||||
this.log(text, Color.Red)
|
||||
}
|
||||
|
||||
logGreen(text: string): void {
|
||||
this.log(text, Color.Green)
|
||||
}
|
||||
|
||||
logVerbose(text: string, color?: Color): void {
|
||||
if (this._options.verbose) {
|
||||
console.log(text);
|
||||
this.log(text, color);
|
||||
}
|
||||
}
|
||||
|
||||
logDebug(text: string): void {
|
||||
logDebug(text: string, color?: Color): void {
|
||||
if (this._options.debug) {
|
||||
console.log(text);
|
||||
this.log(text, color);
|
||||
}
|
||||
}
|
||||
}
|
14
gulpfile.ts
14
gulpfile.ts
|
@ -10,7 +10,7 @@ import * as glob from "glob";
|
|||
import * as gulp from "gulp";
|
||||
import * as path from "path";
|
||||
import { argv } from "yargs";
|
||||
import { findAzureRestApiSpecsRepository, findSdkDirectory, findMissingSdks, copyExistingNodeJsReadme } from "./.scripts/generate-sdks";
|
||||
import { findAzureRestApiSpecsRepository, findSdkDirectory, findMissingSdks, copyExistingNodeJsReadme, updateTypeScriptReadmeFile, saveContentToFile } from "./.scripts/generate-sdks";
|
||||
|
||||
const azureSDKForJSRepoRoot: string = __dirname;
|
||||
const azureRestAPISpecsRoot: string = argv['azure-rest-api-specs-root'] || path.resolve(azureSDKForJSRepoRoot, '..', 'azure-rest-api-specs');
|
||||
|
@ -269,14 +269,20 @@ gulp.task("generate-ts-readme", async () => {
|
|||
try {
|
||||
console.log(`Passed arguments: ${process.argv}`);
|
||||
|
||||
const azureRestApiSpecsRepository = await findAzureRestApiSpecsRepository();
|
||||
const azureRestApiSpecsRepository: string = await findAzureRestApiSpecsRepository();
|
||||
console.log(`Found azure-rest-api-specs repository in ${azureRestApiSpecsRepository}`);
|
||||
|
||||
const sdkPath = await findSdkDirectory(azureRestApiSpecsRepository);
|
||||
const sdkPath: string = await findSdkDirectory(azureRestApiSpecsRepository);
|
||||
console.log(`Found specification in ${sdkPath}`);
|
||||
|
||||
await copyExistingNodeJsReadme(sdkPath);
|
||||
const typescriptReadmePath: string = await copyExistingNodeJsReadme(sdkPath);
|
||||
console.log(`Copied readme file successfully`);
|
||||
|
||||
const newContent: string = await updateTypeScriptReadmeFile(typescriptReadmePath);
|
||||
console.log(`Generated content of the new readme file successfully`);
|
||||
|
||||
await saveContentToFile(typescriptReadmePath, newContent);
|
||||
console.log(`Content saved successfully to ${typescriptReadmePath}`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/colors": "^1.2.1",
|
||||
"@types/js-yaml": "^3.11.2",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/node": "^10.11.4",
|
||||
"colors": "^1.3.2",
|
||||
"fs": "0.0.1-security",
|
||||
"gulp": "^3.9.1",
|
||||
"js-yaml": "^3.12.0",
|
||||
"minimist": "^1.2.0",
|
||||
"path": "^0.12.7",
|
||||
"ts-node": "^7.0.1",
|
||||
|
|
Загрузка…
Ссылка в новой задаче