Skip to content

fix: detect go package clause after leading comments - #1723

Open
mokevnin wants to merge 3 commits into
hougesen:mainfrom
Hexlet:fix-go-package-detection
Open

fix: detect go package clause after leading comments#1723
mokevnin wants to merge 3 commits into
hougesen:mainfrom
Hexlet:fix-go-package-detection

Conversation

@mokevnin

@mokevnin mokevnin commented Aug 29, 2026

Copy link
Copy Markdown

Problem

GO_PACKAGE_RE is anchored at the start of the snippet, not per line. A go block that opens with a comment therefore looks like a snippet without a package clause, and mdsf prepends its temporary package:

```go
// main.go
package main

func main() {}
```

gofmt then sees two package clauses and fails with expected declaration, found 'package'. Since error running gofmt exits zero, the block is neither formatted nor reported as unformatted — it just silently drops out of the check. Both a file-name comment and a //go:build constraint hit this, and both are common in documentation.

Change

A package clause is the first token of a Go file that is neither whitespace nor a comment, so has_go_package skips leading // and /* */ comments and applies the existing anchored pattern to the remainder. GO_PACKAGE_RE keeps its original semantics, and the TODO: check for multiline comments above it is resolved: a block comment containing a line that starts with package is not mistaken for a package clause.

Checks

cargo test -p mdsf --lib parser passes, with a new test_has_go_package module covering both directions (leading file-name comment, //go:build, a block comment before a real package clause, and the same block comment without one). cargo clippy --all-targets is clean. On a corpus of Go-heavy markdown, the block above goes from error running gofmt to being formatted normally.

`GO_PACKAGE_RE` is anchored at the start of the snippet, so a go block
that opens with a comment — a file-name comment or a `//go:build`
constraint — is treated as having no package clause. mdsf then prepends
its temporary package and hands gofmt two package clauses, which fails
with «expected declaration, found 'package'».

The failure is quiet: mdsf prints `error running gofmt` and exits zero,
so the block is not formatted and not reported as unformatted either.

Anchor the pattern per line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread mdsf/src/parser/mod.rs Outdated
// TODO: check for multiline comments
pub static GO_PACKAGE_RE: std::sync::LazyLock<Regex> =
std::sync::LazyLock::new(|| Regex::new(r"^\s*package\s+\w").unwrap());
std::sync::LazyLock::new(|| Regex::new(r"(?m)^\s*package\s+\w").unwrap());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enable multine matching, won't this break some use cases.

package is a reserved word in Go, so it sounds safe

But you may something odd like this snippet without a package

/*

I like my
package manager
*/

const foo = 1

But I feel like there is no better solution without dealing with complicated regexp to remove comments

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that example is a real hole and it pushed the fix to the right place.

Dropped the (?m) and matched Go's own rule instead: the package clause is the first token that is neither whitespace nor a comment. has_go_package skips leading // and /* */ and applies the existing anchored pattern to the remainder, so your snippet stays without a package clause and still gets the temporary one. No comment-removing regex needed, and the TODO: check for multiline comments above GO_PACKAGE_RE is gone with it.

Both directions are covered in a new test_has_go_package module, your snippet included.

mokevnin and others added 2 commits August 29, 2026 16:43
A package clause is the first token of a Go file that is neither
whitespace nor a comment. Match that rule directly instead of widening
the anchored pattern to every line, so a block comment containing a line
that starts with `package` is not mistaken for a package clause.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants