1// Copyright 2015 The Go 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 5package main 6 7import ( 8 "fmt" 9 "io/ioutil" 10 "path/filepath" 11 "strings" 12) 13 14var ( 15 configPath string 16 cachedConfig map[string]string 17) 18 19// Config returns the code review config. 20// Configs consist of lines of the form "key: value". 21// Lines beginning with # are comments. 22// If there is no config, it returns an empty map. 23// If the config is malformed, it dies. 24func config() map[string]string { 25 if cachedConfig != nil { 26 return cachedConfig 27 } 28 configPath = filepath.Join(repoRoot(), "codereview.cfg") 29 b, err := ioutil.ReadFile(configPath) 30 raw := string(b) 31 if err != nil { 32 verbosef("%sfailed to load config from %q: %v", raw, configPath, err) 33 cachedConfig = make(map[string]string) 34 return cachedConfig 35 } 36 cachedConfig, err = parseConfig(raw) 37 if err != nil { 38 dief("%v", err) 39 } 40 return cachedConfig 41} 42 43// haveGerrit returns true if gerrit should be used. 44// To enable gerrit, codereview.cfg must be present with "gerrit" property set to 45// the gerrit https URL or the git origin must be to 46// "https://<project>.googlesource.com/<repo>". 47func haveGerrit() bool { 48 gerrit := config()["gerrit"] 49 origin := trim(cmdOutput("git", "config", "remote.origin.url")) 50 return haveGerritInternal(gerrit, origin) 51} 52 53// haveGerritInternal is the same as haveGerrit but factored out 54// for testing. 55func haveGerritInternal(gerrit, origin string) bool { 56 if gerrit == "off" { 57 return false 58 } 59 if gerrit != "" { 60 return true 61 } 62 if strings.Contains(origin, "github.com") { 63 return false 64 } 65 if strings.HasPrefix(origin, "sso://") || strings.HasPrefix(origin, "rpc://") { 66 return true 67 } 68 if !strings.Contains(origin, "https://") { 69 return false 70 } 71 if strings.Count(origin, "/") != 3 { 72 return false 73 } 74 host := origin[:strings.LastIndex(origin, "/")] 75 return strings.HasSuffix(host, ".googlesource.com") 76} 77 78func haveGitHub() bool { 79 origin := trim(cmdOutput("git", "config", "remote.origin.url")) 80 return strings.Contains(origin, "github.com") 81} 82 83func parseConfig(raw string) (map[string]string, error) { 84 cfg := make(map[string]string) 85 for _, line := range nonBlankLines(raw) { 86 line = strings.TrimSpace(line) 87 if strings.HasPrefix(line, "#") { 88 // comment line 89 continue 90 } 91 fields := strings.SplitN(line, ":", 2) 92 if len(fields) != 2 { 93 return nil, fmt.Errorf("bad config line, expected 'key: value': %q", line) 94 } 95 cfg[strings.TrimSpace(fields[0])] = strings.TrimSpace(fields[1]) 96 } 97 return cfg, nil 98} 99