Skip to content

Commit faa2d23

Browse files
committed
Merge branch 'dklimpel-load_directories'
2 parents d678dc0 + df57571 commit faa2d23

File tree

2 files changed

+58
-31
lines changed

2 files changed

+58
-31
lines changed

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ linkchecker:
5959
name: ghcr.io/tcort/markdown-link-check:3.11.2
6060
entrypoint: ["/bin/sh", "-c"]
6161
script:
62-
- find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
62+
- markdown-link-check ./docs
6363
rules:
6464
- changes:
6565
- "**/*.md"
@@ -169,19 +169,22 @@ markdown-link-check ./README.md
169169

170170
#### Check links from a local markdown folder (recursive)
171171

172-
Avoid using `find -exec` because it will swallow the error from each consecutive run.
173-
Instead, use `xargs`:
172+
This checks all files in folder `./docs` with file extension `*.md`:
173+
174174
```shell
175-
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
175+
markdown-link-check ./docs
176176
```
177177

178-
There is an [open issue](https://github.com/tcort/markdown-link-check/issues/78) for allowing the tool to specify
179-
multiple files on the command line.
178+
The files can also be searched for and filtered manually:
179+
180+
```shell
181+
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
182+
```
180183

181184
#### Usage
182185

183186
```shell
184-
Usage: markdown-link-check [options] [filenameOrUrl]
187+
Usage: markdown-link-check [options] [filenameOrDirectorynameOrUrl]
185188
186189
Options:
187190
-p, --progress show progress bar

markdown-link-check

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ function commaSeparatedCodesList(value, dummyPrevious) {
3131
});
3232
}
3333

34+
/**
35+
* Load all files in the rootFolder and all subfolders that end with .md
36+
*/
37+
function loadAllMarkdownFiles(rootFolder = '.') {
38+
const files = [];
39+
fs.readdirSync(rootFolder).forEach(file => {
40+
const fullPath = path.join(rootFolder, file);
41+
if (fs.lstatSync(fullPath).isDirectory()) {
42+
files.push(...loadAllMarkdownFiles(fullPath));
43+
} else if (fullPath.endsWith('.md')) {
44+
files.push(fullPath);
45+
}
46+
});
47+
return files;
48+
}
49+
3450
function commaSeparatedReportersList(value) {
3551
return value.split(',').map((reporter) => require(path.resolve('reporters', reporter)));
3652
}
@@ -44,12 +60,12 @@ function getInputs() {
4460
.option('-c, --config [config]', 'apply a config file (JSON), holding e.g. url specific header configuration')
4561
.option('-q, --quiet', 'displays errors only')
4662
.option('-v, --verbose', 'displays detailed error information')
47-
.option('-i --ignore <paths>', 'ignore input paths including an ignore path', commaSeparatedPathsList)
63+
.option('-i, --ignore <paths>', 'ignore input paths including an ignore path', commaSeparatedPathsList)
4864
.option('-a, --alive <code>', 'comma separated list of HTTP codes to be considered as alive', commaSeparatedCodesList)
4965
.option('-r, --retry', 'retry after the duration indicated in \'retry-after\' header when HTTP code is 429')
5066
.option('--reporters <names>', 'specify reporters to use', commaSeparatedReportersList)
5167
.option('--projectBaseUrl <url>', 'the URL to use for {{BASEURL}} replacement')
52-
.arguments('[filenamesOrUrls...]')
68+
.arguments('[filenamesOrDirectorynamesOrUrls...]')
5369
.action(function (filenamesOrUrls) {
5470
let filenameForOutput;
5571
let stream;
@@ -75,6 +91,7 @@ function getInputs() {
7591
for (const filenameOrUrl of filenamesOrUrls) {
7692
filenameForOutput = filenameOrUrl;
7793
let baseUrl = '';
94+
// remote file
7895
if (/https?:/.test(filenameOrUrl)) {
7996
stream = needle.get(
8097
filenameOrUrl, { agent: new ProxyAgent(), use_proxy_from_env_var: false }
@@ -86,37 +103,44 @@ function getInputs() {
86103
parsed.search = '';
87104
parsed.hash = '';
88105
if (parsed.pathname.lastIndexOf('/') !== -1) {
89-
parsed.pathname = parsed.pathname.substr(0, parsed.pathname.lastIndexOf('/') + 1);
106+
parsed.pathname = parsed.pathname.substring(0, parsed.pathname.lastIndexOf('/') + 1);
90107
}
91108
baseUrl = parsed.toString();
92-
} catch (err) { /* ignore error */
93-
}
109+
inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
110+
} catch (err) {
111+
/* ignore error */
112+
}
94113
} else {
95-
const stats = fs.statSync(filenameOrUrl);
96-
if (stats.isDirectory()){
97-
console.error(chalk.red('\nERROR: ' + filenameOrUrl + ' is a directory! Please provide a valid filename as an argument.'));
98-
process.exit(1);
114+
// local file or directory
115+
let files = [];
116+
117+
if (fs.statSync(filenameOrUrl).isDirectory()){
118+
files = loadAllMarkdownFiles(filenameOrUrl)
119+
} else {
120+
files = [filenameOrUrl]
99121
}
100122

101-
const resolved = path.resolve(filenameOrUrl);
123+
for (let file of files) {
124+
filenameForOutput = file;
125+
const resolved = path.resolve(filenameForOutput);
102126

103-
// skip paths given if it includes a path to ignore.
104-
// todo: allow ignore paths to be glob or regex instead of just includes?
105-
if (ignore && ignore.some((ignorePath) => resolved.includes(ignorePath))) {
106-
continue;
107-
}
127+
// skip paths given if it includes a path to ignore.
128+
// todo: allow ignore paths to be glob or regex instead of just includes?
129+
if (ignore && ignore.some((ignorePath) => resolved.includes(ignorePath))) {
130+
continue;
131+
}
108132

109-
if (process.platform === 'win32') {
110-
baseUrl = 'file://' + path.dirname(resolved).replace(/\\/g, '/');
111-
}
112-
else {
113-
baseUrl = 'file://' + path.dirname(resolved);
114-
}
133+
if (process.platform === 'win32') {
134+
baseUrl = 'file://' + path.dirname(resolved).replace(/\\/g, '/');
135+
}
136+
else {
137+
baseUrl = 'file://' + path.dirname(resolved);
138+
}
115139

116-
stream = fs.createReadStream(filenameOrUrl);
140+
stream = fs.createReadStream(filenameForOutput);
141+
inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
142+
}
117143
}
118-
119-
inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
120144
}
121145
}
122146
).parse(process.argv);

0 commit comments

Comments
 (0)