From 520a4a7a8fb1a2b34934f35522f68ee013c3af70 Mon Sep 17 00:00:00 2001 From: Wiktor Zykubek Date: Sun, 29 Dec 2024 05:33:32 +0100 Subject: [PATCH] refactor: upgrade/rewrite almost whole source code --- main.go | 171 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 70 deletions(-) diff --git a/main.go b/main.go index 980a8a7..8b2fe6e 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,9 @@ package main import ( + "bytes" "embed" + "errors" "flag" "fmt" "io/fs" @@ -14,140 +16,169 @@ import ( "gopkg.in/yaml.v3" ) -type InputData struct { - AuthorName string - AuthorEmail string - Year int -} +//go:embed all:templates +var TemplatesDir embed.FS -type LicenseData struct { - FullName string `yaml:"title"` +type LicenseTemplate struct { + Title string `yaml:"title"` ID string `yaml:"spdx-id"` Description string `yaml:"description"` // TODO Permissions []string `yaml:"permissions"` // TODO Limitations []string `yaml:"limitations"` // TODO Conditions []string `yaml:"conditions"` // TODO + Body string } -//go:embed all:templates -var TemplatesDir embed.FS +type LicenseContext struct { + AuthorName string + AuthorEmail string + Year int +} -func getGitUserData() (string, string, error) { - var userData [2]string - for i, v := range []string{"user.name", "user.email"} { - cmd := exec.Command("git", "config", "--get", v) - out, err := cmd.Output() - if err != nil { - return "", "", fmt.Errorf("Can't read Git config: %w", err) - } +type Licenser struct { + LicenseID string + LicenseContext LicenseContext + OutputFile string + licenseBody string +} - userData[i] = strings.TrimSpace(string(out)) +func NewLicenseContext(authorName string, authorEmail string) (LicenseContext, error) { + var err error + if authorName == "" { + authorName, err = gitUserData("user.name") + } + if authorEmail == "" { + authorEmail, err = gitUserData("user.email") + } + if err != nil { + return LicenseContext{}, err } - return userData[0], userData[1], nil + return LicenseContext{ + AuthorName: authorName, + AuthorEmail: authorEmail, + Year: time.Now().Year(), + }, nil } -func getTemplateList() []string { - files, err := fs.ReadDir(TemplatesDir, "templates") +func (l *Licenser) ParseTemplate() (LicenseTemplate, error) { + licenseID := strings.ToUpper(l.LicenseID) + tmplPath := "templates/" + licenseID + ".tmpl" + data, err := TemplatesDir.ReadFile(tmplPath) if err != nil { - panic(err) + return LicenseTemplate{}, err } - var tmplList []string - for _, v := range files { - tmplList = append(tmplList, strings.Replace(v.Name(), ".tmpl", "", 1)) - } + parts := strings.SplitN(string(data), "---", 3) - return tmplList -} + var licenseTmpl LicenseTemplate + yaml.Unmarshal([]byte(parts[1]), &licenseTmpl) + licenseTmpl.Body = strings.TrimSpace(parts[2]) -func listLicenses() { - licList := getTemplateList() - fmt.Println(strings.Join(licList, ", ")) + return licenseTmpl, nil } -func parseFrontMatter(tmplPath string) (LicenseData, string, error) { - data, err := TemplatesDir.ReadFile(tmplPath) +func (l *Licenser) Generate() error { + license, err := l.ParseTemplate() if err != nil { - return LicenseData{}, "", err + return errors.New("Not supported license") } - parts := strings.SplitN(string(data), "---", 3) + tmpl, _ := template.New(l.LicenseID).Parse(license.Body) + + var output bytes.Buffer + tmpl.Execute(&output, l.LicenseContext) - var licData LicenseData - yaml.Unmarshal([]byte(parts[1]), &licData) + l.licenseBody = output.String() - return licData, strings.TrimSpace(parts[2]), nil + return nil } -func genLicense(licName string, inputData InputData, outFileName string) error { - tmplPath := "templates/" + licName + ".tmpl" - _, lcnsBody, err := parseFrontMatter(tmplPath) +func (l *Licenser) WriteFile() error { + outFile, err := os.Create(l.OutputFile) if err != nil { return err } + defer outFile.Close() - tmpl, err := template.New(licName).Parse(lcnsBody) - if err != nil { - return fmt.Errorf("Not supported license") + if _, err := outFile.WriteString(l.licenseBody); err != nil { + return err } - outFile, err := os.Create(outFileName) + return nil +} + +func gitUserData(key string) (string, error) { + cmd := exec.Command("git", "config", "--get", key) + out, err := cmd.Output() if err != nil { - return err + return "", errors.New("Can't read Git config") } - defer outFile.Close() - err = tmpl.Execute(outFile, inputData) + value := strings.TrimSpace(string(out)) + return value, nil +} + +func templateList() []string { + files, err := fs.ReadDir(TemplatesDir, "templates") if err != nil { - return err + panic(err) } - return nil + var tmplList []string + for _, v := range files { + tmplList = append(tmplList, strings.Replace(v.Name(), ".tmpl", "", 1)) + } + + return tmplList +} + +func listLicenses() { + tmplList := templateList() + fmt.Println(strings.Join(tmplList, ", ")) } func main() { OutputFile := flag.String("output", "LICENSE", "Specify different output file") - LicenseName := flag.String("license", "", "Specify license by SPDX ID (e.g. BSD-3-Clause)") + LicenseID := flag.String("license", "", "Specify license by SPDX ID (e.g. BSD-3-Clause)") AuthorName := flag.String("name", "", "Set the author name (read from Git by default)") AuthorEmail := flag.String("email", "", "Set the author email (read from Git by default)") ListLicenses := flag.Bool("list", false, "List available licenses") flag.Parse() - *LicenseName = strings.ToUpper(*LicenseName) - if *ListLicenses { listLicenses() os.Exit(0) } - if *LicenseName == "" { + if *LicenseID == "" { fmt.Printf("Error: No license specified\n\nUse --license LICENSE\n\nAvailable licenses:\n") listLicenses() os.Exit(1) } - if *AuthorName == "" || *AuthorEmail == "" { - var err error - *AuthorName, *AuthorEmail, err = getGitUserData() - if err != nil { - fmt.Printf( - "Error: Can't read Git config.\n\nUse --name \"NAME\" and --email EMAIL instead.\n", - ) - os.Exit(3) - } + licenseCtx, err := NewLicenseContext(*AuthorName, *AuthorEmail) + if err != nil && err.Error() == "Can't read Git config" { + fmt.Printf( + "Error: Can't read Git config.\n\nUse --name \"NAME\" and --email EMAIL instead.\n", + ) + os.Exit(3) } - inputData := InputData{ - AuthorName: *AuthorName, - AuthorEmail: *AuthorEmail, - Year: time.Now().Year(), + licenser := Licenser{ + LicenseID: *LicenseID, + LicenseContext: licenseCtx, + OutputFile: *OutputFile, } - err := genLicense(*LicenseName, inputData, *OutputFile) - if err != nil { - fmt.Printf("Error: There is no '%s' license\n\nAvailable licenses:\n", *LicenseName) + err = licenser.Generate() + if err != nil && err.Error() == "Not supported license" { + fmt.Printf("Error: There is no '%s' license\n\nAvailable licenses:\n", *LicenseID) listLicenses() os.Exit(2) } + + if err = licenser.WriteFile(); err != nil { + panic(err) + } }