blob: 30281ab351ef722f093d50a30932c0dc70ffad89 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors.All rights reserved.
// Use of this source code is governed by a BSD - style license that can be
// found in the LICENSE file.
// This script is useful for checking whether the current source files under a
// uboringssl directory are compatible with those in a boringssl repository.
// This can be used to determine whether any upstream changes need to be ported
// from boringssl to uboringssl.
package main
import (
"bufio"
"flag"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
const (
DefaultBoringSSL = "//third_party/boringssl"
DefaultZircon = "//zircon/third_party/ulib/uboringssl"
)
// These files are special; they are either auto-generated, manually modified, or explicitly added.
var skipped_files = map[string]bool {
"/crypto/cpu-aarch64-zircon.cpp": true,
"/crypto/err/err_data.c": true,
"/include/openssl/base.h": true,
}
// GetRealPath returns a canonical path, with '//' replaced by $FUCHSIA_DIR
func GetRealPath(path string) string {
if strings.HasPrefix(path, "//") {
root, set := os.LookupEnv("FUCHSIA_DIR")
if !set {
log.Fatal("FUCHSIA_DIR not set")
}
path = root + string(os.PathSeparator) + path[2:]
}
var err error
if path, err = filepath.Abs(path); err != nil {
log.Fatal(err)
}
if path, err = filepath.EvalSymlinks(path); err !=nil {
log.Fatal(err)
}
return path
}
// CheckReadMe returns whether the README.fuchsia.md in uboringssl references
// the current boringssl revision or not.
func CheckReadMe(zxRoot, bsslRoot string) bool {
cmd := exec.Command("git", "log", "-n1", "--pretty=%H")
cmd.Dir = bsslRoot
out, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
file, err := os.Open(zxRoot + string(os.PathSeparator) + "README.fuchsia.md")
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if strings.Contains(scanner.Text(), strings.TrimSpace(string(out))) {
return true
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
return false
}
// ReadNextLine reads the next newline-delimited line of text from a source
// file, skipping over _KERNEL guards and any code within __Fuchsia__ guards.
func ReadNextLine(scanner *bufio.Scanner) (string, bool) {
ignoring := false
for scanner.Scan() {
text := scanner.Text()
if ignoring || strings.Contains(text, "_KERNEL") {
continue
}
if strings.Contains(text, "__Fuchsia__") {
ignoring = !ignoring
continue
}
return text, true
}
err := scanner.Err()
if err != nil {
log.Fatal(err)
}
return "", false
}
// IsSameFile returns whether a uboringssl and boringssl file match, except
// for the allowable differences that are ignored by ReadNextLine.
func IsSameFile(zxPath string, bsslPath string) bool {
same := true
zxFile, err := os.Open(zxPath)
if err != nil {
log.Fatal(err)
}
bsslFile, err := os.Open(bsslPath)
if err != nil {
log.Fatal(err)
}
zxScan := bufio.NewScanner(zxFile)
bsslScan := bufio.NewScanner(bsslFile)
zxText, zxMore := ReadNextLine(zxScan)
bsslText, bsslMore := ReadNextLine(bsslScan)
for zxMore && bsslMore {
if !zxMore {
bsslText, bsslMore = ReadNextLine(bsslScan)
same = false
continue
}
if !bsslMore {
zxText, zxMore = ReadNextLine(zxScan)
same = false
continue
}
if zxText != bsslText {
same = false
}
zxText, zxMore = ReadNextLine(zxScan)
bsslText, bsslMore = ReadNextLine(bsslScan)
}
return same
}
// CompareAll walks the files in uboringssl and checks whether each is a
// valid addition or matches a corresponding file in boringssl.
func CompareAll(zxRoot, bsslRoot string) []string {
files := []string{}
walker := func(zxPath string, zxInfo os.FileInfo, err error) error {
if err != nil {
return err
}
if zxInfo.IsDir() {
return nil
}
stem := zxPath[len(zxRoot):]
if skipped_files[stem] {
return nil
}
bsslPath := bsslRoot + stem
if _, err = os.Stat(bsslPath); err != nil || !IsSameFile(zxPath, bsslPath) {
files = append(files, stem)
}
return nil
}
stems := []string{"crypto", "decrepit", "include"}
for _, stem := range stems {
path := zxRoot + string(os.PathSeparator) + stem
if err := filepath.Walk(path, walker); err != nil {
log.Fatal(err)
}
}
return files
}
// Main function
func main() {
bsslFlag := flag.String("boringssl", DefaultBoringSSL, "BoringSSL repository")
zxFlag := flag.String("uboringssl", DefaultZircon, "uboringssl path")
flag.Parse()
zxRoot := GetRealPath(*zxFlag)
bsslRoot := GetRealPath(*bsslFlag)
ready := CheckReadMe(zxRoot, bsslRoot)
if !ready {
fmt.Println("[-] The README file needs to be updated.")
}
files := CompareAll(zxRoot, bsslRoot)
if len(files) != 0 {
fmt.Println("[-] The following files do not match:")
for _, file := range files {
fmt.Println("[-] " + file)
}
ready = false
}
if ready {
fmt.Printf("[+] %s and %s are in sync.\n", *zxFlag, *bsslFlag)
} else {
fmt.Printf("\n[-] %s and %s are NOT in sync.\n", *zxFlag, *bsslFlag)
}
}