You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generate-go-licenses.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. //go:build ignore
  4. package main
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "io/fs"
  9. "os"
  10. "path"
  11. "path/filepath"
  12. "regexp"
  13. "sort"
  14. "strings"
  15. )
  16. // regexp is based on go-license, excluding README and NOTICE
  17. // https://github.com/google/go-licenses/blob/master/licenses/find.go
  18. var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)
  19. type LicenseEntry struct {
  20. Name string `json:"name"`
  21. Path string `json:"path"`
  22. LicenseText string `json:"licenseText"`
  23. }
  24. func main() {
  25. if len(os.Args) != 3 {
  26. fmt.Println("usage: go run generate-go-licenses.go <base-dir> <out-json-file>")
  27. os.Exit(1)
  28. }
  29. base, out := os.Args[1], os.Args[2]
  30. // Add ext for excluded files because license_test.go will be included for some reason.
  31. // And there are more files that should be excluded, check with:
  32. //
  33. // go run github.com/google/go-licenses@v1.6.0 save . --force --save_path=.go-licenses 2>/dev/null
  34. // find .go-licenses -type f | while read FILE; do echo "${$(basename $FILE)##*.}"; done | sort -u
  35. // AUTHORS
  36. // COPYING
  37. // LICENSE
  38. // Makefile
  39. // NOTICE
  40. // gitignore
  41. // go
  42. // md
  43. // mod
  44. // sum
  45. // toml
  46. // txt
  47. // yml
  48. //
  49. // It could be removed once we have a better regex.
  50. excludedExt := map[string]bool{
  51. ".gitignore": true,
  52. ".go": true,
  53. ".mod": true,
  54. ".sum": true,
  55. ".toml": true,
  56. ".yml": true,
  57. }
  58. var paths []string
  59. err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
  60. if err != nil {
  61. return err
  62. }
  63. if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt[filepath.Ext(entry.Name())] {
  64. return nil
  65. }
  66. paths = append(paths, path)
  67. return nil
  68. })
  69. if err != nil {
  70. panic(err)
  71. }
  72. sort.Strings(paths)
  73. var entries []LicenseEntry
  74. for _, filePath := range paths {
  75. licenseText, err := os.ReadFile(filePath)
  76. if err != nil {
  77. panic(err)
  78. }
  79. pkgPath := filepath.ToSlash(filePath)
  80. pkgPath = strings.TrimPrefix(pkgPath, base+"/")
  81. pkgName := path.Dir(pkgPath)
  82. // There might be a bug somewhere in go-licenses that sometimes interprets the
  83. // root package as "." and sometimes as "code.gitea.io/gitea". Workaround by
  84. // removing both of them for the sake of stable output.
  85. if pkgName == "." || pkgName == "code.gitea.io/gitea" {
  86. continue
  87. }
  88. entries = append(entries, LicenseEntry{
  89. Name: pkgName,
  90. Path: pkgPath,
  91. LicenseText: string(licenseText),
  92. })
  93. }
  94. jsonBytes, err := json.MarshalIndent(entries, "", " ")
  95. if err != nil {
  96. panic(err)
  97. }
  98. // Ensure file has a final newline
  99. if jsonBytes[len(jsonBytes)-1] != '\n' {
  100. jsonBytes = append(jsonBytes, '\n')
  101. }
  102. err = os.WriteFile(out, jsonBytes, 0o644)
  103. if err != nil {
  104. panic(err)
  105. }
  106. }