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

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