1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2024-11-24 08:57:03 -05:00
forgejo/modules/repository/license.go
Jason Song ea1afb945d
Replace placeholders in licenses (#24354)
Replace #22117. Implement it in a more maintainable way.

Some licenses have placeholders e.g. the BSD licenses start with this
line:
```
Copyright (c) <year> <owner>. 
```
This PR replaces the placeholders with the correct value when initialize
a new repo.

### FAQ

- Why not use a regex?
It will be a pretty complicated regex which could be hard to maintain.

- There're still missing placeholders.
There are over 500 licenses, it's impossible for anyone to inspect all
of them alone. Please help to add them if you find any, and it is also
OK to leave them for the future.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2023-05-05 13:46:17 +00:00

113 lines
2.8 KiB
Go

// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repository
import (
"bufio"
"bytes"
"fmt"
"regexp"
"strings"
"code.gitea.io/gitea/modules/options"
)
type licenseValues struct {
Owner string
Email string
Repo string
Year string
}
func getLicense(name string, values *licenseValues) ([]byte, error) {
data, err := options.License(name)
if err != nil {
return nil, fmt.Errorf("GetRepoInitFile[%s]: %w", name, err)
}
return fillLicensePlaceholder(name, values, data), nil
}
func fillLicensePlaceholder(name string, values *licenseValues, origin []byte) []byte {
placeholder := getLicensePlaceholder(name)
scanner := bufio.NewScanner(bytes.NewReader(origin))
output := bytes.NewBuffer(nil)
for scanner.Scan() {
line := scanner.Text()
if placeholder.MatchLine == nil || placeholder.MatchLine.MatchString(line) {
for _, v := range placeholder.Owner {
line = strings.ReplaceAll(line, v, values.Owner)
}
for _, v := range placeholder.Email {
line = strings.ReplaceAll(line, v, values.Email)
}
for _, v := range placeholder.Repo {
line = strings.ReplaceAll(line, v, values.Repo)
}
for _, v := range placeholder.Year {
line = strings.ReplaceAll(line, v, values.Year)
}
}
output.WriteString(line + "\n")
}
return output.Bytes()
}
type licensePlaceholder struct {
Owner []string
Email []string
Repo []string
Year []string
MatchLine *regexp.Regexp
}
func getLicensePlaceholder(name string) *licensePlaceholder {
// Some universal placeholders.
// If you want to add a new one, make sure you have check it by `grep -r 'NEW_WORD' options/license` and all of them are placeholders.
ret := &licensePlaceholder{
Owner: []string{
"<name of author>",
"<owner>",
"[NAME]",
"[name of copyright owner]",
"[name of copyright holder]",
"<COPYRIGHT HOLDERS>",
"<copyright holders>",
"<AUTHOR>",
"<author's name or designee>",
"[one or more legally recognised persons or entities offering the Work under the terms and conditions of this Licence]",
},
Email: []string{
"[EMAIL]",
},
Repo: []string{
"<program>",
"<one line to give the program's name and a brief idea of what it does.>",
},
Year: []string{
"<year>",
"[YEAR]",
"{YEAR}",
"[yyyy]",
"[Year]",
"[year]",
},
}
// Some special placeholders for specific licenses.
// It's unsafe to apply them to all licenses.
switch name {
case "0BSD":
return &licensePlaceholder{
Owner: []string{"AUTHOR"},
Email: []string{"EMAIL"},
Year: []string{"YEAR"},
MatchLine: regexp.MustCompile(`Copyright \(C\) YEAR by AUTHOR EMAIL`), // there is another AUTHOR in the file, but it's not a placeholder
}
// Other special placeholders can be added here.
}
return ret
}