1// Copyright © 2015 Steve Francia <spf@spf13.com>.
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// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Parts inspired by https://github.com/ryanuber/go-license
15
16package cmd
17
18import (
19	"strings"
20	"time"
21
22	"github.com/spf13/viper"
23)
24
25// Licenses contains all possible licenses a user can choose from.
26var Licenses = make(map[string]License)
27
28// License represents a software license agreement, containing the Name of
29// the license, its possible matches (on the command line as given to cobra),
30// the header to be used with each file on the file's creating, and the text
31// of the license
32type License struct {
33	Name            string   // The type of license in use
34	PossibleMatches []string // Similar names to guess
35	Text            string   // License text data
36	Header          string   // License header for source files
37}
38
39func init() {
40	// Allows a user to not use a license.
41	Licenses["none"] = License{"None", []string{"none", "false"}, "", ""}
42
43	initApache2()
44	initMit()
45	initBsdClause3()
46	initBsdClause2()
47	initGpl2()
48	initGpl3()
49	initLgpl()
50	initAgpl()
51}
52
53// getLicense returns license specified by user in flag or in config.
54// If user didn't specify the license, it returns Apache License 2.0.
55//
56// TODO: Inspect project for existing license
57func getLicense() License {
58	// If explicitly flagged, use that.
59	if userLicense != "" {
60		return findLicense(userLicense)
61	}
62
63	// If user wants to have custom license, use that.
64	if viper.IsSet("license.header") || viper.IsSet("license.text") {
65		return License{Header: viper.GetString("license.header"),
66			Text: viper.GetString("license.text")}
67	}
68
69	// If user wants to have built-in license, use that.
70	if viper.IsSet("license") {
71		return findLicense(viper.GetString("license"))
72	}
73
74	// If user didn't set any license, use Apache 2.0 by default.
75	return Licenses["apache"]
76}
77
78func copyrightLine() string {
79	author := viper.GetString("author")
80
81	year := viper.GetString("year") // For tests.
82	if year == "" {
83		year = time.Now().Format("2006")
84	}
85
86	return "Copyright © " + year + " " + author
87}
88
89// findLicense looks for License object of built-in licenses.
90// If it didn't find license, then the app will be terminated and
91// error will be printed.
92func findLicense(name string) License {
93	found := matchLicense(name)
94	if found == "" {
95		er("unknown license: " + name)
96	}
97	return Licenses[found]
98}
99
100// matchLicense compares the given a license name
101// to PossibleMatches of all built-in licenses.
102// It returns blank string, if name is blank string or it didn't find
103// then appropriate match to name.
104func matchLicense(name string) string {
105	if name == "" {
106		return ""
107	}
108
109	for key, lic := range Licenses {
110		for _, match := range lic.PossibleMatches {
111			if strings.EqualFold(name, match) {
112				return key
113			}
114		}
115	}
116
117	return ""
118}
119