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