Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@azure/avocado

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@azure/avocado - npm Package Compare versions

Comparing version 0.6.2 to 0.6.3

9

CHANGELOG.md
# Changelog
## 0.6.3
- Add rule MISSING_README to validate each RP folder must have readme.md.
- Modify unit test.
## 0.6.2
- Support $(this-folder)
## 0.6.1

@@ -4,0 +13,0 @@

3

dist/dev-ops.d.ts
import * as cli from './cli';
import * as err from './errors';
import * as asyncIt from '@ts-common/async-iterator';

@@ -44,2 +45,4 @@ export declare type FileChangeKind = 'Added' | 'Deleted' | 'Modified';

};
export declare const hasCommonRPFolder: (pathA: string, pathB: string) => boolean;
export declare const isPRRelatedError: (fileChanges: readonly FileChange[], error: err.Error) => boolean;
/**

@@ -46,0 +49,0 @@ * If the function is called in Azure DevOps CI for a Pull Request, it creates a

@@ -21,2 +21,14 @@ "use strict";

};
exports.hasCommonRPFolder = (pathA, pathB) => {
const regex = new RegExp(/specification\/(\w)+\//);
const matchA = pathA.match(regex);
const matchB = pathB.match(regex);
return matchA !== null && matchB !== null && matchA[0] === matchB[0];
};
exports.isPRRelatedError = (fileChanges, error) => {
if (error.code === 'MISSING_README') {
return fileChanges.some(item => exports.hasCommonRPFolder(item.path, error.folderUrl));
}
return false;
};
/**

@@ -23,0 +35,0 @@ * If the function is called in Azure DevOps CI for a Pull Request, it creates a

9

dist/errors.d.ts
import * as jsonParser from '@ts-common/json-parser';
declare type ErrorMessage = 'The example JSON file is not referenced from the swagger file.' | 'The swagger JSON file is not referenced from the readme file.' | 'The `readme.md` is not an AutoRest markdown file.' | 'The JSON file is not found but it is referenced from the readme file.' | 'The JSON file has a circular reference.' | 'The file is not a valid JSON file.';
declare type ErrorMessage = 'The example JSON file is not referenced from the swagger file.' | 'The swagger JSON file is not referenced from the readme file.' | 'The `readme.md` is not an AutoRest markdown file.' | 'The JSON file is not found but it is referenced from the readme file.' | 'The JSON file has a circular reference.' | 'The file is not a valid JSON file.' | 'Can not find readme.md in the folder. If no readme.md file, it will block SDK generation.';
export interface IErrorBase {

@@ -56,4 +56,9 @@ readonly level: 'Warning' | 'Error';

} & IErrorBase;
export declare type Error = JsonParseError | FileError | NotAutoRestMarkDown;
export declare type MissingReadmeError = {
readonly code: 'MISSING_README';
readonly message: ErrorMessage;
readonly folderUrl: string;
} & IErrorBase;
export declare type Error = JsonParseError | FileError | NotAutoRestMarkDown | MissingReadmeError;
export {};
//# sourceMappingURL=errors.d.ts.map

@@ -47,2 +47,8 @@ "use strict";

}
case 'MISSING_README': {
return {
code: error.code,
url: error.folderUrl,
};
}
}

@@ -114,3 +120,46 @@ };

const isExample = (filePath) => filePath.split(path.sep).some(name => name === 'examples');
const containsReadme = async (folder) => {
const readmePath = path.resolve(folder, 'readme.md');
return fs.exists(readmePath);
};
/**
* Validate each RP folder must have its readme file.
*
* @param specification specification folder
*/
const validateRPFolderMustContainReadme = (specification) => asyncIt.iterable(async function* () {
const validDirs = ['data-plane', 'resource-manager'];
const ignoredDirs = ['common'];
const allJsonDir = fs
.recursiveReaddir(specification)
.filter(filePath => path.extname(filePath) === '.json' &&
validDirs.some(item => filePath.includes(item) && !ignoredDirs.some(ignoredItem => filePath.toLowerCase().includes(ignoredItem))))
.map(filepath => path.dirname(filepath));
const allJsonSet = new Set();
for await (const dir of allJsonDir) {
if (allJsonSet.has(dir)) {
continue;
}
allJsonSet.add(dir);
// tslint:disable-next-line: no-let
let curDir = dir;
// tslint:disable-next-line: no-let
let found = false;
while (curDir !== specification) {
if (await containsReadme(curDir)) {
found = true;
}
curDir = path.dirname(curDir);
}
if (!found) {
yield {
level: 'Error',
code: 'MISSING_README',
message: 'Can not find readme.md in the folder. If no readme.md file, it will block SDK generation.',
folderUrl: dir,
};
}
}
});
/**
* The function will validate file reference as a directed graph and will detect circular reference.

@@ -254,2 +303,3 @@ * Detect circular reference in a directed graph using colors.

.filter(f => path.basename(f).toLowerCase() === 'readme.md');
yield* validateRPFolderMustContainReadme(specification);
yield* allReadMeFiles.flatMap(validateReadMeFile);

@@ -293,5 +343,11 @@ const referencedFiles = await allReadMeFiles

const sourceMap = await avocadoForDir(pr.workingDir);
const fileChanges = await pr.diff();
// remove existing errors.
/* Note: For MISSING_README error if the error is related to the PR changes,
avocado will directly report it even though it's not a new involved error in the pull request.*/
for (const e of targetMap.keys()) {
sourceMap.delete(e);
const error = sourceMap.get(e);
if (error !== undefined && !devOps.isPRRelatedError(fileChanges, error)) {
sourceMap.delete(e);
}
}

@@ -298,0 +354,0 @@ yield* sourceMap.values();

{
"name": "@azure/avocado",
"version": "0.6.2",
"version": "0.6.3",
"description": "A validator of OpenAPI configurations",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -22,2 +22,3 @@ # Avocado

- Validate whether `swagger file` has a circular reference and report a warning. For more detail, see [CIRCULAR REFERENCE](#circular-reference)
- Validate whether each RP folder contains readme file for SDK generation.

@@ -45,2 +46,32 @@ ## How to use

### JSON_PARSE
Level: ERROR
To solve json parse error, you need make sure the json format is valid.
### NO_JSON_FILE_FOUND
Level: ERROR
Readme file references a non-existing json file. To solve the error you need to check whether the json file is existing.
### UNREFERENCED_JSON_FILE
Level: ERROR
Json file must be referenced by the readme input file section or other json files. Eg, example swagger file should be referenced by main swagger json and for SDK generation main swagger should be referenced by the readme input file section. To solve the error you need to place the non-referenced file to proper place.
### MISSING_README
Level: ERROR
Each resource provider folder must have a readme file which is required by downstream SDK generation. To solve the error, you need create a readme file contains SDK generation config.
### NOT_AUTOREST_MARKDOWN
Level: ERROR
Each readme in resource provider folder should follow autorest markdown format. To solve the error, you need check the readme block quote whether contains `see https://aka.ms/autorest` literally.
### CIRCULAR REFERENCE

@@ -47,0 +78,0 @@

@@ -7,2 +7,3 @@ // Copyright (c) Microsoft Corporation. All rights reserved.

import * as path from 'path'
import * as err from './errors'
import * as fs from '@ts-common/fs'

@@ -73,2 +74,16 @@ import * as asyncIt from '@ts-common/async-iterator'

export const hasCommonRPFolder = (pathA: string, pathB: string) => {
const regex = new RegExp(/specification\/(\w)+\//)
const matchA = pathA.match(regex)
const matchB = pathB.match(regex)
return matchA !== null && matchB !== null && matchA[0] === matchB[0]
}
export const isPRRelatedError = (fileChanges: readonly FileChange[], error: err.Error): boolean => {
if (error.code === 'MISSING_README') {
return fileChanges.some(item => hasCommonRPFolder(item.path, error.folderUrl))
}
return false
}
/**

@@ -75,0 +90,0 @@ * If the function is called in Azure DevOps CI for a Pull Request, it creates a

@@ -13,2 +13,3 @@ // Copyright (c) Microsoft Corporation. All rights reserved.

| 'The file is not a valid JSON file.'
| 'Can not find readme.md in the folder. If no readme.md file, it will block SDK generation.'

@@ -72,2 +73,8 @@ export interface IErrorBase {

export type Error = JsonParseError | FileError | NotAutoRestMarkDown
export type MissingReadmeError = {
readonly code: 'MISSING_README'
readonly message: ErrorMessage
readonly folderUrl: string
} & IErrorBase
export type Error = JsonParseError | FileError | NotAutoRestMarkDown | MissingReadmeError

@@ -46,2 +46,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved.

}
case 'MISSING_README': {
return {
code: error.code,
url: error.folderUrl,
}
}
}

@@ -152,3 +158,56 @@ }

const containsReadme = async (folder: string): Promise<boolean> => {
const readmePath = path.resolve(folder, 'readme.md')
return fs.exists(readmePath)
}
/**
* Validate each RP folder must have its readme file.
*
* @param specification specification folder
*/
const validateRPFolderMustContainReadme = (specification: string): asyncIt.AsyncIterableEx<err.Error> =>
asyncIt.iterable<err.Error>(async function*() {
const validDirs: ReadonlyArray<string> = ['data-plane', 'resource-manager']
const ignoredDirs: ReadonlyArray<string> = ['common']
const allJsonDir = fs
.recursiveReaddir(specification)
.filter(
filePath =>
path.extname(filePath) === '.json' &&
validDirs.some(
item =>
filePath.includes(item) && !ignoredDirs.some(ignoredItem => filePath.toLowerCase().includes(ignoredItem)),
),
)
.map(filepath => path.dirname(filepath))
const allJsonSet = new Set<string>()
for await (const dir of allJsonDir) {
if (allJsonSet.has(dir)) {
continue
}
allJsonSet.add(dir)
// tslint:disable-next-line: no-let
let curDir = dir
// tslint:disable-next-line: no-let
let found = false
while (curDir !== specification) {
if (await containsReadme(curDir)) {
found = true
}
curDir = path.dirname(curDir)
}
if (!found) {
yield {
level: 'Error',
code: 'MISSING_README',
message: 'Can not find readme.md in the folder. If no readme.md file, it will block SDK generation.',
folderUrl: dir,
}
}
}
})
/**
* The function will validate file reference as a directed graph and will detect circular reference.

@@ -319,2 +378,4 @@ * Detect circular reference in a directed graph using colors.

yield* validateRPFolderMustContainReadme(specification)
yield* allReadMeFiles.flatMap(validateReadMeFile)

@@ -366,5 +427,12 @@

const fileChanges = await pr.diff()
// remove existing errors.
/* Note: For MISSING_README error if the error is related to the PR changes,
avocado will directly report it even though it's not a new involved error in the pull request.*/
for (const e of targetMap.keys()) {
sourceMap.delete(e)
const error = sourceMap.get(e)
if (error !== undefined && !devOps.isPRRelatedError(fileChanges, error)) {
sourceMap.delete(e)
}
}

@@ -371,0 +439,0 @@ yield* sourceMap.values()

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc