go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/submodule_update/integration_update.go (about) 1 // Copyright 2023 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // integration_update uses jiri to find package and projects updates. 5 package main 6 7 import ( 8 "context" 9 "encoding/json" 10 "errors" 11 "flag" 12 "fmt" 13 "os" 14 15 "github.com/google/subcommands" 16 "go.fuchsia.dev/infra/cmd/submodule_update/gitutil" 17 "go.fuchsia.dev/infra/cmd/submodule_update/submodule" 18 ) 19 20 // integrationUpdateCmd is a subcommand that figure out what has changed in superpoject. 21 type integrationUpdateCmd struct { 22 baseCmd 23 updateConfig 24 // Skip add and commit changes 25 noCommit bool 26 jiriPath string 27 jiriGitPath string 28 } 29 30 // snapshotPaths is the list of snapshot paths imported from recipe. 31 type snapshotPaths struct { 32 Ensure string `json:"ensure"` 33 InternalEnsure string `json:"internal_ensure"` 34 InternalVersion string `json:"internal_version"` 35 Snapshot string `json:"snapshot"` 36 Version string `json:"version"` 37 } 38 39 // config imported from json input file. 40 type updateConfig struct { 41 Branch string `json:"branch"` 42 Author string `json:"commit_author_name"` 43 Email string `json:"commit_author_email"` 44 Message string `json:"commit_message"` 45 Project string `json:"project"` 46 CurrentRevision string `json:"current_revision"` 47 PreviousRevision string `json:"previous_revision"` 48 SnapshotPaths snapshotPaths `json:"snapshot_paths"` 49 SuperprojectRoot string `json:"superproject_path"` 50 JiriProjectsPath string `json:"jiri_projects_path"` 51 } 52 53 func (*integrationUpdateCmd) Name() string { return "integration_update" } 54 func (*integrationUpdateCmd) Synopsis() string { 55 return "Check integration updates." 56 } 57 func (*integrationUpdateCmd) Usage() string { 58 return "Find what projects and packages changed" 59 } 60 61 func (p *integrationUpdateCmd) SetFlags(f *flag.FlagSet) { 62 p.baseCmd.SetFlags(f) 63 f.StringVar(&p.jiriPath, "jiri_path", "", "location of jiri exe") 64 f.StringVar(&p.jiriGitPath, "jiri_git", "", "path to root of jiri checkout") 65 f.BoolVar(&p.noCommit, "no-commit", false, "do not commit") 66 } 67 68 func (p *integrationUpdateCmd) Validate() error { 69 if err := p.checkSuperproject(); err != nil { 70 return err 71 } 72 return nil 73 } 74 75 func (p *integrationUpdateCmd) ParseJSON() error { 76 // Read json inputs 77 jsonInputFile, err := os.ReadFile(p.jsonInput) 78 if err != nil { 79 return err 80 } 81 if err := json.Unmarshal(jsonInputFile, &p.updateConfig); err != nil { 82 return err 83 } 84 if p.CurrentRevision == "" { 85 return errors.New("current revision is missing") 86 } 87 // We don't check previous revision here, since it's not being used. 88 if p.updateConfig.Branch == "" { 89 return errors.New("commit branch is required") 90 } 91 if p.updateConfig.Project == "" { 92 return errors.New("commit project is required") 93 } 94 if p.updateConfig.Author == "" { 95 return errors.New("commit author is required") 96 } 97 if p.updateConfig.Email == "" { 98 return errors.New("commit author email is required") 99 } 100 if p.updateConfig.Message == "" { 101 return errors.New("commit message is required") 102 } 103 if p.updateConfig.JiriProjectsPath == "" { 104 return errors.New("jiri projects path is required") 105 } 106 if p.updateConfig.SuperprojectRoot == "" { 107 return errors.New("super project path is required") 108 } 109 return nil 110 } 111 112 func (p *integrationUpdateCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcommands.ExitStatus { 113 if err := p.Validate(); err != nil { 114 fmt.Printf("error: %s\n", err) 115 return subcommands.ExitFailure 116 } 117 if err := p.ParseJSON(); err != nil { 118 fmt.Printf("error: %s\n", err) 119 return subcommands.ExitFailure 120 } 121 fmt.Printf("Updating superproject %s to integration.git revision %s on branch %s\n", p.updateConfig.SuperprojectRoot, p.updateConfig.CurrentRevision, p.updateConfig.Branch) 122 fmt.Println() 123 124 scm := gitutil.New(gitutil.UserNameOpt(p.updateConfig.Author), gitutil.UserEmailOpt(p.updateConfig.Email), gitutil.RootDirOpt(p.updateConfig.SuperprojectRoot)) 125 cipdPaths := map[string]string{ 126 "ensure": p.updateConfig.SnapshotPaths.Ensure, 127 "version": p.updateConfig.SnapshotPaths.Version, 128 "internalEnsure": p.updateConfig.SnapshotPaths.InternalEnsure, 129 "internalVersion": p.updateConfig.SnapshotPaths.InternalVersion, 130 } 131 132 return submodule.UpdateSuperproject(scm, p.updateConfig.Message, p.updateConfig.JiriProjectsPath, cipdPaths, p.jsonOutput, p.noCommit, p.updateConfig.SuperprojectRoot) 133 }