diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fa198ffb5e..046666f31fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -123,6 +123,8 @@ ([Amjad Mohamed](https://github.com/andho)) +- Docs generator now strips trailing slashes from Gitea/Forgejo hosts so sidebar "Repository" and "View Source" links never include `//`, and single-line “View Source” anchors emit `#Lx` instead of `#Lx-x`. ([Aayush Tripathi](https://github.com/aayush-tripathi)) + ### Language server ### Formatter diff --git a/compiler-core/src/config.rs b/compiler-core/src/config.rs index c9e29d7e031..e5bbdc37f09 100644 --- a/compiler-core/src/config.rs +++ b/compiler-core/src/config.rs @@ -827,7 +827,11 @@ impl Repository { } Repository::Gitea { repo, user, host, .. - } => Some(format!("{host}/{user}/{repo}")), + } => { + let string_host = host.to_string(); + let cleaned_host = string_host.trim_end_matches('/'); + Some(format!("{cleaned_host}/{user}/{repo}")) + } Repository::Custom { url } => Some(url.clone()), Repository::None => None, } diff --git a/compiler-core/src/docs/source_links.rs b/compiler-core/src/docs/source_links.rs index 8fdc3080633..71c424b9e28 100644 --- a/compiler-core/src/docs/source_links.rs +++ b/compiler-core/src/docs/source_links.rs @@ -70,13 +70,17 @@ impl SourceLinker { )), Repository::Gitea { user, repo, host, .. - } => Some(( - format!( - "{host}/{user}/{repo}/src/tag/v{}/{}#L", - project_config.version, path_in_repo - ), - "-".into(), - )), + } => { + let string_host = host.to_string(); + let cleaned_host = string_host.trim_end_matches('/'); + Some(( + format!( + "{cleaned_host}/{user}/{repo}/src/tag/v{}/{}#L", + project_config.version, path_in_repo + ), + "-".into(), + )) + } Repository::Custom { .. } | Repository::None => None, }; @@ -90,7 +94,11 @@ impl SourceLinker { Some((base, line_sep)) => { let start_line = self.line_numbers.line_number(span.start); let end_line = self.line_numbers.line_number(span.end); - format!("{base}{start_line}{line_sep}{end_line}") + if start_line == end_line { + format!("{base}{start_line}") + } else { + format!("{base}{start_line}{line_sep}{end_line}") + } } None => "".into(), diff --git a/compiler-core/src/docs/tests.rs b/compiler-core/src/docs/tests.rs index 2c1fb83cad5..655bd268f0c 100644 --- a/compiler-core/src/docs/tests.rs +++ b/compiler-core/src/docs/tests.rs @@ -26,6 +26,7 @@ use crate::{ use camino::Utf8PathBuf; use ecow::EcoString; use hexpm::version::Version; +use http::Uri; use itertools::Itertools; use serde_json::to_string as serde_to_string; @@ -626,7 +627,7 @@ fn source_link_for_github_repository() { let modules = vec![("app.gleam", "pub type Wibble = Int")]; assert!( compile(config, modules) - .contains("https://github.com/wibble/wobble/blob/v0.1.0/src/app.gleam#L1-L1") + .contains("https://github.com/wibble/wobble/blob/v0.1.0/src/app.gleam#L1") ); } @@ -641,9 +642,11 @@ fn source_link_for_github_repository_with_path() { }; let modules = vec![("app.gleam", "pub type Wibble = Int")]; - assert!(compile(config, modules).contains( - "https://github.com/wibble/wobble/blob/v0.1.0/path/to/package/src/app.gleam#L1-L1" - )); + assert!( + compile(config, modules).contains( + "https://github.com/wibble/wobble/blob/v0.1.0/path/to/package/src/app.gleam#L1" + ) + ); } #[test] @@ -1162,3 +1165,17 @@ pub type Wibble { NONE ); } +#[test] +fn gitea_repository_url_has_no_double_slash() { + let repo = Repository::Gitea { + host: "https://code.example.org/".parse::().unwrap(), + user: "person".into(), + repo: "forgejo_bug".into(), + path: None, + }; + + assert_eq!( + repo.url().unwrap(), + "https://code.example.org/person/forgejo_bug" + ); +}