github.com/wolfi-dev/wolfictl@v0.16.11/pkg/distro/detectv2.go (about) 1 package distro 2 3 import ( 4 "fmt" 5 "os" 6 "slices" 7 8 "github.com/go-git/go-git/v5" 9 ) 10 11 // DetectV2 tries to detect which distro the user wants to operate on by seeing 12 // if the current working directory is the distro's packages repo. No 13 // advisory-related repositories are detected. 14 func DetectV2() (Distro, error) { 15 cwd, err := os.Getwd() 16 if err != nil { 17 return Distro{}, err 18 } 19 20 d, err := DetectFromDirV2(cwd) 21 if err != nil { 22 return Distro{}, err 23 } 24 25 return d, nil 26 } 27 28 // DetectFromDirV2 tries to identify a Distro by inspecting the given directory 29 // to see if it is a repository for a distro's packages. 30 func DetectFromDirV2(dir string) (Distro, error) { 31 distro, err := identifyDistroFromLocalPackagesRepoDir(dir) 32 if err != nil { 33 return Distro{}, err 34 } 35 36 forkPoint, err := findRepoForkPoint(distro.Local.PackagesRepo.Dir, distro.Local.PackagesRepo.UpstreamName) 37 if err != nil { 38 return Distro{}, err 39 } 40 distro.Local.PackagesRepo.ForkPoint = forkPoint 41 42 return distro, nil 43 } 44 45 var ErrNotPackagesRepo = fmt.Errorf("directory is not a distro (packages) repository") 46 47 func identifyDistroFromLocalPackagesRepoDir(dir string) (Distro, error) { 48 repo, err := git.PlainOpen(dir) 49 if err != nil { 50 return Distro{}, fmt.Errorf("unable to identify distro: couldn't open git repo: %v: %w", err, ErrNotDistroRepo) 51 } 52 53 config, err := repo.Config() 54 if err != nil { 55 return Distro{}, err 56 } 57 58 for _, remoteConfig := range config.Remotes { 59 urls := remoteConfig.URLs 60 if len(urls) == 0 { 61 continue 62 } 63 64 url := urls[0] 65 66 for _, d := range []AbsoluteProperties{wolfiDistro, chainguardDistro, extraPackagesDistro} { 67 // Fill in the local properties that we can cheaply here. We'll fill in the rest 68 // later, outside of this function call. 69 70 if slices.Contains(d.DistroRemoteURLs(), url) { 71 return Distro{ 72 Absolute: d, 73 Local: LocalProperties{ 74 PackagesRepo: LocalRepo{ 75 Dir: dir, 76 UpstreamName: remoteConfig.Name, 77 ForkPoint: "", // This is slightly expensive to compute, so we do it later and only once per repo. 78 }, 79 }, 80 }, nil 81 } 82 } 83 } 84 85 return Distro{}, ErrNotPackagesRepo 86 }