From 01380b9b2ddb8e0ffcedd52077ecb5ad14e0d40d Mon Sep 17 00:00:00 2001 From: Mustafa Gezen Date: Wed, 24 Feb 2021 08:27:51 +0100 Subject: [PATCH] messy code ahead. implement new directives (spec_change) and restructure code to prevent import cycles --- cmd/srpmproc/main.go | 41 ++- internal/blob/file/file.go | 54 ++++ internal/data/import.go | 32 +++ internal/data/process.go | 31 ++ internal/directives/add.go | 3 +- internal/directives/delete.go | 3 +- internal/directives/directives.go | 31 +- internal/directives/lookaside.go | 11 + internal/directives/patch.go | 3 +- internal/directives/replace.go | 3 +- internal/directives/spec_change.go | 327 +++++++++++++++++++++ internal/git.go | 79 ++--- internal/gitrpm.go | 2 +- internal/mode.go | 7 - internal/patch.go | 154 ++-------- internal/process.go | 130 +++------ internal/srpm.go | 49 ++-- internal/utils.go | 5 +- pb/cfg.pb.go | 446 +++++++++++++++++++++++------ proto/cfg.proto | 34 ++- 20 files changed, 1046 insertions(+), 399 deletions(-) create mode 100644 internal/blob/file/file.go create mode 100644 internal/data/import.go create mode 100644 internal/data/process.go create mode 100644 internal/directives/lookaside.go create mode 100644 internal/directives/spec_change.go diff --git a/cmd/srpmproc/main.go b/cmd/srpmproc/main.go index 7a57eb3..ff79ba7 100644 --- a/cmd/srpmproc/main.go +++ b/cmd/srpmproc/main.go @@ -3,10 +3,17 @@ package main import ( "fmt" "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob/file" "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob/gcs" "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob/s3" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/memfs" + "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "io/ioutil" "log" + "os" "os/user" "path/filepath" "strings" @@ -28,8 +35,12 @@ var ( rpmPrefix string importBranchPrefix string branchPrefix string + singleTag string noDupMode bool moduleMode bool + tmpFsMode bool + noStorageDownload bool + noStorageUpload bool ) var root = &cobra.Command{ @@ -45,13 +56,15 @@ func mn(_ *cobra.Command, _ []string) { log.Fatalf("unsupported upstream version %d", version) } - var importer internal.ImportMode + var importer data.ImportMode var blobStorage blob.Storage if strings.HasPrefix(storageAddr, "gs://") { blobStorage = gcs.New(strings.Replace(storageAddr, "gs://", "", 1)) } else if strings.HasPrefix(storageAddr, "s3://") { blobStorage = s3.New(strings.Replace(storageAddr, "s3://", "", 1)) + } else if strings.HasPrefix(storageAddr, "file://") { + blobStorage = file.New(strings.Replace(storageAddr, "file://", "", 1)) } else { log.Fatalf("invalid blob storage") } @@ -83,7 +96,22 @@ func mn(_ *cobra.Command, _ []string) { log.Fatalf("could not get git authenticator: %v", err) } - internal.ProcessRPM(&internal.ProcessData{ + fsCreator := func() billy.Filesystem { + return memfs.New() + } + + if tmpFsMode { + tmpDir, err := ioutil.TempDir(os.TempDir(), "srpmproc-*") + if err != nil { + log.Fatalf("could not create temp dir: %v", err) + } + log.Printf("using temp dir: %s", tmpDir) + fsCreator = func() billy.Filesystem { + return osfs.New(tmpDir) + } + } + + internal.ProcessRPM(&data.ProcessData{ Importer: importer, RpmLocation: sourceRpmLocation, UpstreamPrefix: upstreamPrefix, @@ -96,9 +124,14 @@ func mn(_ *cobra.Command, _ []string) { ModulePrefix: modulePrefix, ImportBranchPrefix: importBranchPrefix, BranchPrefix: branchPrefix, + SingleTag: singleTag, Authenticator: authenticator, NoDupMode: noDupMode, ModuleMode: moduleMode, + TmpFsMode: tmpFsMode, + NoStorageDownload: noStorageDownload, + NoStorageUpload: noStorageUpload, + FsCreator: fsCreator, }) } @@ -120,8 +153,12 @@ func main() { root.Flags().StringVar(&rpmPrefix, "rpm-prefix", "https://git.centos.org/rpms", "Where to retrieve SRPM content. Only used when source-rpm is not a local file") root.Flags().StringVar(&importBranchPrefix, "import-branch-prefix", "c", "Import branch prefix") root.Flags().StringVar(&branchPrefix, "branch-prefix", "r", "Branch prefix (replaces import-branch-prefix)") + root.Flags().StringVar(&singleTag, "single-tag", "", "If set, only this tag is imported") root.Flags().BoolVar(&noDupMode, "no-dup-mode", false, "If enabled, skips already imported tags") root.Flags().BoolVar(&moduleMode, "module-mode", false, "If enabled, imports a module instead of a package") + root.Flags().BoolVar(&tmpFsMode, "tmpfs-mode", false, "If enabled, packages are imported and patched but not pushed") + root.Flags().BoolVar(&noStorageDownload, "no-storage-download", false, "If enabled, blobs are always downloaded from upstream") + root.Flags().BoolVar(&noStorageUpload, "no-storage-upload", false, "If enabled, blobs are not uploaded to blob storage") if err := root.Execute(); err != nil { log.Fatal(err) diff --git a/internal/blob/file/file.go b/internal/blob/file/file.go new file mode 100644 index 0000000..3032ccf --- /dev/null +++ b/internal/blob/file/file.go @@ -0,0 +1,54 @@ +package file + +import ( + "io/ioutil" + "log" + "os" + "path/filepath" +) + +type File struct { + path string +} + +func New(path string) *File { + return &File{ + path: path, + } +} + +func (f *File) Write(path string, content []byte) { + w, err := os.OpenFile(filepath.Join(f.path, path), os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644) + if err != nil { + log.Fatalf("could not open file: %v", err) + } + + _, err = w.Write(content) + if err != nil { + log.Fatalf("could not write file to file: %v", err) + } + + // Close, just like writing a file. + if err := w.Close(); err != nil { + log.Fatalf("could not close file writer to source: %v", err) + } +} + +func (f *File) Read(path string) []byte { + r, err := os.OpenFile(filepath.Join(f.path, path), os.O_RDONLY, 0644) + if err != nil { + return nil + } + + body, err := ioutil.ReadAll(r) + if err != nil { + return nil + } + + return body +} + +func (f *File) Exists(path string) bool { + _, err := os.Stat(filepath.Join(f.path, path)) + return !os.IsNotExist(err) +} diff --git a/internal/data/import.go b/internal/data/import.go new file mode 100644 index 0000000..63c3318 --- /dev/null +++ b/internal/data/import.go @@ -0,0 +1,32 @@ +package data + +import ( + "github.com/cavaliercoder/go-rpm" + "github.com/go-git/go-git/v5" + "hash" +) + +type ImportMode interface { + RetrieveSource(pd *ProcessData) *ModeData + WriteSource(pd *ProcessData, md *ModeData) + PostProcess(md *ModeData) + ImportName(pd *ProcessData, md *ModeData) string +} + +type ModeData struct { + Repo *git.Repository + Worktree *git.Worktree + RpmFile *rpm.PackageFile + FileWrites map[string][]byte + TagBranch string + PushBranch string + Branches []string + SourcesToIgnore []*IgnoredSource + BlobCache map[string][]byte +} + +type IgnoredSource struct { + Name string + HashFunction hash.Hash + Expired bool +} diff --git a/internal/data/process.go b/internal/data/process.go new file mode 100644 index 0000000..081a5f6 --- /dev/null +++ b/internal/data/process.go @@ -0,0 +1,31 @@ +package data + +import ( + "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob" + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" +) + +type ProcessData struct { + RpmLocation string + UpstreamPrefix string + SshKeyLocation string + SshUser string + Version int + GitCommitterName string + GitCommitterEmail string + Mode int + ModulePrefix string + ImportBranchPrefix string + BranchPrefix string + SingleTag string + Authenticator *ssh.PublicKeys + Importer ImportMode + BlobStorage blob.Storage + NoDupMode bool + ModuleMode bool + TmpFsMode bool + NoStorageDownload bool + NoStorageUpload bool + FsCreator func() billy.Filesystem +} diff --git a/internal/directives/add.go b/internal/directives/add.go index 570eb2a..00e3f83 100644 --- a/internal/directives/add.go +++ b/internal/directives/add.go @@ -3,6 +3,7 @@ package directives import ( "errors" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" "github.com/go-git/go-git/v5" "io/ioutil" @@ -10,7 +11,7 @@ import ( "path/filepath" ) -func add(cfg *srpmprocpb.Cfg, patchTree *git.Worktree, pushTree *git.Worktree) error { +func add(cfg *srpmprocpb.Cfg, _ *data.ProcessData, _ *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) error { for _, add := range cfg.Add { filePath := checkAddPrefix(filepath.Base(add.File)) diff --git a/internal/directives/delete.go b/internal/directives/delete.go index 86a166b..8e64338 100644 --- a/internal/directives/delete.go +++ b/internal/directives/delete.go @@ -3,11 +3,12 @@ package directives import ( "errors" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" "github.com/go-git/go-git/v5" ) -func del(cfg *srpmprocpb.Cfg, _ *git.Worktree, pushTree *git.Worktree) error { +func del(cfg *srpmprocpb.Cfg, _ *data.ProcessData, _ *data.ModeData, _ *git.Worktree, pushTree *git.Worktree) error { for _, del := range cfg.Delete { filePath := del.File _, err := pushTree.Filesystem.Stat(filePath) diff --git a/internal/directives/directives.go b/internal/directives/directives.go index 84ce497..641e670 100644 --- a/internal/directives/directives.go +++ b/internal/directives/directives.go @@ -2,6 +2,7 @@ package directives import ( "encoding/json" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" "github.com/go-git/go-git/v5" "log" @@ -19,27 +20,23 @@ func checkAddPrefix(file string) string { return filepath.Join("SOURCES", file) } -func Apply(cfg *srpmprocpb.Cfg, patchTree *git.Worktree, pushTree *git.Worktree) { +func Apply(cfg *srpmprocpb.Cfg, pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) { var errs []string - err := replace(cfg, patchTree, pushTree) - if err != nil { - errs = append(errs, err.Error()) + directives := []func(*srpmprocpb.Cfg, *data.ProcessData, *data.ModeData, *git.Worktree, *git.Worktree) error{ + replace, + del, + add, + patch, + lookaside, + specChange, } - err = del(cfg, patchTree, pushTree) - if err != nil { - errs = append(errs, err.Error()) - } - - err = add(cfg, patchTree, pushTree) - if err != nil { - errs = append(errs, err.Error()) - } - - err = patch(cfg, patchTree, pushTree) - if err != nil { - errs = append(errs, err.Error()) + for _, directive := range directives { + err := directive(cfg, pd, md, patchTree, pushTree) + if err != nil { + errs = append(errs, err.Error()) + } } if len(errs) > 0 { diff --git a/internal/directives/lookaside.go b/internal/directives/lookaside.go new file mode 100644 index 0000000..4830f70 --- /dev/null +++ b/internal/directives/lookaside.go @@ -0,0 +1,11 @@ +package directives + +import ( + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" + srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" + "github.com/go-git/go-git/v5" +) + +func lookaside(cfg *srpmprocpb.Cfg, _ *data.ProcessData, _ *data.ModeData, _ *git.Worktree, pushTree *git.Worktree) error { + return nil +} diff --git a/internal/directives/patch.go b/internal/directives/patch.go index a719cef..26cafca 100644 --- a/internal/directives/patch.go +++ b/internal/directives/patch.go @@ -4,13 +4,14 @@ import ( "bytes" "errors" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/go-git/go-git/v5" "log" ) -func patch(cfg *srpmprocpb.Cfg, patchTree *git.Worktree, pushTree *git.Worktree) error { +func patch(cfg *srpmprocpb.Cfg, _ *data.ProcessData, _ *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) error { for _, patch := range cfg.Patch { patchFile, err := patchTree.Filesystem.Open(patch.File) if err != nil { diff --git a/internal/directives/replace.go b/internal/directives/replace.go index 2c024f0..8315c9c 100644 --- a/internal/directives/replace.go +++ b/internal/directives/replace.go @@ -3,13 +3,14 @@ package directives import ( "errors" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" "github.com/go-git/go-git/v5" "io/ioutil" "os" ) -func replace(cfg *srpmprocpb.Cfg, patchTree *git.Worktree, pushTree *git.Worktree) error { +func replace(cfg *srpmprocpb.Cfg, _ *data.ProcessData, _ *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) error { for _, replace := range cfg.Replace { filePath := checkAddPrefix(replace.File) stat, err := pushTree.Filesystem.Stat(filePath) diff --git a/internal/directives/spec_change.go b/internal/directives/spec_change.go new file mode 100644 index 0000000..c191c4a --- /dev/null +++ b/internal/directives/spec_change.go @@ -0,0 +1,327 @@ +package directives + +import ( + "errors" + "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" + srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" + "github.com/go-git/go-git/v5" + "io/ioutil" + "math" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "time" +) + +type sourcePatchOperationInLoopRequest struct { + cfg *srpmprocpb.Cfg + field string + value *string + longestField int + lastNum *int + in *bool + expectedField string +} + +type sourcePatchOperationAfterLoopRequest struct { + cfg *srpmprocpb.Cfg + inLoopNum int + lastNum *int + longestField int + newLines *[]string + in *bool + expectedField string + operation srpmprocpb.SpecChange_FileOperation_Type +} + +func sourcePatchOperationInLoop(req *sourcePatchOperationInLoopRequest) error { + if strings.HasPrefix(req.field, req.expectedField) { + for _, file := range req.cfg.SpecChange.File { + if file.Type != srpmprocpb.SpecChange_FileOperation_Source { + continue + } + + switch file.Mode.(type) { + case *srpmprocpb.SpecChange_FileOperation_Delete: + if file.Name == *req.value { + *req.value = "" + } + break + } + } + sourceNum, err := strconv.Atoi(strings.Split(req.field, req.expectedField)[1]) + if err != nil { + return errors.New(fmt.Sprintf("INVALID_%s_NUM", strings.ToUpper(req.expectedField))) + } + *req.lastNum = sourceNum + } + + return nil +} + +func sourcePatchOperationAfterLoop(req *sourcePatchOperationAfterLoopRequest) (bool, error) { + if req.inLoopNum == *req.lastNum && *req.in { + for _, file := range req.cfg.SpecChange.File { + if file.Type != req.operation { + continue + } + + switch file.Mode.(type) { + case *srpmprocpb.SpecChange_FileOperation_Add: + field := fmt.Sprintf("%s%d", req.expectedField, *req.lastNum+1) + spaces := calculateSpaces(req.longestField, len(field)) + *req.newLines = append(*req.newLines, fmt.Sprintf("%s:%s%s", field, spaces, file.Name)) + *req.lastNum++ + break + } + } + *req.in = false + + return true, nil + } + + return false, nil +} + +func calculateSpaces(longestField int, fieldLength int) string { + return strings.Repeat(" ", longestField+8-fieldLength) +} + +func searchAndReplaceLine(line string, sar []*srpmprocpb.SpecChange_SearchAndReplaceOperation) string { + for _, searchAndReplace := range sar { + switch searchAndReplace.Identifier.(type) { + case *srpmprocpb.SpecChange_SearchAndReplaceOperation_Any: + line = strings.Replace(line, searchAndReplace.Find, searchAndReplace.Replace, int(searchAndReplace.N)) + break + case *srpmprocpb.SpecChange_SearchAndReplaceOperation_StartsWith: + if strings.HasPrefix(line, searchAndReplace.Find) { + line = strings.Replace(line, searchAndReplace.Find, searchAndReplace.Replace, int(searchAndReplace.N)) + } + break + case *srpmprocpb.SpecChange_SearchAndReplaceOperation_EndsWith: + if strings.HasSuffix(line, searchAndReplace.Find) { + line = strings.Replace(line, searchAndReplace.Find, searchAndReplace.Replace, int(searchAndReplace.N)) + } + break + } + } + + return line +} + +func specChange(cfg *srpmprocpb.Cfg, pd *data.ProcessData, md *data.ModeData, _ *git.Worktree, pushTree *git.Worktree) error { + // no spec change operations present + // skip parsing spec + if cfg.SpecChange == nil { + return nil + } + + specFiles, err := pushTree.Filesystem.ReadDir("SPECS") + if err != nil { + return errors.New("COULD_NOT_READ_SPECS_DIR") + } + + if len(specFiles) != 1 { + return errors.New("ONLY_ONE_SPEC_FILE_IS_SUPPORTED") + } + + filePath := filepath.Join("SPECS", specFiles[0].Name()) + stat, err := pushTree.Filesystem.Stat(filePath) + if err != nil { + return errors.New("COULD_NOT_STAT_SPEC_FILE") + } + + specFile, err := pushTree.Filesystem.OpenFile(filePath, os.O_RDONLY, 0644) + if err != nil { + return errors.New("COULD_NOT_READ_SPEC_FILE") + } + + specBts, err := ioutil.ReadAll(specFile) + if err != nil { + return errors.New("COULD_NOT_READ_ALL_BYTES") + } + + specStr := string(specBts) + lines := strings.Split(specStr, "\n") + + var newLines []string + lastSourceNum := 0 + lastPatchNum := 0 + inSources := false + inPatches := false + inChangelog := false + lastSource := "" + lastPatch := "" + + version := "" + importNameSplit := strings.SplitN(pd.Importer.ImportName(pd, md), "-", 2) + if len(importNameSplit) == 2 { + versionSplit := strings.SplitN(importNameSplit[1], ".el", 2) + if len(versionSplit) == 2 { + version = versionSplit[0] + } + } + + fieldValueRegex := regexp.MustCompile("^[A-Z].+:") + + longestField := 0 + for _, line := range lines { + if fieldValueRegex.MatchString(line) { + fieldValue := strings.SplitN(line, ":", 2) + field := strings.TrimSpace(fieldValue[0]) + longestField = int(math.Max(float64(len(field)), float64(longestField))) + + if strings.HasPrefix(field, "Source") { + lastSource = field + } + + if strings.HasPrefix(field, "Patch") { + lastPatch = field + } + } + } + + for _, line := range lines { + inLoopSourceNum := lastSourceNum + inLoopPatchNum := lastPatchNum + prefixLine := strings.TrimSpace(line) + + if fieldValueRegex.MatchString(line) { + line = searchAndReplaceLine(line, cfg.SpecChange.SearchAndReplace) + fieldValue := strings.SplitN(line, ":", 2) + field := strings.TrimSpace(fieldValue[0]) + value := strings.TrimSpace(fieldValue[1]) + + if field == lastSource { + inSources = true + } else if field == lastPatch { + inPatches = true + } + + if field == "Version" && version == "" { + version = value + } + + for _, searchAndReplace := range cfg.SpecChange.SearchAndReplace { + switch identifier := searchAndReplace.Identifier.(type) { + case *srpmprocpb.SpecChange_SearchAndReplaceOperation_Field: + if field == identifier.Field { + value = strings.Replace(value, searchAndReplace.Find, searchAndReplace.Replace, int(searchAndReplace.N)) + } + break + } + } + + spaces := calculateSpaces(longestField, len(field)) + + err := sourcePatchOperationInLoop(&sourcePatchOperationInLoopRequest{ + cfg: cfg, + field: field, + value: &value, + lastNum: &lastSourceNum, + longestField: longestField, + expectedField: "Source", + in: &inSources, + }) + if err != nil { + return err + } + + err = sourcePatchOperationInLoop(&sourcePatchOperationInLoopRequest{ + cfg: cfg, + field: field, + value: &value, + longestField: longestField, + lastNum: &lastPatchNum, + in: &inPatches, + expectedField: "Patch", + }) + if err != nil { + return err + } + + if value != "" { + newLines = append(newLines, fmt.Sprintf("%s:%s%s", field, spaces, value)) + } + } else { + executed, err := sourcePatchOperationAfterLoop(&sourcePatchOperationAfterLoopRequest{ + cfg: cfg, + inLoopNum: inLoopSourceNum, + lastNum: &lastSourceNum, + longestField: longestField, + newLines: &newLines, + expectedField: "Source", + in: &inSources, + operation: srpmprocpb.SpecChange_FileOperation_Source, + }) + if err != nil { + return err + } + + if executed && !strings.Contains(specStr, "Patch") { + newLines = append(newLines, "") + inPatches = true + } + + executed, err = sourcePatchOperationAfterLoop(&sourcePatchOperationAfterLoopRequest{ + cfg: cfg, + inLoopNum: inLoopPatchNum, + lastNum: &lastPatchNum, + longestField: longestField, + newLines: &newLines, + expectedField: "Patch", + in: &inPatches, + operation: srpmprocpb.SpecChange_FileOperation_Patch, + }) + if err != nil { + return err + } + + if executed && !strings.Contains(specStr, "%changelog") { + newLines = append(newLines, "") + newLines = append(newLines, "%changelog") + inChangelog = true + } + + if inChangelog { + now := time.Now().Format("Mon Jan 02 2006") + for _, changelog := range cfg.SpecChange.Changelog { + newLines = append(newLines, fmt.Sprintf("* %s %s <%s> - %s", now, changelog.AuthorName, changelog.AuthorEmail, version)) + for _, msg := range changelog.Message { + newLines = append(newLines, fmt.Sprintf("- %s", msg)) + } + newLines = append(newLines, "") + } + inChangelog = false + } else { + line = searchAndReplaceLine(line, cfg.SpecChange.SearchAndReplace) + } + + if strings.HasPrefix(prefixLine, "%changelog") { + inChangelog = true + } + + newLines = append(newLines, line) + } + } + + err = pushTree.Filesystem.Remove(filePath) + if err != nil { + return errors.New(fmt.Sprintf("COULD_NOT_REMOVE_OLD_SPEC_FILE:%s", filePath)) + } + + f, err := pushTree.Filesystem.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, stat.Mode()) + if err != nil { + return errors.New(fmt.Sprintf("COULD_NOT_OPEN_REPLACEMENT_SPEC_FILE:%s", filePath)) + } + + _, err = f.Write([]byte(strings.Join(newLines, "\n"))) + if err != nil { + return errors.New("COULD_NOT_WRITE_NEW_SPEC_FILE") + } + + return nil +} diff --git a/internal/git.go b/internal/git.go index ab32e1a..c7b75cd 100644 --- a/internal/git.go +++ b/internal/git.go @@ -2,6 +2,7 @@ package internal import ( "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -38,15 +39,15 @@ func (p remoteTargetSlice) Swap(i, j int) { type GitMode struct{} -func (g *GitMode) RetrieveSource(pd *ProcessData) *modeData { +func (g *GitMode) RetrieveSource(pd *data.ProcessData) *data.ModeData { repo, err := git.Init(memory.NewStorage(), memfs.New()) if err != nil { - log.Fatalf("could not init git repo: %v", err) + log.Fatalf("could not init git Repo: %v", err) } w, err := repo.Worktree() if err != nil { - log.Fatalf("could not get worktree: %v", err) + log.Fatalf("could not get Worktree: %v", err) } refspec := config.RefSpec("+refs/heads/*:refs/remotes/*") @@ -116,17 +117,17 @@ func (g *GitMode) RetrieveSource(pd *ProcessData) *modeData { sortedBranches = append(sortedBranches, branch.remote) } - return &modeData{ - repo: repo, - worktree: w, - rpmFile: createPackageFile(filepath.Base(pd.RpmLocation)), - fileWrites: nil, - branches: sortedBranches, + return &data.ModeData{ + Repo: repo, + Worktree: w, + RpmFile: createPackageFile(filepath.Base(pd.RpmLocation)), + FileWrites: nil, + Branches: sortedBranches, } } -func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { - remote, err := md.repo.Remote("upstream") +func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) { + remote, err := md.Repo.Remote("upstream") if err != nil { log.Fatalf("could not get upstream remote: %v", err) } @@ -134,13 +135,13 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { var refspec config.RefSpec var branchName string - if strings.HasPrefix(md.tagBranch, "refs/heads") { - refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.tagBranch, md.tagBranch)) - branchName = strings.TrimPrefix(md.tagBranch, "refs/heads/") + if strings.HasPrefix(md.TagBranch, "refs/heads") { + refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.TagBranch, md.TagBranch)) + branchName = strings.TrimPrefix(md.TagBranch, "refs/heads/") } else { - match := tagImportRegex.FindStringSubmatch(md.tagBranch) + match := tagImportRegex.FindStringSubmatch(md.TagBranch) branchName = match[2] - refspec = config.RefSpec(fmt.Sprintf("+refs/heads/%s:%s", branchName, md.tagBranch)) + refspec = config.RefSpec(fmt.Sprintf("+refs/heads/%s:%s", branchName, md.TagBranch)) } log.Printf("checking out upstream refspec %s", refspec) err = remote.Fetch(&git.FetchOptions{ @@ -153,20 +154,20 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { log.Fatalf("could not fetch upstream: %v", err) } - err = md.worktree.Checkout(&git.CheckoutOptions{ - Branch: plumbing.ReferenceName(md.tagBranch), + err = md.Worktree.Checkout(&git.CheckoutOptions{ + Branch: plumbing.ReferenceName(md.TagBranch), Force: true, }) if err != nil { log.Fatalf("could not checkout source from git: %v", err) } - _, err = md.worktree.Add(".") + _, err = md.Worktree.Add(".") if err != nil { - log.Fatalf("could not add worktree: %v", err) + log.Fatalf("could not add Worktree: %v", err) } - metadataFile, err := md.worktree.Filesystem.Open(fmt.Sprintf(".%s.metadata", md.rpmFile.Name())) + metadataFile, err := md.Worktree.Filesystem.Open(fmt.Sprintf(".%s.metadata", md.RpmFile.Name())) if err != nil { log.Printf("warn: could not open metadata file, so skipping: %v", err) return @@ -194,16 +195,16 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { var body []byte - if md.blobCache[hash] != nil { - body = md.blobCache[hash] + if md.BlobCache[hash] != nil { + body = md.BlobCache[hash] log.Printf("retrieving %s from cache", hash) } else { fromBlobStorage := pd.BlobStorage.Read(hash) - if fromBlobStorage != nil { + if fromBlobStorage != nil && !pd.NoStorageDownload { body = fromBlobStorage log.Printf("downloading %s from blob storage", hash) } else { - url := fmt.Sprintf("https://git.centos.org/sources/%s/%s/%s", md.rpmFile.Name(), branchName, hash) + url := fmt.Sprintf("https://git.centos.org/sources/%s/%s/%s", md.RpmFile.Name(), branchName, hash) log.Printf("downloading %s", url) req, err := http.NewRequest("GET", url, nil) @@ -227,10 +228,10 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { } } - md.blobCache[hash] = body + md.BlobCache[hash] = body } - f, err := md.worktree.Filesystem.Create(path) + f, err := md.Worktree.Filesystem.Create(path) if err != nil { log.Fatalf("could not open file pointer: %v", err) } @@ -240,9 +241,9 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { log.Fatal("checksum in metadata does not match dist-git file") } - md.sourcesToIgnore = append(md.sourcesToIgnore, &ignoredSource{ - name: path, - hashFunction: hasher, + md.SourcesToIgnore = append(md.SourcesToIgnore, &data.IgnoredSource{ + Name: path, + HashFunction: hasher, }) _, err = f.Write(body) @@ -253,28 +254,28 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { } } -func (g *GitMode) PostProcess(md *modeData) { - for _, source := range md.sourcesToIgnore { - _, err := md.worktree.Filesystem.Stat(source.name) +func (g *GitMode) PostProcess(md *data.ModeData) { + for _, source := range md.SourcesToIgnore { + _, err := md.Worktree.Filesystem.Stat(source.Name) if err == nil { - err := md.worktree.Filesystem.Remove(source.name) + err := md.Worktree.Filesystem.Remove(source.Name) if err != nil { log.Fatalf("could not remove dist-git file: %v", err) } } } - _, err := md.worktree.Add(".") + _, err := md.Worktree.Add(".") if err != nil { log.Fatalf("could not add git sources: %v", err) } } -func (g *GitMode) ImportName(_ *ProcessData, md *modeData) string { - if tagImportRegex.MatchString(md.tagBranch) { - match := tagImportRegex.FindStringSubmatch(md.tagBranch) +func (g *GitMode) ImportName(_ *data.ProcessData, md *data.ModeData) string { + if tagImportRegex.MatchString(md.TagBranch) { + match := tagImportRegex.FindStringSubmatch(md.TagBranch) return match[3] } - return strings.TrimPrefix(md.tagBranch, "refs/heads/") + return strings.TrimPrefix(md.TagBranch, "refs/heads/") } diff --git a/internal/gitrpm.go b/internal/gitrpm.go index c7e7971..9c0d40d 100644 --- a/internal/gitrpm.go +++ b/internal/gitrpm.go @@ -6,7 +6,7 @@ import ( // TODO: ugly hack, should create an interface // since GitMode does not parse an RPM file, we just mimick -// the headers of an actual file to reuse rpmFile.Name() +// the headers of an actual file to reuse RpmFile.Name() func createPackageFile(name string) *rpm.PackageFile { return &rpm.PackageFile{ Lead: rpm.Lead{}, diff --git a/internal/mode.go b/internal/mode.go index 9c9db65..5bf0569 100644 --- a/internal/mode.go +++ b/internal/mode.go @@ -1,8 +1 @@ package internal - -type ImportMode interface { - RetrieveSource(pd *ProcessData) *modeData - WriteSource(pd *ProcessData, md *modeData) - PostProcess(md *modeData) - ImportName(pd *ProcessData, md *modeData) string -} diff --git a/internal/patch.go b/internal/patch.go index c7d4a63..f6904db 100644 --- a/internal/patch.go +++ b/internal/patch.go @@ -1,12 +1,11 @@ package internal import ( - "bytes" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" "git.rockylinux.org/release-engineering/public/srpmproc/internal/directives" "git.rockylinux.org/release-engineering/public/srpmproc/modulemd" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" - "github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" @@ -19,107 +18,7 @@ import ( "strings" ) -func srpmPatches(patchTree *git.Worktree, pushTree *git.Worktree) { - // check SRPM patches - _, err := patchTree.Filesystem.Stat("ROCKY/SRPM") - if err == nil { - // iterate through patches - infos, err := patchTree.Filesystem.ReadDir("ROCKY/SRPM") - if err != nil { - log.Fatalf("could not walk patches: %v", err) - } - - for _, info := range infos { - // can only process .patch files - if !strings.HasSuffix(info.Name(), ".patch") { - continue - } - - log.Printf("applying %s", info.Name()) - filePath := filepath.Join("ROCKY/SRPM", info.Name()) - - patch, err := patchTree.Filesystem.Open(filePath) - if err != nil { - log.Fatalf("could not open patch file %s: %v", info.Name(), err) - } - files, _, err := gitdiff.Parse(patch) - if err != nil { - log.Fatalf("could not parse patch file: %v", err) - } - - for _, patchedFile := range files { - srcPath := patchedFile.NewName - if !strings.HasPrefix(srcPath, "SPECS") { - srcPath = filepath.Join("SOURCES", patchedFile.NewName) - } - var output bytes.Buffer - if !patchedFile.IsDelete && !patchedFile.IsNew { - patchSubjectFile, err := pushTree.Filesystem.Open(srcPath) - if err != nil { - log.Fatalf("could not open patch subject: %v", err) - } - - err = gitdiff.NewApplier(patchSubjectFile).ApplyFile(&output, patchedFile) - if err != nil { - log.Fatalf("could not apply patch: %v", err) - } - } - - oldName := filepath.Join("SOURCES", patchedFile.OldName) - _ = pushTree.Filesystem.Remove(oldName) - _ = pushTree.Filesystem.Remove(srcPath) - - if patchedFile.IsNew { - newFile, err := pushTree.Filesystem.Create(srcPath) - if err != nil { - log.Fatalf("could not create new file: %v", err) - } - err = gitdiff.NewApplier(newFile).ApplyFile(&output, patchedFile) - if err != nil { - log.Fatalf("could not apply patch: %v", err) - } - _, err = newFile.Write(output.Bytes()) - if err != nil { - log.Fatalf("could not write post-patch file: %v", err) - } - _, err = pushTree.Add(srcPath) - if err != nil { - log.Fatalf("could not add file %s to git: %v", srcPath, err) - } - log.Printf("git add %s", srcPath) - } else if !patchedFile.IsDelete { - newFile, err := pushTree.Filesystem.Create(srcPath) - if err != nil { - log.Fatalf("could not create post-patch file: %v", err) - } - _, err = newFile.Write(output.Bytes()) - if err != nil { - log.Fatalf("could not write post-patch file: %v", err) - } - _, err = pushTree.Add(srcPath) - if err != nil { - log.Fatalf("could not add file %s to git: %v", srcPath, err) - } - log.Printf("git add %s", srcPath) - } else { - _, err = pushTree.Remove(oldName) - if err != nil { - log.Fatalf("could not remove file %s to git: %v", oldName, err) - } - log.Printf("git rm %s", oldName) - } - } - - _, err = pushTree.Add(filePath) - if err != nil { - log.Fatalf("could not add file %s to git: %v", filePath, err) - } - log.Printf("git add %s", filePath) - } - } -} - -func cfgPatches(patchTree *git.Worktree, pushTree *git.Worktree) { +func cfgPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) { // check CFG patches _, err := patchTree.Filesystem.Stat("ROCKY/CFG") if err == nil { @@ -152,32 +51,31 @@ func cfgPatches(patchTree *git.Worktree, pushTree *git.Worktree) { log.Fatalf("could not unmarshal cfg file: %v", err) } - directives.Apply(&cfg, patchTree, pushTree) + directives.Apply(&cfg, pd, md, patchTree, pushTree) } } } -func applyPatches(patchTree *git.Worktree, pushTree *git.Worktree) { +func applyPatches(pd *data.ProcessData, md *data.ModeData, patchTree *git.Worktree, pushTree *git.Worktree) { // check if patches exist _, err := patchTree.Filesystem.Stat("ROCKY") if err == nil { - srpmPatches(patchTree, pushTree) - cfgPatches(patchTree, pushTree) + cfgPatches(pd, md, patchTree, pushTree) } } -func executePatchesRpm(pd *ProcessData, md *modeData) { +func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) { // fetch patch repository repo, err := git.Init(memory.NewStorage(), memfs.New()) if err != nil { - log.Fatalf("could not create new dist repo: %v", err) + log.Fatalf("could not create new dist Repo: %v", err) } w, err := repo.Worktree() if err != nil { - log.Fatalf("could not get dist worktree: %v", err) + log.Fatalf("could not get dist Worktree: %v", err) } - remoteUrl := fmt.Sprintf("%s/patch/%s.git", pd.UpstreamPrefix, md.rpmFile.Name()) + remoteUrl := fmt.Sprintf("%s/patch/%s.git", pd.UpstreamPrefix, md.RpmFile.Name()) refspec := config.RefSpec(fmt.Sprintf("+refs/heads/*:refs/remotes/origin/*")) _, err = repo.CreateRemote(&config.RemoteConfig{ @@ -195,12 +93,12 @@ func executePatchesRpm(pd *ProcessData, md *modeData) { Auth: pd.Authenticator, }) - refName := plumbing.NewBranchReferenceName(md.pushBranch) + refName := plumbing.NewBranchReferenceName(md.PushBranch) log.Printf("set reference to ref: %s", refName) if err != nil { // no patches active - log.Println("info: patch repo not found") + log.Println("info: patch Repo not found") return } else { err = w.Checkout(&git.CheckoutOptions{ @@ -209,28 +107,28 @@ func executePatchesRpm(pd *ProcessData, md *modeData) { }) // common patches found, apply them if err == nil { - applyPatches(w, md.worktree) + applyPatches(pd, md, w, md.Worktree) } else { log.Println("info: no common patches found") } err = w.Checkout(&git.CheckoutOptions{ - Branch: plumbing.NewRemoteReferenceName("origin", md.pushBranch), + Branch: plumbing.NewRemoteReferenceName("origin", md.PushBranch), Force: true, }) // branch specific patches found, apply them if err == nil { - applyPatches(w, md.worktree) + applyPatches(pd, md, w, md.Worktree) } else { log.Println("info: no branch specific patches found") } } } -func getTipStream(pd *ProcessData, module string, pushBranch string) string { +func getTipStream(pd *data.ProcessData, module string, pushBranch string) string { repo, err := git.Init(memory.NewStorage(), memfs.New()) if err != nil { - log.Fatalf("could not init git repo: %v", err) + log.Fatalf("could not init git Repo: %v", err) } remoteUrl := fmt.Sprintf("%s/rpms/%s.git", pd.UpstreamPrefix, module) @@ -267,15 +165,15 @@ func getTipStream(pd *ProcessData, module string, pushBranch string) string { return tipHash } -func patchModuleYaml(pd *ProcessData, md *modeData) { +func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) { // special case for platform.yaml - _, err := md.worktree.Filesystem.Open("platform.yaml") + _, err := md.Worktree.Filesystem.Open("platform.yaml") if err == nil { return } mdTxtPath := "SOURCES/modulemd.src.txt" - f, err := md.worktree.Filesystem.Open(mdTxtPath) + f, err := md.Worktree.Filesystem.Open(mdTxtPath) if err != nil { log.Fatalf("could not open modulemd file: %v", err) } @@ -300,16 +198,16 @@ func patchModuleYaml(pd *ProcessData, md *modeData) { if strings.HasPrefix(rpm.Ref, "stream-rhel-") { repString := fmt.Sprintf("%s%ss-", pd.BranchPrefix, string(split[4][0])) newString := fmt.Sprintf("%s%s-", pd.BranchPrefix, string(split[4][0])) - pushBranch = strings.Replace(md.pushBranch, repString, newString, 1) + pushBranch = strings.Replace(md.PushBranch, repString, newString, 1) } else if strings.HasPrefix(rpm.Ref, "stream-") && len(split) == 2 { - pushBranch = md.pushBranch + pushBranch = md.PushBranch } else if strings.HasPrefix(rpm.Ref, "stream-") && len(split) == 3 { // example: ant pushBranch = fmt.Sprintf("%s%d-stream-%s", pd.BranchPrefix, pd.Version, split[2]) } else if strings.HasPrefix(rpm.Ref, "stream-") { pushBranch = fmt.Sprintf("%s%s-stream-%s", pd.BranchPrefix, string(split[3][0]), split[1]) } else if strings.HasPrefix(rpm.Ref, "rhel-") { - pushBranch = md.pushBranch + pushBranch = md.PushBranch } else { log.Fatal("could not recognize modulemd ref") } @@ -317,7 +215,7 @@ func patchModuleYaml(pd *ProcessData, md *modeData) { rpm.Ref = pushBranch tipHash = getTipStream(pd, name, pushBranch) - err = module.Marshal(md.worktree.Filesystem, mdTxtPath) + err = module.Marshal(md.Worktree.Filesystem, mdTxtPath) if err != nil { log.Fatalf("could not marshal modulemd: %v", err) } @@ -325,13 +223,13 @@ func patchModuleYaml(pd *ProcessData, md *modeData) { rpm.Ref = tipHash } - rootModule := fmt.Sprintf("%s.yaml", md.rpmFile.Name()) - err = module.Marshal(md.worktree.Filesystem, rootModule) + rootModule := fmt.Sprintf("%s.yaml", md.RpmFile.Name()) + err = module.Marshal(md.Worktree.Filesystem, rootModule) if err != nil { log.Fatalf("could not marshal root modulemd: %v", err) } - _, err = md.worktree.Add(rootModule) + _, err = md.Worktree.Add(rootModule) if err != nil { log.Fatalf("could not add root modulemd: %v", err) } diff --git a/internal/process.go b/internal/process.go index bcf2c7d..abba6bd 100644 --- a/internal/process.go +++ b/internal/process.go @@ -4,16 +4,13 @@ import ( "encoding/hex" "encoding/json" "fmt" - "git.rockylinux.org/release-engineering/public/srpmproc/internal/blob" - "github.com/cavaliercoder/go-rpm" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/go-git/go-git/v5/storage/memory" - "hash" "io/ioutil" "log" "os" @@ -25,54 +22,17 @@ import ( var tagImportRegex *regexp.Regexp -type ProcessData struct { - RpmLocation string - UpstreamPrefix string - SshKeyLocation string - SshUser string - Version int - GitCommitterName string - GitCommitterEmail string - Mode int - ModulePrefix string - ImportBranchPrefix string - BranchPrefix string - Authenticator *ssh.PublicKeys - Importer ImportMode - BlobStorage blob.Storage - NoDupMode bool - ModuleMode bool -} - -type ignoredSource struct { - name string - hashFunction hash.Hash - expired bool -} - -type modeData struct { - repo *git.Repository - worktree *git.Worktree - rpmFile *rpm.PackageFile - fileWrites map[string][]byte - tagBranch string - pushBranch string - branches []string - sourcesToIgnore []*ignoredSource - blobCache map[string][]byte -} - // ProcessRPM checks the RPM specs and discards any remote files // This functions also sorts files into directories // .spec files goes into -> SPECS // metadata files goes to root // source files goes into -> SOURCES // all files that are remote goes into .gitignore -// all ignored files' hash goes into .{name}.metadata -func ProcessRPM(pd *ProcessData) { +// all ignored files' hash goes into .{Name}.metadata +func ProcessRPM(pd *data.ProcessData) { tagImportRegex = regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s.|%s.-.+)/(.*))", pd.ImportBranchPrefix, pd.ImportBranchPrefix)) md := pd.Importer.RetrieveSource(pd) - md.blobCache = map[string][]byte{} + md.BlobCache = map[string][]byte{} remotePrefix := "rpms" if pd.ModuleMode { @@ -89,9 +49,9 @@ func ProcessRPM(pd *ProcessData) { if pd.NoDupMode { repo, err := git.Init(memory.NewStorage(), memfs.New()) if err != nil { - log.Fatalf("could not init git repo: %v", err) + log.Fatalf("could not init git Repo: %v", err) } - remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, md.rpmFile.Name()) + remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, md.RpmFile.Name()) refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*") remote, err := repo.CreateRemote(&config.RemoteConfig{ @@ -118,38 +78,42 @@ func ProcessRPM(pd *ProcessData) { } } - sourceRepo := *md.repo - sourceWorktree := *md.worktree + sourceRepo := *md.Repo + sourceWorktree := *md.Worktree - for _, branch := range md.branches { - md.repo = &sourceRepo - md.worktree = &sourceWorktree - md.tagBranch = branch - for _, source := range md.sourcesToIgnore { - source.expired = true + if pd.SingleTag != "" { + md.Branches = []string{fmt.Sprintf("refs/tags/%s", pd.SingleTag)} + } + + for _, branch := range md.Branches { + md.Repo = &sourceRepo + md.Worktree = &sourceWorktree + md.TagBranch = branch + for _, source := range md.SourcesToIgnore { + source.Expired = true } - if strings.Contains(md.tagBranch, "-beta") { + if strings.Contains(md.TagBranch, "-beta") { continue } - rpmFile := md.rpmFile - // create new repo for final dist - repo, err := git.Init(memory.NewStorage(), memfs.New()) + rpmFile := md.RpmFile + // create new Repo for final dist + repo, err := git.Init(memory.NewStorage(), pd.FsCreator()) if err != nil { - log.Fatalf("could not create new dist repo: %v", err) + log.Fatalf("could not create new dist Repo: %v", err) } w, err := repo.Worktree() if err != nil { - log.Fatalf("could not get dist worktree: %v", err) + log.Fatalf("could not get dist Worktree: %v", err) } var matchString string - if !tagImportRegex.MatchString(md.tagBranch) { + if !tagImportRegex.MatchString(md.TagBranch) { if pd.ModuleMode { prefix := fmt.Sprintf("refs/heads/%s%d", pd.ImportBranchPrefix, pd.Version) - if strings.HasPrefix(md.tagBranch, prefix) { - replace := strings.Replace(md.tagBranch, "refs/heads/", "", 1) + if strings.HasPrefix(md.TagBranch, prefix) { + replace := strings.Replace(md.TagBranch, "refs/heads/", "", 1) matchString = fmt.Sprintf("refs/tags/imports/%s/%s", replace, filepath.Base(pd.RpmLocation)) log.Printf("using match string: %s", matchString) } @@ -158,11 +122,11 @@ func ProcessRPM(pd *ProcessData) { continue } } else { - matchString = md.tagBranch + matchString = md.TagBranch } match := tagImportRegex.FindStringSubmatch(matchString) - md.pushBranch = pd.BranchPrefix + strings.TrimPrefix(match[2], pd.ImportBranchPrefix) + md.PushBranch = pd.BranchPrefix + strings.TrimPrefix(match[2], pd.ImportBranchPrefix) newTag := "imports/" + pd.BranchPrefix + strings.TrimPrefix(match[1], "imports/"+pd.ImportBranchPrefix) shouldContinue := true @@ -179,7 +143,7 @@ func ProcessRPM(pd *ProcessData) { // create a new remote remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, rpmFile.Name()) log.Printf("using remote: %s", remoteUrl) - refspec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/origin/%s", md.pushBranch, md.pushBranch)) + refspec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/origin/%s", md.PushBranch, md.PushBranch)) log.Printf("using refspec: %s", refspec) _, err = repo.CreateRemote(&config.RemoteConfig{ @@ -197,7 +161,7 @@ func ProcessRPM(pd *ProcessData) { Auth: pd.Authenticator, }) - refName := plumbing.NewBranchReferenceName(md.pushBranch) + refName := plumbing.NewBranchReferenceName(md.PushBranch) log.Printf("set reference to ref: %s", refName) if err != nil { @@ -207,7 +171,7 @@ func ProcessRPM(pd *ProcessData) { } } else { err = w.Checkout(&git.CheckoutOptions{ - Branch: plumbing.NewRemoteReferenceName("origin", md.pushBranch), + Branch: plumbing.NewRemoteReferenceName("origin", md.PushBranch), Force: true, }) if err != nil { @@ -217,9 +181,9 @@ func ProcessRPM(pd *ProcessData) { pd.Importer.WriteSource(pd, md) - copyFromFs(md.worktree.Filesystem, w.Filesystem, ".") - md.repo = repo - md.worktree = w + copyFromFs(md.Worktree.Filesystem, w.Filesystem, ".") + md.Repo = repo + md.Worktree = w if pd.ModuleMode { patchModuleYaml(pd, md) @@ -227,17 +191,17 @@ func ProcessRPM(pd *ProcessData) { executePatchesRpm(pd, md) } - // get ignored files hash and add to .{name}.metadata + // get ignored files hash and add to .{Name}.metadata metadataFile := fmt.Sprintf(".%s.metadata", rpmFile.Name()) metadata, err := w.Filesystem.Create(metadataFile) if err != nil { log.Fatalf("could not create metadata file: %v", err) } - for _, source := range md.sourcesToIgnore { - sourcePath := source.name + for _, source := range md.SourcesToIgnore { + sourcePath := source.Name _, err := w.Filesystem.Stat(sourcePath) - if source.expired || err != nil { + if source.Expired || err != nil { continue } @@ -250,12 +214,12 @@ func ProcessRPM(pd *ProcessData) { log.Fatalf("could not read the whole of ignored source file: %v", err) } - source.hashFunction.Reset() - _, err = source.hashFunction.Write(sourceFileBts) + source.HashFunction.Reset() + _, err = source.HashFunction.Write(sourceFileBts) if err != nil { log.Fatalf("could not write bytes to hash function: %v", err) } - checksum := hex.EncodeToString(source.hashFunction.Sum(nil)) + checksum := hex.EncodeToString(source.HashFunction.Sum(nil)) checksumLine := fmt.Sprintf("%s %s\n", checksum, sourcePath) _, err = metadata.Write([]byte(checksumLine)) if err != nil { @@ -266,7 +230,7 @@ func ProcessRPM(pd *ProcessData) { if strContains(alreadyUploadedBlobs, path) { continue } - if !pd.BlobStorage.Exists(path) { + if !pd.BlobStorage.Exists(path) && !pd.NoStorageUpload { pd.BlobStorage.Write(path, sourceFileBts) log.Printf("wrote %s to blob storage", path) } @@ -317,11 +281,11 @@ func ProcessRPM(pd *ProcessData) { } else { log.Printf("tip %s", head.String()) hashes = append(hashes, head.Hash()) - refOrigin := "refs/heads/" + md.pushBranch + refOrigin := "refs/heads/" + md.PushBranch pushRefspecs = append(pushRefspecs, config.RefSpec(fmt.Sprintf("HEAD:%s", refOrigin))) } - // we are now finished with the tree and are going to push it to the src repo + // we are now finished with the tree and are going to push it to the src Repo // create import commit commit, err := w.Commit("import "+pd.Importer.ImportName(pd, md), &git.CommitOptions{ Author: &object.Signature{ @@ -348,7 +312,7 @@ func ProcessRPM(pd *ProcessData) { Email: pd.GitCommitterEmail, When: time.Now(), }, - Message: "import " + md.tagBranch + " from " + pd.RpmLocation, + Message: "import " + md.TagBranch + " from " + pd.RpmLocation, SignKey: nil, }) if err != nil { @@ -368,7 +332,7 @@ func ProcessRPM(pd *ProcessData) { } hashString := obj.Hash.String() - latestHashForBranch[md.pushBranch] = hashString + latestHashForBranch[md.PushBranch] = hashString } err := json.NewEncoder(os.Stdout).Encode(latestHashForBranch) diff --git a/internal/srpm.go b/internal/srpm.go index 7c3b455..ed03381 100644 --- a/internal/srpm.go +++ b/internal/srpm.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/sha256" "fmt" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" "github.com/cavaliercoder/go-cpio" "github.com/cavaliercoder/go-rpm" "github.com/go-git/go-billy/v5/memfs" @@ -20,7 +21,7 @@ import ( type SrpmMode struct{} -func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData { +func (s *SrpmMode) RetrieveSource(pd *data.ProcessData) *data.ModeData { cmd := exec.Command("rpm2cpio", pd.RpmLocation) cpioBytes, err := cmd.Output() if err != nil { @@ -30,7 +31,7 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData { // create in memory git repository repo, err := git.Init(memory.NewStorage(), memfs.New()) if err != nil { - log.Fatalf("could not init git repo: %v", err) + log.Fatalf("could not init git Repo: %v", err) } // read the rpm in cpio format @@ -56,7 +57,7 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData { w, err := repo.Worktree() if err != nil { - log.Fatalf("could not get worktree: %v", err) + log.Fatalf("could not get Worktree: %v", err) } // create structure @@ -78,29 +79,29 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData { log.Fatalf("could not read package, invalid?: %v", err) } - var sourcesToIgnore []*ignoredSource + var sourcesToIgnore []*data.IgnoredSource for _, source := range rpmFile.Source() { if strings.Contains(source, ".tar") { - sourcesToIgnore = append(sourcesToIgnore, &ignoredSource{ - name: source, - hashFunction: sha256.New(), + sourcesToIgnore = append(sourcesToIgnore, &data.IgnoredSource{ + Name: source, + HashFunction: sha256.New(), }) } } branch := fmt.Sprintf("%s%d", pd.BranchPrefix, pd.Version) - return &modeData{ - repo: repo, - worktree: w, - rpmFile: rpmFile, - fileWrites: fileWrites, - branches: []string{branch}, - sourcesToIgnore: sourcesToIgnore, + return &data.ModeData{ + Repo: repo, + Worktree: w, + RpmFile: rpmFile, + FileWrites: fileWrites, + Branches: []string{branch}, + SourcesToIgnore: sourcesToIgnore, } } -func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { - for fileName, contents := range md.fileWrites { +func (s *SrpmMode) WriteSource(_ *data.ProcessData, md *data.ModeData) { + for fileName, contents := range md.FileWrites { var newPath string if filepath.Ext(fileName) == ".spec" { newPath = filepath.Join("SPECS", fileName) @@ -109,7 +110,7 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { } mode := os.FileMode(0666) - for _, file := range md.rpmFile.Files() { + for _, file := range md.RpmFile.Files() { if file.Name() == fileName { mode = file.Mode() } @@ -117,7 +118,7 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { // add the file to the virtual filesystem // we will move it to correct destination later - f, err := md.worktree.Filesystem.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode) + f, err := md.Worktree.Filesystem.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode) if err != nil { log.Fatalf("could not create file %s: %v", fileName, err) } @@ -130,22 +131,22 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { _ = f.Close() // don't add ignored file to git - if ignoredContains(md.sourcesToIgnore, fileName) { + if ignoredContains(md.SourcesToIgnore, fileName) { continue } - _, err = md.worktree.Add(newPath) + _, err = md.Worktree.Add(newPath) if err != nil { log.Fatalf("could not add source file: %v", err) } } // add sources to ignore (remote sources) - gitIgnore, err := md.worktree.Filesystem.Create(".gitignore") + gitIgnore, err := md.Worktree.Filesystem.Create(".gitignore") if err != nil { log.Fatalf("could not create .gitignore: %v", err) } - for _, ignore := range md.sourcesToIgnore { + for _, ignore := range md.SourcesToIgnore { line := fmt.Sprintf("SOURCES/%s\n", ignore) _, err := gitIgnore.Write([]byte(line)) if err != nil { @@ -158,8 +159,8 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { } } -func (s *SrpmMode) PostProcess(_ *modeData) {} +func (s *SrpmMode) PostProcess(_ *data.ModeData) {} -func (s *SrpmMode) ImportName(pd *ProcessData, _ *modeData) string { +func (s *SrpmMode) ImportName(pd *data.ProcessData, _ *data.ModeData) string { return filepath.Base(pd.RpmLocation) } diff --git a/internal/utils.go b/internal/utils.go index b8b5690..2cac9db 100644 --- a/internal/utils.go +++ b/internal/utils.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "crypto/sha512" "encoding/hex" + "git.rockylinux.org/release-engineering/public/srpmproc/internal/data" "github.com/go-git/go-billy/v5" "hash" "io" @@ -47,9 +48,9 @@ func copyFromFs(from billy.Filesystem, to billy.Filesystem, path string) { } } -func ignoredContains(a []*ignoredSource, b string) bool { +func ignoredContains(a []*data.IgnoredSource, b string) bool { for _, val := range a { - if val.name == b { + if val.Name == b { return true } } diff --git a/pb/cfg.pb.go b/pb/cfg.pb.go index 61372f5..47d596c 100644 --- a/pb/cfg.pb.go +++ b/pb/cfg.pb.go @@ -220,6 +220,9 @@ func (x *Delete) GetFile() string { } // Add directive adds a file from the patch repository to the rpm repository. +// The file is added in the `SOURCES` directory +// Won't add to spec automatically. +// Use the `SpecChange` directive for that type Add struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -343,9 +346,9 @@ type SpecChange struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Types that are assignable to Operation: - // *SpecChange_FileOperation_ - Operation isSpecChange_Operation `protobuf_oneof:"operation"` + File []*SpecChange_FileOperation `protobuf:"bytes,1,rep,name=file,proto3" json:"file,omitempty"` + Changelog []*SpecChange_ChangelogOperation `protobuf:"bytes,2,rep,name=changelog,proto3" json:"changelog,omitempty"` + SearchAndReplace []*SpecChange_SearchAndReplaceOperation `protobuf:"bytes,3,rep,name=search_and_replace,json=searchAndReplace,proto3" json:"search_and_replace,omitempty"` } func (x *SpecChange) Reset() { @@ -380,30 +383,27 @@ func (*SpecChange) Descriptor() ([]byte, []int) { return file_cfg_proto_rawDescGZIP(), []int{4} } -func (m *SpecChange) GetOperation() isSpecChange_Operation { - if m != nil { - return m.Operation +func (x *SpecChange) GetFile() []*SpecChange_FileOperation { + if x != nil { + return x.File } return nil } -func (x *SpecChange) GetFileOperation() *SpecChange_FileOperation { - if x, ok := x.GetOperation().(*SpecChange_FileOperation_); ok { - return x.FileOperation +func (x *SpecChange) GetChangelog() []*SpecChange_ChangelogOperation { + if x != nil { + return x.Changelog } return nil } -type isSpecChange_Operation interface { - isSpecChange_Operation() +func (x *SpecChange) GetSearchAndReplace() []*SpecChange_SearchAndReplaceOperation { + if x != nil { + return x.SearchAndReplace + } + return nil } -type SpecChange_FileOperation_ struct { - FileOperation *SpecChange_FileOperation `protobuf:"bytes,1,opt,name=file_operation,json=fileOperation,proto3,oneof"` -} - -func (*SpecChange_FileOperation_) isSpecChange_Operation() {} - type Patch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -468,12 +468,12 @@ type Cfg struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Replace []*Replace `protobuf:"bytes,1,rep,name=replace,proto3" json:"replace,omitempty"` - Delete []*Delete `protobuf:"bytes,2,rep,name=delete,proto3" json:"delete,omitempty"` - Add []*Add `protobuf:"bytes,3,rep,name=add,proto3" json:"add,omitempty"` - Lookaside []*Lookaside `protobuf:"bytes,4,rep,name=lookaside,proto3" json:"lookaside,omitempty"` - SpecChange []*SpecChange `protobuf:"bytes,5,rep,name=spec_change,json=specChange,proto3" json:"spec_change,omitempty"` - Patch []*Patch `protobuf:"bytes,6,rep,name=patch,proto3" json:"patch,omitempty"` + Replace []*Replace `protobuf:"bytes,1,rep,name=replace,proto3" json:"replace,omitempty"` + Delete []*Delete `protobuf:"bytes,2,rep,name=delete,proto3" json:"delete,omitempty"` + Add []*Add `protobuf:"bytes,3,rep,name=add,proto3" json:"add,omitempty"` + Lookaside []*Lookaside `protobuf:"bytes,4,rep,name=lookaside,proto3" json:"lookaside,omitempty"` + SpecChange *SpecChange `protobuf:"bytes,5,opt,name=spec_change,json=specChange,proto3" json:"spec_change,omitempty"` + Patch []*Patch `protobuf:"bytes,6,rep,name=patch,proto3" json:"patch,omitempty"` } func (x *Cfg) Reset() { @@ -536,7 +536,7 @@ func (x *Cfg) GetLookaside() []*Lookaside { return nil } -func (x *Cfg) GetSpecChange() []*SpecChange { +func (x *Cfg) GetSpecChange() *SpecChange { if x != nil { return x.SpecChange } @@ -558,7 +558,7 @@ type SpecChange_FileOperation struct { unknownFields protoimpl.UnknownFields // File name - File string `protobuf:"bytes,1,opt,name=file,proto3" json:"file,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // File type Type SpecChange_FileOperation_Type `protobuf:"varint,2,opt,name=type,proto3,enum=srpmproc.SpecChange_FileOperation_Type" json:"type,omitempty"` // Types that are assignable to Mode: @@ -599,9 +599,9 @@ func (*SpecChange_FileOperation) Descriptor() ([]byte, []int) { return file_cfg_proto_rawDescGZIP(), []int{4, 0} } -func (x *SpecChange_FileOperation) GetFile() string { +func (x *SpecChange_FileOperation) GetName() string { if x != nil { - return x.File + return x.Name } return "" } @@ -654,6 +654,214 @@ func (*SpecChange_FileOperation_Add) isSpecChange_FileOperation_Mode() {} func (*SpecChange_FileOperation_Delete) isSpecChange_FileOperation_Mode() {} +// ChangelogOperation adds a new changelog entry +type SpecChange_ChangelogOperation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthorName string `protobuf:"bytes,1,opt,name=author_name,json=authorName,proto3" json:"author_name,omitempty"` + AuthorEmail string `protobuf:"bytes,2,opt,name=author_email,json=authorEmail,proto3" json:"author_email,omitempty"` + Message []string `protobuf:"bytes,3,rep,name=message,proto3" json:"message,omitempty"` +} + +func (x *SpecChange_ChangelogOperation) Reset() { + *x = SpecChange_ChangelogOperation{} + if protoimpl.UnsafeEnabled { + mi := &file_cfg_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SpecChange_ChangelogOperation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SpecChange_ChangelogOperation) ProtoMessage() {} + +func (x *SpecChange_ChangelogOperation) ProtoReflect() protoreflect.Message { + mi := &file_cfg_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SpecChange_ChangelogOperation.ProtoReflect.Descriptor instead. +func (*SpecChange_ChangelogOperation) Descriptor() ([]byte, []int) { + return file_cfg_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *SpecChange_ChangelogOperation) GetAuthorName() string { + if x != nil { + return x.AuthorName + } + return "" +} + +func (x *SpecChange_ChangelogOperation) GetAuthorEmail() string { + if x != nil { + return x.AuthorEmail + } + return "" +} + +func (x *SpecChange_ChangelogOperation) GetMessage() []string { + if x != nil { + return x.Message + } + return nil +} + +// SearchAndReplaceOperation replaces substring with value +// in a specified field +type SpecChange_SearchAndReplaceOperation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Identifier: + // *SpecChange_SearchAndReplaceOperation_Field + // *SpecChange_SearchAndReplaceOperation_Any + // *SpecChange_SearchAndReplaceOperation_StartsWith + // *SpecChange_SearchAndReplaceOperation_EndsWith + Identifier isSpecChange_SearchAndReplaceOperation_Identifier `protobuf_oneof:"identifier"` + Find string `protobuf:"bytes,5,opt,name=find,proto3" json:"find,omitempty"` + Replace string `protobuf:"bytes,6,opt,name=replace,proto3" json:"replace,omitempty"` + // How many occurences to replace. + // Set to -1 for all + N int32 `protobuf:"zigzag32,7,opt,name=n,proto3" json:"n,omitempty"` +} + +func (x *SpecChange_SearchAndReplaceOperation) Reset() { + *x = SpecChange_SearchAndReplaceOperation{} + if protoimpl.UnsafeEnabled { + mi := &file_cfg_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SpecChange_SearchAndReplaceOperation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SpecChange_SearchAndReplaceOperation) ProtoMessage() {} + +func (x *SpecChange_SearchAndReplaceOperation) ProtoReflect() protoreflect.Message { + mi := &file_cfg_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SpecChange_SearchAndReplaceOperation.ProtoReflect.Descriptor instead. +func (*SpecChange_SearchAndReplaceOperation) Descriptor() ([]byte, []int) { + return file_cfg_proto_rawDescGZIP(), []int{4, 2} +} + +func (m *SpecChange_SearchAndReplaceOperation) GetIdentifier() isSpecChange_SearchAndReplaceOperation_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *SpecChange_SearchAndReplaceOperation) GetField() string { + if x, ok := x.GetIdentifier().(*SpecChange_SearchAndReplaceOperation_Field); ok { + return x.Field + } + return "" +} + +func (x *SpecChange_SearchAndReplaceOperation) GetAny() bool { + if x, ok := x.GetIdentifier().(*SpecChange_SearchAndReplaceOperation_Any); ok { + return x.Any + } + return false +} + +func (x *SpecChange_SearchAndReplaceOperation) GetStartsWith() bool { + if x, ok := x.GetIdentifier().(*SpecChange_SearchAndReplaceOperation_StartsWith); ok { + return x.StartsWith + } + return false +} + +func (x *SpecChange_SearchAndReplaceOperation) GetEndsWith() bool { + if x, ok := x.GetIdentifier().(*SpecChange_SearchAndReplaceOperation_EndsWith); ok { + return x.EndsWith + } + return false +} + +func (x *SpecChange_SearchAndReplaceOperation) GetFind() string { + if x != nil { + return x.Find + } + return "" +} + +func (x *SpecChange_SearchAndReplaceOperation) GetReplace() string { + if x != nil { + return x.Replace + } + return "" +} + +func (x *SpecChange_SearchAndReplaceOperation) GetN() int32 { + if x != nil { + return x.N + } + return 0 +} + +type isSpecChange_SearchAndReplaceOperation_Identifier interface { + isSpecChange_SearchAndReplaceOperation_Identifier() +} + +type SpecChange_SearchAndReplaceOperation_Field struct { + // replace occurrences in field value + Field string `protobuf:"bytes,1,opt,name=field,proto3,oneof"` +} + +type SpecChange_SearchAndReplaceOperation_Any struct { + // replace occurrences in any line + Any bool `protobuf:"varint,2,opt,name=any,proto3,oneof"` +} + +type SpecChange_SearchAndReplaceOperation_StartsWith struct { + // replace occurrences that starts with find + StartsWith bool `protobuf:"varint,3,opt,name=starts_with,json=startsWith,proto3,oneof"` +} + +type SpecChange_SearchAndReplaceOperation_EndsWith struct { + // replace occurrences that ends with find + EndsWith bool `protobuf:"varint,4,opt,name=ends_with,json=endsWith,proto3,oneof"` +} + +func (*SpecChange_SearchAndReplaceOperation_Field) isSpecChange_SearchAndReplaceOperation_Identifier() { +} + +func (*SpecChange_SearchAndReplaceOperation_Any) isSpecChange_SearchAndReplaceOperation_Identifier() { +} + +func (*SpecChange_SearchAndReplaceOperation_StartsWith) isSpecChange_SearchAndReplaceOperation_Identifier() { +} + +func (*SpecChange_SearchAndReplaceOperation_EndsWith) isSpecChange_SearchAndReplaceOperation_Identifier() { +} + var File_cfg_proto protoreflect.FileDescriptor var file_cfg_proto_rawDesc = []byte{ @@ -673,15 +881,24 @@ var file_cfg_proto_rawDesc = []byte{ 0x22, 0x33, 0x0a, 0x09, 0x4c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x03, 0x74, 0x61, 0x72, 0x22, 0xab, 0x02, 0x0a, 0x0a, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, - 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x48, 0x00, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x1a, 0xc2, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x52, 0x03, 0x74, 0x61, 0x72, 0x22, 0xf8, 0x05, 0x0a, 0x0a, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, + 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x09, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x67, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x6c, 0x6f, 0x67, 0x12, 0x5c, 0x0a, 0x12, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x61, 0x6e, + 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2e, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x6e, 0x64, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x10, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x1a, 0xc2, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, @@ -691,31 +908,53 @@ var file_cfg_proto_rawDesc = []byte{ 0x74, 0x65, 0x22, 0x2a, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x42, 0x06, - 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x22, 0x8e, 0x02, 0x0a, 0x03, 0x43, 0x66, 0x67, - 0x12, 0x2b, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x52, 0x65, 0x70, - 0x6c, 0x61, 0x63, 0x65, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x28, 0x0a, - 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x03, 0x61, 0x64, 0x64, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, - 0x41, 0x64, 0x64, 0x52, 0x03, 0x61, 0x64, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, - 0x61, 0x73, 0x69, 0x64, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x72, - 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, - 0x52, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x73, - 0x70, 0x65, 0x63, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x50, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x73, 0x74, 0x67, 0x2f, 0x73, 0x72, 0x70, - 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2f, 0x70, 0x62, 0x3b, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, - 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x72, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xd3, 0x01, 0x0a, 0x19, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x12, 0x12, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x03, 0x61, 0x6e, 0x79, 0x12, 0x21, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x73, 0x5f, + 0x77, 0x69, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x65, 0x6e, + 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6e, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52, + 0x01, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x22, 0x33, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x22, 0x8e, 0x02, 0x0a, 0x03, 0x43, 0x66, 0x67, 0x12, 0x2b, 0x0a, + 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x72, 0x70, + 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x03, 0x61, 0x64, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x41, 0x64, 0x64, + 0x52, 0x03, 0x61, 0x64, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, + 0x64, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, + 0x72, 0x6f, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x52, 0x09, 0x6c, + 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x63, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, + 0x25, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x2e, 0x72, 0x6f, + 0x63, 0x6b, 0x79, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x72, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x2d, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, + 0x2f, 0x70, 0x62, 0x3b, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -731,32 +970,36 @@ func file_cfg_proto_rawDescGZIP() []byte { } var file_cfg_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_cfg_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_cfg_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_cfg_proto_goTypes = []interface{}{ - (SpecChange_FileOperation_Type)(0), // 0: srpmproc.SpecChange.FileOperation.Type - (*Replace)(nil), // 1: srpmproc.Replace - (*Delete)(nil), // 2: srpmproc.Delete - (*Add)(nil), // 3: srpmproc.Add - (*Lookaside)(nil), // 4: srpmproc.Lookaside - (*SpecChange)(nil), // 5: srpmproc.SpecChange - (*Patch)(nil), // 6: srpmproc.Patch - (*Cfg)(nil), // 7: srpmproc.Cfg - (*SpecChange_FileOperation)(nil), // 8: srpmproc.SpecChange.FileOperation + (SpecChange_FileOperation_Type)(0), // 0: srpmproc.SpecChange.FileOperation.Type + (*Replace)(nil), // 1: srpmproc.Replace + (*Delete)(nil), // 2: srpmproc.Delete + (*Add)(nil), // 3: srpmproc.Add + (*Lookaside)(nil), // 4: srpmproc.Lookaside + (*SpecChange)(nil), // 5: srpmproc.SpecChange + (*Patch)(nil), // 6: srpmproc.Patch + (*Cfg)(nil), // 7: srpmproc.Cfg + (*SpecChange_FileOperation)(nil), // 8: srpmproc.SpecChange.FileOperation + (*SpecChange_ChangelogOperation)(nil), // 9: srpmproc.SpecChange.ChangelogOperation + (*SpecChange_SearchAndReplaceOperation)(nil), // 10: srpmproc.SpecChange.SearchAndReplaceOperation } var file_cfg_proto_depIdxs = []int32{ - 8, // 0: srpmproc.SpecChange.file_operation:type_name -> srpmproc.SpecChange.FileOperation - 1, // 1: srpmproc.Cfg.replace:type_name -> srpmproc.Replace - 2, // 2: srpmproc.Cfg.delete:type_name -> srpmproc.Delete - 3, // 3: srpmproc.Cfg.add:type_name -> srpmproc.Add - 4, // 4: srpmproc.Cfg.lookaside:type_name -> srpmproc.Lookaside - 5, // 5: srpmproc.Cfg.spec_change:type_name -> srpmproc.SpecChange - 6, // 6: srpmproc.Cfg.patch:type_name -> srpmproc.Patch - 0, // 7: srpmproc.SpecChange.FileOperation.type:type_name -> srpmproc.SpecChange.FileOperation.Type - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 8, // 0: srpmproc.SpecChange.file:type_name -> srpmproc.SpecChange.FileOperation + 9, // 1: srpmproc.SpecChange.changelog:type_name -> srpmproc.SpecChange.ChangelogOperation + 10, // 2: srpmproc.SpecChange.search_and_replace:type_name -> srpmproc.SpecChange.SearchAndReplaceOperation + 1, // 3: srpmproc.Cfg.replace:type_name -> srpmproc.Replace + 2, // 4: srpmproc.Cfg.delete:type_name -> srpmproc.Delete + 3, // 5: srpmproc.Cfg.add:type_name -> srpmproc.Add + 4, // 6: srpmproc.Cfg.lookaside:type_name -> srpmproc.Lookaside + 5, // 7: srpmproc.Cfg.spec_change:type_name -> srpmproc.SpecChange + 6, // 8: srpmproc.Cfg.patch:type_name -> srpmproc.Patch + 0, // 9: srpmproc.SpecChange.FileOperation.type:type_name -> srpmproc.SpecChange.FileOperation.Type + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_cfg_proto_init() } @@ -861,25 +1104,52 @@ func file_cfg_proto_init() { return nil } } + file_cfg_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SpecChange_ChangelogOperation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cfg_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SpecChange_SearchAndReplaceOperation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_cfg_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Replace_WithFile)(nil), (*Replace_WithInline)(nil), } - file_cfg_proto_msgTypes[4].OneofWrappers = []interface{}{ - (*SpecChange_FileOperation_)(nil), - } file_cfg_proto_msgTypes[7].OneofWrappers = []interface{}{ (*SpecChange_FileOperation_Add)(nil), (*SpecChange_FileOperation_Delete)(nil), } + file_cfg_proto_msgTypes[9].OneofWrappers = []interface{}{ + (*SpecChange_SearchAndReplaceOperation_Field)(nil), + (*SpecChange_SearchAndReplaceOperation_Any)(nil), + (*SpecChange_SearchAndReplaceOperation_StartsWith)(nil), + (*SpecChange_SearchAndReplaceOperation_EndsWith)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cfg_proto_rawDesc, NumEnums: 1, - NumMessages: 8, + NumMessages: 10, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/cfg.proto b/proto/cfg.proto index 35c613a..c3c3b45 100644 --- a/proto/cfg.proto +++ b/proto/cfg.proto @@ -62,7 +62,7 @@ message SpecChange { Patch = 2; } // File name - string file = 1; + string name = 1; // File type Type type = 2; @@ -75,9 +75,35 @@ message SpecChange { bool delete = 4; } } - oneof operation { - FileOperation file_operation = 1; + // ChangelogOperation adds a new changelog entry + message ChangelogOperation { + string author_name = 1; + string author_email = 2; + repeated string message = 3; } + // SearchAndReplaceOperation replaces substring with value + // in a specified field + message SearchAndReplaceOperation { + oneof identifier { + // replace occurrences in field value + string field = 1; + // replace occurrences in any line + bool any = 2; + // replace occurrences that starts with find + bool starts_with = 3; + // replace occurrences that ends with find + bool ends_with = 4; + } + string find = 5; + string replace = 6; + // How many occurences to replace. + // Set to -1 for all + sint32 n = 7; + } + + repeated FileOperation file = 1; + repeated ChangelogOperation changelog = 2; + repeated SearchAndReplaceOperation search_and_replace = 3; } message Patch { @@ -95,6 +121,6 @@ message Cfg { repeated Delete delete = 2; repeated Add add = 3; repeated Lookaside lookaside = 4; - repeated SpecChange spec_change = 5; + SpecChange spec_change = 5; repeated Patch patch = 6; }