Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

conaninfo_parser.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package conan
  4. import (
  5. "bufio"
  6. "io"
  7. "strings"
  8. "code.gitea.io/gitea/modules/util"
  9. )
  10. // Conaninfo represents infos of a Conan package
  11. type Conaninfo struct {
  12. Settings map[string]string `json:"settings"`
  13. FullSettings map[string]string `json:"full_settings"`
  14. Requires []string `json:"requires"`
  15. FullRequires []string `json:"full_requires"`
  16. Options map[string]string `json:"options"`
  17. FullOptions map[string]string `json:"full_options"`
  18. RecipeHash string `json:"recipe_hash"`
  19. Environment map[string][]string `json:"environment"`
  20. }
  21. func ParseConaninfo(r io.Reader) (*Conaninfo, error) {
  22. sections, err := readSections(io.LimitReader(r, 1<<20))
  23. if err != nil {
  24. return nil, err
  25. }
  26. info := &Conaninfo{}
  27. for section, lines := range sections {
  28. if len(lines) == 0 {
  29. continue
  30. }
  31. switch section {
  32. case "settings":
  33. info.Settings = toMap(lines)
  34. case "full_settings":
  35. info.FullSettings = toMap(lines)
  36. case "options":
  37. info.Options = toMap(lines)
  38. case "full_options":
  39. info.FullOptions = toMap(lines)
  40. case "requires":
  41. info.Requires = lines
  42. case "full_requires":
  43. info.FullRequires = lines
  44. case "recipe_hash":
  45. info.RecipeHash = lines[0]
  46. case "env":
  47. info.Environment = toMapArray(lines)
  48. }
  49. }
  50. return info, nil
  51. }
  52. func readSections(r io.Reader) (map[string][]string, error) {
  53. sections := make(map[string][]string)
  54. section := ""
  55. lines := make([]string, 0, 5)
  56. scanner := bufio.NewScanner(r)
  57. for scanner.Scan() {
  58. line := strings.TrimSpace(scanner.Text())
  59. if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
  60. if section != "" {
  61. sections[section] = lines
  62. }
  63. section = line[1 : len(line)-1]
  64. lines = make([]string, 0, 5)
  65. continue
  66. }
  67. if section != "" {
  68. if line != "" {
  69. lines = append(lines, line)
  70. }
  71. continue
  72. }
  73. if line != "" {
  74. return nil, util.NewInvalidArgumentErrorf("invalid conaninfo.txt")
  75. }
  76. }
  77. if err := scanner.Err(); err != nil {
  78. return nil, err
  79. }
  80. if section != "" {
  81. sections[section] = lines
  82. }
  83. return sections, nil
  84. }
  85. func toMap(lines []string) map[string]string {
  86. result := make(map[string]string)
  87. for _, line := range lines {
  88. parts := strings.SplitN(line, "=", 2)
  89. if len(parts) != 2 || len(parts[0]) == 0 || len(parts[1]) == 0 {
  90. continue
  91. }
  92. result[parts[0]] = parts[1]
  93. }
  94. return result
  95. }
  96. func toMapArray(lines []string) map[string][]string {
  97. result := make(map[string][]string)
  98. for _, line := range lines {
  99. parts := strings.SplitN(line, "=", 2)
  100. if len(parts) != 2 || len(parts[0]) == 0 || len(parts[1]) == 0 {
  101. continue
  102. }
  103. var items []string
  104. if strings.HasPrefix(parts[1], "[") && strings.HasSuffix(parts[1], "]") {
  105. items = strings.Split(parts[1], ",")
  106. } else {
  107. items = []string{parts[1]}
  108. }
  109. result[parts[0]] = items
  110. }
  111. return result
  112. }