Create link-checker.roc (#7747)

* Create link-checker.roc

Create markdown link checker for glossary.md

Signed-off-by: Magdielian-code <oziomaagaecheta81@gmail.com>

* CI check + finishing touches

* improvements + test failure

* test succeeded

---------

Signed-off-by: Magdielian-code <oziomaagaecheta81@gmail.com>
Co-authored-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
This commit is contained in:
Magdielian-code 2025-04-18 19:10:10 +01:00 committed by GitHub
parent d54d8c95a0
commit 1c86a3e346
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 134 additions and 29 deletions

42
.github/workflows/alwayscheck.yml vendored Normal file
View file

@ -0,0 +1,42 @@
on:
pull_request:
name: SpellCheck+LinkCheck
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Do not add permissions here! Configure them at the job level!
permissions: {}
env:
RUST_BACKTRACE: 1
jobs:
spell-link-check:
name: spell and md link check
runs-on: [ubuntu-24.04]
timeout-minutes: 20
env:
FORCE_COLOR: 1
steps:
- uses: actions/checkout@v4
- run: cargo install typos-cli --version 1.0.11
- name: do spell check with typos-cli 1.0.11
run: typos
- name: setup Roc
run: |
curl -s -OL https://github.com/roc-lang/roc/releases/download/alpha3-rolling/roc-linux_x86_64-alpha3-rolling.tar.gz
tar -xf roc-linux_x86_64-alpha3-rolling.tar.gz
rm roc-linux_x86_64-alpha3-rolling.tar.gz
cd roc_nightly-*
# make roc binary available
echo "$(pwd)" >> $GITHUB_PATH
- run: roc version
- run: roc ./ci/glossary-link-checker.roc

View file

@ -1,29 +0,0 @@
on:
pull_request:
name: SpellCheck
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Do not add permissions here! Configure them at the job level!
permissions: {}
env:
RUST_BACKTRACE: 1
jobs:
spell-check:
name: spell check
runs-on: [ubuntu-22.04]
timeout-minutes: 10
env:
FORCE_COLOR: 1
steps:
- uses: actions/checkout@v4
- run: cargo install typos-cli --version 1.0.11
- name: do spell check with typos-cli 1.0.11
run: typos

View file

@ -0,0 +1,92 @@
app [main!] { cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }
import cli.Stdout
import cli.Stderr
import cli.Path
import "../Glossary.md" as glossary_as_str : Str
# This script checks if all markdown links that point to files or dirs are valid for the file Glossary.md
# TODO check links to other markdown headers as well, e.g. #tokenization
main! = |_args|
md_links =
glossary_as_str
|> extract_md_links
full_check_res =
md_links
|> List.for_each_try!(
|link_str|
check_res = check_link!(link_str)
when check_res is
Ok(_) ->
# Stdout.line!("Check successful for $(link_str)")?
Ok({})
Err(BadLink(bad_link_str)) ->
Stderr.line!("I could not find the path: '$(bad_link_str)'. If you recently modified this path, please update '$(bad_link_str)' in Glossary.md at the root of the repo.\n")?
Err(LinkCheckFailed)
)
when full_check_res is
Ok(_) ->
Stdout.line!("Successfuly checked $(List.len(md_links) |> Num.to_str) links.")
Err(_) ->
Err(Exit(1, "Link check failed. Please check the above errors."))
expect
md_text = "foo [bar](src/baz.md)..."
links = extract_md_links(md_text)
links == ["src/baz.md"]
extract_md_links : Str -> List Str
extract_md_links = |md_content|
split_list = Str.split_on(md_content, "](")
links =
split_list
|> List.drop_first(1)
|> List.map(
|link|
res = Str.split_on(link, ")") |> List.first()
when res is
Ok(str) -> str
Err(_) -> ""
)
links
expect
md_text = "foo [bar](src/baz.md)...[zod](boz.md)"
links = extract_md_links(md_text)
links == ["src/baz.md", "boz.md"]
expect
md_text =
"""
foo [bar](src/baz.md)...
hey asjkl [zod](boz.md) asmd
[bam](crates/check/can_solo/src/desugar.rs)
"""
links = extract_md_links(md_text)
links == ["src/baz.md", "boz.md", "crates/check/can_solo/src/desugar.rs"]
check_link! : Str => Result {} [BadLink Str]
check_link! = |link_str|
if Str.starts_with(link_str, "http") || Str.starts_with(link_str, "#") then
# TODO check links to other markdown headers as well, e.g. #tokenization
Ok({})
else
path = Path.from_str(link_str)
when Path.type!(path) is
Ok(_) ->
Ok({})
Err(_) ->
Err(BadLink(link_str))