package opensuse import ( "encoding/xml" "fmt" "strings" ) // Service is one element of an OBS _service file. type Service struct { Name string Mode string // "", manual, buildtime, disabled, localonly Params map[string]string } // scmServices are the source services that fetch from a VCS; their "url" param is upstream. var scmServices = map[string]bool{"obs_scm": true, "tar_scm": true, "obs_gbp": true, "go_modules_scm": false} // IsSCM reports whether the service checks out a repository. func (s Service) IsSCM() bool { return scmServices[s.Name] } // URL returns the repository/download URL the service fetches, if any. func (s Service) URL() string { if u := s.Params["url"]; u != "" { return u } if s.Name == "download_url" { proto, host, p := s.Params["protocol"], s.Params["host"], s.Params["path"] if host != "" && p != "" { if proto == "" { proto = "https" } return proto + "://" + host + "/" + strings.TrimPrefix(p, "/") } } return "" } type xmlServices struct { XMLName xml.Name `xml:"services"` Services []struct { Name string `xml:"name,attr"` Mode string `xml:"mode,attr"` Params []struct { Name string `xml:"name,attr"` Value string `xml:",chardata"` } `xml:"param"` } `xml:"service"` } // ParseService parses an OBS _service file. func ParseService(data []byte) ([]Service, error) { var x xmlServices if err := xml.Unmarshal(data, &x); err != nil { return nil, fmt.Errorf("_service: %w", err) } var out []Service for _, s := range x.Services { svc := Service{Name: s.Name, Mode: s.Mode, Params: map[string]string{}} for _, p := range s.Params { svc.Params[p.Name] = strings.TrimSpace(p.Value) } out = append(out, svc) } return out, nil }