Add finding missing SDKs and generate TS readme commands #2 (#30)

* 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:
Kamil Pajdzik 2018-10-04 14:30:26 -07:00 коммит произвёл GitHub
Родитель 28d7e6894a
Коммит 04bd3f4f70
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 147 добавлений и 33 удалений

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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",