Skip to content

Commit

Permalink
feat(gnomod): support parsing deprecated message (#773)
Browse files Browse the repository at this point in the history
  • Loading branch information
harry-hov committed Apr 26, 2023
1 parent 7ac2a9d commit 71f0bd5
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 1 deletion.
4 changes: 3 additions & 1 deletion gnovm/pkg/gnomod/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ func (f *File) add(errs *modfile.ErrorList, block *modfile.LineBlock, line *modf
errorf("repeated module statement")
return
}
deprecated := parseDeprecation(block, line)
f.Module = &modfile.Module{
Syntax: line,
Syntax: line,
Deprecated: deprecated,
}
if len(args) != 1 {
errorf("usage: module module/path")
Expand Down
118 changes: 118 additions & 0 deletions gnovm/pkg/gnomod/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package gnomod

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestModuleDeprecated(t *testing.T) {
for _, tc := range []struct {
desc, in, expected string
}{
{
desc: "no_comment",
in: `module m`,
},
{
desc: "other_comment",
in: `// yo
module m`,
},
{
desc: "deprecated_no_colon",
in: `//Deprecated
module m`,
},
{
desc: "deprecated_no_space",
in: `//Deprecated:blah
module m`,
expected: "blah",
},
{
desc: "deprecated_simple",
in: `// Deprecated: blah
module m`,
expected: "blah",
},
{
desc: "deprecated_lowercase",
in: `// deprecated: blah
module m`,
},
{
desc: "deprecated_multiline",
in: `// Deprecated: one
// two
module m`,
expected: "one\ntwo",
},
{
desc: "deprecated_mixed",
in: `// some other comment
// Deprecated: blah
module m`,
},
{
desc: "deprecated_middle",
in: `// module m is Deprecated: blah
module m`,
},
{
desc: "deprecated_multiple",
in: `// Deprecated: a
// Deprecated: b
module m`,
expected: "a\nDeprecated: b",
},
{
desc: "deprecated_paragraph",
in: `// Deprecated: a
// b
//
// c
module m`,
expected: "a\nb",
},
{
desc: "deprecated_paragraph_space",
in: `// Deprecated: the next line has a space
//
// c
module m`,
expected: "the next line has a space",
},
{
desc: "deprecated_suffix",
in: `module m // Deprecated: blah`,
expected: "blah",
},
{
desc: `deprecated_mixed_suffix`,
in: `// some other comment
module m // Deprecated: blah`,
},
{
desc: "deprecated_mixed_suffix_paragraph",
in: `// some other comment
//
module m // Deprecated: blah`,
expected: "blah",
},
{
desc: "deprecated_block",
in: `// Deprecated: blah
module (
m
)`,
expected: "blah",
},
} {
t.Run(tc.desc, func(t *testing.T) {
f, err := Parse("in", []byte(tc.in))
assert.Nil(t, err)
assert.Equal(t, tc.expected, f.Module.Deprecated)
})
}
}
40 changes: 40 additions & 0 deletions gnovm/pkg/gnomod/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"unicode"
Expand Down Expand Up @@ -793,3 +794,42 @@ func parseReplace(filename string, line *modfile.Line, verb string, args []strin
Syntax: line,
}, nil
}

// parseDeprecation extracts the text of comments on a "module" directive and
// extracts a deprecation message from that.
//
// A deprecation message is contained in a paragraph within a block of comments
// that starts with "Deprecated:" (case sensitive). The message runs until the
// end of the paragraph and does not include the "Deprecated:" prefix. If the
// comment block has multiple paragraphs that start with "Deprecated:",
// parseDeprecation returns the message from the first.
func parseDeprecation(block *modfile.LineBlock, line *modfile.Line) string {
text := parseDirectiveComment(block, line)
rx := regexp.MustCompile(`(?s)(?:^|\n\n)Deprecated: *(.*?)(?:$|\n\n)`)
m := rx.FindStringSubmatch(text)
if m == nil {
return ""
}
return m[1]
}

// parseDirectiveComment extracts the text of comments on a directive.
// If the directive's lien does not have comments and is part of a block that
// does have comments, the block's comments are used.
func parseDirectiveComment(block *modfile.LineBlock, line *modfile.Line) string {
comments := line.Comment()
if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 {
comments = block.Comment()
}
groups := [][]modfile.Comment{comments.Before, comments.Suffix}
var lines []string
for _, g := range groups {
for _, c := range g {
if !strings.HasPrefix(c.Token, "//") {
continue // blank line
}
lines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, "//")))
}
}
return strings.Join(lines, "\n")
}

0 comments on commit 71f0bd5

Please sign in to comment.