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  }