github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/packages/conan/conaninfo_parser.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package conan
     7  
     8  import (
     9  	"bufio"
    10  	"errors"
    11  	"io"
    12  	"strings"
    13  )
    14  
    15  // Conaninfo represents infos of a Conan package
    16  type Conaninfo struct {
    17  	Settings     map[string]string   `json:"settings"`
    18  	FullSettings map[string]string   `json:"full_settings"`
    19  	Requires     []string            `json:"requires"`
    20  	FullRequires []string            `json:"full_requires"`
    21  	Options      map[string]string   `json:"options"`
    22  	FullOptions  map[string]string   `json:"full_options"`
    23  	RecipeHash   string              `json:"recipe_hash"`
    24  	Environment  map[string][]string `json:"environment"`
    25  }
    26  
    27  func ParseConaninfo(r io.Reader) (*Conaninfo, error) {
    28  	sections, err := readSections(io.LimitReader(r, 1<<20))
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  
    33  	info := &Conaninfo{}
    34  	for section, lines := range sections {
    35  		if len(lines) == 0 {
    36  			continue
    37  		}
    38  		switch section {
    39  		case "settings":
    40  			info.Settings = toMap(lines)
    41  		case "full_settings":
    42  			info.FullSettings = toMap(lines)
    43  		case "options":
    44  			info.Options = toMap(lines)
    45  		case "full_options":
    46  			info.FullOptions = toMap(lines)
    47  		case "requires":
    48  			info.Requires = lines
    49  		case "full_requires":
    50  			info.FullRequires = lines
    51  		case "recipe_hash":
    52  			info.RecipeHash = lines[0]
    53  		case "env":
    54  			info.Environment = toMapArray(lines)
    55  		}
    56  	}
    57  	return info, nil
    58  }
    59  
    60  func readSections(r io.Reader) (map[string][]string, error) {
    61  	sections := make(map[string][]string)
    62  
    63  	section := ""
    64  	lines := make([]string, 0, 5)
    65  
    66  	scanner := bufio.NewScanner(r)
    67  	for scanner.Scan() {
    68  		line := strings.TrimSpace(scanner.Text())
    69  		if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
    70  			if section != "" {
    71  				sections[section] = lines
    72  			}
    73  			section = line[1 : len(line)-1]
    74  			lines = make([]string, 0, 5)
    75  			continue
    76  		}
    77  		if section != "" {
    78  			if line != "" {
    79  				lines = append(lines, line)
    80  			}
    81  			continue
    82  		}
    83  		if line != "" {
    84  			return nil, errors.New("Invalid conaninfo.txt")
    85  		}
    86  	}
    87  	if err := scanner.Err(); err != nil {
    88  		return nil, err
    89  	}
    90  	if section != "" {
    91  		sections[section] = lines
    92  	}
    93  	return sections, nil
    94  }
    95  
    96  func toMap(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  		result[parts[0]] = parts[1]
   104  	}
   105  	return result
   106  }
   107  
   108  func toMapArray(lines []string) map[string][]string {
   109  	result := make(map[string][]string)
   110  	for _, line := range lines {
   111  		parts := strings.SplitN(line, "=", 2)
   112  		if len(parts) != 2 || len(parts[0]) == 0 || len(parts[1]) == 0 {
   113  			continue
   114  		}
   115  		var items []string
   116  		if strings.HasPrefix(parts[1], "[") && strings.HasSuffix(parts[1], "]") {
   117  			items = strings.Split(parts[1], ",")
   118  		} else {
   119  			items = []string{parts[1]}
   120  		}
   121  		result[parts[0]] = items
   122  	}
   123  	return result
   124  }