go.fuchsia.dev/jiri@v0.0.0-20240502161911-b66513b29486/cmd/jiri/check_clean.go (about) 1 // Copyright 2022 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "sort" 12 13 "go.fuchsia.dev/jiri" 14 "go.fuchsia.dev/jiri/cmdline" 15 "go.fuchsia.dev/jiri/gitutil" 16 "go.fuchsia.dev/jiri/project" 17 ) 18 19 var cmdCheckClean = &cmdline.Command{ 20 Runner: jiri.RunnerFunc(runCheckClean), 21 Name: "check-clean", 22 Short: "Checks if the checkout is clean", 23 Long: ` 24 Exits non-zero and prints repositories (and their status) if they contain 25 uncommitted changes. 26 `, 27 } 28 29 func runCheckClean(jirix *jiri.X, args []string) error { 30 localProjects, err := project.LocalProjects(jirix, project.FastScan) 31 if err != nil { 32 return err 33 } 34 cDir, err := os.Getwd() 35 if err != nil { 36 return err 37 } 38 states, err := project.GetProjectStates(jirix, localProjects, false) 39 if err != nil { 40 return err 41 } 42 var keys project.ProjectKeys 43 for key := range localProjects { 44 keys = append(keys, key) 45 } 46 sort.Sort(keys) 47 dirtyProjects := make(map[string]string) 48 for _, key := range keys { 49 localProject := localProjects[key] 50 state, ok := states[key] 51 if !ok { 52 // this should not happen 53 panic(fmt.Sprintf("State not found for project %q", localProject.Name)) 54 } 55 if statusFlags.branch != "" && (statusFlags.branch != state.CurrentBranch.Name) { 56 continue 57 } 58 relativePath, err := filepath.Rel(cDir, localProject.Path) 59 if err != nil { 60 return err 61 } 62 scm := gitutil.New(jirix, gitutil.RootDirOpt(localProject.Path)) 63 changes, err := scm.ShortStatus() 64 if err != nil { 65 jirix.Logger.Errorf("%s :%s\n\n", fmt.Sprintf("getting changes for project %s(%s)", localProject.Name, relativePath), err) 66 jirix.IncrementFailures() 67 continue 68 } 69 if changes != "" { 70 dirtyProjects[relativePath] = changes 71 } 72 } 73 var finalErr error 74 if jirix.Failures() != 0 { 75 finalErr = fmt.Errorf("completed with non-fatal errors") 76 } else if len(dirtyProjects) > 0 { 77 finalErr = fmt.Errorf("Checkout is not clean!") 78 } 79 80 if len(dirtyProjects) > 0 { 81 fmt.Println("Dirty projects:") 82 for relativePath, changes := range dirtyProjects { 83 fmt.Printf("%s\n%s\n\n", relativePath, changes) 84 } 85 } 86 87 return finalErr 88 }