github.com/abemedia/appcast@v0.4.0/integrations/yum/build.go (about) 1 package yum 2 3 import ( 4 "context" 5 "io/fs" 6 "log" 7 "os" 8 "path" 9 "strings" 10 "unsafe" 11 12 "github.com/abemedia/appcast/pkg/crypto/pgp" 13 "github.com/abemedia/appcast/source" 14 "github.com/abemedia/appcast/target" 15 ) 16 17 type Config struct { 18 Source *source.Source 19 Version string 20 Prerelease bool 21 Target target.Target 22 PGPKey *pgp.PrivateKey 23 } 24 25 //nolint:funlen,gocognit 26 func Build(ctx context.Context, c *Config) error { 27 repo, err := openRepo(ctx, c.Target) 28 if err != nil { 29 return err 30 } 31 defer os.RemoveAll(repo.dir) 32 33 version := c.Version 34 if v := getVersionConstraint(repo.primary.Package); v != "" { 35 version += "," + v 36 } 37 38 releases, err := c.Source.ListReleases(ctx, &source.ListOptions{ 39 Version: version, 40 Prerelease: c.Prerelease, 41 }) 42 if err == source.ErrNoReleaseFound { 43 return nil 44 } 45 if err != nil { 46 return err 47 } 48 49 var hasReleases bool 50 for _, release := range releases { 51 for _, asset := range release.Assets { 52 if path.Ext(asset.Name) != ".rpm" { 53 continue 54 } 55 b, err := c.Source.DownloadAsset(ctx, release.Version, asset.Name) 56 if err != nil { 57 return err 58 } 59 if err = repo.Add(b); err != nil { 60 return err 61 } 62 hasReleases = true 63 } 64 } 65 if !hasReleases { 66 return nil 67 } 68 69 if err = repo.Write(c.PGPKey); err != nil { 70 return err 71 } 72 73 files := os.DirFS(repo.dir) 74 err = fs.WalkDir(files, ".", func(path string, d fs.DirEntry, err error) error { 75 if err != nil || d.IsDir() { 76 return err 77 } 78 b, err := fs.ReadFile(files, path) 79 if err != nil { 80 return err 81 } 82 w, err := c.Target.NewWriter(ctx, path) 83 if err != nil { 84 return err 85 } 86 if _, err = w.Write(b); err != nil { 87 return err 88 } 89 return w.Close() 90 }) 91 if err != nil { 92 return err 93 } 94 95 for _, path := range repo.files { 96 if err = c.Target.Remove(ctx, path); err != nil { 97 log.Printf("Failed to delete %s: %s", path, err) 98 } 99 } 100 101 return nil 102 } 103 104 func getVersionConstraint(pkgs []Package) string { 105 if len(pkgs) == 0 { 106 return "" 107 } 108 109 v := make([]byte, 0, len(pkgs)*len("!=0.0.0,")) 110 for _, p := range pkgs { 111 v = append(v, '!', '=') 112 v = append(v, strings.Replace(p.Version.Ver, "~", "-", 1)...) 113 v = append(v, ',') 114 } 115 116 return unsafe.String(unsafe.SliceData(v), len(v)-1) 117 }