* stack trace crunching

* add azure-openapi-validator

* nail version

* artificial order

* make all external tools consume abs. URI

* make everything consume absolute URIs

* cleanup

* ai

* fixed that exit code

* slightly improved samples

* silence

* cleanup

* more cleanup

* reboust silence

* rem dependency
This commit is contained in:
Johannes Bader 2017-05-15 16:37:31 -07:00 коммит произвёл GitHub
Родитель f547506b80
Коммит a4603ff40f
57 изменённых файлов: 259 добавлений и 381 удалений

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

@ -14,7 +14,9 @@ input-file:
This time, we not only want to generate code, we also want to validate.
``` yaml
azure-arm: true # enables validation messages
azure-validator: true # Azure specific validation
model-validator: true # validation of examples against the API definition
semantic-validator: true # general semantic checks such as: Does the specified `default` value actually have the type specified for the corresponding field?
```
## Generation
@ -22,6 +24,7 @@ azure-arm: true # enables validation messages
Also generate for some languages.
``` yaml
azure-arm: true # generate code using Azure ARM flavor
csharp:
output-folder: CSharp
java:

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

@ -1 +1 @@
0
11

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

@ -12,7 +12,7 @@ input-file:
## Validation
``` yaml
azure-arm: true
azure-validator: true
```
## Suppression

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

@ -1 +1 @@
0
11

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

@ -1 +1 @@
0
7

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

@ -51,6 +51,20 @@ swagger-document/individual/azure-validator:
- azure-validator-individual
inputs:
- swagger-document/individual/transform
swagger-document/azure-openapi-validator:
pluginName: azure-openapi-validator
configScope:
- azure-validator-composed
inputs:
- swagger-document/transform
- swagger-document/azure-validator
swagger-document/individual/azure-openapi-validator:
pluginName: azure-openapi-validator
configScope:
- azure-validator-individual
inputs:
- swagger-document/individual/transform
- swagger-document/individual/azure-validator
csharp/modeler:
pluginName: modeler
configScope:

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

@ -1 +1 @@
0
11

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

@ -1 +1 @@
0
1

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

@ -1,10 +1,3 @@
Error occurred. Exiting.
{ Error: Error occurred. Exiting.
at ...
at ...
at ...
at ...
at ...
at ...
at ...
at ...

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

@ -1 +1 @@
0
1

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

@ -2,8 +2,3 @@ Process() Cancelled due to exception : Error occurred. Exiting.
Error occurred. Exiting.
{ Error: Error occurred. Exiting.
at ...
at ...
at ...
at ...
at ...
at ...

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

@ -2,7 +2,3 @@ Process() Cancelled due to exception : Error occurred. Exiting.
Error occurred. Exiting.
{ Error: Error occurred. Exiting.
at ...
at ...
at ...
at ...
at ...

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

@ -1,23 +1,7 @@
FATAL: System.ArgumentException: Reference path 'Cowball' does not exist in the definition section of the Swagger document.
at ...
at ...
at ...
at ...
at ...
at ...
at ...
at ...
at ...
at ...
at ...
--- End of stack trace from previous location where exception was thrown ---
at ...
at ...
at ...
at ...
FATAL: csharp/modeler - FAILED
Error: Plugin modeler reported failure.
at ...
at ...
at ...
at ...

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

@ -1 +1 @@
0
4

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

@ -456,7 +456,7 @@ async function main() {
// for relaxed profiling (assuming that no one calls `main` from electron... use AAAL!)
if (require("process").versions.electron) await new Promise(_ => { });
process.exit(0);
process.exit(exitcode);
} catch (e) {
if (e instanceof Exception) {
console.log(e.message);

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

@ -3,6 +3,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
require("./lib/polyfill.min.js");
export { IFileSystem } from "./lib/file-system"
export { Message, Channel } from "./lib/message"

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

@ -3,9 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from "path";
import { ResolveUri, GetFilenameWithoutExtension } from "./lib/ref/uri";
import { DataHandleRead, DataStoreViewReadonly } from "./lib/data-store/data-store";
import { DataStoreViewReadonly } from "./lib/data-store/data-store";
import { AutoRestConfigurationImpl } from "./lib/configuration";
const regexLegacyArg = /^-[^-]/;
@ -60,7 +59,7 @@ export async function CreateConfiguration(baseFolderUri: string, inputScope: Dat
const codegenerator = switches["g"] || switches["codegenerator"] || "CSharp";
const usedCodeGenerator = codegenerator.toLowerCase().replace("azure.", "").replace(".fluent", "");
if (codegenerator.toLowerCase() === "none") {
result["azure-validator"] = true;
(<any>result)["azure-validator"] = true;
} else {
(<any>result)[usedCodeGenerator] = {};
if (codegenerator.toLowerCase().startsWith("azure.")) {

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

@ -1,17 +1,17 @@
import { Stringify } from './ref/yaml';
import { RunPipeline } from './pipeline/pipeline';
import { SmartPosition, Position } from './ref/source-map';
import { DataStore, Metadata } from './data-store/data-store';
import { IEnumerable, From, Push } from './ref/linq';
import { IEvent, EventDispatcher, EventEmitter } from "./events";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RunPipeline } from "./pipeline/pipeline";
import { Push } from "./ref/linq";
import { IEvent, EventEmitter } from "./events";
import { IFileSystem } from "./file-system";
import { Configuration, ConfigurationView, MessageEmitter } from './configuration';
import { DocumentType } from "./document-type";
export { ConfigurationView } from './configuration';
import { Message, Channel } from './message';
import * as Constants from './constants';
import { Artifact } from './artifact';
import { Exception, OperationCanceledException } from './exception';
import { Configuration, ConfigurationView, MessageEmitter } from "./configuration";
export { ConfigurationView } from "./configuration";
import { Message, Channel } from "./message";
import * as Constants from "./constants";
import { Artifact } from "./artifact";
export class AutoRest extends EventEmitter {
private _configurations = new Array<any>();
@ -167,9 +167,14 @@ export class AutoRest extends EventEmitter {
}
if (view.InputFileUris.length === 0) {
throw new Exception("No input files provided.\n\nUse --help to get help information.", 0);
if (view.GetEntry("allow-no-input")) {
return true;
} else {
return new Error("No input files provided.\n\nUse --help to get help information.");
}
}
const result = await Promise.race([
await Promise.race([
RunPipeline(view, <IFileSystem>this.fileSystem),
new Promise((_, rej) => view.CancellationToken.onCancellationRequested(() => rej("Cancellation requested.")))]);
@ -178,8 +183,7 @@ export class AutoRest extends EventEmitter {
view.messageEmitter.removeAllListeners();
return true;
}
catch (e) {
} catch (e) {
if (e instanceof Error) {
/* if (!(e instanceof OperationCanceledException)) {
console.error(e.message);

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

@ -4,16 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import { BlameTree } from "./source-map/blaming";
import { Clone } from "./ref/yaml";
import { OperationAbortedException } from "./exception";
import { TryDecodeEnhancedPositionFromName } from "./source-map/source-map";
import { Suppressor } from "./pipeline/suppression";
import { matches, stringify } from "./ref/jsonpath";
import { MergeOverwriteOrAppend, resolveRValue, ShallowCopy } from "./source-map/merging";
import { stringify } from "./ref/jsonpath";
import { MergeOverwriteOrAppend, resolveRValue } from "./source-map/merging";
import { DataHandleRead, DataStore } from "./data-store/data-store";
import { EventEmitter, IEvent } from "./events";
import { CodeBlock, EvaluateGuard, ParseCodeBlocks } from "./parsing/literate-yaml";
import { CreateFolderUri, EnsureIsFolderUri, ReadUri, ResolveUri } from "./ref/uri";
import { EvaluateGuard, ParseCodeBlocks } from "./parsing/literate-yaml";
import { CreateFolderUri, EnsureIsFolderUri, ResolveUri } from "./ref/uri";
import { From } from "./ref/linq";
import { IFileSystem } from "./file-system";
import * as Constants from "./constants";
@ -25,6 +24,7 @@ const RESOLVE_MACROS_AT_RUNTIME = true;
export interface AutoRestConfigurationImpl {
__info?: string | null;
"allow-no-input"?: boolean;
"input-file": string[] | string;
"base-folder"?: string;
"directive"?: Directive[] | Directive;
@ -43,11 +43,8 @@ export interface AutoRestConfigurationImpl {
"client-side-validation"?: boolean; // C#
"fluent"?: boolean;
"azure-arm"?: boolean;
"azure-validator"?: boolean;
"model-validator"?: boolean;
"semantic-validator"?: boolean;
"override-info"?: any; // make sure source maps are pulling it! (see "composite swagger" method)
"namespace"?: string; // TODO: the modeler cares :( because it is badly designed
"namespace"?: string;
"license-header"?: string;
"add-credentials"?: boolean;
"package-name"?: string; // Ruby, Python, ...
@ -188,6 +185,7 @@ export class ConfigurationView {
}
// default values that are the least priority.
// TODO: why is this here and not in default-configuration?
this.rawConfig = MergeConfigurations(this.rawConfig, <any>{
"base-folder": ".",
"output-folder": "generated",
@ -275,7 +273,11 @@ export class ConfigurationView {
}
public GetEntry(key: keyof AutoRestConfigurationImpl): any {
return (this.config as any)[key];
let result = this.config as any;
for (const keyPart of key.split(".")) {
result = result[keyPart];
}
return result;
}
public get Raw(): AutoRestConfigurationImpl {
@ -293,12 +295,12 @@ export class ConfigurationView {
public * GetNestedConfiguration(pluginName: string): Iterable<ConfigurationView> {
for (const section of ValuesOf<any>((this.config as any)[pluginName])) {
if (section) {
yield this.GetPluginViewImmediate(section === true ? {} : section);
yield this.GetNestedConfigurationImmediate(section === true ? {} : section);
}
}
}
public GetPluginViewImmediate(...scope: any[]): ConfigurationView {
public GetNestedConfigurationImmediate(...scope: any[]): ConfigurationView {
return new ConfigurationView(this.messageEmitter, this.configFileFolderUri, ...scope, this.config).Indexer;
}

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

@ -1,9 +1,14 @@
import * as marked from 'marked'
import * as chalk from 'chalk'
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as moment from 'moment';
import * as marked from "marked";
import * as chalk from "chalk";
const markedTerminal = require('marked-terminal')
import * as moment from "moment";
const markedTerminal = require("marked-terminal");
marked.setOptions({
renderer: new markedTerminal({
@ -15,7 +20,7 @@ marked.setOptions({
blockquote: chalk.yellow,
tab: 2
})
})
});
export class Console {
public static quiet: boolean = false;

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

@ -1,3 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export const MagicString: string = "\n> see https://aka.ms/autorest";
export const DefaultConfiguratiion: string = "readme.md";

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

@ -6,13 +6,13 @@
import { LineIndices } from "../parsing/text-utility";
import { CancellationToken } from "../ref/cancallation";
import { Mappings, Mapping, SmartPosition, Position } from "../ref/source-map";
import { EnsureIsFolderUri, ReadUri, ResolveUri, WriteString } from '../ref/uri';
import { FastStringify, Parse, ParseNode, ParseToAst as parseAst, Stringify, YAMLNode } from '../ref/yaml';
import { EnsureIsFolderUri, ReadUri, ResolveUri, WriteString } from "../ref/uri";
import { FastStringify, ParseNode, ParseToAst as parseAst, YAMLNode } from "../ref/yaml";
import { From } from "linq-es2015";
import { RawSourceMap, SourceMapGenerator, SourceMapConsumer } from "source-map";
import { Compile, CompilePosition } from "../source-map/source-map";
import { BlameTree } from "../source-map/blaming";
import { Lazy, LazyPromise } from '../lazy';
import { Lazy } from "../lazy";
import { IFileSystem } from "../file-system";
import { OperationCanceledException } from "../exception";

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

@ -1,3 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export enum DocumentType {
Markdown = <any>"markdown",
Yaml = <any>"yaml",

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

@ -1,4 +1,9 @@
import * as events from 'events';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as events from "events";
export interface IEvent<TSender extends events.EventEmitter, TArgs> {
Subscribe(fn: (sender: TSender, args: TArgs) => void): () => void;

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

@ -1,3 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Exception extends Error {
constructor(message: string, public exitCode: number = 1) {
super(message);

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

@ -1,6 +1,10 @@
import { EnumerateFiles, ExistsUri } from './ref/uri';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnumerateFiles } from "./ref/uri";
import { From } from "./ref/linq";
import * as a from "./ref/async";
import { ResolveUri, ReadUri, WriteString } from "./ref/uri";
import * as Constants from "./constants";

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

@ -1,4 +1,9 @@
import { EnhancedPosition, Position, SmartPosition } from './ref/source-map';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnhancedPosition, Position } from "./ref/source-map";
export enum Channel {
Information = <any>"information",

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

@ -1,199 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Why not observables or on "data"&"end" pattern?
*
* - syntax support of MultiPromise
* - you can `await` to consume them
* - you can use `async` methods to create them
* - "data"&"end" pattern has drawbacks
* - on consumer side
* - single occurrence of "end" purely contractual and NOT guaranteed by type system! => pot. source of bugs
* - if all data is required for processing, it has to be collected manually (introduces mutable state)
* - on producer side
* - event subscription system requires mutable state (list of subscribers)
* - in general
* - can a consumer unsubscribe? how? (sounds like further state!)
* - can a consumer miss some events by subscribing "too late", i.e. after an event was fired?
* - if yes: induces management complexity (all pipeline steps have to be hooked up FULLY before starting any computation)
* - if no: so you have to buffer everything. even after "end" was fired, someone may subscribe...
* - in contrast, MultiPromise provides all that for free
* - immutable data structure, no explicit state
* - type system enforces order of events and single end of things
* - minimum amount of "past events" stored due to single linked list strucutre:
* - whoever holds a MultiPromise prevents garbage collection
* - consumption of an event effectively decrements ref-count on associated node
* - leverages error infrastrucure of Promise
* - easy to "marshal" from/to any other paradigm (events, streams, regular promises, ...)
*/
export type MultiPromiseItem<T> = { readonly current: T, readonly next: MultiPromise<T> };
export type MultiPromise<T> = Promise<MultiPromiseItem<T> | null>;
export module MultiPromiseUtility {
export function empty<T>(): MultiPromise<T> {
return Promise.resolve(null);
}
export async function list<T>(items: T[]): MultiPromise<T> {
let result: MultiPromise<T> = empty<T>();
for (const item of items.reverse()) {
result = Promise.resolve({
current: item,
next: result
});
}
return result;
}
export function single<T>(value: T): MultiPromise<T> {
return fromPromise<T>(Promise.resolve(value));
}
export function fromPromise<T>(promise: Promise<T>): MultiPromise<T> {
return new Promise<{ current: T, next: MultiPromise<T> }>((resolve, reject) => {
promise.then(value => resolve({ current: value, next: empty<T>() }));
promise.catch(err => reject(err));
});
}
export async function bind<T, U>(promise: MultiPromise<T>, f: (item: T) => MultiPromise<U>): MultiPromise<U> {
const node = await promise;
if (node === null) {
return null;
}
const sub = f(node.current);
return concatRace(sub, bind(node.next, f));
}
export function deferred<T>(promise: Promise<MultiPromise<T>>): MultiPromise<T> {
return bind(fromPromise(promise), x => x);
}
export async function toAsyncCallbacks<T>(promise: MultiPromise<T>, callback: (item: T) => Promise<void>): Promise<void> {
let res: MultiPromiseItem<T> | null;
while (res = await promise) {
await callback(res.current);
promise = res.next;
}
}
export function toCallbacks<T>(promise: MultiPromise<T>, callback: (item: T) => void): Promise<void> {
return toAsyncCallbacks(promise, async item => callback(item));
}
export function fromCallbacks<T>(executor: (callback: (item: T) => void) => Promise<void>): MultiPromise<T> {
let nextResolve: (item: MultiPromiseItem<T> | null) => void;
const end = () => { nextResolve(null); nextResolve = () => { }; };
const next = () => new Promise<MultiPromiseItem<T> | null>(res => nextResolve = res);
const result = next();
const worker = async () => {
await executor(item => {
nextResolve({
current: item,
next: next()
})
});
end();
};
process.nextTick(async () => {
try {
await worker();
} catch (e) {
console.error(`Error occurred in callback executor:`);
console.error(e);
end();
}
});
return result;
}
export async function gather<T>(promise: MultiPromise<T>): Promise<T[]> {
const result: T[] = [];
await toCallbacks(promise, item => result.push(item));
return result;
}
export async function getSingle<T>(promise: MultiPromise<T>): Promise<T> {
const result = await gather<T>(promise);
if (result.length !== 1) {
throw new Error(`Expected single item but got ${result.length}`);
}
return result[0];
}
export async function map<T, U>(promise: MultiPromise<T>, selector: (item: T, index: number) => Promise<U>, startIndex: number = 0): MultiPromise<U> {
const head = await promise;
if (head === null) {
return null;
}
const current = await selector(head.current, startIndex);
return {
current: current,
next: map(head.next, selector, startIndex + 1)
};
}
function race<T>(a: Promise<T>, b: Promise<T>): Promise<[T, Promise<T>]> {
return Promise.race([a.then(x => [x, b]), b.then(x => [x, a])]);
}
export async function concatRace<T>(a: MultiPromise<T>, b: MultiPromise<T>): MultiPromise<T> {
const [winner, loser] = await race(a, b);
if (winner === null) {
return loser;
}
return {
current: winner.current,
next: concatRace(winner.next, loser)
};
}
export function joinRace<T>(...promise: MultiPromise<T>[]): MultiPromise<T> {
return promise.reduce(concatRace, MultiPromiseUtility.empty<T>());
}
export async function concat<T>(a: MultiPromise<T>, b: MultiPromise<T>): MultiPromise<T> {
const head = await a;
if (head === null) {
return b;
}
return {
current: head.current,
next: concat(head.next, b)
};
}
export function join<T>(...promise: MultiPromise<T>[]): MultiPromise<T> {
return promise.reduce(concat, MultiPromiseUtility.empty<T>());
}
}
export class MultiPromiseBuilder<T> {
private resolve: (promise: MultiPromise<T>) => void;
private deferredPromise: MultiPromise<T>;
private sources: MultiPromise<T>[] | null = [];
public constructor() {
this.deferredPromise = MultiPromiseUtility.deferred(new Promise(resolve => this.resolve = resolve));
}
public get Promise(): MultiPromise<T> {
return this.deferredPromise;
}
public AddSource(promise: MultiPromise<T>): void {
if (!this.sources) {
throw new Error("Promise has already been built.");
}
this.sources.push(promise);
}
public Build(): void {
if (!this.sources) {
throw new Error("Promise has already been built.");
}
const sources = this.sources;
this.sources = null;
this.resolve(MultiPromiseUtility.joinRace(...sources));
}
}

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

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OutstandingTaskAlreadyCompletedException } from './exception';
import { OutstandingTaskAlreadyCompletedException } from "./exception";
export class OutstandingTaskAwaiter {
private locked: boolean = false;

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

@ -1,17 +1,16 @@
import { OperationAbortedException } from '../exception';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Descendants, Kind, CloneAst, YAMLMapping, newScalar, ParseNode } from "../ref/yaml";
import { MergeYamls, IdentitySourceMapping, resolveRValue } from "../source-map/merging";
import { Mapping } from "../ref/source-map";
import { OperationAbortedException } from "../exception";
import { ParseNode } from "../ref/yaml";
import { MergeYamls, resolveRValue } from "../source-map/merging";
import { DataHandleRead, DataHandleWrite, DataStoreView } from "../data-store/data-store";
import { Parse as ParseLiterate } from "./literate";
import { IndexToPosition, Lines } from "./text-utility";
import { IndexToPosition } from "./text-utility";
import { ConfigurationView } from "../autorest-core";
import { Channel, Message, SourceLocation, Range } from "../message";
import { Channel, SourceLocation } from "../message";
import { safeEval } from "../ref/safe-eval";
export class CodeBlock {

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

@ -1,9 +1,10 @@
import { DataHandleRead } from '../data-store/data-store';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DataHandleRead } from "../data-store/data-store";
const regexNewLine = /\r?\n/g;
export function LineIndices(text: string): number[] {

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

@ -61,7 +61,7 @@ export async function ProcessCodeModel(codeModel: DataHandleRead, scope: DataSto
const nodeOriginal = CloneAst(node);
const key = nodeOriginal.key.value;
const origKey = key + "_Original";
nodeOriginal.key.value = origKey
nodeOriginal.key.value = origKey;
parent.mappings.push(nodeOriginal);
mapping.push({
name: "original gfm",

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

@ -1,16 +1,16 @@
import { nodes } from '../ref/jsonpath';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nodes } from "../ref/jsonpath";
import { safeEval } from "../ref/safe-eval";
import { ManipulateObject } from "./object-manipulator";
import { DataHandleRead, DataStoreView } from "../data-store/data-store";
import { DirectiveView } from "../configuration";
import { ConfigurationView } from "../autorest-core";
import { From } from "../ref/linq";
import { Channel, Message, SourceLocation } from '../message';
import { Channel, Message, SourceLocation } from "../message";
export class Manipulator {
private transformations: DirectiveView[];
@ -80,7 +80,7 @@ export class Manipulator {
const doc = data.ReadObject<any>();
const allHits = nodes(doc, w);
for (const hit of allHits) {
let testResults = [...safeEval<any>(`(function* () { ${t.indexOf('yield') === -1 ? `yield (${t}\n)` : `${t}\n`} })()`, { $: hit.value, $doc: doc, $path: hit.path })];
let testResults = [...safeEval<any>(`(function* () { ${t.indexOf("yield") === -1 ? `yield (${t}\n)` : `${t}\n`} })()`, { $: hit.value, $doc: doc, $path: hit.path })];
for (const testResult of testResults) {
if (testResult === false || typeof testResult !== "boolean") {
const messageText = typeof testResult === "string" ? testResult : "Custom test failed";

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

@ -1,17 +1,16 @@
import { JsonPath, stringify } from '../ref/jsonpath';
import { safeEval } from '../ref/safe-eval';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { JsonPath, stringify } from "../ref/jsonpath";
import { safeEval } from "../ref/safe-eval";
import { LazyPromise } from "../lazy";
import { OutstandingTaskAwaiter } from "../outstanding-task-awaiter";
import { AutoRestPlugin } from "./plugin-endpoint";
import { Manipulator } from "./manipulation";
import { ProcessCodeModel } from "./commonmark-documentation";
import { Channel } from "../message";
import { MultiPromise } from "../multi-promise";
import { ResolveUri } from "../ref/uri";
import { ConfigurationView } from "../configuration";
import { DataHandleRead, DataStoreView, DataStoreViewReadonly, QuickScope } from "../data-store/data-store";
@ -20,9 +19,7 @@ import { ComposeSwaggers, LoadLiterateSwaggers, LoadLiterateSwaggerOverrides } f
import { IFileSystem } from "../file-system";
import { EmitArtifacts } from "./artifact-emitter";
export type DataPromise = MultiPromise<DataHandleRead>;
type PipelinePlugin = (config: ConfigurationView, input: DataStoreViewReadonly, working: DataStoreView, output: DataStoreView) => Promise<void>;
export type PipelinePlugin = (config: ConfigurationView, input: DataStoreViewReadonly, working: DataStoreView, output: DataStoreView) => Promise<void>;
interface PipelineNode {
outputArtifact?: string;
pluginName: string;
@ -63,8 +60,9 @@ function CreatePluginTransformer(): PipelinePlugin {
};
const manipulator = new Manipulator(config);
const files = await input.Enum();
for (const file of files) {
for (let file of files) {
const fileIn = await input.ReadStrict(file);
file = file.substr(file.indexOf("/output/") + "/output/".length);
const fileOut = await manipulator.Process(fileIn, working, documentIdResolver(file));
await (await output.Write("./" + file)).Forward(fileOut);
}
@ -78,7 +76,7 @@ function CreatePluginTransformerImmediate(): PipelinePlugin {
};
const files = await input.Enum(); // first all the immediate-configs, then a single swagger-document
const scopes = await Promise.all(files.slice(0, files.length - 1).map(f => input.ReadStrict(f)));
const manipulator = new Manipulator(config.GetPluginViewImmediate(...scopes.map(s => s.ReadObject<any>())));
const manipulator = new Manipulator(config.GetNestedConfigurationImmediate(...scopes.map(s => s.ReadObject<any>())));
const file = files[files.length - 1];
const fileIn = await input.ReadStrict(file);
const fileOut = await manipulator.Process(fileIn, working, documentIdResolver(file));
@ -94,7 +92,7 @@ function CreatePluginComposer(): PipelinePlugin {
await (await output.Write("composed")).Forward(swagger);
};
}
function CreatePluginExternal(host: PromiseLike<AutoRestPlugin>, pluginName: string, fullKeys: boolean = true): PipelinePlugin {
function CreatePluginExternal(host: PromiseLike<AutoRestPlugin>, pluginName: string): PipelinePlugin {
return async (config, input, working, output) => {
const plugin = await host;
const pluginNames = await plugin.GetPluginNames(config.CancellationToken);
@ -102,11 +100,6 @@ function CreatePluginExternal(host: PromiseLike<AutoRestPlugin>, pluginName: str
throw new Error(`Plugin ${pluginName} not found.`);
}
// forward input scope (relative/absolute key mess...)
if (fullKeys) {
input = new QuickScope(await Promise.all((await input.Enum()).map(x => input.ReadStrict(x))));
}
const result = await plugin.Process(
pluginName,
key => config.GetEntry(key as any),
@ -122,9 +115,10 @@ function CreatePluginExternal(host: PromiseLike<AutoRestPlugin>, pluginName: str
function CreateCommonmarkProcessor(): PipelinePlugin {
return async (config, input, working, output) => {
const files = await input.Enum();
for (const file of files) {
for (let file of files) {
const fileIn = await input.ReadStrict(file);
const fileOut = await ProcessCodeModel(fileIn, working);
file = file.substr(file.indexOf("/output/") + "/output/".length);
await (await output.Write("./" + file + "/_code-model-v1")).Forward(fileOut);
}
};
@ -250,6 +244,8 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
// externals:
const oavPluginHost = new LazyPromise(async () => await AutoRestPlugin.FromModule(`${__dirname}/plugins/openapi-validation-tools`));
const aiPluginHost = new LazyPromise(async () => await AutoRestPlugin.FromModule(`${__dirname}/../../node_modules/autorest-interactive`));
const aoavPluginHost = new LazyPromise(async () => await AutoRestPlugin.FromModule(`${__dirname}/../../node_modules/azure-openapi-validator`));
const autoRestDotNet = new LazyPromise(async () => await GetAutoRestDotNetPlugin());
// TODO: enhance with custom declared plugins
@ -262,6 +258,7 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
"model-validator": CreatePluginExternal(oavPluginHost, "model-validator"),
"semantic-validator": CreatePluginExternal(oavPluginHost, "semantic-validator"),
"azure-validator": CreatePluginExternal(autoRestDotNet, "azure-validator"),
"azure-openapi-validator": CreatePluginExternal(aoavPluginHost, "azure-openapi-validator"),
"modeler": CreatePluginExternal(autoRestDotNet, "modeler"),
"csharp": CreatePluginExternal(autoRestDotNet, "csharp"),
@ -272,11 +269,36 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
"java": CreatePluginExternal(autoRestDotNet, "java"),
"azureresourceschema": CreatePluginExternal(autoRestDotNet, "azureresourceschema"),
"jsonrpcclient": CreatePluginExternal(autoRestDotNet, "jsonrpcclient"),
"csharp-simplifier": CreatePluginExternal(autoRestDotNet, "csharp-simplifier", false),
"csharp-simplifier": CreatePluginExternal(autoRestDotNet, "csharp-simplifier"),
"commonmarker": CreateCommonmarkProcessor(),
"emitter": CreateArtifactEmitter(),
"pipeline-emitter": CreateArtifactEmitter(async () => new QuickScope([await (await configView.DataStore.Write("pipeline")).WriteObject(pipeline.pipeline)]))
"pipeline-emitter": CreateArtifactEmitter(async () => new QuickScope([await (await configView.DataStore.Write("pipeline")).WriteObject(pipeline.pipeline)])),
"autorest-interactive": async (
config: ConfigurationView,
input: DataStoreViewReadonly,
working: DataStoreView,
output: DataStoreView) => {
await CreatePluginExternal(aiPluginHost, "autorest-interactive")(
config.GetNestedConfigurationImmediate({
__status: new Proxy<any>({}, {
get(_, key) {
const expr = new Buffer(key.toString(), "base64").toString("ascii");
try {
return safeEval(expr, {
pipeline: pipeline.pipeline,
tasks: tasks
});
} catch (e) {
return "" + e;
}
}
})
}),
config.DataStore,
working,
output);
}
};
// TODO: think about adding "number of files in scope" kind of validation in between pipeline steps
@ -293,8 +315,7 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
let inputScopes: DataStoreViewReadonly[] = await Promise.all(node.inputs.map(getTask));
if (inputScopes.length === 0) {
inputScopes = [fsInput];
}
if (inputScopes.length > 1) {
} else {
const handles: DataHandleRead[] = [];
for (const pscope of inputScopes) {
const scope = await pscope;
@ -341,7 +362,12 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
// execute pipeline
const barrier = new OutstandingTaskAwaiter();
for (const name of Object.keys(pipeline.pipeline)) {
barrier.Await(getTask(name));
const task = getTask(name);
const taskx: { _state: "running" | "failed" | "complete" } = task as any;
taskx._state = "running";
task.catch(() => taskx._state = "failed");
task.then(() => taskx._state = "complete");
barrier.Await(task);
}
await barrier.Wait();
}

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

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { RequestType0, RequestType1, RequestType2 } from "../ref/jsonrpc";
import { NotificationType0, NotificationType1, NotificationType2, NotificationType3, NotificationType4 } from "../ref/jsonrpc";
import { NotificationType4 } from "../ref/jsonrpc";
import { Mapping, RawSourceMap, SmartPosition } from "../ref/source-map";
import { Message } from "../message";

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

@ -1,18 +1,17 @@
import { LazyPromise } from '../lazy';
import { EventEmitter, IEvent } from '../events';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MultiPromise, MultiPromiseUtility } from '../multi-promise';
import { LazyPromise } from "../lazy";
import { EventEmitter } from "../events";
import { fork, ChildProcess } from "child_process";
import { Mappings, Mapping, RawSourceMap, SmartPosition, Position } from "../ref/source-map";
import { Mappings, RawSourceMap, SmartPosition } from "../ref/source-map";
import { CancellationToken } from "../ref/cancallation";
import { createMessageConnection, MessageConnection } from "../ref/jsonrpc";
import { DataStoreViewReadonly, DataStoreView, DataHandleRead } from "../data-store/data-store";
import { DataStoreViewReadonly, DataStoreView } from "../data-store/data-store";
import { IAutoRestPluginInitiator_Types, IAutoRestPluginTarget_Types, IAutoRestPluginInitiator } from "./plugin-api";
import { Channel, Message } from "../message";
import { Message } from "../message";
interface IAutoRestPluginTargetEndpoint {
GetPluginNames(cancellationToken: CancellationToken): Promise<string[]>;
@ -48,7 +47,6 @@ export class AutoRestPlugin extends EventEmitter {
);
childProc.stderr.pipe(process.stderr);
const plugin = new AutoRestPlugin(channel);
channel.onClose(() => { throw "AutoRest plugin terminated."; });
channel.listen();
return plugin;
}
@ -83,13 +81,15 @@ export class AutoRestPlugin extends EventEmitter {
channel.onNotification(IAutoRestPluginInitiator_Types.WriteFile, this.apiInitiator.WriteFile);
channel.onNotification(IAutoRestPluginInitiator_Types.Message, this.apiInitiator.Message);
const terminationPromise = new Promise<never>((_, rej) => channel.onClose(() => { rej(new Error("AutoRest plugin terminated.")); }));
// target
this.apiTarget = {
async GetPluginNames(cancellationToken: CancellationToken): Promise<string[]> {
return await channel.sendRequest(IAutoRestPluginTarget_Types.GetPluginNames, cancellationToken);
return await Promise.race([terminationPromise, channel.sendRequest(IAutoRestPluginTarget_Types.GetPluginNames, cancellationToken)]);
},
async Process(pluginName: string, sessionId: string, cancellationToken: CancellationToken): Promise<boolean> {
return await channel.sendRequest(IAutoRestPluginTarget_Types.Process, pluginName, sessionId, cancellationToken);
return await Promise.race([terminationPromise, channel.sendRequest(IAutoRestPluginTarget_Types.Process, pluginName, sessionId, cancellationToken)]);
}
};
}
@ -121,8 +121,6 @@ export class AutoRestPlugin extends EventEmitter {
}
private static CreateEndpointFor(pluginName: string, configuration: (key: string) => any, inputScope: DataStoreViewReadonly, outputScope: DataStoreView, onMessage: (message: Message) => void, cancellationToken: CancellationToken): IAutoRestPluginInitiatorEndpoint {
let messageId: number = 0;
const inputFileNames = new LazyPromise(async () => inputScope.Enum());
const inputFileHandles = new LazyPromise(async () => {
const names = await inputFileNames;
@ -162,7 +160,7 @@ export class AutoRestPlugin extends EventEmitter {
await finishPrev;
notify();
},
async Message(message: Message, path?: SmartPosition, sourceFile?: string): Promise<void> {
async Message(message: Message): Promise<void> {
const finishPrev = finishNotifications;
let notify: () => void = () => { };
finishNotifications = new Promise<void>(res => notify = res);

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

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LazyPromise } from '../../lazy';
import { LazyPromise } from "../../lazy";
import { SpawnJsonRpcAutoRest } from "../../../interop/autorest-dotnet";
import { AutoRestPlugin } from "../plugin-endpoint";

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

@ -51,5 +51,5 @@ export class Suppressor {
return m;
}
// TODO: make method that'll complain about supressions that weren't used!
// TODO: make method that'll complain about suppressions that weren't used!
}

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

@ -1,23 +1,23 @@
import { Lines } from '../parsing/text-utility';
import {
CommonmarkHeadingFollowingText,
CommonmarkHeadingText,
CommonmarkSubHeadings,
ParseCommonmark
} from '../parsing/literate';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Channel, SourceLocation } from '../message';
import { Lines } from "../parsing/text-utility";
import {
CommonmarkHeadingFollowingText,
CommonmarkHeadingText,
CommonmarkSubHeadings,
ParseCommonmark
} from "../parsing/literate";
import { Channel, SourceLocation } from "../message";
import { OperationAbortedException } from "../exception";
import { safeEval } from "../ref/safe-eval";
import { ConfigurationView } from "../autorest-core";
import { DataStoreView, DataHandleRead, DataStoreViewReadonly } from "../data-store/data-store";
import { IsPrefix, JsonPath, JsonPathComponent, stringify } from "../ref/jsonpath";
import { ResolvePath, ResolveRelativeNode } from "../parsing/yaml";
import { Clone, CloneAst, Descendants, StringifyAst, ToAst, YAMLNodeWithPath } from '../ref/yaml';
import { Clone, CloneAst, Descendants, StringifyAst, ToAst, YAMLNodeWithPath } from "../ref/yaml";
import { ResolveUri } from "../ref/uri";
import { From } from "../ref/linq";
import { Mappings, Mapping } from "../ref/source-map";
@ -244,7 +244,7 @@ export async function LoadLiterateSwaggerOverride(config: ConfigurationView, inp
// replace queries
const candidProperties = ["name", "operationId", "$ref"];
clue = clue.replace(/\.\#(.+?)\b/g, (_, match) => `..[?(${candidProperties.map(p => `(@[${JSON.stringify(p)}] && @[${JSON.stringify(p)}].indexOf(${JSON.stringify(match)}) !== -1)`).join(' || ')})]`);
clue = clue.replace(/\.\#(.+?)\b/g, (_, match) => `..[?(${candidProperties.map(p => `(@[${JSON.stringify(p)}] && @[${JSON.stringify(p)}].indexOf(${JSON.stringify(match)}) !== -1)`).join(" || ")})]`);
// console.log(clue);
@ -277,7 +277,6 @@ export async function LoadLiterateSwagger(config: ConfigurationView, inputScope:
const data = await ParseLiterateYaml(config, await inputScope.ReadStrict(inputFileUri), workingScope.CreateScope("yaml"));
const externalFiles: { [uri: string]: DataHandleRead } = {};
externalFiles[inputFileUri] = data;
//WriteString(`file:///C:/output/${(<any>workingScope).name}_before.yaml`, await externalFiles[inputFileUri].ReadData());
await EnsureCompleteDefinitionIsPresent(config,
inputScope,
workingScope.CreateScope("ref-resolving"),
@ -287,7 +286,6 @@ export async function LoadLiterateSwagger(config: ConfigurationView, inputScope:
data.ReadObject<any>(),
IdentitySourceMapping(data.key, data.ReadYamlAst()));
const result = await StripExternalReferences(externalFiles[inputFileUri], workingScope.CreateScope("strip-ext-references"));
//WriteString(`file:///C:/output/${(<any>workingScope).name}_after.yaml`, await result.ReadData());
return result;
}

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

@ -1,3 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from "fs";
import * as path from "path";
import * as promisify from "pify";

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

@ -1,9 +1,9 @@
import { safeEval } from './safe-eval';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { safeEval } from "./safe-eval";
import * as jsonpath from "jsonpath";
// patch in smart filter expressions

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

@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Enumerable as IEnumerable } from "linq-es2015";
export { Enumerable, Enumerable as IEnumerable, From } from "linq-es2015";
export async function ToArray<T>(iterable: AsyncIterable<T>): Promise<Array<T>> {
@ -17,13 +17,12 @@ export function Push<T>(destination: Array<T>, source: any) {
if (source) {
if (IsIterable(source)) {
destination.push(...source);
}
else {
} else {
destination.push(source)
}
}
}
export function IsIterable(target: any) {
return target && target[Symbol.iterator] && typeof target !== 'string'
return target && target[Symbol.iterator] && typeof target !== "string";
}

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

@ -1,4 +1,3 @@
import { Range } from '../message';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.

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

@ -1,4 +1,3 @@
import { IndexToPosition } from '../parsing/text-utility';
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
@ -6,7 +5,6 @@ import { IndexToPosition } from '../parsing/text-utility';
import * as yamlAst from "yaml-ast-parser";
import { JsonPath } from "./jsonpath";
import { Message, SourceLocation, Channel } from '../message';
import { NewEmptyObject } from "../parsing/stable-object";
/**

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

@ -2,14 +2,13 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OutstandingTaskAwaiter } from "../outstanding-task-awaiter";
import { IndexToPosition } from "../parsing/text-utility";
import { ConfigurationView, MessageEmitter } from "../configuration";
import { Message, Channel } from "../message";
import { From } from "../ref/linq";
import { ConfigurationView } from "../configuration";
import { Channel } from "../message";
import { JsonPath, stringify } from "../ref/jsonpath";
import * as yaml from "../ref/yaml";
import { Mapping, Mappings } from "../ref/source-map";
import { Mappings } from "../ref/source-map";
import { DataHandleRead, DataHandleWrite } from "../data-store/data-store";
// // TODO: may want ASTy merge! (supporting circular structure and such?)

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

@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnhancedPosition, Mappings, Position, SmartPosition } from '../ref/source-map';
import { EnhancedPosition, Mappings, SmartPosition } from "../ref/source-map";
import { Descendants, ToAst } from "../ref/yaml";
import { JsonPath, parse, stringify } from '../ref/jsonpath';
import { JsonPath, stringify } from "../ref/jsonpath";
import * as yaml from "../parsing/yaml";
import { DataHandleRead } from "../data-store/data-store";

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

@ -43,6 +43,7 @@
"jsonpath": "^0.2.11",
"linq-es2015": "^2.4.13",
"oav": "0.4.1",
"azure-openapi-validator": "git+https://github.com/olydis/azure-openapi-validator.git#b45423f4560585e64f574bbffbb5cdf894cfbd53",
"pify": "^2.3.0",
"safe-eval": "^0.3.0",
"source-map": "^0.5.6",

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

@ -27,6 +27,14 @@ plugins:
pipeline:
pipeline-emitter: # emits the pipeline graph
scope: scope-pipeline-emitter
autorest-interactive:
scope: autorest-interactive
scope-pipeline-emitter:
input-artifact: pipeline
is-object: true
output-uri-expr: |
"pipeline"
```
#### Loading
@ -64,11 +72,6 @@ pipeline:
input: transform
scope: scope-swagger-document/emitter
scope-pipeline-emitter:
input-artifact: pipeline
is-object: true
output-uri-expr: |
"pipeline"
scope-swagger-document/emitter:
input-artifact: swagger-document
is-object: true
@ -100,12 +103,22 @@ pipeline:
``` yaml
pipeline:
# validator written in C#
swagger-document/azure-validator:
input: transform
scope: azure-validator-composed
swagger-document/individual/azure-validator:
input: individual/transform
scope: azure-validator-individual
# validator written in TypeScript
swagger-document/azure-openapi-validator:
input:
- transform
- azure-validator # artificial predecessor in order to ensure order of messages for CI purposes
swagger-document/individual/azure-openapi-validator:
input:
- transform
- azure-validator # artificial predecessor in order to ensure order of messages for CI purposes
```
Activate `azure-validator` when setting `azure-arm`!?

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

@ -15,7 +15,7 @@ import { parse } from "../lib/ref/jsonpath";
@suite class Blaming {
@test @timeout(30000) async "end to end blaming with literate swagger"() {
@test @timeout(0) async "end to end blaming with literate swagger"() {
const autoRest = new AutoRest(new RealFileSystem(), ResolveUri(CreateFolderUri(__dirname), "resources/literate-example/readme-composite.md"));
// PumpMessagesToConsole(autoRest);
const view = await autoRest.view;

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

@ -89,7 +89,7 @@ import { Message, Channel } from "../lib/message";
await pickyRun({ suppress: ["AvoidNestedProperties"], where: "$..properties.properties", from: "swagger.md" });
}
@test @timeout(60000) async "set descriptions on different levels"() {
@test @timeout(0) async "set descriptions on different levels"() {
const autoRest = new AutoRest(new RealFileSystem(), ResolveUri(CreateFolderUri(__dirname), "resources/literate-example/"));
const GenerateCodeModel = async (config: any) => {

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

@ -8,7 +8,7 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"sourceMap": true,
"strictNullChecks": true,
"strict": true,
"declaration": true,
"stripInternal": true,
"noEmitHelpers": true,

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

@ -123,8 +123,18 @@ class App {
// Remove bootstrapper args from cmdline
process.argv = From<string>(process.argv).Where(each => !RemoveArgs.Any(i => each === i || each.startsWith(`${i}=`) || each.startsWith(`${i}:`))).ToArray();
// use this to make the core aware that this run may be legal even without any inputs
// this is a valid scenario for "preparation calls" to autorest like `autorest --reset` or `autorest --latest`
const allowNoInput = () => {
// if there is *any* other argument left, that's an indicator that the core is supposed to do something
if (process.argv.length <= 2 /*expecting node and this script*/) {
process.argv.push("--allow-no-input");
}
};
if (this.reset) {
rm('-rf', Installer.RootFolder);
allowNoInput();
}
// check if we're up to date with the bootstrapper
@ -176,6 +186,9 @@ class App {
// or, grab the latest version
this.version = 'latest';
}
} else {
// a version was explicitly asked for => may just be a preparation call
allowNoInput();
}
// if necessary, go get the package we need.
@ -184,7 +197,7 @@ class App {
// find out the latest version
let releases = await this.GetReleases();
if (this.version == 'latest-release') {
if (this.version === 'latest-release') {
Console.Verbose('Requested "latest-release" version');
releases = releases.Where(each => each.prerelease == false);
} else {

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

@ -66,7 +66,7 @@ public class AzureValidator : NewPlugin
}
}
}
}, new object[0]);
});
}
protected override async Task<bool> ProcessInternal()

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

@ -1,16 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.Perks.JsonRPC;
using AutoRest.Core.Extensibility;
using AutoRest.Core;
using AutoRest.Core.Utilities;
using System;
using System.Text.RegularExpressions;
public class CSharpSimplifier : NewPlugin
{
private string codeGenerator;
static readonly Regex ExpectedUriPrefix = new Regex("^mem:///csharp/generate/([0-9]+/)?output/");
public CSharpSimplifier(Connection connection, string sessionId) : base(connection, sessionId)
{ }
@ -23,7 +22,11 @@ public class CSharpSimplifier : NewPlugin
var files = await ListInputs();
foreach (var file in files)
{
fs.WriteAllText(file, await ReadFile(file));
if (!ExpectedUriPrefix.IsMatch(file))
{
throw new FormatException($"Unexpected file URI format: '{file}'");
}
fs.WriteAllText(ExpectedUriPrefix.Replace(file, ""), await ReadFile(file));
}
// simplify

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

@ -46,7 +46,7 @@ public abstract class NewPlugin
public Task<string> GetValue(string key) => GetValue<string>(key);
public Task<string[]> ListInputs() => _connection.Request<string[]>("ListInputs", _sessionId);
public void Message(Message message, object sourcemap) => _connection.Notify("Message", _sessionId, message, sourcemap);
public void Message(Message message) => _connection.Notify("Message", _sessionId, message);
public void WriteFile(string filename, string content, object sourcemap) => _connection.Notify("WriteFile", _sessionId, filename, content, sourcemap);
protected string _sessionId;
@ -73,7 +73,7 @@ public abstract class NewPlugin
{
Channel = "fatal",
Text = e.ToString()
}, null);
});
return false;
}
}

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

@ -638,7 +638,8 @@ task 'regenerate-samples', '', (done) ->
.filter((file) -> file.match(/.(map|txt)$/))
.forEach((file) ->
sed "-i", /\bfile:\/\/[^\s]*\/autorest[^\/\\]*/g, "", file # blame locations
sed "-i", /\sat .*/g, "at ...", file # exception stack traces
sed "-i", /\sat .*/g, "at ...", file # exception stack traces
(cat file).replace(/(at \.\.\.\s*)+/g, "at ...\n").to(file) # minify exception stack traces
)
next null
, true # don't fail on failures (since we wanna record them)

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

@ -8,9 +8,9 @@ namespace AutoRest.Swagger.Validation.Core
[Flags]
public enum ValidationCategory
{
None = 1 << 0,
RPCViolation = 1 << 1,
OneAPIViolation = 1 << 2,
SDKViolation = 1 << 3
None = 0,
RPCViolation = 1 << 0,
OneAPIViolation = 1 << 1,
SDKViolation = 1 << 2
}
}