diff --git a/modload/module.go b/modload/module.go index ce70824..d0e738b 100644 --- a/modload/module.go +++ b/modload/module.go @@ -25,6 +25,7 @@ import ( "github.com/goplus/mod" "github.com/goplus/mod/env" "github.com/goplus/mod/modfile" + "github.com/goplus/mod/sumfile" "github.com/qiniu/x/errors" "golang.org/x/mod/module" @@ -63,6 +64,14 @@ func (p Module) workFile() string { return "" } +func (p Module) sumFile() string { + if syn := p.Syntax; syn != nil { + dir, _ := filepath.Split(syn.Name) + return dir + "go.sum" + } + return "" +} + // Root returns absolute root path of this module. func (p Module) Root() string { if syn := p.Syntax; syn != nil { @@ -343,6 +352,9 @@ func (p Module) SaveWithGopMod(gop *env.Gop, flags int) (err error) { return } } + if (flags & FlagDepModGop) == 0 { + return + } var work *gomodfile.WorkFile var workFile = p.workFile() @@ -372,17 +384,23 @@ func (p Module) requireGop(gop *env.Gop, gopVer string, old, flags int) { p.File.AddRequire(gopMod, gopVer) } if (flags&FlagDepModX) != 0 && (old&FlagDepModX) == 0 { // depends module github.com/qiniu/x - if x, ok := getXVer(gop); ok { + if x, xsum, ok := getXVer(gop); ok { p.File.AddRequire(x.Path, x.Version) + if sumf, err := sumfile.Load(p.sumFile()); err == nil && sumf.Lookup(xMod) == nil { + sumf.Add(xsum) + sumf.Save() + } } } } -func getXVer(gop *env.Gop) (modVer module.Version, ok bool) { +func getXVer(gop *env.Gop) (modVer module.Version, xsum []string, ok bool) { if mod, err := LoadFrom(gop.Root+"/go.mod", ""); err == nil { for _, r := range mod.File.Require { if r.Mod.Path == xMod { - return r.Mod, true + if sumf, err := sumfile.Load(gop.Root + "/go.sum"); err == nil { + return r.Mod, sumf.Lookup(xMod), true + } } } } diff --git a/modload/module_test.go b/modload/module_test.go index 79b4143..fdb109d 100644 --- a/modload/module_test.go +++ b/modload/module_test.go @@ -139,6 +139,9 @@ func TestSaveDefault(t *testing.T) { if v := Default.workFile(); v != "" { t.Fatal("Default.workFile:", v) } + if v := Default.sumFile(); v != "" { + t.Fatal("Default.sumFile:", v) + } if err := Default.Save(); err != ErrSaveDefault { t.Fatal("Default.Save:", err) } @@ -215,7 +218,7 @@ require ( ` { t.Fatal("SaveWithGopMod:", v) } - if _, ok := getXVer(&env.Gop{Root: "/foo/bar"}); ok { + if _, _, ok := getXVer(&env.Gop{Root: "/foo/bar"}); ok { t.Fatal("getXVer: ok?") } @@ -224,6 +227,10 @@ require ( log.Fatal("mod.SaveWithGopMod 3:", err) } + if err = mod.SaveWithGopMod(&env.Gop{Version: "v1.2.0 devel", Root: ".gop"}, FlagDepModX); err != nil { + log.Fatal("mod.SaveWithGopMod 4:", err) + } + mod.Opt.Projects = append(mod.Opt.Projects, spxProject) mod.Save() b, err = os.ReadFile(mod.Opt.Syntax.Name) diff --git a/sumfile/sumfile.go b/sumfile/sumfile.go new file mode 100644 index 0000000..7c6e8bb --- /dev/null +++ b/sumfile/sumfile.go @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sumfile + +import ( + "os" + "sort" + "strings" +) + +type File struct { + lines []string + gosum string +} + +func Load(gosum string) (sumf *File, err error) { + var lines []string + b, err := os.ReadFile(gosum) + if err != nil { + if !os.IsNotExist(err) { + return + } + } else { + text := string(b) + lines = strings.Split(strings.TrimRight(text, "\n"), "\n") + } + return &File{lines, gosum}, nil +} + +func (p *File) Save() (err error) { + n := 0 + for _, line := range p.lines { + n += 1 + len(line) + } + b := make([]byte, 0, n) + for _, line := range p.lines { + b = append(b, line...) + b = append(b, '\n') + } + return os.WriteFile(p.gosum, b, 0666) +} + +func (p *File) Lookup(modPath string) []string { + prefix := modPath + " " + lines := p.lines + for i, line := range lines { + if line > prefix { + if strings.HasPrefix(line, prefix) { + for j, line := range lines[i+1:] { + if !strings.HasPrefix(line, prefix) { + lines = lines[:i+1+j] + break + } + } + return lines[i:] + } + break + } + } + return nil +} + +func (p *File) Add(lines []string) { + p.lines = append(p.lines, lines...) + sort.Strings(p.lines) +}