Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding @promotion decorator and learnMoreDocs validation #287

Merged
merged 14 commits into from
Feb 22, 2024
Merged
2 changes: 1 addition & 1 deletion packages/typespec-azure-portal-core/lib/decorators.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extern dec browse(target: Model, options: BrowseOptions);
/**
* Provides a Model customizing deployment promotion apiVersion for ARM resource.
* The apiVersion will be used as a version to deploy to Portal.
* @param options Property options provides promotion information of the resourceType.
* @param options Property options provides promotion information of the resourceType.
*/
extern dec promotion(target: Model, options: PromotionOptions);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan to always take a single version or an array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only single version always :)


Expand Down
32 changes: 17 additions & 15 deletions packages/typespec-azure-portal-core/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
resolvePath,
validateDecoratorUniqueOnNode,
} from "@typespec/compiler";
import * as versioning from "@typespec/versioning";
yejee94 marked this conversation as resolved.
Show resolved Hide resolved
import { PortalCoreKeys, reportDiagnostic } from "./lib.js";
import { AboutOptions, BrowseOptions, PromotionOptions, marketplaceOfferOptions } from "./types.js";
import * as versioning from "@typespec/versioning";

/**
* This is a Browse decorator which will be use to put more info on the browse view.
Expand Down Expand Up @@ -75,8 +75,10 @@ export function $promotion(context: DecoratorContext, target: Model, options: Mo
if (autoUpdate) {
promotionResult.autoUpdate = true;
}
if(versions && versions[1] && versions[1].size > 0) {
const versionsList = (versions[1] as versioning.VersionMap).getVersions().map(version => version.value);
if (versions && versions[1] && versions[1].size > 0) {
const versionsList = (versions[1] as versioning.VersionMap)
.getVersions()
.map((version) => version.value);
if (!versionsList.includes(currentApiVersion)) {
reportDiagnostic(program, {
code: "invalid-apiversion",
Expand Down Expand Up @@ -118,7 +120,7 @@ export function checkIsValidApiVersion(program: Program, target: Model, version:
target,
});
return false;
};
}
return true;
}

Expand Down Expand Up @@ -230,18 +232,18 @@ export function $about(context: DecoratorContext, target: Model, options: Model)

function checkIsValidLinks(program: Program, target: Model, links: Type[]) {
let valid = true;
links.forEach(value => {
links.forEach((value) => {
const pattern = /^https:\/\//;
if (!(value as StringLiteral).value.match(pattern)) {
reportDiagnostic(program, {
code: "invalid-link",
format: {
link: (value as StringLiteral).value
},
target,
});
valid = false;
}
if (!(value as StringLiteral).value.match(pattern)) {
reportDiagnostic(program, {
code: "invalid-link",
format: {
link: (value as StringLiteral).value,
},
target,
});
valid = false;
}
});
return valid;
}
Expand Down
12 changes: 6 additions & 6 deletions packages/typespec-azure-portal-core/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,24 @@ export const $lib = createTypeSpecLibrary({
"invalid-apiversion": {
severity: "error",
messages: {
versionsList: paramMessage `@promotion apiVersion ${"version"} is not listed on ARM service API Version lists`,
serviceVersion: paramMessage `@promotion apiVersion ${"version"} is not same as the @service.version`,
promotionVersion: paramMessage `@promotion apiVersion ${"version"} is invalid, should be yyyy-mm-dd or yyyy-mm-dd-preview format`
versionsList: paramMessage`@promotion apiVersion ${"version"} is not listed on ARM service API Version lists`,
serviceVersion: paramMessage`@promotion apiVersion ${"version"} is not same as the @service.version`,
promotionVersion: paramMessage`@promotion apiVersion ${"version"} is invalid, should be yyyy-mm-dd or yyyy-mm-dd-preview format`,
},
},
"invalid-link": {
severity: "error",
messages: {
default: paramMessage `@about learnMoreDocs ${"link"} does not start with https://`,
default: paramMessage`@about learnMoreDocs ${"link"} does not start with https://`,
},
}
},
},
state: {
browse: { description: "State for the @browse decorator" },
about: { description: "State for the @about decorator" },
marketplaceOffer: { description: "State for the @marketplaceOffer decorator" },
displayName: { description: "State for the @displayName decorator" },
promotion: {description: "State for the @promotion decorator" },
promotion: { description: "State for the @promotion decorator" },
},
} as const);

Expand Down
49 changes: 33 additions & 16 deletions packages/typespec-azure-portal-core/test/decorators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,16 @@ describe("TypeSpec-Azure-Portal-Core decorators test", () => {
learnMoreDocs: ["www.azure.com", "www.portal.azure.com"],
})`;
const diagnostics = await runner.diagnose(createTestSpec(undefined, aboutTest));
expectDiagnostics(diagnostics, [{
code: "@azure-tools/typespec-azure-portal-core/invalid-link",
message: "@about learnMoreDocs www.azure.com does not start with https://",
},
{
code: "@azure-tools/typespec-azure-portal-core/invalid-link",
message: "@about learnMoreDocs www.portal.azure.com does not start with https://",
}]);
expectDiagnostics(diagnostics, [
{
code: "@azure-tools/typespec-azure-portal-core/invalid-link",
message: "@about learnMoreDocs www.azure.com does not start with https://",
},
{
code: "@azure-tools/typespec-azure-portal-core/invalid-link",
message: "@about learnMoreDocs www.portal.azure.com does not start with https://",
},
]);
});

it("@marketplaceOffer.id", async () => {
Expand All @@ -112,7 +114,9 @@ describe("TypeSpec-Azure-Portal-Core decorators test", () => {

it("@marketplaceOffer.id with space", async () => {
const marketplaceOffer = `@test @marketplaceOffer({id: "id space"})`;
const diagnostics = await runner.diagnose(createTestSpec(undefined, undefined, marketplaceOffer));
const diagnostics = await runner.diagnose(
createTestSpec(undefined, undefined, marketplaceOffer)
);
expectDiagnostics(diagnostics, {
code: "@azure-tools/typespec-azure-portal-core/invalid-offer-id",
message: "@marketplaceOffer id cannot have a blank space.",
Expand All @@ -121,15 +125,19 @@ describe("TypeSpec-Azure-Portal-Core decorators test", () => {

it("@promotion", async () => {
const promotion = `@test @promotion({apiVersion: "2024-02-20-preview"})`;
const { Foo } = await runner.compile(createTestSpec(undefined, undefined, undefined, promotion));
const { Foo } = await runner.compile(
createTestSpec(undefined, undefined, undefined, promotion)
);
const promotionOptions = getPromotion(runner.program, Foo);
strictEqual(promotionOptions.apiVersion, "2024-02-20-preview");
strictEqual(promotionOptions.autoUpdate, false);
});

it("@promotion with wrong apiVersion", async () => {
const promotion = `@test @promotion({apiVersion: "2024-02-20"})`;
const diagnostics = await runner.diagnose(createTestSpec(undefined, undefined, undefined, promotion));
const diagnostics = await runner.diagnose(
createTestSpec(undefined, undefined, undefined, promotion)
);
expectDiagnostics(diagnostics, {
code: "@azure-tools/typespec-azure-portal-core/invalid-apiversion",
message: "@promotion apiVersion 2024-02-20 is not listed on ARM service API Version lists",
Expand All @@ -138,10 +146,13 @@ describe("TypeSpec-Azure-Portal-Core decorators test", () => {

it("@promotion with incorrect apiVersion", async () => {
const promotion = `@test @promotion({apiVersion: "2023-01"})`;
const diagnostics = await runner.diagnose(createTestSpec(undefined, undefined, undefined, promotion));
const diagnostics = await runner.diagnose(
createTestSpec(undefined, undefined, undefined, promotion)
);
expectDiagnostics(diagnostics, {
code: "@azure-tools/typespec-azure-portal-core/invalid-apiversion",
message: "@promotion apiVersion 2023-01 is invalid, should be yyyy-mm-dd or yyyy-mm-dd-preview format",
message:
"@promotion apiVersion 2023-01 is invalid, should be yyyy-mm-dd or yyyy-mm-dd-preview format",
});
});

Expand All @@ -150,15 +161,21 @@ describe("TypeSpec-Azure-Portal-Core decorators test", () => {
apiVersion: Versions.v2024_02_20_preview,
autoUpdate: true
})`;
const { Foo } = await runner.compile(createTestSpec(undefined, undefined, undefined, promotion));
const { Foo } = await runner.compile(
createTestSpec(undefined, undefined, undefined, promotion)
);
const promotionOptions = getPromotion(runner.program, Foo);
strictEqual(promotionOptions.apiVersion, "2024-02-20-preview");
strictEqual(promotionOptions.autoUpdate, true);
});

});

export function createTestSpec(browseDec?: string, aboutDec?: string, marketplaceOffer?: string, promotion?: string) {
export function createTestSpec(
browseDec?: string,
aboutDec?: string,
marketplaceOffer?: string,
promotion?: string
) {
return `
@service({title: "Microsoft.Foo"})
@armProviderNamespace
Expand Down
Loading