forked from google/go-licenses
/
classifier.go
101 lines (91 loc) · 3.52 KB
/
classifier.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright 2019 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package licenses
import (
"fmt"
"io/ioutil"
"github.com/google/licenseclassifier"
)
// Type identifies a class of software license.
type Type string
// License types
const (
// Unknown license type.
Unknown = Type("")
// Restricted licenses require mandatory source distribution if we ship a
// product that includes third-party code protected by such a license.
Restricted = Type("restricted")
// Reciprocal licenses allow usage of software made available under such
// licenses freely in *unmodified* form. If the third-party source code is
// modified in any way these modifications to the original third-party
// source code must be made available.
Reciprocal = Type("reciprocal")
// Notice licenses contain few restrictions, allowing original or modified
// third-party software to be shipped in any product without endangering or
// encumbering our source code. All of the licenses in this category do,
// however, have an "original Copyright notice" or "advertising clause",
// wherein any external distributions must include the notice or clause
// specified in the license.
Notice = Type("notice")
// Permissive licenses are even more lenient than a 'notice' license.
// Not even a copyright notice is required for license compliance.
Permissive = Type("permissive")
// Unencumbered covers licenses that basically declare that the code is "free for any use".
Unencumbered = Type("unencumbered")
// Forbidden licenses are forbidden to be used.
Forbidden = Type("FORBIDDEN")
)
func (t Type) String() string {
switch t {
case Unknown:
// licenseclassifier uses an empty string to indicate an unknown license
// type, which is unclear to users when printed as a string.
return "unknown"
default:
return string(t)
}
}
// Classifier can detect the type of a software license.
type Classifier interface {
Identify(licensePath string) (string, Type, error)
}
type googleClassifier struct {
classifier *licenseclassifier.License
}
// NewClassifier creates a classifier that requires a specified confidence threshold
// in order to return a positive license classification.
func NewClassifier(confidenceThreshold float64, options ...licenseclassifier.OptionFunc) (Classifier, error) {
c, err := licenseclassifier.New(confidenceThreshold, options...)
if err != nil {
return nil, err
}
return &googleClassifier{classifier: c}, nil
}
// Identify returns the name and type of a license, given its file path.
// An empty license path results in an empty name and Unknown type.
func (c *googleClassifier) Identify(licensePath string) (string, Type, error) {
if licensePath == "" {
return "", Unknown, nil
}
content, err := ioutil.ReadFile(licensePath)
if err != nil {
return "", "", err
}
matches := c.classifier.MultipleMatch(string(content), true)
if len(matches) == 0 {
return "", "", fmt.Errorf("unknown license")
}
licenseName := matches[0].Name
return licenseName, Type(licenseclassifier.LicenseType(licenseName)), nil
}