cli/prepare.go
cli/prepare.goBrowse 1970 files
888 tokens
3,251 bytes
Token encoding: o200k_base
Snapshot 21a254f
← Back to SKILL.md
1package cli2 3import (4 "context"5 "encoding/json"6 "os"7 "path/filepath"8 9 "github.com/charmbracelet/log"10 "github.com/railwayapp/railpack/core"11 "github.com/urfave/cli/v3"12)13 14var PrepareCommand = &cli.Command{15 Name: "prepare",16 Aliases: []string{"p"},17 Usage: "prepares all the files necessary for a platform to build an app with the BuildKit frontend",18 ArgsUsage: "DIRECTORY",19 EnableShellCompletion: true,20 Flags: append([]cli.Flag{21 &cli.StringFlag{22 Name: "plan-out",23 Usage: "output file for the JSON serialized build plan",24 },25 &cli.StringFlag{26 Name: "info-out",27 Usage: "output file for the JSON serialized build result info",28 },29 &cli.BoolFlag{30 Name: "show-plan",31 Usage: "dump the build plan to stdout",32 },33 &cli.BoolFlag{34 Name: "hide-pretty-plan",35 Usage: "hide the pretty-printed build result output",36 },37 }, commonPlanFlags()...),38 Action: func(ctx context.Context, cmd *cli.Command) error {39 buildResult, _, _, err := GenerateBuildResultForCommand(cmd)40 if err != nil {41 return cli.Exit(err, exitCodeForError(err))42 }43 44 // Pretty print the result to stdout unless hidden45 if !cmd.Bool("hide-pretty-plan") {46 core.PrettyPrintBuildResult(buildResult, core.PrintOptions{Version: Version})47 }48 49 if !buildResult.Success {50 // still write the info file so callers can read the failure from it rather than stdout51 if err := writeInfoFile(cmd, buildResult); err != nil {52 return cli.Exit(err, ExitCodeFailure)53 }54 55 os.Exit(ExitCodeFailure)56 return nil57 }58 59 // Show plan to stdout if requested60 if cmd.Bool("show-plan") {61 planMap, err := addSchemaToPlanMap(buildResult.Plan)62 if err != nil {63 return cli.Exit(err, ExitCodeFailure)64 }65 serialized, err := json.MarshalIndent(planMap, "", " ")66 if err != nil {67 return cli.Exit(err, ExitCodeFailure)68 }69 _, _ = os.Stdout.Write(serialized)70 }71 72 // Save plan if requested73 if planOut := cmd.String("plan-out"); planOut != "" {74 // Include $schema in the plan JSON for editor support75 planMap, err := addSchemaToPlanMap(buildResult.Plan)76 if err != nil {77 return cli.Exit(err, ExitCodeFailure)78 }79 if err := writeJSONFile(planOut, planMap, "Build plan written to %s"); err != nil {80 return cli.Exit(err, ExitCodeFailure)81 }82 }83 84 if err := writeInfoFile(cmd, buildResult); err != nil {85 return cli.Exit(err, ExitCodeFailure)86 }87 88 return nil89 },90}91 92// writes the build result to the --info-out file, if one was requested. The plan is93// dropped from the copy since it is written separately with --plan-out.94func writeInfoFile(cmd *cli.Command, buildResult *core.BuildResult) error {95 infoOut := cmd.String("info-out")96 if infoOut == "" {97 return nil98 }99 100 info := *buildResult101 info.Plan = nil102 103 return writeJSONFile(infoOut, &info, "Build result info written to %s")104}105 106func writeJSONFile(path string, data any, logMessage string) error {107 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {108 return err109 }110 111 serialized, err := json.MarshalIndent(data, "", " ")112 if err != nil {113 return err114 }115 116 if err := os.WriteFile(path, serialized, 0644); err != nil {117 return err118 }119 120 log.Debugf(logMessage, path)121 return nil122}123