Skip to content

Commit 79c5a35

Browse files
committed
Check:links and insecure HTTP usage
1 parent 8099915 commit 79c5a35

16 files changed

Lines changed: 475 additions & 311 deletions

File tree

.devcontainer/ubuntu-24.04/.p10k.zsh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,7 +1399,7 @@
13991399

14001400
# Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext
14011401
# segment. Parameter expansions are very flexible and fast, too. See reference:
1402-
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
1402+
# https://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
14031403
#
14041404
# Within the expansion the following parameters are always available:
14051405
#
@@ -1618,7 +1618,7 @@
16181618

16191619
# Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by
16201620
# google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference:
1621-
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
1621+
# https://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
16221622
#
16231623
# You can use the following parameters in the expansion. Each of them corresponds to one of the
16241624
# fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The full license text of applicable licenses is provided below.
1717

1818
Apache License
1919
Version 2.0, January 2004
20-
http://www.apache.org/licenses/
20+
https://www.apache.org/licenses/
2121

2222
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
2323

LICENSE-Apache-2.0

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Apache License
22
Version 2.0, January 2004
3-
http://www.apache.org/licenses/
3+
https://www.apache.org/licenses/
44

55
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
66

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"scripts": {
4343
"preprepare": "npm run download:rpc-interface",
4444
"prepare": "concurrently npm:download:uv2csolution npm:download:debug-adapters npm:download:toolbox",
45-
"clean": "git clean -f -x ./dist ./out ./tools",
45+
"clean": "git clean -f -x ./dist ./out ./tools ./coverage ./e2e-report ./e2e-screenshots ./test-results",
4646
"prebuild": "npm run font",
4747
"build": "webpack --mode production",
4848
"prewatch": "npm run font",
@@ -68,7 +68,8 @@
6868
"font": "fantasticon",
6969
"lint:md": "markdownlint **/*.md -c ./.github/markdownlint.jsonc -i ./node_modules -i ./dist -i ./coverage -i ./tools -i ./test-data -i ./src/e2e-tests/data -i CHANGELOG.md",
7070
"copyright:check": "tsx scripts/copyright-manager.ts --mode=check",
71-
"copyright:fix": "tsx scripts/copyright-manager.ts --mode=fix"
71+
"copyright:fix": "tsx scripts/copyright-manager.ts --mode=fix",
72+
"check:links": "tsx scripts/check-links.ts -i ./node_modules/** -i ./.github/** -c ./.github/markdown-link-check.jsonc"
7273
},
7374
"dependencies": {
7475
"@ant-design/icons": "^5.6.1",

scripts/check-links.ts

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!npx tsx
2+
3+
/**
4+
* Copyright 2026 Arm Limited
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import { execFile as execFileCallback } from "child_process";
20+
import { readFile as readFileCallback } from "fs";
21+
import { glob } from "glob";
22+
import { resolve } from "path";
23+
import { promisify } from "util";
24+
import yargs from "yargs";
25+
import { hideBin } from "yargs/helpers";
26+
27+
const execFile = promisify(execFileCallback);
28+
const readFile = promisify(readFileCallback);
29+
30+
31+
async function getChangedFiles(): Promise<string[]> {
32+
const changedFiles = new Set<string>();
33+
34+
const unstaged = await execFile("git", [
35+
"diff",
36+
"--name-only",
37+
"--diff-filter=ACMR"
38+
]);
39+
unstaged.stdout
40+
.split(/\r?\n/)
41+
.map((f) => f.trim())
42+
.filter(Boolean)
43+
.forEach((f) => changedFiles.add(f));
44+
45+
const staged = await execFile("git", [
46+
"diff",
47+
"--name-only",
48+
"--diff-filter=ACMR",
49+
"--cached"
50+
]);
51+
staged.stdout
52+
.split(/\r?\n/)
53+
.map((f) => f.trim())
54+
.filter(Boolean)
55+
.forEach((f) => changedFiles.add(f));
56+
57+
// Explicitly include newly added files from the index.
58+
const stagedAdded = await execFile("git", [
59+
"diff",
60+
"--name-only",
61+
"--diff-filter=A",
62+
"--cached"
63+
]);
64+
stagedAdded.stdout
65+
.split(/\r?\n/)
66+
.map((f) => f.trim())
67+
.filter(Boolean)
68+
.forEach((f) => changedFiles.add(f));
69+
70+
return Array.from(changedFiles);
71+
}
72+
73+
async function checkForInsecureUrls(files: string[]): Promise<void> {
74+
const insecurePattern = /http:\/\//;
75+
76+
for (const file of files) {
77+
try {
78+
const content = await readFile(file, "utf8");
79+
80+
// Skip likely binary files.
81+
if (content.includes("\0")) {
82+
continue;
83+
}
84+
85+
const lines = content.split(/\r?\n/);
86+
for (let i = 0; i < lines.length; i++) {
87+
if (!insecurePattern.test(lines[i])) {
88+
continue;
89+
}
90+
91+
console.error(`Insecure URL found in ${file}:${i + 1}`);
92+
console.error(` ${lines[i].trim()}`);
93+
process.exitCode = 1;
94+
}
95+
} catch {
96+
// Ignore unreadable/non-text files.
97+
}
98+
}
99+
}
100+
101+
async function main() {
102+
const argv = yargs(hideBin(process.argv))
103+
.option("config", {
104+
alias: "c",
105+
type: "string",
106+
description: "Path to markdown-link-check config file",
107+
default: ".github/markdown-link-check.jsonc",
108+
})
109+
.option("ignore", {
110+
alias: "i",
111+
type: "array",
112+
description: "Directories to ignore",
113+
default: ["node_modules/**"],
114+
})
115+
.option("checkHttp", {
116+
type: "boolean",
117+
description: "Scan changed files for insecure http URLs",
118+
default: true,
119+
})
120+
.help()
121+
.alias("help", "h")
122+
.parseSync();
123+
124+
const configPath = resolve(argv.config);
125+
const mdFiles = await glob("**/*.md", {
126+
ignore: argv.ignore as string[],
127+
});
128+
129+
if (mdFiles.length === 0) {
130+
console.log("No markdown files found.");
131+
} else {
132+
console.log(`Checking ${mdFiles.length} markdown file(s)...`);
133+
for (const file of mdFiles) {
134+
try {
135+
const { stdout } = await execFile(
136+
"npx", ["markdown-link-check", "-v", "-c", configPath, file], { shell: true }
137+
);
138+
console.log(stdout);
139+
} catch (err: any) {
140+
console.error(`Error in file: ${file}`);
141+
console.error(err.stdout || err.message);
142+
process.exitCode = 1;
143+
}
144+
}
145+
}
146+
147+
if (argv.checkHttp) {
148+
const changedFiles = await getChangedFiles();
149+
150+
if (changedFiles.length === 0) {
151+
console.log("No changed files found for insecure URL check.");
152+
return;
153+
}
154+
155+
console.log(`Checking ${changedFiles.length} changed file(s) for insecure URLs...`);
156+
await checkForInsecureUrls(changedFiles);
157+
}
158+
}
159+
160+
main().catch((error) => {
161+
console.error(error);
162+
process.exit(1);
163+
});

0 commit comments

Comments
 (0)