github.com/octohelm/cuekit@v0.0.0-20240424021256-e7df8d743066/pkg/mod/modregistry/registry.go (about) 1 package modregistry 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/octohelm/cuekit/pkg/mod/modfile" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "cuelang.org/go/mod/modconfig" 12 13 "github.com/octohelm/cuekit/pkg/mod/modmem" 14 "github.com/octohelm/cuekit/pkg/mod/module" 15 ) 16 17 func NewRegistry(m *module.Module) (modconfig.Registry, error) { 18 userCacheDir, err := os.UserCacheDir() 19 if err != nil { 20 return nil, err 21 } 22 23 if err := m.Load(true); err != nil { 24 return nil, err 25 } 26 27 r := &resolver{ 28 CacheDir: getEnv("CUE_CACHE_DIR", filepath.Join(userCacheDir, "cue")), 29 Root: m, 30 } 31 32 std, err := modconfig.NewRegistry(&modconfig.Config{ 33 Env: []string{ 34 fmt.Sprintf("CUE_REGISTRY=%s", getEnv("CUE_REGISTRY", "ghcr.io")), 35 fmt.Sprintf("CUE_CACHE_DIR=%s", r.CacheDir), 36 }, 37 }) 38 if err != nil { 39 return nil, err 40 } 41 42 if err := modmem.DefaultRegistry.Dump(r.CacheDir); err != nil { 43 return nil, err 44 } 45 46 return ®istry{ 47 mem: modmem.DefaultRegistry, 48 local: r, 49 std: std, 50 }, nil 51 } 52 53 type registry struct { 54 mem modmem.Registry 55 local *resolver 56 std modconfig.Registry 57 } 58 59 func (r *registry) Fetch(ctx context.Context, mv module.Version) (loc module.SourceLoc, err error) { 60 defer func() { 61 if err == nil { 62 mod := &module.Module{ 63 SourceLoc: loc, 64 } 65 66 if err := mod.Load(true); err == nil { 67 if version := mod.Overwrites.Version; version != "" { 68 r.local.Root.Overwrites.AddDep(mod.Module, &modfile.DepOverwrite{ 69 Path: mod.Overwrites.Path, 70 Version: version, 71 }) 72 } 73 } 74 75 _ = r.local.Root.Save() 76 } 77 }() 78 79 if depOverwrite, ok := r.local.Root.GetDepOverwrite(mv.Path()); ok { 80 if depOverwrite.IsLocalReplacement() { 81 return r.local.ResolveLocal(ctx, depOverwrite.Path) 82 } 83 84 return r.local.Resolve(ctx, mv.Path(), depOverwrite.Version) 85 } 86 87 sl, err := r.std.Fetch(ctx, mv) 88 if err != nil { 89 if r.isNotExistsOfCueRegistry(err) { 90 resp, err := r.local.Fetch(ctx, mv) 91 return resp, err 92 } 93 return module.SourceLoc{}, err 94 } 95 return sl, nil 96 } 97 98 func (r *registry) isNotExistsOfCueRegistry(err error) bool { 99 if err != nil { 100 errMsg := err.Error() 101 return strings.Contains(errMsg, "HTTP response 403") || strings.Contains(errMsg, "HTTP response 400") 102 } 103 return false 104 } 105 106 func (r *registry) Requirements(ctx context.Context, mv module.Version) ([]module.Version, error) { 107 if m, ok := r.mem.Resolve(mv.Path()); ok { 108 m.SourceLoc = module.SourceLocOfOSDir(r.mem.CacheDir(r.local.CacheDir, m.Module, m.Overwrites.Version)) 109 if err := m.Load(true); err != nil { 110 return nil, err 111 } 112 return m.DepVersions(), nil 113 } 114 115 if depOverwrite, ok := r.local.Root.GetDepOverwrite(mv.Path()); ok { 116 if depOverwrite.IsLocalReplacement() { 117 s, err := r.local.ResolveLocal(ctx, depOverwrite.Path) 118 if err != nil { 119 return nil, err 120 } 121 m := &module.Module{SourceLoc: s} 122 if err := m.Load(false); err != nil { 123 return nil, err 124 } 125 return m.DepVersions(), nil 126 } 127 s, err := r.local.Fetch(ctx, mv) 128 if err != nil { 129 return nil, err 130 } 131 m := &module.Module{ 132 SourceLoc: s, 133 } 134 if err := m.Load(false); err != nil { 135 return nil, err 136 } 137 return m.DepVersions(), nil 138 } 139 140 return r.std.Requirements(ctx, mv) 141 } 142 143 func (r *registry) ModuleVersions(ctx context.Context, mpath string) ([]string, error) { 144 if m, ok := r.mem.Resolve(mpath); ok { 145 return []string{m.Overwrites.Version}, nil 146 } 147 148 if depOverwrite, ok := r.local.Root.GetDepOverwrite(mpath); ok { 149 if depOverwrite.IsLocalReplacement() { 150 return []string{"v0.0.0"}, nil 151 } 152 } 153 154 versions, _ := r.local.ModuleVersions(ctx, mpath) 155 if len(versions) > 0 { 156 return versions, nil 157 } 158 159 versions2, _ := r.std.ModuleVersions(ctx, mpath) 160 return versions2, nil 161 }