Created
October 22, 2024 17:55
-
-
Save jlsherrill/182d330896194a6df20e7ae8f881cb96 to your computer and use it in GitHub Desktop.
Generate csvs with list of packages and number of errata from updateinfo.xml files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/xml" | |
"fmt" | |
"io/ioutil" | |
"os" | |
"slices" | |
"time" | |
) | |
type Updates struct { | |
XMLName xml.Name `xml:"updates"` | |
Updates []Update `xml:"update"` | |
} | |
type Update struct { | |
XMLName xml.Name `xml:"update"` | |
Type string `xml:"type,attr"` | |
Issued Issued `xml:"issued"` | |
PkgList PkgList `xml:"pkglist"` | |
} | |
type Issued struct { | |
XMLName xml.Name `xml:"issued"` | |
Date customTime `xml:"date,attr"` | |
} | |
type customTime struct { | |
time.Time | |
} | |
func (c *customTime) UnmarshalXMLAttr(attr xml.Attr) error { | |
parse, _ := time.Parse("2006-01-02 15:04:05 UTC", attr.Value) | |
*c = customTime{parse} | |
return nil | |
} | |
type PkgList struct { | |
XMLName xml.Name `xml:"pkglist"` | |
PkgCollections []PkgCollection `xml:"collection"` | |
} | |
type PkgCollection struct { | |
XMLName xml.Name `xml:"collection"` | |
Packages []Package `xml:"package"` | |
} | |
type Package struct { | |
XMLName xml.Name `xml:"package"` | |
Name string `xml:"name,attr"` | |
Arch string `xml:"arch,attr"` | |
} | |
func LoadXml(file string) (*Updates, error) { | |
var updates Updates | |
xmlFile, err := os.Open(fmt.Sprintf("xml/%s", file)) | |
if err != nil { | |
return nil, err | |
} | |
byteValue, _ := ioutil.ReadAll(xmlFile) | |
err = xml.Unmarshal(byteValue, &updates) | |
if err != nil { | |
return nil, err | |
} | |
return &updates, nil | |
} | |
func processOS(appstream string, baseos string, outputFilename string, includeAfter time.Time) error { | |
m := make(map[string]int) | |
updates, err := LoadXml(appstream) | |
if err != nil { | |
return fmt.Errorf("Error loading XML: %v", err) | |
} | |
err = processUpdates(m, updates.Updates, includeAfter) | |
if err != nil { | |
return fmt.Errorf("Error processing updates for appstream: %v", err) | |
} | |
updates, err = LoadXml(baseos) | |
if err != nil { | |
return fmt.Errorf("Error loading XML for baseos: %v", err) | |
} | |
err = processUpdates(m, updates.Updates, includeAfter) | |
if err != nil { | |
return fmt.Errorf("Error processing updates for baseos: %v", err) | |
} | |
file, err := os.Create(outputFilename) | |
if err != nil { | |
return fmt.Errorf("Error creating output file: %v", err) | |
} | |
for k, v := range m { | |
_, err = file.WriteString(fmt.Sprintf("%s,%d\n", k, v)) | |
if err != nil { | |
return fmt.Errorf("Error writing to output file: %v", err) | |
} | |
} | |
return nil | |
} | |
func processUpdates(tracker map[string]int, updates []Update, includeAfter time.Time) error { | |
for _, update := range updates { | |
pkgsForUpdate := []string{} | |
if update.Issued.Date.Before(includeAfter) { | |
continue | |
} | |
if update.Type != "security" { | |
continue | |
} | |
for _, pkgList := range update.PkgList.PkgCollections { | |
for _, pkg := range pkgList.Packages { | |
if !slices.Contains(pkgsForUpdate, pkg.Name) { | |
pkgsForUpdate = append(pkgsForUpdate, pkg.Name) | |
} | |
} | |
} | |
// For each update add each package to the map, or increment it by 1 if its there | |
for _, name := range pkgsForUpdate { | |
tracker[name] = tracker[name] + 1 | |
} | |
} | |
return nil | |
} | |
func main() { | |
thisYear := time.Date(2024, 01, 01, 0, 0, 0, 0, time.UTC) | |
err := processOS("9_appstream.xml", "9_baseos.xml", "9Count_2024.csv", thisYear) | |
if err != nil { | |
fmt.Println(err) | |
} | |
err = processOS("8_appstream.xml", "8_baseos.xml", "8Count_2024.csv", thisYear) | |
if err != nil { | |
fmt.Println(err) | |
} | |
start := time.Date(1990, 01, 01, 0, 0, 0, 0, time.UTC) | |
err = processOS("9_appstream.xml", "9_baseos.xml", "9Count_all.csv", start) | |
if err != nil { | |
fmt.Println(err) | |
} | |
err = processOS("8_appstream.xml", "8_baseos.xml", "8Count_all.csv", start) | |
if err != nil { | |
fmt.Println(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment