github.com/pojntfx/hydrapp/hydrapp@v0.0.0-20240516002902-d08759d6ca9f/pkg/builders/docs/builder.go (about) 1 package docs 2 3 import ( 4 "context" 5 "errors" 6 "io" 7 "path/filepath" 8 "strings" 9 10 "github.com/docker/docker/client" 11 "github.com/pojntfx/hydrapp/hydrapp/pkg/builders" 12 cconfig "github.com/pojntfx/hydrapp/hydrapp/pkg/config" 13 "github.com/pojntfx/hydrapp/hydrapp/pkg/executors" 14 "github.com/pojntfx/hydrapp/hydrapp/pkg/renderers" 15 "github.com/pojntfx/hydrapp/hydrapp/pkg/renderers/docs" 16 "github.com/pojntfx/hydrapp/hydrapp/pkg/utils" 17 uutils "github.com/pojntfx/hydrapp/hydrapp/pkg/utils" 18 ) 19 20 const ( 21 Image = "ghcr.io/pojntfx/hydrapp-build-docs" 22 ) 23 24 var ( 25 ErrInvalidRPMDistro = errors.New("invalid RPM distro") 26 ) 27 28 func NewBuilder( 29 ctx context.Context, 30 cli *client.Client, 31 32 image string, // OCI image to use 33 pull bool, // Whether to pull the image or not 34 src, // Input directory 35 dst string, // Output directory 36 onID func(id string), // Callback to handle container ID 37 stdout io.Writer, // Writer to handle container output 38 branchID, // Branch ID 39 branchName, // Branch name 40 goMain string, // Directory with the main package to build 41 cfg *cconfig.Root, // hydrapp config file 42 overwrite bool, // Overwrite files even if they exist 43 ) *Builder { 44 return &Builder{ 45 ctx, 46 cli, 47 48 image, 49 pull, 50 src, 51 dst, 52 onID, 53 stdout, 54 branchID, 55 branchName, 56 goMain, 57 cfg, 58 overwrite, 59 } 60 } 61 62 type Builder struct { 63 ctx context.Context 64 cli *client.Client 65 66 image string 67 pull bool 68 src, 69 dst string 70 onID func(id string) 71 stdout io.Writer 72 branchID, 73 branchName, 74 goMain string 75 cfg *cconfig.Root 76 overwrite bool 77 } 78 79 func (b *Builder) Render(workdir string, ejecting bool) error { 80 appID := builders.GetAppIDForBranch(b.cfg.App.ID, b.branchID) 81 appName := builders.GetAppNameForBranch(b.cfg.App.Name, b.branchName) 82 macOSBinaryName := builders.GetAppIDForBranch(b.cfg.App.ID, b.branchID) + ".darwin.dmg" 83 84 flatpaks := []docs.Artifact{} 85 for _, f := range b.cfg.Flatpak { 86 flatpaks = append(flatpaks, docs.Artifact{ 87 Architecture: f.Architecture, 88 URL: b.cfg.App.BaseURL + builders.GetPathForBranch(f.Path, b.branchID, "/") + "/hydrapp.flatpakrepo", 89 }) 90 } 91 92 msis := []docs.Artifact{} 93 for _, m := range b.cfg.MSI { 94 msis = append(msis, docs.Artifact{ 95 Architecture: m.Architecture, 96 URL: b.cfg.App.BaseURL + builders.GetPathForBranch(m.Path, b.branchID, "/") + "/" + builders.GetAppIDForBranch(b.cfg.App.ID, b.branchID) + ".windows-" + uutils.GetArchIdentifier(m.Architecture) + ".msi", 97 }) 98 } 99 100 rpms := []docs.DistroArtifact{} 101 for _, r := range b.cfg.RPM { 102 parts := strings.Split(r.Distro, "-") 103 if len(parts) < 2 { 104 return ErrInvalidRPMDistro 105 } 106 107 rpms = append(rpms, docs.DistroArtifact{ 108 Artifact: docs.Artifact{ 109 Architecture: r.Architecture, 110 URL: b.cfg.App.BaseURL + builders.GetPathForBranch(r.Path, b.branchID, "/") + "/repodata/hydrapp.repo", 111 }, 112 DistroName: parts[0], 113 DistroVersion: parts[1], 114 }) 115 } 116 117 debs := []docs.DistroArtifact{} 118 for _, d := range b.cfg.DEB { 119 debs = append(debs, docs.DistroArtifact{ 120 Artifact: docs.Artifact{ 121 Architecture: d.Architecture, 122 URL: b.cfg.App.BaseURL + builders.GetPathForBranch(d.Path, b.branchID, "/"), 123 }, 124 DistroName: d.OS, 125 DistroVersion: d.Distro, 126 }) 127 } 128 129 return utils.WriteRenders( 130 filepath.Join(workdir, b.goMain), 131 []renderers.Renderer{ 132 docs.NewInstallationRenderer( 133 appID, 134 appName, 135 b.cfg.App.BaseURL+builders.GetPathForBranch(b.cfg.APK.Path, b.branchID, "/")+"/repo", // F-Droid requires the path to end with `/repo`: `CRITICAL: repo_url needs to end with /repo` 136 b.cfg.App.BaseURL+builders.GetPathForBranch(b.cfg.DMG.Path, b.branchID, "/")+"/"+macOSBinaryName, 137 macOSBinaryName, 138 b.cfg.App.BaseURL+builders.GetPathForBranch(b.cfg.Binaries.Path, b.branchID, "/"), 139 flatpaks, 140 msis, 141 rpms, 142 debs, 143 strings.TrimSpace(b.cfg.DMG.Path) != "", 144 strings.TrimSpace(b.cfg.APK.Path) != "", 145 strings.TrimSpace(b.cfg.Binaries.Path) != "", 146 ), 147 }, 148 b.overwrite, 149 ejecting, 150 ) 151 } 152 153 func (b *Builder) Build() error { 154 dst := builders.GetFilepathForBranch(b.dst, b.branchID) 155 156 return executors.DockerRunImage( 157 b.ctx, 158 b.cli, 159 b.image, 160 b.pull, 161 true, 162 b.src, 163 dst, 164 b.onID, 165 b.stdout, 166 map[string]string{ 167 "GOMAIN": b.goMain, 168 }, 169 b.Render, 170 []string{}, 171 ) 172 }