Skip to content
New issue

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

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

Already on GitHub? # to your account

Check for latest component versions #1165

Merged
merged 2 commits into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
781 changes: 326 additions & 455 deletions packages/linter/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/linter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@ampproject/toolbox-cache-list": "^2.8.0-canary.0",
"@ampproject/toolbox-cache-url": "^2.8.0-canary.5",
"@ampproject/toolbox-optimizer": "^2.8.0-canary.5",
"@ampproject/toolbox-validator-rules": "^2.8.0-canary.0",
"amphtml-validator": "1.0.34",
"chalk": "4.1.0",
"cheerio": "1.0.0-rc.5",
Expand Down
2 changes: 2 additions & 0 deletions packages/linter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { GoogleFontPreconnect } from "./rules/GoogleFontPreconnect";
import { BoilerplateIsRemoved } from "./rules/BoilerplateIsRemoved";
import { AmpImgUsesSrcSet } from "./rules/AmpImgUsesSrcSet";
import { ViewportDisablesTapDelay } from "./rules/ViewportDisablesTapDelay";
import { IsUsingLatestComponentVersion } from "./rules/IsUsingLatestComponentVersion";
import { RuleConstructor } from "./rule";
import { isArray } from "util";
import * as cheerio from "cheerio";
Expand Down Expand Up @@ -153,6 +154,7 @@ function testsForMode(type: LintMode) {
AmpImgUsesSrcSet,
AmpImgPlaceholderIsDataUri,
ViewportDisablesTapDelay,
IsUsingLatestComponentVersion,
])
);
return tests.get(type) || [];
Expand Down
43 changes: 43 additions & 0 deletions packages/linter/src/rules/IsUsingLatestComponentVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Context } from "../index";
import { Rule } from "../rule";
import validatorRules from "@ampproject/toolbox-validator-rules";

const COMPONENT_SRC_MATCHER = /\/v0\/([^.]+)-(\d+(?:\.\d+)*)\.m?js/;

export class IsUsingLatestComponentVersion extends Rule {
async run({ $ }: Context) {
const versionMap = {};
$("script[src]").each((i, script) => {
const match = COMPONENT_SRC_MATCHER.exec($(script).attr("src"));
if (match) {
versionMap[match[1]] = match[2];
}
});

const rules = await validatorRules.fetch();
const componentVersions = {};
rules.extensions.forEach((e) => {
const versions = e.version.filter((v) => v !== "latest");
if (e.htmlFormat.some((h) => h === "AMP")) {
componentVersions[e.name] = versions[versions.length - 1];
}
});

const isUsingLatestComponentVersion = Object.entries(versionMap).filter(
([name, version]) => {
return componentVersions[name] !== version;
}
);

return isUsingLatestComponentVersion.length === 0
? this.pass()
: this.warn("Use the latest version of components");
}
meta() {
return {
url: "",
title: "Outdated components are used",
info: "",
};
}
}
21 changes: 21 additions & 0 deletions packages/linter/tests/local.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { GoogleFontPreconnect } from "../src/rules/GoogleFontPreconnect";
import { BoilerplateIsRemoved } from "../src/rules/BoilerplateIsRemoved";
import { AmpImgUsesSrcSet } from "../src/rules/AmpImgUsesSrcSet";
import { ViewportDisablesTapDelay } from "../src/rules/ViewportDisablesTapDelay";
import { IsUsingLatestComponentVersion } from "../src/rules/IsUsingLatestComponentVersion";

describe(AmpImgAmpPixelPreferred.name, () => {
it(`${AmpImgAmpPixelPreferred.name} - <amp-img height="1" width="1">`, async () => {
Expand Down Expand Up @@ -695,3 +696,23 @@ describe(ViewportDisablesTapDelay.name, () => {
);
});
});

describe(IsUsingLatestComponentVersion.name, () => {
it(`${IsUsingLatestComponentVersion.name} - Page is using latest version of components`, async () => {
return assertPass(
runLocalTest(
IsUsingLatestComponentVersion,
`${__dirname}/local/IsUsingLatestComponentVersion-1/source.html`
)
);
});

it(`${IsUsingLatestComponentVersion.name} - Page is using old version of a component`, async () => {
return assertWarn(
runLocalTest(
IsUsingLatestComponentVersion,
`${__dirname}/local/IsUsingLatestComponentVersion-2/source.html`
)
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<link href="https://cdn.ampproject.org/v0.js" rel="preload" as="script">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Hello, AMPs</title>
<link rel="canonical" href="http://example.ampproject.org/article-metadata.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>
</style>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.2.js"></script>
</head>
<body>
<h1>Hello, AMP!</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<link href="https://cdn.ampproject.org/v0.js" rel="preload" as="script">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Hello, AMPs</title>
<link rel="canonical" href="http://example.ampproject.org/article-metadata.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>
</style>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
</head>
<body>
<h1>Hello, AMP!</h1>
</body>
</html>