@@ -19,8 +19,10 @@ package cppkg
1919import (
2020 "errors"
2121 "os"
22+ "strings"
2223
2324 "github.com/goccy/go-yaml"
25+ "github.com/goplus/llgo/internal/github"
2426 "golang.org/x/mod/semver"
2527)
2628
@@ -73,11 +75,16 @@ type Package struct {
7375 Version string
7476 Folder string
7577 Template * Template
78+
79+ gr * github.Release // optional
7680}
7781
7882var (
7983 // ErrVersionNotFound is returned when the specified version is not found.
8084 ErrVersionNotFound = errors .New ("version not found" )
85+
86+ // ErrDynamicTag is returned when the tag is dynamic.
87+ ErrDynamicTag = errors .New ("dynamic tag" )
8188)
8289
8390const (
@@ -109,15 +116,32 @@ func (p *Manager) Lookup(pkgPath, ver string, flags int) (_ *Package, err error)
109116 if err != nil {
110117 return
111118 }
119+
120+ if ver == "" || ver == "latest" {
121+ if conf .Template .Tag == "" {
122+ return nil , ErrDynamicTag
123+ }
124+ gr , e := github .GetRelease (pkgPath , "" )
125+ if e != nil {
126+ return nil , e
127+ }
128+ ver , err = verByTag (gr .TagName , conf .Template .Tag )
129+ if err != nil {
130+ return
131+ }
132+ templ := conf .Template
133+ return & Package {conf .PkgName , pkgPath , ver , templ .Folder , & templ , gr }, nil
134+ }
135+
112136 if v , ok := conf .Versions [ver ]; ok {
113- return & Package {conf .PkgName , pkgPath , ver , v .Folder , nil }, nil
137+ return & Package {conf .PkgName , pkgPath , ver , v .Folder , nil , nil }, nil
114138 }
115139 if compareVer (ver , conf .Template .FromVer ) < 0 {
116140 err = ErrVersionNotFound
117141 return
118142 }
119- folder := conf .Template . Folder
120- return & Package {conf .PkgName , pkgPath , ver , folder , & conf . Template }, nil
143+ templ := conf .Template
144+ return & Package {conf .PkgName , pkgPath , ver , templ . Folder , & templ , nil }, nil
121145}
122146
123147func (p * Manager ) indexRoot () string {
@@ -158,3 +182,15 @@ func indexInit(root string, flags int) (err error) {
158182func compareVer (v1 , v2 string ) int {
159183 return semver .Compare ("v" + v1 , "v" + v2 )
160184}
185+
186+ func verByTag (tag , tagPattern string ) (ver string , err error ) {
187+ if pos := strings .IndexByte (tagPattern , '*' ); pos >= 0 {
188+ prefix := tagPattern [:pos ]
189+ suffix := tagPattern [pos + 1 :]
190+ if strings .HasPrefix (tag , prefix ) && strings .HasSuffix (tag , suffix ) {
191+ ver = tag [pos : len (tag )- len (suffix )]
192+ return
193+ }
194+ }
195+ return "" , errors .New ("tag not match: " + tag + " with " + tagPattern )
196+ }
0 commit comments