github.com/yourbase/yb@v0.7.1/cmd/yb/exec.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/spf13/cobra" 9 "github.com/yourbase/yb" 10 "github.com/yourbase/yb/internal/build" 11 "github.com/yourbase/yb/internal/ybdata" 12 "zombiezen.com/go/log" 13 ) 14 15 type execCmd struct { 16 execEnvName string 17 env []commandLineEnv 18 netrcFiles []string 19 mode executionMode 20 } 21 22 func newExecCmd() *cobra.Command { 23 b := new(execCmd) 24 c := &cobra.Command{ 25 Use: "exec", 26 Short: "Run the package", 27 Long: `Run the package using the instructions in the .yourbase.yml exec block.` + 28 "\n\n" + 29 `yb exec will search for the .yourbase.yml file in the current directory ` + 30 `and its parent directories. The exec block's commands will be run in the ` + 31 `directory the .yourbase.yml file appears in.`, 32 Args: cobra.NoArgs, 33 SilenceErrors: true, 34 SilenceUsage: true, 35 RunE: func(cmd *cobra.Command, args []string) error { 36 return b.run(cmd.Context()) 37 }, 38 } 39 envFlagsVar(c.Flags(), &b.env) 40 netrcFlagVar(c.Flags(), &b.netrcFiles) 41 executionModeVar(c.Flags(), &b.mode) 42 // TODO(light): Use a less confusing name for this flag when it is using targets. 43 c.Flags().StringVar(&b.execEnvName, "environment", yb.DefaultExecEnvironment, "Environment to run as") 44 return c 45 } 46 47 func (b *execCmd) run(ctx context.Context) error { 48 dataDirs, err := ybdata.DirsFromEnv() 49 if err != nil { 50 return err 51 } 52 downloader := ybdata.NewDownloader(dataDirs.Downloads()) 53 baseEnv, err := envFromCommandLine(b.env) 54 if err != nil { 55 return err 56 } 57 const useDocker = true 58 dockerClient, err := connectDockerClient(b.mode) 59 if err != nil { 60 return err 61 } 62 63 ctx = withLogOutput(ctx, os.Stdout) 64 pkg, _, err := findPackage() 65 if err != nil { 66 return err 67 } 68 execTarget := pkg.ExecEnvironments[b.execEnvName] 69 if execTarget == nil { 70 return fmt.Errorf("exec %s: no such environment", b.execEnvName) 71 } 72 showDockerWarningsIfNeeded(ctx, b.mode, []*yb.Target{execTarget}) 73 dockerNetworkID, removeNetwork, err := newDockerNetwork(ctx, dockerClient, b.mode, []*yb.Target{execTarget}) 74 if err != nil { 75 return err 76 } 77 defer removeNetwork() 78 bio, err := newBiome(ctx, execTarget, newBiomeOptions{ 79 packageDir: pkg.Path, 80 dataDirs: dataDirs, 81 downloader: downloader, 82 baseEnv: baseEnv, 83 netrcFiles: b.netrcFiles, 84 executionMode: b.mode, 85 dockerClient: dockerClient, 86 dockerNetworkID: dockerNetworkID, 87 }) 88 if err != nil { 89 return err 90 } 91 defer func() { 92 if err := bio.Close(); err != nil { 93 log.Warnf(ctx, "Clean up environment: %v", err) 94 } 95 }() 96 sys := build.Sys{ 97 Biome: bio, 98 Downloader: downloader, 99 DockerClient: dockerClient, 100 DockerNetworkID: dockerNetworkID, 101 Stdout: os.Stdout, 102 Stderr: os.Stderr, 103 } 104 execBiome, err := build.Setup(withLogPrefix(ctx, execTarget.Name+setupLogPrefix), sys, execTarget) 105 if err != nil { 106 return err 107 } 108 sys.Biome = execBiome 109 defer func() { 110 if err := execBiome.Close(); err != nil { 111 log.Errorf(ctx, "Clean up environment %s: %v", b.execEnvName, err) 112 } 113 }() 114 return build.Execute(ctx, sys, announceCommand(os.Stdout), execTarget) 115 }