Update build_broken_logs script
This can now discover which make module types have been deprecated and suggest what needs to happen with the BUILD_BROKEN_USES_* flags. Bug: 130720555 Test: go run .../build_broken_logs.go * (see header comment) Change-Id: Iffaa32c0b0079e99b926162257a7c15c530c15a1
This commit is contained in:
parent
f9192060bd
commit
9dfaa06e45
1 changed files with 115 additions and 45 deletions
|
@ -54,11 +54,13 @@ const (
|
|||
DefaultDeprecated
|
||||
)
|
||||
|
||||
var buildBrokenSettings = []struct {
|
||||
type Setting struct {
|
||||
name string
|
||||
behavior BuildBrokenBehavior
|
||||
warnings []string
|
||||
}{
|
||||
}
|
||||
|
||||
var buildBrokenSettings = []Setting{
|
||||
{
|
||||
name: "BUILD_BROKEN_DUP_RULES",
|
||||
behavior: DefaultFalse,
|
||||
|
@ -68,6 +70,19 @@ var buildBrokenSettings = []struct {
|
|||
name: "BUILD_BROKEN_USES_NETWORK",
|
||||
behavior: DefaultDeprecated,
|
||||
},
|
||||
{
|
||||
name: "BUILD_BROKEN_USES_BUILD_COPY_HEADERS",
|
||||
behavior: DefaultTrue,
|
||||
warnings: []string{
|
||||
"COPY_HEADERS has been deprecated",
|
||||
"COPY_HEADERS is deprecated",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Branch struct {
|
||||
Settings []Setting
|
||||
Logs []ProductLog
|
||||
}
|
||||
|
||||
type ProductBranch struct {
|
||||
|
@ -82,35 +97,48 @@ type ProductLog struct {
|
|||
}
|
||||
|
||||
type Log struct {
|
||||
BuildBroken []*bool
|
||||
HasBroken []bool
|
||||
WarningModuleTypes []string
|
||||
ErrorModuleTypes []string
|
||||
|
||||
BuildBroken map[string]*bool
|
||||
HasBroken map[string]int
|
||||
}
|
||||
|
||||
func Merge(l, l2 Log) Log {
|
||||
if len(l.BuildBroken) == 0 {
|
||||
l.BuildBroken = make([]*bool, len(buildBrokenSettings))
|
||||
if l.BuildBroken == nil {
|
||||
l.BuildBroken = map[string]*bool{}
|
||||
}
|
||||
if len(l.HasBroken) == 0 {
|
||||
l.HasBroken = make([]bool, len(buildBrokenSettings))
|
||||
if l.HasBroken == nil {
|
||||
l.HasBroken = map[string]int{}
|
||||
}
|
||||
|
||||
if len(l.BuildBroken) != len(l2.BuildBroken) || len(l.HasBroken) != len(l2.HasBroken) {
|
||||
panic("mis-matched logs")
|
||||
}
|
||||
|
||||
for i, v := range l.BuildBroken {
|
||||
for n, v := range l.BuildBroken {
|
||||
if v == nil {
|
||||
l.BuildBroken[i] = l2.BuildBroken[i]
|
||||
l.BuildBroken[n] = l2.BuildBroken[n]
|
||||
}
|
||||
}
|
||||
for i := range l.HasBroken {
|
||||
l.HasBroken[i] = l.HasBroken[i] || l2.HasBroken[i]
|
||||
for n, v := range l2.BuildBroken {
|
||||
if _, ok := l.BuildBroken[n]; !ok {
|
||||
l.BuildBroken[n] = v
|
||||
}
|
||||
}
|
||||
|
||||
for n := range l.HasBroken {
|
||||
if l.HasBroken[n] < l2.HasBroken[n] {
|
||||
l.HasBroken[n] = l2.HasBroken[n]
|
||||
}
|
||||
}
|
||||
for n := range l2.HasBroken {
|
||||
if _, ok := l.HasBroken[n]; !ok {
|
||||
l.HasBroken[n] = l2.HasBroken[n]
|
||||
}
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func PrintResults(products []ProductLog) {
|
||||
func PrintResults(branch Branch) {
|
||||
products := branch.Logs
|
||||
devices := map[string]Log{}
|
||||
deviceNames := []string{}
|
||||
|
||||
|
@ -124,39 +152,48 @@ func PrintResults(products []ProductLog) {
|
|||
|
||||
sort.Strings(deviceNames)
|
||||
|
||||
for i, setting := range buildBrokenSettings {
|
||||
for _, setting := range branch.Settings {
|
||||
printed := false
|
||||
n := setting.name
|
||||
|
||||
for _, device := range deviceNames {
|
||||
log := devices[device]
|
||||
|
||||
if setting.behavior == DefaultTrue {
|
||||
if log.BuildBroken[i] == nil || *log.BuildBroken[i] == false {
|
||||
if log.HasBroken[i] {
|
||||
if log.BuildBroken[n] == nil || *log.BuildBroken[n] == false {
|
||||
if log.HasBroken[n] > 0 {
|
||||
printed = true
|
||||
fmt.Printf(" %s needs to set %s := true\n", device, setting.name)
|
||||
plural := ""
|
||||
if log.HasBroken[n] > 1 {
|
||||
plural = "s"
|
||||
}
|
||||
} else if !log.HasBroken[i] {
|
||||
fmt.Printf(" %s needs to set %s := true (%d instance%s)\n", device, setting.name, log.HasBroken[n], plural)
|
||||
}
|
||||
} else if log.HasBroken[n] == 0 {
|
||||
printed = true
|
||||
fmt.Printf(" %s sets %s := true, but does not need it\n", device, setting.name)
|
||||
}
|
||||
} else if setting.behavior == DefaultFalse {
|
||||
if log.BuildBroken[i] == nil {
|
||||
if log.BuildBroken[n] == nil {
|
||||
// Nothing to be done
|
||||
} else if *log.BuildBroken[i] == false {
|
||||
} else if *log.BuildBroken[n] == false {
|
||||
printed = true
|
||||
fmt.Printf(" %s sets %s := false, which is the default and can be removed\n", device, setting.name)
|
||||
} else if !log.HasBroken[i] {
|
||||
} else if log.HasBroken[n] == 0 {
|
||||
printed = true
|
||||
fmt.Printf(" %s sets %s := true, but does not need it\n", device, setting.name)
|
||||
}
|
||||
} else if setting.behavior == DefaultDeprecated {
|
||||
if log.BuildBroken[i] != nil {
|
||||
if log.BuildBroken[n] != nil {
|
||||
printed = true
|
||||
if log.HasBroken[i] {
|
||||
fmt.Printf(" %s sets %s := %v, which is deprecated, but has failures\n", device, setting.name, *log.BuildBroken[i])
|
||||
if log.HasBroken[n] > 0 {
|
||||
plural := ""
|
||||
if log.HasBroken[n] > 1 {
|
||||
plural = "s"
|
||||
}
|
||||
fmt.Printf(" %s sets %s := %v, which is deprecated, but has %d failure%s\n", device, setting.name, *log.BuildBroken[n], log.HasBroken[n], plural)
|
||||
} else {
|
||||
fmt.Printf(" %s sets %s := %v, which is deprecated and can be removed\n", device, setting.name, *log.BuildBroken[i])
|
||||
fmt.Printf(" %s sets %s := %v, which is deprecated and can be removed\n", device, setting.name, *log.BuildBroken[n])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,17 +205,45 @@ func PrintResults(products []ProductLog) {
|
|||
}
|
||||
}
|
||||
|
||||
func ParseBranch(name string) []ProductLog {
|
||||
func ParseBranch(name string) Branch {
|
||||
products, err := filepath.Glob(filepath.Join(name, "*"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ret := []ProductLog{}
|
||||
ret := Branch{Logs: []ProductLog{}}
|
||||
for _, product := range products {
|
||||
product = filepath.Base(product)
|
||||
|
||||
ret = append(ret, ParseProduct(ProductBranch{Branch: name, Name: product}))
|
||||
ret.Logs = append(ret.Logs, ParseProduct(ProductBranch{Branch: name, Name: product}))
|
||||
}
|
||||
|
||||
ret.Settings = append(ret.Settings, buildBrokenSettings...)
|
||||
if len(ret.Logs) > 0 {
|
||||
for _, mtype := range ret.Logs[0].WarningModuleTypes {
|
||||
if mtype == "BUILD_COPY_HEADERS" || mtype == "" {
|
||||
continue
|
||||
}
|
||||
ret.Settings = append(ret.Settings, Setting{
|
||||
name: "BUILD_BROKEN_USES_" + mtype,
|
||||
behavior: DefaultTrue,
|
||||
warnings: []string{mtype + " has been deprecated"},
|
||||
})
|
||||
}
|
||||
for _, mtype := range ret.Logs[0].ErrorModuleTypes {
|
||||
if mtype == "BUILD_COPY_HEADERS" || mtype == "" {
|
||||
continue
|
||||
}
|
||||
ret.Settings = append(ret.Settings, Setting{
|
||||
name: "BUILD_BROKEN_USES_" + mtype,
|
||||
behavior: DefaultFalse,
|
||||
warnings: []string{mtype + " has been deprecated"},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, productLog := range ret.Logs {
|
||||
ScanProduct(ret.Settings, productLog)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
@ -192,15 +257,15 @@ func ParseProduct(p ProductBranch) ProductLog {
|
|||
ret := ProductLog{
|
||||
ProductBranch: p,
|
||||
Log: Log{
|
||||
BuildBroken: make([]*bool, len(buildBrokenSettings)),
|
||||
HasBroken: make([]bool, len(buildBrokenSettings)),
|
||||
BuildBroken: map[string]*bool{},
|
||||
HasBroken: map[string]int{},
|
||||
},
|
||||
}
|
||||
|
||||
lines := strings.Split(string(soongLog), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Split(line, " ")
|
||||
if len(fields) != 5 {
|
||||
if len(fields) < 5 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -208,30 +273,35 @@ func ParseProduct(p ProductBranch) ProductLog {
|
|||
ret.Device = fields[4]
|
||||
}
|
||||
|
||||
if fields[3] == "DEFAULT_WARNING_BUILD_MODULE_TYPES" {
|
||||
ret.WarningModuleTypes = fields[4:]
|
||||
}
|
||||
if fields[3] == "DEFAULT_ERROR_BUILD_MODULE_TYPES" {
|
||||
ret.ErrorModuleTypes = fields[4:]
|
||||
}
|
||||
|
||||
if strings.HasPrefix(fields[3], "BUILD_BROKEN_") {
|
||||
for i, setting := range buildBrokenSettings {
|
||||
if setting.name == fields[3] {
|
||||
ret.BuildBroken[i] = ParseBoolPtr(fields[4])
|
||||
}
|
||||
}
|
||||
ret.BuildBroken[fields[3]] = ParseBoolPtr(fields[4])
|
||||
}
|
||||
}
|
||||
|
||||
stdLog, err := ioutil.ReadFile(filepath.Join(p.Branch, p.Name, "std_full.log"))
|
||||
return ret
|
||||
}
|
||||
|
||||
func ScanProduct(settings []Setting, l ProductLog) {
|
||||
stdLog, err := ioutil.ReadFile(filepath.Join(l.Branch, l.Name, "std_full.log"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stdStr := string(stdLog)
|
||||
|
||||
for i, setting := range buildBrokenSettings {
|
||||
for _, setting := range settings {
|
||||
for _, warning := range setting.warnings {
|
||||
if strings.Contains(stdStr, warning) {
|
||||
ret.HasBroken[i] = true
|
||||
l.HasBroken[setting.name] += strings.Count(stdStr, warning)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func ParseBoolPtr(str string) *bool {
|
||||
|
|
Loading…
Reference in a new issue