mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-08-26 20:23:49 +00:00
feat(build): lint-locale-usage should handle dynamically generated msgids with known prefix
This commit is contained in:
parent
c7349ed42d
commit
560eb35a85
3 changed files with 93 additions and 7 deletions
|
@ -20,7 +20,11 @@ func (handler Handler) handleGoTrBasicLit(fset *token.FileSet, argLit *ast.Basic
|
|||
if err == nil {
|
||||
// found interesting strings
|
||||
if strings.HasSuffix(arg, ".") || strings.HasSuffix(arg, "_") {
|
||||
handler.OnMsgidPrefix(fset, argLit.ValuePos, arg)
|
||||
prep, trunc := PrepareMsgidPrefix(arg)
|
||||
if trunc {
|
||||
handler.OnWarning(fset, argLit.ValuePos, fmt.Sprintf("needed to truncate message id prefix: %s", arg))
|
||||
}
|
||||
handler.OnMsgidPrefix(fset, argLit.ValuePos, prep)
|
||||
} else {
|
||||
handler.OnMsgid(fset, argLit.ValuePos, arg)
|
||||
}
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
tmplParser "text/template/parse"
|
||||
|
||||
|
@ -68,12 +70,7 @@ func (handler Handler) handleTemplateNode(fset *token.FileSet, node tmplParser.N
|
|||
|
||||
for _, argNum := range ltf {
|
||||
if len(nodeCommand.Args) >= int(argNum+2) {
|
||||
nodeString, ok := nodeCommand.Args[int(argNum+1)].(*tmplParser.StringNode)
|
||||
if ok {
|
||||
// found interesting strings
|
||||
// the column numbers are a bit "off", but much better than nothing
|
||||
handler.OnMsgid(fset, token.Pos(nodeString.Pos), nodeString.Text)
|
||||
}
|
||||
handler.handleTemplateMsgid(fset, nodeCommand.Args[int(argNum+1)])
|
||||
} else {
|
||||
argc := len(nodeCommand.Args) - 1
|
||||
gotUnexpectedInvoke = &argc
|
||||
|
@ -88,6 +85,82 @@ func (handler Handler) handleTemplateNode(fset *token.FileSet, node tmplParser.N
|
|||
}
|
||||
}
|
||||
|
||||
func (handler Handler) handleTemplateMsgid(fset *token.FileSet, node tmplParser.Node) {
|
||||
// the column numbers are a bit "off", but much better than nothing
|
||||
pos := token.Pos(node.Position())
|
||||
|
||||
switch node.Type() {
|
||||
case tmplParser.NodeString:
|
||||
nodeString := node.(*tmplParser.StringNode)
|
||||
// found interesting strings
|
||||
handler.OnMsgid(fset, pos, nodeString.Text)
|
||||
|
||||
case tmplParser.NodePipe:
|
||||
nodePipe := node.(*tmplParser.PipeNode)
|
||||
handler.handleTemplatePipeNode(fset, nodePipe)
|
||||
|
||||
if len(nodePipe.Cmds) == 0 {
|
||||
handler.OnWarning(fset, pos, fmt.Sprintf("unsupported invocation of locate function (no commands): %s", node.String()))
|
||||
} else if len(nodePipe.Cmds) != 1 {
|
||||
handler.OnWarning(fset, pos, fmt.Sprintf("unsupported invocation of locate function (too many commands): %s", node.String()))
|
||||
return
|
||||
}
|
||||
nodeCommand := nodePipe.Cmds[0]
|
||||
if len(nodeCommand.Args) < 2 {
|
||||
handler.OnWarning(fset, pos, fmt.Sprintf("unsupported invocation of locate function (not enough arguments): %s", node.String()))
|
||||
return
|
||||
}
|
||||
|
||||
nodeIdent, ok := nodeCommand.Args[0].(*tmplParser.IdentifierNode)
|
||||
if !ok || (nodeIdent.Ident != "print" && nodeIdent.Ident != "printf") {
|
||||
// handler.OnWarning(fset, pos, fmt.Sprintf("unsupported invocation of locate function (bad command): %s", node.String()))
|
||||
return
|
||||
}
|
||||
|
||||
nodeString, ok := nodeCommand.Args[1].(*tmplParser.StringNode)
|
||||
if !ok {
|
||||
//handler.OnWarning(
|
||||
// fset,
|
||||
// pos,
|
||||
// fmt.Sprintf("unsupported invocation of locate function (string should be first argument to %s): %s", nodeIdent.Ident, node.String()),
|
||||
//)
|
||||
return
|
||||
}
|
||||
|
||||
msgidPrefix := nodeString.Text
|
||||
stringPos := token.Pos(nodeString.Pos)
|
||||
|
||||
if len(nodeCommand.Args) == 2 {
|
||||
// found interesting strings
|
||||
handler.OnMsgid(fset, stringPos, msgidPrefix)
|
||||
} else {
|
||||
if nodeIdent.Ident == "printf" {
|
||||
parts := strings.SplitN(msgidPrefix, "%", 2)
|
||||
if len(parts) != 2 {
|
||||
handler.OnWarning(
|
||||
fset,
|
||||
stringPos,
|
||||
fmt.Sprintf("unsupported invocation of locate function (format string doesn't match \"prefix%%smth\" pattern): %s", nodeString.String()),
|
||||
)
|
||||
return
|
||||
}
|
||||
msgidPrefix = parts[0]
|
||||
}
|
||||
|
||||
msgidPrefixFin, truncated := PrepareMsgidPrefix(msgidPrefix)
|
||||
if truncated {
|
||||
handler.OnWarning(fset, stringPos, fmt.Sprintf("needed to truncate message id prefix: %s", msgidPrefix))
|
||||
}
|
||||
|
||||
// found interesting strings
|
||||
handler.OnMsgidPrefix(fset, stringPos, msgidPrefixFin)
|
||||
}
|
||||
|
||||
default:
|
||||
// handler.OnWarning(fset, pos, fmt.Sprintf("unknown invocation of locate function: %s", node.String()))
|
||||
}
|
||||
}
|
||||
|
||||
func (handler Handler) handleTemplatePipeNode(fset *token.FileSet, pipeNode *tmplParser.PipeNode) {
|
||||
if pipeNode == nil {
|
||||
return
|
||||
|
|
|
@ -161,6 +161,15 @@ func ParseAllowedMaskedUsages(fname string, usedMsgids *container.Set[string], a
|
|||
return nil
|
||||
}
|
||||
|
||||
// Truncating a message id prefix to the last dot
|
||||
func PrepareMsgidPrefix(s string) (string, bool) {
|
||||
index := strings.LastIndexByte(s, 0x2e)
|
||||
if index == -1 {
|
||||
return "", true
|
||||
}
|
||||
return s[:index], index != len(s)-1
|
||||
}
|
||||
|
||||
// This command assumes that we get started from the project root directory
|
||||
//
|
||||
// Possible command line flags:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue