Skip to content

Commit

Permalink
Merge branch 'dklimpel-load_directories'
Browse files Browse the repository at this point in the history
  • Loading branch information
tcort committed Nov 5, 2024
2 parents d678dc0 + df57571 commit faa2d23
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 31 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ linkchecker:
name: ghcr.io/tcort/markdown-link-check:3.11.2
entrypoint: ["/bin/sh", "-c"]
script:
- find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
- markdown-link-check ./docs
rules:
- changes:
- "**/*.md"
Expand Down Expand Up @@ -169,19 +169,22 @@ markdown-link-check ./README.md

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

Avoid using `find -exec` because it will swallow the error from each consecutive run.
Instead, use `xargs`:
This checks all files in folder `./docs` with file extension `*.md`:

```shell
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
markdown-link-check ./docs
```

There is an [open issue](https://github.com/tcort/markdown-link-check/issues/78) for allowing the tool to specify
multiple files on the command line.
The files can also be searched for and filtered manually:

```shell
find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check
```

#### Usage

```shell
Usage: markdown-link-check [options] [filenameOrUrl]
Usage: markdown-link-check [options] [filenameOrDirectorynameOrUrl]
Options:
-p, --progress show progress bar
Expand Down
72 changes: 48 additions & 24 deletions markdown-link-check
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ function commaSeparatedCodesList(value, dummyPrevious) {
});
}

/**
* Load all files in the rootFolder and all subfolders that end with .md
*/
function loadAllMarkdownFiles(rootFolder = '.') {
const files = [];
fs.readdirSync(rootFolder).forEach(file => {
const fullPath = path.join(rootFolder, file);
if (fs.lstatSync(fullPath).isDirectory()) {
files.push(...loadAllMarkdownFiles(fullPath));
} else if (fullPath.endsWith('.md')) {
files.push(fullPath);
}
});
return files;
}

function commaSeparatedReportersList(value) {
return value.split(',').map((reporter) => require(path.resolve('reporters', reporter)));
}
Expand All @@ -44,12 +60,12 @@ function getInputs() {
.option('-c, --config [config]', 'apply a config file (JSON), holding e.g. url specific header configuration')
.option('-q, --quiet', 'displays errors only')
.option('-v, --verbose', 'displays detailed error information')
.option('-i --ignore <paths>', 'ignore input paths including an ignore path', commaSeparatedPathsList)
.option('-i, --ignore <paths>', 'ignore input paths including an ignore path', commaSeparatedPathsList)
.option('-a, --alive <code>', 'comma separated list of HTTP codes to be considered as alive', commaSeparatedCodesList)
.option('-r, --retry', 'retry after the duration indicated in \'retry-after\' header when HTTP code is 429')
.option('--reporters <names>', 'specify reporters to use', commaSeparatedReportersList)
.option('--projectBaseUrl <url>', 'the URL to use for {{BASEURL}} replacement')
.arguments('[filenamesOrUrls...]')
.arguments('[filenamesOrDirectorynamesOrUrls...]')
.action(function (filenamesOrUrls) {
let filenameForOutput;
let stream;
Expand All @@ -75,6 +91,7 @@ function getInputs() {
for (const filenameOrUrl of filenamesOrUrls) {
filenameForOutput = filenameOrUrl;
let baseUrl = '';
// remote file
if (/https?:/.test(filenameOrUrl)) {
stream = needle.get(
filenameOrUrl, { agent: new ProxyAgent(), use_proxy_from_env_var: false }
Expand All @@ -86,37 +103,44 @@ function getInputs() {
parsed.search = '';
parsed.hash = '';
if (parsed.pathname.lastIndexOf('/') !== -1) {
parsed.pathname = parsed.pathname.substr(0, parsed.pathname.lastIndexOf('/') + 1);
parsed.pathname = parsed.pathname.substring(0, parsed.pathname.lastIndexOf('/') + 1);
}
baseUrl = parsed.toString();
} catch (err) { /* ignore error */
}
inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
} catch (err) {
/* ignore error */
}
} else {
const stats = fs.statSync(filenameOrUrl);
if (stats.isDirectory()){
console.error(chalk.red('\nERROR: ' + filenameOrUrl + ' is a directory! Please provide a valid filename as an argument.'));
process.exit(1);
// local file or directory
let files = [];

if (fs.statSync(filenameOrUrl).isDirectory()){
files = loadAllMarkdownFiles(filenameOrUrl)
} else {
files = [filenameOrUrl]
}

const resolved = path.resolve(filenameOrUrl);
for (let file of files) {
filenameForOutput = file;
const resolved = path.resolve(filenameForOutput);

// skip paths given if it includes a path to ignore.
// todo: allow ignore paths to be glob or regex instead of just includes?
if (ignore && ignore.some((ignorePath) => resolved.includes(ignorePath))) {
continue;
}
// skip paths given if it includes a path to ignore.
// todo: allow ignore paths to be glob or regex instead of just includes?
if (ignore && ignore.some((ignorePath) => resolved.includes(ignorePath))) {
continue;
}

if (process.platform === 'win32') {
baseUrl = 'file://' + path.dirname(resolved).replace(/\\/g, '/');
}
else {
baseUrl = 'file://' + path.dirname(resolved);
}
if (process.platform === 'win32') {
baseUrl = 'file://' + path.dirname(resolved).replace(/\\/g, '/');
}
else {
baseUrl = 'file://' + path.dirname(resolved);
}

stream = fs.createReadStream(filenameOrUrl);
stream = fs.createReadStream(filenameForOutput);
inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
}
}

inputs.push(new Input(filenameForOutput, stream, {baseUrl: baseUrl}));
}
}
).parse(process.argv);
Expand Down

0 comments on commit faa2d23

Please sign in to comment.