1package git2go 2 3import ( 4 "context" 5 "fmt" 6 "io" 7 "time" 8 9 "gitlab.com/gitlab-org/gitaly/v14/internal/git/repository" 10) 11 12// Error strings present in the legacy Ruby implementation 13const ( 14 LegacyErrPrefixInvalidBranch = "Invalid branch" 15 LegacyErrPrefixInvalidSubmodulePath = "Invalid submodule path" 16 LegacyErrPrefixFailedCommit = "Failed to create commit" 17) 18 19// SubmoduleCommand instructs how to commit a submodule update to a repo 20type SubmoduleCommand struct { 21 // Repository is the path to commit the submodule change 22 Repository string `json:"repository"` 23 24 // AuthorName is the author name of submodule commit. 25 AuthorName string `json:"author_name"` 26 // AuthorMail is the author mail of submodule commit. 27 AuthorMail string `json:"author_mail"` 28 // AuthorDate is the auithor date of submodule commit. 29 AuthorDate time.Time `json:"author_date"` 30 // Message is the message to be used for the submodule commit. 31 Message string `json:"message"` 32 33 // CommitSHA is where the submodule should point 34 CommitSHA string `json:"commit_sha"` 35 // Submodule is the actual submodule string to commit to the tree 36 Submodule string `json:"submodule"` 37 // Branch where to commit submodule update 38 Branch string `json:"branch"` 39} 40 41// SubmoduleResult contains results from a committing a submodule update 42type SubmoduleResult struct { 43 // CommitID is the object ID of the generated submodule commit. 44 CommitID string `json:"commit_id"` 45} 46 47// SubmoduleCommandFromSerialized deserializes the submodule request from its JSON representation encoded with base64. 48func SubmoduleCommandFromSerialized(serialized string) (SubmoduleCommand, error) { 49 var request SubmoduleCommand 50 if err := deserialize(serialized, &request); err != nil { 51 return SubmoduleCommand{}, err 52 } 53 54 if err := request.verify(); err != nil { 55 return SubmoduleCommand{}, fmt.Errorf("submodule: %w", err) 56 } 57 58 return request, nil 59} 60 61// SerializeTo serializes the submodule result and writes it into the writer. 62func (s SubmoduleResult) SerializeTo(w io.Writer) error { 63 return serializeTo(w, s) 64} 65 66// Submodule attempts to commit the request submodule change 67func (b Executor) Submodule(ctx context.Context, repo repository.GitRepo, s SubmoduleCommand) (SubmoduleResult, error) { 68 if err := s.verify(); err != nil { 69 return SubmoduleResult{}, fmt.Errorf("submodule: %w", err) 70 } 71 72 serialized, err := serialize(s) 73 if err != nil { 74 return SubmoduleResult{}, err 75 } 76 77 stdout, err := b.run(ctx, repo, nil, "submodule", "-request", serialized) 78 if err != nil { 79 return SubmoduleResult{}, err 80 } 81 82 var response SubmoduleResult 83 if err := deserialize(stdout.String(), &response); err != nil { 84 return SubmoduleResult{}, err 85 } 86 87 return response, nil 88} 89 90func (s SubmoduleCommand) verify() (err error) { 91 if s.Repository == "" { 92 return InvalidArgumentError("missing repository") 93 } 94 if s.AuthorName == "" { 95 return InvalidArgumentError("missing author name") 96 } 97 if s.AuthorMail == "" { 98 return InvalidArgumentError("missing author mail") 99 } 100 if s.CommitSHA == "" { 101 return InvalidArgumentError("missing commit SHA") 102 } 103 if s.Branch == "" { 104 return InvalidArgumentError("missing branch name") 105 } 106 if s.Submodule == "" { 107 return InvalidArgumentError("missing submodule") 108 } 109 return nil 110} 111