messy code ahead. implement new directives (spec_change) and restructure code to prevent import cycles

This commit is contained in:
Mustafa Gezen 2021-02-24 08:27:51 +01:00
parent 2782a66848
commit 01380b9b2d
20 changed files with 1046 additions and 399 deletions

View File

@ -3,10 +3,17 @@ package main
import ( import (
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/blob" "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/gcs"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/blob/s3" "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" "github.com/go-git/go-git/v5/plumbing/transport/ssh"
"io/ioutil"
"log" "log"
"os"
"os/user" "os/user"
"path/filepath" "path/filepath"
"strings" "strings"
@ -28,8 +35,12 @@ var (
rpmPrefix string rpmPrefix string
importBranchPrefix string importBranchPrefix string
branchPrefix string branchPrefix string
singleTag string
noDupMode bool noDupMode bool
moduleMode bool moduleMode bool
tmpFsMode bool
noStorageDownload bool
noStorageUpload bool
) )
var root = &cobra.Command{ var root = &cobra.Command{
@ -45,13 +56,15 @@ func mn(_ *cobra.Command, _ []string) {
log.Fatalf("unsupported upstream version %d", version) log.Fatalf("unsupported upstream version %d", version)
} }
var importer internal.ImportMode var importer data.ImportMode
var blobStorage blob.Storage var blobStorage blob.Storage
if strings.HasPrefix(storageAddr, "gs://") { if strings.HasPrefix(storageAddr, "gs://") {
blobStorage = gcs.New(strings.Replace(storageAddr, "gs://", "", 1)) blobStorage = gcs.New(strings.Replace(storageAddr, "gs://", "", 1))
} else if strings.HasPrefix(storageAddr, "s3://") { } else if strings.HasPrefix(storageAddr, "s3://") {
blobStorage = s3.New(strings.Replace(storageAddr, "s3://", "", 1)) blobStorage = s3.New(strings.Replace(storageAddr, "s3://", "", 1))
} else if strings.HasPrefix(storageAddr, "file://") {
blobStorage = file.New(strings.Replace(storageAddr, "file://", "", 1))
} else { } else {
log.Fatalf("invalid blob storage") log.Fatalf("invalid blob storage")
} }
@ -83,7 +96,22 @@ func mn(_ *cobra.Command, _ []string) {
log.Fatalf("could not get git authenticator: %v", err) 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, Importer: importer,
RpmLocation: sourceRpmLocation, RpmLocation: sourceRpmLocation,
UpstreamPrefix: upstreamPrefix, UpstreamPrefix: upstreamPrefix,
@ -96,9 +124,14 @@ func mn(_ *cobra.Command, _ []string) {
ModulePrefix: modulePrefix, ModulePrefix: modulePrefix,
ImportBranchPrefix: importBranchPrefix, ImportBranchPrefix: importBranchPrefix,
BranchPrefix: branchPrefix, BranchPrefix: branchPrefix,
SingleTag: singleTag,
Authenticator: authenticator, Authenticator: authenticator,
NoDupMode: noDupMode, NoDupMode: noDupMode,
ModuleMode: moduleMode, 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(&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(&importBranchPrefix, "import-branch-prefix", "c", "Import branch prefix")
root.Flags().StringVar(&branchPrefix, "branch-prefix", "r", "Branch prefix (replaces 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(&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(&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 { if err := root.Execute(); err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -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)
}

32
internal/data/import.go Normal file
View File

@ -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
}

31
internal/data/process.go Normal file
View File

@ -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
}

View File

@ -3,6 +3,7 @@ package directives
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"io/ioutil" "io/ioutil"
@ -10,7 +11,7 @@ import (
"path/filepath" "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 { for _, add := range cfg.Add {
filePath := checkAddPrefix(filepath.Base(add.File)) filePath := checkAddPrefix(filepath.Base(add.File))

View File

@ -3,11 +3,12 @@ package directives
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb"
"github.com/go-git/go-git/v5" "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 { for _, del := range cfg.Delete {
filePath := del.File filePath := del.File
_, err := pushTree.Filesystem.Stat(filePath) _, err := pushTree.Filesystem.Stat(filePath)

View File

@ -2,6 +2,7 @@ package directives
import ( import (
"encoding/json" "encoding/json"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"log" "log"
@ -19,27 +20,23 @@ func checkAddPrefix(file string) string {
return filepath.Join("SOURCES", file) 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 var errs []string
err := replace(cfg, patchTree, pushTree) directives := []func(*srpmprocpb.Cfg, *data.ProcessData, *data.ModeData, *git.Worktree, *git.Worktree) error{
if err != nil { replace,
errs = append(errs, err.Error()) del,
add,
patch,
lookaside,
specChange,
} }
err = del(cfg, patchTree, pushTree) for _, directive := range directives {
if err != nil { err := directive(cfg, pd, md, patchTree, pushTree)
errs = append(errs, err.Error()) 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())
} }
if len(errs) > 0 { if len(errs) > 0 {

View File

@ -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
}

View File

@ -4,13 +4,14 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb"
"github.com/bluekeyes/go-gitdiff/gitdiff" "github.com/bluekeyes/go-gitdiff/gitdiff"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"log" "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 { for _, patch := range cfg.Patch {
patchFile, err := patchTree.Filesystem.Open(patch.File) patchFile, err := patchTree.Filesystem.Open(patch.File)
if err != nil { if err != nil {

View File

@ -3,13 +3,14 @@ package directives
import ( import (
"errors" "errors"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"io/ioutil" "io/ioutil"
"os" "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 { for _, replace := range cfg.Replace {
filePath := checkAddPrefix(replace.File) filePath := checkAddPrefix(replace.File)
stat, err := pushTree.Filesystem.Stat(filePath) stat, err := pushTree.Filesystem.Stat(filePath)

View File

@ -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
}

View File

@ -2,6 +2,7 @@ package internal
import ( import (
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
"github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/config"
@ -38,15 +39,15 @@ func (p remoteTargetSlice) Swap(i, j int) {
type GitMode struct{} 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()) repo, err := git.Init(memory.NewStorage(), memfs.New())
if err != nil { 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() w, err := repo.Worktree()
if err != nil { 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/*") refspec := config.RefSpec("+refs/heads/*:refs/remotes/*")
@ -116,17 +117,17 @@ func (g *GitMode) RetrieveSource(pd *ProcessData) *modeData {
sortedBranches = append(sortedBranches, branch.remote) sortedBranches = append(sortedBranches, branch.remote)
} }
return &modeData{ return &data.ModeData{
repo: repo, Repo: repo,
worktree: w, Worktree: w,
rpmFile: createPackageFile(filepath.Base(pd.RpmLocation)), RpmFile: createPackageFile(filepath.Base(pd.RpmLocation)),
fileWrites: nil, FileWrites: nil,
branches: sortedBranches, Branches: sortedBranches,
} }
} }
func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) { func (g *GitMode) WriteSource(pd *data.ProcessData, md *data.ModeData) {
remote, err := md.repo.Remote("upstream") remote, err := md.Repo.Remote("upstream")
if err != nil { if err != nil {
log.Fatalf("could not get upstream remote: %v", err) 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 refspec config.RefSpec
var branchName string var branchName string
if strings.HasPrefix(md.tagBranch, "refs/heads") { if strings.HasPrefix(md.TagBranch, "refs/heads") {
refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.tagBranch, md.tagBranch)) refspec = config.RefSpec(fmt.Sprintf("+%s:%s", md.TagBranch, md.TagBranch))
branchName = strings.TrimPrefix(md.tagBranch, "refs/heads/") branchName = strings.TrimPrefix(md.TagBranch, "refs/heads/")
} else { } else {
match := tagImportRegex.FindStringSubmatch(md.tagBranch) match := tagImportRegex.FindStringSubmatch(md.TagBranch)
branchName = match[2] 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) log.Printf("checking out upstream refspec %s", refspec)
err = remote.Fetch(&git.FetchOptions{ 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) log.Fatalf("could not fetch upstream: %v", err)
} }
err = md.worktree.Checkout(&git.CheckoutOptions{ err = md.Worktree.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName(md.tagBranch), Branch: plumbing.ReferenceName(md.TagBranch),
Force: true, Force: true,
}) })
if err != nil { if err != nil {
log.Fatalf("could not checkout source from git: %v", err) log.Fatalf("could not checkout source from git: %v", err)
} }
_, err = md.worktree.Add(".") _, err = md.Worktree.Add(".")
if err != nil { 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 { if err != nil {
log.Printf("warn: could not open metadata file, so skipping: %v", err) log.Printf("warn: could not open metadata file, so skipping: %v", err)
return return
@ -194,16 +195,16 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) {
var body []byte var body []byte
if md.blobCache[hash] != nil { if md.BlobCache[hash] != nil {
body = md.blobCache[hash] body = md.BlobCache[hash]
log.Printf("retrieving %s from cache", hash) log.Printf("retrieving %s from cache", hash)
} else { } else {
fromBlobStorage := pd.BlobStorage.Read(hash) fromBlobStorage := pd.BlobStorage.Read(hash)
if fromBlobStorage != nil { if fromBlobStorage != nil && !pd.NoStorageDownload {
body = fromBlobStorage body = fromBlobStorage
log.Printf("downloading %s from blob storage", hash) log.Printf("downloading %s from blob storage", hash)
} else { } 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) log.Printf("downloading %s", url)
req, err := http.NewRequest("GET", url, nil) 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 { if err != nil {
log.Fatalf("could not open file pointer: %v", err) 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") log.Fatal("checksum in metadata does not match dist-git file")
} }
md.sourcesToIgnore = append(md.sourcesToIgnore, &ignoredSource{ md.SourcesToIgnore = append(md.SourcesToIgnore, &data.IgnoredSource{
name: path, Name: path,
hashFunction: hasher, HashFunction: hasher,
}) })
_, err = f.Write(body) _, err = f.Write(body)
@ -253,28 +254,28 @@ func (g *GitMode) WriteSource(pd *ProcessData, md *modeData) {
} }
} }
func (g *GitMode) PostProcess(md *modeData) { func (g *GitMode) PostProcess(md *data.ModeData) {
for _, source := range md.sourcesToIgnore { for _, source := range md.SourcesToIgnore {
_, err := md.worktree.Filesystem.Stat(source.name) _, err := md.Worktree.Filesystem.Stat(source.Name)
if err == nil { if err == nil {
err := md.worktree.Filesystem.Remove(source.name) err := md.Worktree.Filesystem.Remove(source.Name)
if err != nil { if err != nil {
log.Fatalf("could not remove dist-git file: %v", err) log.Fatalf("could not remove dist-git file: %v", err)
} }
} }
} }
_, err := md.worktree.Add(".") _, err := md.Worktree.Add(".")
if err != nil { if err != nil {
log.Fatalf("could not add git sources: %v", err) log.Fatalf("could not add git sources: %v", err)
} }
} }
func (g *GitMode) ImportName(_ *ProcessData, md *modeData) string { func (g *GitMode) ImportName(_ *data.ProcessData, md *data.ModeData) string {
if tagImportRegex.MatchString(md.tagBranch) { if tagImportRegex.MatchString(md.TagBranch) {
match := tagImportRegex.FindStringSubmatch(md.tagBranch) match := tagImportRegex.FindStringSubmatch(md.TagBranch)
return match[3] return match[3]
} }
return strings.TrimPrefix(md.tagBranch, "refs/heads/") return strings.TrimPrefix(md.TagBranch, "refs/heads/")
} }

View File

@ -6,7 +6,7 @@ import (
// TODO: ugly hack, should create an interface // TODO: ugly hack, should create an interface
// since GitMode does not parse an RPM file, we just mimick // 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 { func createPackageFile(name string) *rpm.PackageFile {
return &rpm.PackageFile{ return &rpm.PackageFile{
Lead: rpm.Lead{}, Lead: rpm.Lead{},

View File

@ -1,8 +1 @@
package internal package internal
type ImportMode interface {
RetrieveSource(pd *ProcessData) *modeData
WriteSource(pd *ProcessData, md *modeData)
PostProcess(md *modeData)
ImportName(pd *ProcessData, md *modeData) string
}

View File

@ -1,12 +1,11 @@
package internal package internal
import ( import (
"bytes"
"fmt" "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/internal/directives"
"git.rockylinux.org/release-engineering/public/srpmproc/modulemd" "git.rockylinux.org/release-engineering/public/srpmproc/modulemd"
srpmprocpb "git.rockylinux.org/release-engineering/public/srpmproc/pb" 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-billy/v5/memfs"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/config"
@ -19,107 +18,7 @@ import (
"strings" "strings"
) )
func srpmPatches(patchTree *git.Worktree, pushTree *git.Worktree) { func cfgPatches(pd *data.ProcessData, md *data.ModeData, 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) {
// check CFG patches // check CFG patches
_, err := patchTree.Filesystem.Stat("ROCKY/CFG") _, err := patchTree.Filesystem.Stat("ROCKY/CFG")
if err == nil { if err == nil {
@ -152,32 +51,31 @@ func cfgPatches(patchTree *git.Worktree, pushTree *git.Worktree) {
log.Fatalf("could not unmarshal cfg file: %v", err) 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 // check if patches exist
_, err := patchTree.Filesystem.Stat("ROCKY") _, err := patchTree.Filesystem.Stat("ROCKY")
if err == nil { if err == nil {
srpmPatches(patchTree, pushTree) cfgPatches(pd, md, patchTree, pushTree)
cfgPatches(patchTree, pushTree)
} }
} }
func executePatchesRpm(pd *ProcessData, md *modeData) { func executePatchesRpm(pd *data.ProcessData, md *data.ModeData) {
// fetch patch repository // fetch patch repository
repo, err := git.Init(memory.NewStorage(), memfs.New()) repo, err := git.Init(memory.NewStorage(), memfs.New())
if err != nil { 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() w, err := repo.Worktree()
if err != nil { 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/*")) refspec := config.RefSpec(fmt.Sprintf("+refs/heads/*:refs/remotes/origin/*"))
_, err = repo.CreateRemote(&config.RemoteConfig{ _, err = repo.CreateRemote(&config.RemoteConfig{
@ -195,12 +93,12 @@ func executePatchesRpm(pd *ProcessData, md *modeData) {
Auth: pd.Authenticator, Auth: pd.Authenticator,
}) })
refName := plumbing.NewBranchReferenceName(md.pushBranch) refName := plumbing.NewBranchReferenceName(md.PushBranch)
log.Printf("set reference to ref: %s", refName) log.Printf("set reference to ref: %s", refName)
if err != nil { if err != nil {
// no patches active // no patches active
log.Println("info: patch repo not found") log.Println("info: patch Repo not found")
return return
} else { } else {
err = w.Checkout(&git.CheckoutOptions{ err = w.Checkout(&git.CheckoutOptions{
@ -209,28 +107,28 @@ func executePatchesRpm(pd *ProcessData, md *modeData) {
}) })
// common patches found, apply them // common patches found, apply them
if err == nil { if err == nil {
applyPatches(w, md.worktree) applyPatches(pd, md, w, md.Worktree)
} else { } else {
log.Println("info: no common patches found") log.Println("info: no common patches found")
} }
err = w.Checkout(&git.CheckoutOptions{ err = w.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewRemoteReferenceName("origin", md.pushBranch), Branch: plumbing.NewRemoteReferenceName("origin", md.PushBranch),
Force: true, Force: true,
}) })
// branch specific patches found, apply them // branch specific patches found, apply them
if err == nil { if err == nil {
applyPatches(w, md.worktree) applyPatches(pd, md, w, md.Worktree)
} else { } else {
log.Println("info: no branch specific patches found") 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()) repo, err := git.Init(memory.NewStorage(), memfs.New())
if err != nil { 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) 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 return tipHash
} }
func patchModuleYaml(pd *ProcessData, md *modeData) { func patchModuleYaml(pd *data.ProcessData, md *data.ModeData) {
// special case for platform.yaml // special case for platform.yaml
_, err := md.worktree.Filesystem.Open("platform.yaml") _, err := md.Worktree.Filesystem.Open("platform.yaml")
if err == nil { if err == nil {
return return
} }
mdTxtPath := "SOURCES/modulemd.src.txt" mdTxtPath := "SOURCES/modulemd.src.txt"
f, err := md.worktree.Filesystem.Open(mdTxtPath) f, err := md.Worktree.Filesystem.Open(mdTxtPath)
if err != nil { if err != nil {
log.Fatalf("could not open modulemd file: %v", err) 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-") { if strings.HasPrefix(rpm.Ref, "stream-rhel-") {
repString := fmt.Sprintf("%s%ss-", pd.BranchPrefix, string(split[4][0])) repString := fmt.Sprintf("%s%ss-", pd.BranchPrefix, string(split[4][0]))
newString := fmt.Sprintf("%s%s-", 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 { } 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 { } else if strings.HasPrefix(rpm.Ref, "stream-") && len(split) == 3 {
// example: ant // example: ant
pushBranch = fmt.Sprintf("%s%d-stream-%s", pd.BranchPrefix, pd.Version, split[2]) pushBranch = fmt.Sprintf("%s%d-stream-%s", pd.BranchPrefix, pd.Version, split[2])
} else if strings.HasPrefix(rpm.Ref, "stream-") { } else if strings.HasPrefix(rpm.Ref, "stream-") {
pushBranch = fmt.Sprintf("%s%s-stream-%s", pd.BranchPrefix, string(split[3][0]), split[1]) pushBranch = fmt.Sprintf("%s%s-stream-%s", pd.BranchPrefix, string(split[3][0]), split[1])
} else if strings.HasPrefix(rpm.Ref, "rhel-") { } else if strings.HasPrefix(rpm.Ref, "rhel-") {
pushBranch = md.pushBranch pushBranch = md.PushBranch
} else { } else {
log.Fatal("could not recognize modulemd ref") log.Fatal("could not recognize modulemd ref")
} }
@ -317,7 +215,7 @@ func patchModuleYaml(pd *ProcessData, md *modeData) {
rpm.Ref = pushBranch rpm.Ref = pushBranch
tipHash = getTipStream(pd, name, pushBranch) tipHash = getTipStream(pd, name, pushBranch)
err = module.Marshal(md.worktree.Filesystem, mdTxtPath) err = module.Marshal(md.Worktree.Filesystem, mdTxtPath)
if err != nil { if err != nil {
log.Fatalf("could not marshal modulemd: %v", err) log.Fatalf("could not marshal modulemd: %v", err)
} }
@ -325,13 +223,13 @@ func patchModuleYaml(pd *ProcessData, md *modeData) {
rpm.Ref = tipHash rpm.Ref = tipHash
} }
rootModule := fmt.Sprintf("%s.yaml", md.rpmFile.Name()) rootModule := fmt.Sprintf("%s.yaml", md.RpmFile.Name())
err = module.Marshal(md.worktree.Filesystem, rootModule) err = module.Marshal(md.Worktree.Filesystem, rootModule)
if err != nil { if err != nil {
log.Fatalf("could not marshal root modulemd: %v", err) log.Fatalf("could not marshal root modulemd: %v", err)
} }
_, err = md.worktree.Add(rootModule) _, err = md.Worktree.Add(rootModule)
if err != nil { if err != nil {
log.Fatalf("could not add root modulemd: %v", err) log.Fatalf("could not add root modulemd: %v", err)
} }

View File

@ -4,16 +4,13 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/blob" "git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
"github.com/cavaliercoder/go-rpm"
"github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing" "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/object"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
"github.com/go-git/go-git/v5/storage/memory" "github.com/go-git/go-git/v5/storage/memory"
"hash"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -25,54 +22,17 @@ import (
var tagImportRegex *regexp.Regexp 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 // ProcessRPM checks the RPM specs and discards any remote files
// This functions also sorts files into directories // This functions also sorts files into directories
// .spec files goes into -> SPECS // .spec files goes into -> SPECS
// metadata files goes to root // metadata files goes to root
// source files goes into -> SOURCES // source files goes into -> SOURCES
// all files that are remote goes into .gitignore // all files that are remote goes into .gitignore
// all ignored files' hash goes into .{name}.metadata // all ignored files' hash goes into .{Name}.metadata
func ProcessRPM(pd *ProcessData) { func ProcessRPM(pd *data.ProcessData) {
tagImportRegex = regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s.|%s.-.+)/(.*))", pd.ImportBranchPrefix, pd.ImportBranchPrefix)) tagImportRegex = regexp.MustCompile(fmt.Sprintf("refs/tags/(imports/(%s.|%s.-.+)/(.*))", pd.ImportBranchPrefix, pd.ImportBranchPrefix))
md := pd.Importer.RetrieveSource(pd) md := pd.Importer.RetrieveSource(pd)
md.blobCache = map[string][]byte{} md.BlobCache = map[string][]byte{}
remotePrefix := "rpms" remotePrefix := "rpms"
if pd.ModuleMode { if pd.ModuleMode {
@ -89,9 +49,9 @@ func ProcessRPM(pd *ProcessData) {
if pd.NoDupMode { if pd.NoDupMode {
repo, err := git.Init(memory.NewStorage(), memfs.New()) repo, err := git.Init(memory.NewStorage(), memfs.New())
if err != nil { 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/*") refspec := config.RefSpec("+refs/heads/*:refs/remotes/origin/*")
remote, err := repo.CreateRemote(&config.RemoteConfig{ remote, err := repo.CreateRemote(&config.RemoteConfig{
@ -118,38 +78,42 @@ func ProcessRPM(pd *ProcessData) {
} }
} }
sourceRepo := *md.repo sourceRepo := *md.Repo
sourceWorktree := *md.worktree sourceWorktree := *md.Worktree
for _, branch := range md.branches { if pd.SingleTag != "" {
md.repo = &sourceRepo md.Branches = []string{fmt.Sprintf("refs/tags/%s", pd.SingleTag)}
md.worktree = &sourceWorktree }
md.tagBranch = branch
for _, source := range md.sourcesToIgnore { for _, branch := range md.Branches {
source.expired = true 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 continue
} }
rpmFile := md.rpmFile rpmFile := md.RpmFile
// create new repo for final dist // create new Repo for final dist
repo, err := git.Init(memory.NewStorage(), memfs.New()) repo, err := git.Init(memory.NewStorage(), pd.FsCreator())
if err != nil { 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() w, err := repo.Worktree()
if err != nil { if err != nil {
log.Fatalf("could not get dist worktree: %v", err) log.Fatalf("could not get dist Worktree: %v", err)
} }
var matchString string var matchString string
if !tagImportRegex.MatchString(md.tagBranch) { if !tagImportRegex.MatchString(md.TagBranch) {
if pd.ModuleMode { if pd.ModuleMode {
prefix := fmt.Sprintf("refs/heads/%s%d", pd.ImportBranchPrefix, pd.Version) prefix := fmt.Sprintf("refs/heads/%s%d", pd.ImportBranchPrefix, pd.Version)
if strings.HasPrefix(md.tagBranch, prefix) { if strings.HasPrefix(md.TagBranch, prefix) {
replace := strings.Replace(md.tagBranch, "refs/heads/", "", 1) replace := strings.Replace(md.TagBranch, "refs/heads/", "", 1)
matchString = fmt.Sprintf("refs/tags/imports/%s/%s", replace, filepath.Base(pd.RpmLocation)) matchString = fmt.Sprintf("refs/tags/imports/%s/%s", replace, filepath.Base(pd.RpmLocation))
log.Printf("using match string: %s", matchString) log.Printf("using match string: %s", matchString)
} }
@ -158,11 +122,11 @@ func ProcessRPM(pd *ProcessData) {
continue continue
} }
} else { } else {
matchString = md.tagBranch matchString = md.TagBranch
} }
match := tagImportRegex.FindStringSubmatch(matchString) 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) newTag := "imports/" + pd.BranchPrefix + strings.TrimPrefix(match[1], "imports/"+pd.ImportBranchPrefix)
shouldContinue := true shouldContinue := true
@ -179,7 +143,7 @@ func ProcessRPM(pd *ProcessData) {
// create a new remote // create a new remote
remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, rpmFile.Name()) remoteUrl := fmt.Sprintf("%s/%s/%s.git", pd.UpstreamPrefix, remotePrefix, rpmFile.Name())
log.Printf("using remote: %s", remoteUrl) 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) log.Printf("using refspec: %s", refspec)
_, err = repo.CreateRemote(&config.RemoteConfig{ _, err = repo.CreateRemote(&config.RemoteConfig{
@ -197,7 +161,7 @@ func ProcessRPM(pd *ProcessData) {
Auth: pd.Authenticator, Auth: pd.Authenticator,
}) })
refName := plumbing.NewBranchReferenceName(md.pushBranch) refName := plumbing.NewBranchReferenceName(md.PushBranch)
log.Printf("set reference to ref: %s", refName) log.Printf("set reference to ref: %s", refName)
if err != nil { if err != nil {
@ -207,7 +171,7 @@ func ProcessRPM(pd *ProcessData) {
} }
} else { } else {
err = w.Checkout(&git.CheckoutOptions{ err = w.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewRemoteReferenceName("origin", md.pushBranch), Branch: plumbing.NewRemoteReferenceName("origin", md.PushBranch),
Force: true, Force: true,
}) })
if err != nil { if err != nil {
@ -217,9 +181,9 @@ func ProcessRPM(pd *ProcessData) {
pd.Importer.WriteSource(pd, md) pd.Importer.WriteSource(pd, md)
copyFromFs(md.worktree.Filesystem, w.Filesystem, ".") copyFromFs(md.Worktree.Filesystem, w.Filesystem, ".")
md.repo = repo md.Repo = repo
md.worktree = w md.Worktree = w
if pd.ModuleMode { if pd.ModuleMode {
patchModuleYaml(pd, md) patchModuleYaml(pd, md)
@ -227,17 +191,17 @@ func ProcessRPM(pd *ProcessData) {
executePatchesRpm(pd, md) 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()) metadataFile := fmt.Sprintf(".%s.metadata", rpmFile.Name())
metadata, err := w.Filesystem.Create(metadataFile) metadata, err := w.Filesystem.Create(metadataFile)
if err != nil { if err != nil {
log.Fatalf("could not create metadata file: %v", err) log.Fatalf("could not create metadata file: %v", err)
} }
for _, source := range md.sourcesToIgnore { for _, source := range md.SourcesToIgnore {
sourcePath := source.name sourcePath := source.Name
_, err := w.Filesystem.Stat(sourcePath) _, err := w.Filesystem.Stat(sourcePath)
if source.expired || err != nil { if source.Expired || err != nil {
continue continue
} }
@ -250,12 +214,12 @@ func ProcessRPM(pd *ProcessData) {
log.Fatalf("could not read the whole of ignored source file: %v", err) log.Fatalf("could not read the whole of ignored source file: %v", err)
} }
source.hashFunction.Reset() source.HashFunction.Reset()
_, err = source.hashFunction.Write(sourceFileBts) _, err = source.HashFunction.Write(sourceFileBts)
if err != nil { if err != nil {
log.Fatalf("could not write bytes to hash function: %v", err) 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) checksumLine := fmt.Sprintf("%s %s\n", checksum, sourcePath)
_, err = metadata.Write([]byte(checksumLine)) _, err = metadata.Write([]byte(checksumLine))
if err != nil { if err != nil {
@ -266,7 +230,7 @@ func ProcessRPM(pd *ProcessData) {
if strContains(alreadyUploadedBlobs, path) { if strContains(alreadyUploadedBlobs, path) {
continue continue
} }
if !pd.BlobStorage.Exists(path) { if !pd.BlobStorage.Exists(path) && !pd.NoStorageUpload {
pd.BlobStorage.Write(path, sourceFileBts) pd.BlobStorage.Write(path, sourceFileBts)
log.Printf("wrote %s to blob storage", path) log.Printf("wrote %s to blob storage", path)
} }
@ -317,11 +281,11 @@ func ProcessRPM(pd *ProcessData) {
} else { } else {
log.Printf("tip %s", head.String()) log.Printf("tip %s", head.String())
hashes = append(hashes, head.Hash()) 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))) 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 // create import commit
commit, err := w.Commit("import "+pd.Importer.ImportName(pd, md), &git.CommitOptions{ commit, err := w.Commit("import "+pd.Importer.ImportName(pd, md), &git.CommitOptions{
Author: &object.Signature{ Author: &object.Signature{
@ -348,7 +312,7 @@ func ProcessRPM(pd *ProcessData) {
Email: pd.GitCommitterEmail, Email: pd.GitCommitterEmail,
When: time.Now(), When: time.Now(),
}, },
Message: "import " + md.tagBranch + " from " + pd.RpmLocation, Message: "import " + md.TagBranch + " from " + pd.RpmLocation,
SignKey: nil, SignKey: nil,
}) })
if err != nil { if err != nil {
@ -368,7 +332,7 @@ func ProcessRPM(pd *ProcessData) {
} }
hashString := obj.Hash.String() hashString := obj.Hash.String()
latestHashForBranch[md.pushBranch] = hashString latestHashForBranch[md.PushBranch] = hashString
} }
err := json.NewEncoder(os.Stdout).Encode(latestHashForBranch) err := json.NewEncoder(os.Stdout).Encode(latestHashForBranch)

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
"github.com/cavaliercoder/go-cpio" "github.com/cavaliercoder/go-cpio"
"github.com/cavaliercoder/go-rpm" "github.com/cavaliercoder/go-rpm"
"github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-billy/v5/memfs"
@ -20,7 +21,7 @@ import (
type SrpmMode struct{} 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) cmd := exec.Command("rpm2cpio", pd.RpmLocation)
cpioBytes, err := cmd.Output() cpioBytes, err := cmd.Output()
if err != nil { if err != nil {
@ -30,7 +31,7 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData {
// create in memory git repository // create in memory git repository
repo, err := git.Init(memory.NewStorage(), memfs.New()) repo, err := git.Init(memory.NewStorage(), memfs.New())
if err != nil { 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 // read the rpm in cpio format
@ -56,7 +57,7 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData {
w, err := repo.Worktree() w, err := repo.Worktree()
if err != nil { if err != nil {
log.Fatalf("could not get worktree: %v", err) log.Fatalf("could not get Worktree: %v", err)
} }
// create structure // create structure
@ -78,29 +79,29 @@ func (s *SrpmMode) RetrieveSource(pd *ProcessData) *modeData {
log.Fatalf("could not read package, invalid?: %v", err) log.Fatalf("could not read package, invalid?: %v", err)
} }
var sourcesToIgnore []*ignoredSource var sourcesToIgnore []*data.IgnoredSource
for _, source := range rpmFile.Source() { for _, source := range rpmFile.Source() {
if strings.Contains(source, ".tar") { if strings.Contains(source, ".tar") {
sourcesToIgnore = append(sourcesToIgnore, &ignoredSource{ sourcesToIgnore = append(sourcesToIgnore, &data.IgnoredSource{
name: source, Name: source,
hashFunction: sha256.New(), HashFunction: sha256.New(),
}) })
} }
} }
branch := fmt.Sprintf("%s%d", pd.BranchPrefix, pd.Version) branch := fmt.Sprintf("%s%d", pd.BranchPrefix, pd.Version)
return &modeData{ return &data.ModeData{
repo: repo, Repo: repo,
worktree: w, Worktree: w,
rpmFile: rpmFile, RpmFile: rpmFile,
fileWrites: fileWrites, FileWrites: fileWrites,
branches: []string{branch}, Branches: []string{branch},
sourcesToIgnore: sourcesToIgnore, SourcesToIgnore: sourcesToIgnore,
} }
} }
func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) { func (s *SrpmMode) WriteSource(_ *data.ProcessData, md *data.ModeData) {
for fileName, contents := range md.fileWrites { for fileName, contents := range md.FileWrites {
var newPath string var newPath string
if filepath.Ext(fileName) == ".spec" { if filepath.Ext(fileName) == ".spec" {
newPath = filepath.Join("SPECS", fileName) newPath = filepath.Join("SPECS", fileName)
@ -109,7 +110,7 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) {
} }
mode := os.FileMode(0666) mode := os.FileMode(0666)
for _, file := range md.rpmFile.Files() { for _, file := range md.RpmFile.Files() {
if file.Name() == fileName { if file.Name() == fileName {
mode = file.Mode() mode = file.Mode()
} }
@ -117,7 +118,7 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) {
// add the file to the virtual filesystem // add the file to the virtual filesystem
// we will move it to correct destination later // 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 { if err != nil {
log.Fatalf("could not create file %s: %v", fileName, err) log.Fatalf("could not create file %s: %v", fileName, err)
} }
@ -130,22 +131,22 @@ func (s *SrpmMode) WriteSource(_ *ProcessData, md *modeData) {
_ = f.Close() _ = f.Close()
// don't add ignored file to git // don't add ignored file to git
if ignoredContains(md.sourcesToIgnore, fileName) { if ignoredContains(md.SourcesToIgnore, fileName) {
continue continue
} }
_, err = md.worktree.Add(newPath) _, err = md.Worktree.Add(newPath)
if err != nil { if err != nil {
log.Fatalf("could not add source file: %v", err) log.Fatalf("could not add source file: %v", err)
} }
} }
// add sources to ignore (remote sources) // add sources to ignore (remote sources)
gitIgnore, err := md.worktree.Filesystem.Create(".gitignore") gitIgnore, err := md.Worktree.Filesystem.Create(".gitignore")
if err != nil { if err != nil {
log.Fatalf("could not create .gitignore: %v", err) 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) line := fmt.Sprintf("SOURCES/%s\n", ignore)
_, err := gitIgnore.Write([]byte(line)) _, err := gitIgnore.Write([]byte(line))
if err != nil { 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) return filepath.Base(pd.RpmLocation)
} }

View File

@ -6,6 +6,7 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/hex" "encoding/hex"
"git.rockylinux.org/release-engineering/public/srpmproc/internal/data"
"github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5"
"hash" "hash"
"io" "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 { for _, val := range a {
if val.name == b { if val.Name == b {
return true return true
} }
} }

View File

@ -220,6 +220,9 @@ func (x *Delete) GetFile() string {
} }
// Add directive adds a file from the patch repository to the rpm repository. // 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 { type Add struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -343,9 +346,9 @@ type SpecChange struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// Types that are assignable to Operation: File []*SpecChange_FileOperation `protobuf:"bytes,1,rep,name=file,proto3" json:"file,omitempty"`
// *SpecChange_FileOperation_ Changelog []*SpecChange_ChangelogOperation `protobuf:"bytes,2,rep,name=changelog,proto3" json:"changelog,omitempty"`
Operation isSpecChange_Operation `protobuf_oneof:"operation"` SearchAndReplace []*SpecChange_SearchAndReplaceOperation `protobuf:"bytes,3,rep,name=search_and_replace,json=searchAndReplace,proto3" json:"search_and_replace,omitempty"`
} }
func (x *SpecChange) Reset() { func (x *SpecChange) Reset() {
@ -380,30 +383,27 @@ func (*SpecChange) Descriptor() ([]byte, []int) {
return file_cfg_proto_rawDescGZIP(), []int{4} return file_cfg_proto_rawDescGZIP(), []int{4}
} }
func (m *SpecChange) GetOperation() isSpecChange_Operation { func (x *SpecChange) GetFile() []*SpecChange_FileOperation {
if m != nil { if x != nil {
return m.Operation return x.File
} }
return nil return nil
} }
func (x *SpecChange) GetFileOperation() *SpecChange_FileOperation { func (x *SpecChange) GetChangelog() []*SpecChange_ChangelogOperation {
if x, ok := x.GetOperation().(*SpecChange_FileOperation_); ok { if x != nil {
return x.FileOperation return x.Changelog
} }
return nil return nil
} }
type isSpecChange_Operation interface { func (x *SpecChange) GetSearchAndReplace() []*SpecChange_SearchAndReplaceOperation {
isSpecChange_Operation() 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 { type Patch struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -468,12 +468,12 @@ type Cfg struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Replace []*Replace `protobuf:"bytes,1,rep,name=replace,proto3" json:"replace,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"` Delete []*Delete `protobuf:"bytes,2,rep,name=delete,proto3" json:"delete,omitempty"`
Add []*Add `protobuf:"bytes,3,rep,name=add,proto3" json:"add,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"` 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"` 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"` Patch []*Patch `protobuf:"bytes,6,rep,name=patch,proto3" json:"patch,omitempty"`
} }
func (x *Cfg) Reset() { func (x *Cfg) Reset() {
@ -536,7 +536,7 @@ func (x *Cfg) GetLookaside() []*Lookaside {
return nil return nil
} }
func (x *Cfg) GetSpecChange() []*SpecChange { func (x *Cfg) GetSpecChange() *SpecChange {
if x != nil { if x != nil {
return x.SpecChange return x.SpecChange
} }
@ -558,7 +558,7 @@ type SpecChange_FileOperation struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// File name // 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 // File type
Type SpecChange_FileOperation_Type `protobuf:"varint,2,opt,name=type,proto3,enum=srpmproc.SpecChange_FileOperation_Type" json:"type,omitempty"` 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: // Types that are assignable to Mode:
@ -599,9 +599,9 @@ func (*SpecChange_FileOperation) Descriptor() ([]byte, []int) {
return file_cfg_proto_rawDescGZIP(), []int{4, 0} return file_cfg_proto_rawDescGZIP(), []int{4, 0}
} }
func (x *SpecChange_FileOperation) GetFile() string { func (x *SpecChange_FileOperation) GetName() string {
if x != nil { if x != nil {
return x.File return x.Name
} }
return "" return ""
} }
@ -654,6 +654,214 @@ func (*SpecChange_FileOperation_Add) isSpecChange_FileOperation_Mode() {}
func (*SpecChange_FileOperation_Delete) 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 protoreflect.FileDescriptor
var file_cfg_proto_rawDesc = []byte{ 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, 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, 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, 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, 0x52, 0x03, 0x74, 0x61, 0x72, 0x22, 0xf8, 0x05, 0x0a, 0x0a, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x03,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70,
0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65,
0x67, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x09,
0x48, 0x00, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x6e, 0x1a, 0xc2, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x27, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x43,
0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x6f, 0x67, 0x4f,
0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 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, 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, 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, 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, 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, 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, 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, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x72, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65,
0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b,
0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x09, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a,
0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x22, 0x8e, 0x02, 0x0a, 0x03, 0x43, 0x66, 0x67, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20,
0x12, 0x2b, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c,
0x0b, 0x32, 0x11, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28,
0x6c, 0x61, 0x63, 0x65, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xd3, 0x01, 0x0a, 0x19, 0x53,
0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f,
0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c,
0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x03, 0x61, 0x64, 0x64, 0x18, 0x03, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x12, 0x12, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52,
0x41, 0x64, 0x64, 0x52, 0x03, 0x61, 0x64, 0x64, 0x12, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x21, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x5f, 0x77,
0x61, 0x73, 0x69, 0x64, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x72, 0x69, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x74, 0x61,
0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x72, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x73, 0x5f,
0x52, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x73, 0x69, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x77, 0x69, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x65, 0x6e,
0x70, 0x65, 0x63, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6e, 0x64, 0x18, 0x05,
0x32, 0x14, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65,
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70,
0x67, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x03, 0x28, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52,
0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x01, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
0x63, 0x68, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x73, 0x74, 0x67, 0x2f, 0x73, 0x72, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x16, 0x0a,
0x6d, 0x70, 0x72, 0x6f, 0x63, 0x2f, 0x70, 0x62, 0x3b, 0x73, 0x72, 0x70, 0x6d, 0x70, 0x72, 0x6f, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73,
0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (
@ -731,32 +970,36 @@ func file_cfg_proto_rawDescGZIP() []byte {
} }
var file_cfg_proto_enumTypes = make([]protoimpl.EnumInfo, 1) 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{}{ var file_cfg_proto_goTypes = []interface{}{
(SpecChange_FileOperation_Type)(0), // 0: srpmproc.SpecChange.FileOperation.Type (SpecChange_FileOperation_Type)(0), // 0: srpmproc.SpecChange.FileOperation.Type
(*Replace)(nil), // 1: srpmproc.Replace (*Replace)(nil), // 1: srpmproc.Replace
(*Delete)(nil), // 2: srpmproc.Delete (*Delete)(nil), // 2: srpmproc.Delete
(*Add)(nil), // 3: srpmproc.Add (*Add)(nil), // 3: srpmproc.Add
(*Lookaside)(nil), // 4: srpmproc.Lookaside (*Lookaside)(nil), // 4: srpmproc.Lookaside
(*SpecChange)(nil), // 5: srpmproc.SpecChange (*SpecChange)(nil), // 5: srpmproc.SpecChange
(*Patch)(nil), // 6: srpmproc.Patch (*Patch)(nil), // 6: srpmproc.Patch
(*Cfg)(nil), // 7: srpmproc.Cfg (*Cfg)(nil), // 7: srpmproc.Cfg
(*SpecChange_FileOperation)(nil), // 8: srpmproc.SpecChange.FileOperation (*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{ var file_cfg_proto_depIdxs = []int32{
8, // 0: srpmproc.SpecChange.file_operation:type_name -> srpmproc.SpecChange.FileOperation 8, // 0: srpmproc.SpecChange.file:type_name -> srpmproc.SpecChange.FileOperation
1, // 1: srpmproc.Cfg.replace:type_name -> srpmproc.Replace 9, // 1: srpmproc.SpecChange.changelog:type_name -> srpmproc.SpecChange.ChangelogOperation
2, // 2: srpmproc.Cfg.delete:type_name -> srpmproc.Delete 10, // 2: srpmproc.SpecChange.search_and_replace:type_name -> srpmproc.SpecChange.SearchAndReplaceOperation
3, // 3: srpmproc.Cfg.add:type_name -> srpmproc.Add 1, // 3: srpmproc.Cfg.replace:type_name -> srpmproc.Replace
4, // 4: srpmproc.Cfg.lookaside:type_name -> srpmproc.Lookaside 2, // 4: srpmproc.Cfg.delete:type_name -> srpmproc.Delete
5, // 5: srpmproc.Cfg.spec_change:type_name -> srpmproc.SpecChange 3, // 5: srpmproc.Cfg.add:type_name -> srpmproc.Add
6, // 6: srpmproc.Cfg.patch:type_name -> srpmproc.Patch 4, // 6: srpmproc.Cfg.lookaside:type_name -> srpmproc.Lookaside
0, // 7: srpmproc.SpecChange.FileOperation.type:type_name -> srpmproc.SpecChange.FileOperation.Type 5, // 7: srpmproc.Cfg.spec_change:type_name -> srpmproc.SpecChange
8, // [8:8] is the sub-list for method output_type 6, // 8: srpmproc.Cfg.patch:type_name -> srpmproc.Patch
8, // [8:8] is the sub-list for method input_type 0, // 9: srpmproc.SpecChange.FileOperation.type:type_name -> srpmproc.SpecChange.FileOperation.Type
8, // [8:8] is the sub-list for extension type_name 10, // [10:10] is the sub-list for method output_type
8, // [8:8] is the sub-list for extension extendee 10, // [10:10] is the sub-list for method input_type
0, // [0:8] is the sub-list for field type_name 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() } func init() { file_cfg_proto_init() }
@ -861,25 +1104,52 @@ func file_cfg_proto_init() {
return nil 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{}{ file_cfg_proto_msgTypes[0].OneofWrappers = []interface{}{
(*Replace_WithFile)(nil), (*Replace_WithFile)(nil),
(*Replace_WithInline)(nil), (*Replace_WithInline)(nil),
} }
file_cfg_proto_msgTypes[4].OneofWrappers = []interface{}{
(*SpecChange_FileOperation_)(nil),
}
file_cfg_proto_msgTypes[7].OneofWrappers = []interface{}{ file_cfg_proto_msgTypes[7].OneofWrappers = []interface{}{
(*SpecChange_FileOperation_Add)(nil), (*SpecChange_FileOperation_Add)(nil),
(*SpecChange_FileOperation_Delete)(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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cfg_proto_rawDesc, RawDescriptor: file_cfg_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 8, NumMessages: 10,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -62,7 +62,7 @@ message SpecChange {
Patch = 2; Patch = 2;
} }
// File name // File name
string file = 1; string name = 1;
// File type // File type
Type type = 2; Type type = 2;
@ -75,9 +75,35 @@ message SpecChange {
bool delete = 4; bool delete = 4;
} }
} }
oneof operation { // ChangelogOperation adds a new changelog entry
FileOperation file_operation = 1; 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 { message Patch {
@ -95,6 +121,6 @@ message Cfg {
repeated Delete delete = 2; repeated Delete delete = 2;
repeated Add add = 3; repeated Add add = 3;
repeated Lookaside lookaside = 4; repeated Lookaside lookaside = 4;
repeated SpecChange spec_change = 5; SpecChange spec_change = 5;
repeated Patch patch = 6; repeated Patch patch = 6;
} }