get.porter.sh/porter@v1.3.0/pkg/mixin/pkgmgmt.go (about)

     1  package mixin
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"io"
     7  	"os/exec"
     8  
     9  	"get.porter.sh/porter/pkg/config"
    10  	"get.porter.sh/porter/pkg/pkgmgmt"
    11  	"get.porter.sh/porter/pkg/pkgmgmt/client"
    12  	"get.porter.sh/porter/pkg/tracing"
    13  	"go.uber.org/zap/zapcore"
    14  )
    15  
    16  const (
    17  	Directory = "mixins"
    18  )
    19  
    20  var _ MixinProvider = &PackageManager{}
    21  
    22  // PackageManager handles package management for mixins.
    23  type PackageManager struct {
    24  	*client.FileSystem
    25  }
    26  
    27  func NewPackageManager(c *config.Config) *PackageManager {
    28  	client := &PackageManager{
    29  		FileSystem: client.NewFileSystem(c, Directory),
    30  	}
    31  	client.PreRun = client.PreRunMixinCommandHandler
    32  	client.BuildMetadata = func() pkgmgmt.PackageMetadata {
    33  		return &Metadata{}
    34  	}
    35  	return client
    36  }
    37  
    38  func (c *PackageManager) PreRunMixinCommandHandler(command string, cmd *exec.Cmd) {
    39  	if !IsCoreMixinCommand(command) {
    40  		// For custom commands, don't call the mixin as "mixin CUSTOM" but as "mixin invoke --action CUSTOM"
    41  		for i := range cmd.Args {
    42  			if cmd.Args[i] == command {
    43  				cmd.Args[i] = "invoke"
    44  				break
    45  			}
    46  		}
    47  		cmd.Args = append(cmd.Args, "--action", command)
    48  	}
    49  }
    50  
    51  func (c *PackageManager) GetSchema(ctx context.Context, name string) (string, error) {
    52  	log := tracing.LoggerFromContext(ctx)
    53  
    54  	mixinDir, err := c.GetPackageDir(name)
    55  	if err != nil {
    56  		return "", err
    57  	}
    58  
    59  	r := client.NewRunner(name, mixinDir, false)
    60  
    61  	// Copy the existing context and tweak to pipe the output differently
    62  	mixinSchema := &bytes.Buffer{}
    63  	mixinContext := *c.Context
    64  	mixinContext.Out = mixinSchema
    65  	if !log.ShouldLog(zapcore.DebugLevel) {
    66  		mixinContext.Err = io.Discard
    67  	}
    68  	r.Context = &mixinContext
    69  
    70  	cmd := pkgmgmt.CommandOptions{Command: "schema", PreRun: c.PreRun}
    71  	err = r.Run(ctx, cmd)
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  
    76  	return mixinSchema.String(), nil
    77  }
    78  
    79  var _ pkgmgmt.PackageMetadata = Metadata{}
    80  
    81  // Metadata about an installed mixin.
    82  type Metadata = pkgmgmt.Metadata