1// Copyright 2019 Google LLC.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package api
6
7import (
8	"bytes"
9	"io/ioutil"
10	"os"
11	"path/filepath"
12	"regexp"
13	"testing"
14)
15
16// Files in this package use a BSD-style license.
17var sentinel = regexp.MustCompile(`(//|#) Copyright \d\d\d\d (Google LLC|The Go Authors)(\.)*( All rights reserved\.)*
18(//|#) Use of this source code is governed by a BSD-style
19(//|#) license that can be found in the LICENSE file.
20`)
21
22const prefix = "// Copyright"
23
24// A few files have to be skipped.
25var skip = map[string]bool{
26	"tools.go": true, // This file requires another comment above the license.
27	"internal/third_party/uritemplates/uritemplates.go":      true, // This file is licensed to an individual.
28	"internal/third_party/uritemplates/uritemplates_test.go": true, // This file is licensed to an individual.
29}
30
31// This test validates that all go files in the repo start with an appropriate license.
32func TestLicense(t *testing.T) {
33	err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error {
34		if skip[path] {
35			return nil
36		}
37
38		if err != nil {
39			return err
40		}
41
42		if filepath.Ext(path) != ".go" && filepath.Ext(path) != ".sh" {
43			return nil
44		}
45
46		src, err := ioutil.ReadFile(path)
47		if err != nil {
48			return nil
49		}
50
51		// Verify that the license is matched.
52		if !sentinel.Match(src) {
53			t.Errorf("%v: license header not present", path)
54			return nil
55		}
56
57		// Also check it is at the top of .go files (but not .sh files, because they must have a shebang first).
58		if filepath.Ext(path) == ".go" && !bytes.HasPrefix(src, []byte(prefix)) {
59			t.Errorf("%v: license header not at the top", path)
60		}
61		return nil
62	})
63	if err != nil {
64		t.Fatal(err)
65	}
66}
67