Add support for Zypper
This commit is contained in:
		
							
								
								
									
										20
									
								
								internal/index/common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								internal/index/common.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | package index | ||||||
|  |  | ||||||
|  | import "strings" | ||||||
|  |  | ||||||
|  | type repomd struct { | ||||||
|  | 	Locations []location `xml:"data>location"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type location struct { | ||||||
|  | 	Href string `xml:"href,attr"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r repomd) getFilelists() string { | ||||||
|  | 	for _, loc := range r.Locations { | ||||||
|  | 		if strings.Contains(loc.Href, "filelists.xml") { | ||||||
|  | 			return loc.Href | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
| @@ -27,7 +27,6 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/xml" | 	"encoding/xml" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| @@ -37,23 +36,6 @@ import ( | |||||||
| 	"go.elara.ws/distrohop/internal/tags" | 	"go.elara.ws/distrohop/internal/tags" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type repomd struct { |  | ||||||
| 	Locations []location `xml:"data>location"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type location struct { |  | ||||||
| 	Href string `xml:"href,attr"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r repomd) getGzipFile() string { |  | ||||||
| 	for _, loc := range r.Locations { |  | ||||||
| 		if strings.HasSuffix(loc.Href, "filelists.xml.gz") { |  | ||||||
| 			return loc.Href |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type DNF struct{} | type DNF struct{} | ||||||
|  |  | ||||||
| func (DNF) Name() string { | func (DNF) Name() string { | ||||||
| @@ -65,10 +47,9 @@ func (DNF) IndexURL(baseURL, version, repo, arch string) ([]string, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	repomdPath := fmt.Sprintf("/pub/fedora/linux/releases/%s/%s/%s/os/repodata/repomd.xml", version, repo, arch) | 	 | ||||||
| 	u.Path = repomdPath | 	repomdURL := u.JoinPath("linux/releases", version, repo, arch, "os/repodata/repomd.xml") | ||||||
|  | 	res, err := http.Get(repomdURL.String()) | ||||||
| 	res, err := http.Get(u.String()) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -80,13 +61,13 @@ func (DNF) IndexURL(baseURL, version, repo, arch string) ([]string, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	gzipFile := data.getGzipFile() | 	filelists := data.getFilelists() | ||||||
| 	if gzipFile == "" { | 	if filelists == "" { | ||||||
| 		return nil, errors.New("no gzip file found in repomd.xml") | 		return nil, errors.New("no filelists found in repomd.xml") | ||||||
| 	} | 	} | ||||||
|  | 	 | ||||||
| 	u.Path = fmt.Sprintf("/pub/fedora/linux/releases/%s/%s/%s/os/%s", version, repo, arch, gzipFile) | 	filelistsURL := u.JoinPath("linux/releases", version, repo, arch, "os", filelists) | ||||||
| 	return []string{u.String()}, nil | 	return []string{filelistsURL.String()}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (DNF) ReadPkgData(r io.Reader, out chan Record) { | func (DNF) ReadPkgData(r io.Reader, out chan Record) { | ||||||
|   | |||||||
| @@ -47,6 +47,7 @@ var importers = []Importer{ | |||||||
| 	APT{}, | 	APT{}, | ||||||
| 	DNF{}, | 	DNF{}, | ||||||
| 	Pacman{}, | 	Pacman{}, | ||||||
|  | 	Zypper{}, | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetImporter gets an importer by its name | // GetImporter gets an importer by its name | ||||||
|   | |||||||
							
								
								
									
										69
									
								
								internal/index/zypper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								internal/index/zypper.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | /* | ||||||
|  |  * distrohop - A utility for correlating and identifying equivalent software | ||||||
|  |  * packages across different Linux distributions | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2025 Elara Ivy <elara@elara.ws> | ||||||
|  |  * | ||||||
|  |  * This file is part of distrohop. | ||||||
|  |  * | ||||||
|  |  * distrohop is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU Affero General Public License as | ||||||
|  |  * published by the Free Software Foundation, either version 3 of the | ||||||
|  |  * License, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * distrohop is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU Affero General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Affero General Public License | ||||||
|  |  * along with distrohop.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package index | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/xml" | ||||||
|  | 	"errors" | ||||||
|  | 	"io" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  type Zypper struct{} | ||||||
|  |   | ||||||
|  |  func (Zypper) Name() string { | ||||||
|  | 	return "zypper" | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  func (Zypper) IndexURL(baseURL, version, repo, _ string) ([]string, error) { | ||||||
|  | 	u, err := url.ParseRequestURI(baseURL) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	repomdURL := u.JoinPath(version, "repo", repo, "repodata/repomd.xml") | ||||||
|  | 	res, err := http.Get(repomdURL.String()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	defer res.Body.Close() | ||||||
|  |   | ||||||
|  | 	var data repomd | ||||||
|  | 	err = xml.NewDecoder(res.Body).Decode(&data) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |   | ||||||
|  | 	gzipFile := data.getFilelists() | ||||||
|  | 	if gzipFile == "" { | ||||||
|  | 		return nil, errors.New("no filelists found in repomd.xml") | ||||||
|  | 	} | ||||||
|  |   | ||||||
|  | 	filelistURL := u.JoinPath(version, "repo", repo, gzipFile) | ||||||
|  | 	return []string{filelistURL.String()}, nil | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  func (Zypper) ReadPkgData(r io.Reader, out chan Record) { | ||||||
|  |  	DNF{}.ReadPkgData(r, out) | ||||||
|  |  } | ||||||
		Reference in New Issue
	
	Block a user