github.com/kubri/kubri@v0.5.1-0.20240317001612-bda2aaef967e/pkg/cmd/build.go (about)

     1  package cmd
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"log"
     8  	"time"
     9  
    10  	"github.com/spf13/cobra"
    11  	"golang.org/x/sync/errgroup"
    12  
    13  	"github.com/kubri/kubri/integrations/apk"
    14  	"github.com/kubri/kubri/integrations/appinstaller"
    15  	"github.com/kubri/kubri/integrations/apt"
    16  	"github.com/kubri/kubri/integrations/sparkle"
    17  	"github.com/kubri/kubri/integrations/yum"
    18  	"github.com/kubri/kubri/pkg/config"
    19  )
    20  
    21  func buildCmd() *cobra.Command {
    22  	var configPath string
    23  
    24  	cmd := &cobra.Command{
    25  		Use:     "build",
    26  		Short:   "Publish packages for common package managers and software update frameworks",
    27  		Aliases: []string{"b"},
    28  		RunE: func(cmd *cobra.Command, _ []string) error {
    29  			p, err := config.Load(configPath)
    30  			if err != nil {
    31  				return err
    32  			}
    33  
    34  			integrations := []struct {
    35  				name string
    36  				fn   func(ctx context.Context) error
    37  			}{
    38  				{"APK", fn(apk.Build, p.Apk)},
    39  				{"App Installer", fn(appinstaller.Build, p.Appinstaller)},
    40  				{"APT", fn(apt.Build, p.Apt)},
    41  				{"YUM", fn(yum.Build, p.Yum)},
    42  				{"Sparkle", fn(sparkle.Build, p.Sparkle)},
    43  			}
    44  
    45  			var n int
    46  			start := time.Now()
    47  			g, ctx := errgroup.WithContext(cmd.Context())
    48  
    49  			for _, integration := range integrations {
    50  				if integration.fn != nil {
    51  					integration := integration
    52  					n++
    53  					g.Go(func() error {
    54  						log.Print("Publishing " + integration.name + " packages...")
    55  						if err := integration.fn(ctx); err != nil {
    56  							return fmt.Errorf("failed to publish "+integration.name+" packages: %w", err)
    57  						}
    58  						log.Print("Completed publishing " + integration.name + " packages.")
    59  						return nil
    60  					})
    61  				}
    62  			}
    63  
    64  			if n == 0 {
    65  				return errors.New("no integrations configured")
    66  			}
    67  
    68  			if err := g.Wait(); err != nil {
    69  				return err
    70  			}
    71  
    72  			log.Printf("Completed in %s", time.Since(start).Truncate(time.Millisecond))
    73  
    74  			return nil
    75  		},
    76  	}
    77  
    78  	cmd.Flags().StringVarP(&configPath, "config", "c", "", "load configuration from a file")
    79  
    80  	return cmd
    81  }
    82  
    83  func fn[C any, F func(ctx context.Context, c *C) error](fn F, config *C) func(ctx context.Context) error {
    84  	if config == nil {
    85  		return nil
    86  	}
    87  	return func(ctx context.Context) error {
    88  		return fn(ctx, config)
    89  	}
    90  }