xref: /aosp_15_r20/external/licenseclassifier/tools/identify_license/identify_license.go (revision 46c4c49da23cae783fa41bf46525a6505638499a)
1// Copyright 2017 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// The identify_license program tries to identify the license type of an
16// unknown license. The file containing the license text is specified on the
17// command line. Multiple license files can be analyzed with a single command.
18// The type of the license is returned along with the confidence level of the
19// match. The confidence level is between 0.0 and 1.0, with 1.0 indicating an
20// exact match and 0.0 indicating a complete mismatch. The results are sorted
21// by confidence level.
22//
23//	$ identifylicense LICENSE1 LICENSE2
24//	LICENSE2: MIT (confidence: 0.987)
25//	LICENSE1: BSD-2-Clause (confidence: 0.833)
26package main
27
28import (
29	"context"
30	"flag"
31	"fmt"
32	"log"
33	"os"
34	"path/filepath"
35	"sort"
36	"time"
37
38	"github.com/google/licenseclassifier"
39	"github.com/google/licenseclassifier/tools/identify_license/backend"
40)
41
42var (
43	headers       = flag.Bool("headers", false, "match license headers")
44	forbiddenOnly = flag.Bool("forbidden", false, "identify using forbidden licenses archive")
45	threshold     = flag.Float64("threshold", licenseclassifier.DefaultConfidenceThreshold, "confidence threshold")
46	timeout       = flag.Duration("timeout", 24*time.Hour, "timeout before giving up on classifying a file.")
47)
48
49func init() {
50	flag.Usage = func() {
51		fmt.Fprintf(os.Stderr, `Usage: %s <licensefile> ...
52
53Identify an unknown license.
54
55Options:
56`, filepath.Base(os.Args[0]))
57		flag.PrintDefaults()
58	}
59}
60
61func main() {
62	flag.Parse()
63
64	be, err := backend.New(*threshold, *forbiddenOnly)
65	if err != nil {
66		be.Close()
67		log.Fatalf("cannot create license classifier: %v", err)
68	}
69
70	ctx, cancel := context.WithTimeout(context.Background(), *timeout)
71	defer cancel()
72	if errs := be.ClassifyLicensesWithContext(ctx, flag.Args(), *headers); errs != nil {
73		be.Close()
74		for _, err := range errs {
75			log.Printf("classify license failed: %v", err)
76		}
77		log.Fatal("cannot classify licenses")
78	}
79
80	results := be.GetResults()
81	if len(results) == 0 {
82		be.Close()
83		log.Fatal("Couldn't classify license(s)")
84	}
85
86	sort.Sort(results)
87	for _, r := range results {
88		fmt.Printf("%s: %s (confidence: %v, offset: %v, extent: %v)\n",
89			r.Filename, r.Name, r.Confidence, r.Offset, r.Extent)
90	}
91	be.Close()
92}
93