Skip to content

Commit 858fdbe

Browse files
author
Jay Conrod
committed
modfile: parse deprecation notices in module comments
Deprecation notices start with "Deprecated:" at the beginning of a line and run until the end of the paragraph. This CL reuses text extraction code for retraction rationale, so the same rules apply: comment text may be from the comments above a "module" directive or as a suffix on the same line. For golang/go#40357 Change-Id: Id5524149c6bbda3effc64c6b668b701b5cf428af Reviewed-on: https://go-review.googlesource.com/c/mod/+/301089 Trust: Jay Conrod <[email protected]> Run-TryBot: Jay Conrod <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent 244d49f commit 858fdbe

File tree

2 files changed

+158
-8
lines changed

2 files changed

+158
-8
lines changed

modfile/rule.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ type File struct {
4747

4848
// A Module is the module statement.
4949
type Module struct {
50-
Mod module.Version
51-
Syntax *Line
50+
Mod module.Version
51+
Deprecated string
52+
Syntax *Line
5253
}
5354

5455
// A Go is the go statement.
@@ -278,7 +279,11 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
278279
errorf("repeated module statement")
279280
return
280281
}
281-
f.Module = &Module{Syntax: line}
282+
deprecated := parseDeprecation(block, line)
283+
f.Module = &Module{
284+
Syntax: line,
285+
Deprecated: deprecated,
286+
}
282287
if len(args) != 1 {
283288
errorf("usage: module module/path")
284289
return
@@ -392,7 +397,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
392397
})
393398

394399
case "retract":
395-
rationale := parseRetractRationale(block, line)
400+
rationale := parseDirectiveComment(block, line)
396401
vi, err := parseVersionInterval(verb, "", &args, dontFixRetract)
397402
if err != nil {
398403
if strict {
@@ -619,10 +624,29 @@ func parseString(s *string) (string, error) {
619624
return t, nil
620625
}
621626

622-
// parseRetractRationale extracts the rationale for a retract directive from the
623-
// surrounding comments. If the line does not have comments and is part of a
624-
// block that does have comments, the block's comments are used.
625-
func parseRetractRationale(block *LineBlock, line *Line) string {
627+
var deprecatedRE = lazyregexp.New(`(?s)(?:^|\n\n)Deprecated: *(.*?)(?:$|\n\n)`)
628+
629+
// parseDeprecation extracts the text of comments on a "module" directive and
630+
// extracts a deprecation message from that.
631+
//
632+
// A deprecation message is contained in a paragraph within a block of comments
633+
// that starts with "Deprecated:" (case sensitive). The message runs until the
634+
// end of the paragraph and does not include the "Deprecated:" prefix. If the
635+
// comment block has multiple paragraphs that start with "Deprecated:",
636+
// parseDeprecation returns the message from the first.
637+
func parseDeprecation(block *LineBlock, line *Line) string {
638+
text := parseDirectiveComment(block, line)
639+
m := deprecatedRE.FindStringSubmatch(text)
640+
if m == nil {
641+
return ""
642+
}
643+
return m[1]
644+
}
645+
646+
// parseDirectiveComment extracts the text of comments on a directive.
647+
// If the directive's line does not have comments and is part of a block that
648+
// does have comments, the block's comments are used.
649+
func parseDirectiveComment(block *LineBlock, line *Line) string {
626650
comments := line.Comment()
627651
if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 {
628652
comments = block.Comment()

modfile/rule_test.go

+126
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,118 @@ suffix`,
499499
},
500500
}
501501

502+
var moduleDeprecatedTests = []struct {
503+
desc, in, want string
504+
}{
505+
// retractRationaleTests exercises some of the same code, so these tests
506+
// don't exhaustively cover comment extraction.
507+
{
508+
`no_comment`,
509+
`module m`,
510+
``,
511+
},
512+
{
513+
`other_comment`,
514+
`// yo
515+
module m`,
516+
``,
517+
},
518+
{
519+
`deprecated_no_colon`,
520+
`//Deprecated
521+
module m`,
522+
``,
523+
},
524+
{
525+
`deprecated_no_space`,
526+
`//Deprecated:blah
527+
module m`,
528+
`blah`,
529+
},
530+
{
531+
`deprecated_simple`,
532+
`// Deprecated: blah
533+
module m`,
534+
`blah`,
535+
},
536+
{
537+
`deprecated_lowercase`,
538+
`// deprecated: blah
539+
module m`,
540+
``,
541+
},
542+
{
543+
`deprecated_multiline`,
544+
`// Deprecated: one
545+
// two
546+
module m`,
547+
"one\ntwo",
548+
},
549+
{
550+
`deprecated_mixed`,
551+
`// some other comment
552+
// Deprecated: blah
553+
module m`,
554+
``,
555+
},
556+
{
557+
`deprecated_middle`,
558+
`// module m is Deprecated: blah
559+
module m`,
560+
``,
561+
},
562+
{
563+
`deprecated_multiple`,
564+
`// Deprecated: a
565+
// Deprecated: b
566+
module m`,
567+
"a\nDeprecated: b",
568+
},
569+
{
570+
`deprecated_paragraph`,
571+
`// Deprecated: a
572+
// b
573+
//
574+
// c
575+
module m`,
576+
"a\nb",
577+
},
578+
{
579+
`deprecated_paragraph_space`,
580+
`// Deprecated: the next line has a space
581+
//
582+
// c
583+
module m`,
584+
"the next line has a space",
585+
},
586+
{
587+
`deprecated_suffix`,
588+
`module m // Deprecated: blah`,
589+
`blah`,
590+
},
591+
{
592+
`deprecated_mixed_suffix`,
593+
`// some other comment
594+
module m // Deprecated: blah`,
595+
``,
596+
},
597+
{
598+
`deprecated_mixed_suffix_paragraph`,
599+
`// some other comment
600+
//
601+
module m // Deprecated: blah`,
602+
`blah`,
603+
},
604+
{
605+
`deprecated_block`,
606+
`// Deprecated: blah
607+
module (
608+
m
609+
)`,
610+
`blah`,
611+
},
612+
}
613+
502614
var sortBlocksTests = []struct {
503615
desc, in, out string
504616
strict bool
@@ -848,6 +960,20 @@ func TestRetractRationale(t *testing.T) {
848960
}
849961
}
850962

963+
func TestModuleDeprecated(t *testing.T) {
964+
for _, tt := range moduleDeprecatedTests {
965+
t.Run(tt.desc, func(t *testing.T) {
966+
f, err := Parse("in", []byte(tt.in), nil)
967+
if err != nil {
968+
t.Fatal(err)
969+
}
970+
if f.Module.Deprecated != tt.want {
971+
t.Errorf("got %q; want %q", f.Module.Deprecated, tt.want)
972+
}
973+
})
974+
}
975+
}
976+
851977
func TestSortBlocks(t *testing.T) {
852978
for _, tt := range sortBlocksTests {
853979
t.Run(tt.desc, func(t *testing.T) {

0 commit comments

Comments
 (0)