Skip to content

Commit 7c84ab0

Browse files
authored
Support multiple patch files as arguments (#87)
1 parent d688a59 commit 7c84ab0

File tree

2 files changed

+62
-39
lines changed

2 files changed

+62
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ See the CLI help (`-h` or `-help`) or below for full details.
4545
### Full Usage
4646

4747
```
48-
Usage: patch2pr [options] [patch]
48+
Usage: patch2pr [options] [patch...]
4949
5050
Create a GitHub pull request from a patch file
5151

cmd/patch2pr/main.go

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ func main() {
121121
client := github.NewClient(tc)
122122
client.BaseURL = opts.GitHubURL
123123

124-
var patchFile string
124+
var patchFiles []string
125125
if fs.NArg() == 0 {
126-
patchFile = "-"
126+
patchFiles = []string{"-"}
127127
} else {
128-
patchFile = fs.Arg(0)
128+
patchFiles = fs.Args()
129129
}
130130

131-
res, err := execute(ctx, client, patchFile, &opts)
131+
res, err := execute(ctx, client, patchFiles, &opts)
132132
if err != nil {
133133
die(1, err)
134134
}
@@ -147,6 +147,13 @@ func main() {
147147
}
148148
}
149149

150+
type Patch struct {
151+
path string
152+
files []*gitdiff.File
153+
preamble string
154+
header *gitdiff.PatchHeader
155+
}
156+
150157
type Result struct {
151158
Commit string `json:"commit"`
152159
Tree string `json:"tree"`
@@ -158,7 +165,36 @@ type PullRequestResult struct {
158165
URL string `json:"url"`
159166
}
160167

161-
func execute(ctx context.Context, client *github.Client, patchFile string, opts *Options) (*Result, error) {
168+
func parse(patchFile string) (*Patch, error) {
169+
var r io.ReadCloser
170+
if patchFile == "-" {
171+
r = os.Stdin
172+
} else {
173+
f, err := os.Open(patchFile)
174+
if err != nil {
175+
return nil, fmt.Errorf("open patch file failed: %w", err)
176+
}
177+
r = f
178+
}
179+
180+
files, preamble, err := gitdiff.Parse(r)
181+
if err != nil {
182+
return nil, fmt.Errorf("parsing patch failed: %w", err)
183+
}
184+
_ = r.Close()
185+
186+
var header *gitdiff.PatchHeader
187+
if len(preamble) > 0 {
188+
header, err = gitdiff.ParsePatchHeader(preamble)
189+
if err != nil {
190+
fmt.Fprintf(os.Stderr, "warning: invalid patch header: %v", err)
191+
}
192+
}
193+
194+
return &Patch{patchFile, files, preamble, header}, nil
195+
}
196+
197+
func execute(ctx context.Context, client *github.Client, patchFiles []string, opts *Options) (*Result, error) {
162198
targetRepo := *opts.Repository
163199
patchBase, baseBranch, headBranch := opts.PatchBase, opts.BaseBranch, opts.HeadBranch
164200

@@ -188,50 +224,37 @@ func execute(ctx context.Context, client *github.Client, patchFile string, opts
188224
return nil, fmt.Errorf("get commit for %s failed: %w", patchBase, err)
189225
}
190226

191-
var r io.ReadCloser
192-
if patchFile == "-" {
193-
r = os.Stdin
194-
} else {
195-
f, err := os.Open(patchFile)
227+
var patches []Patch
228+
for _, patchFile := range patchFiles {
229+
patch, err := parse(patchFile)
196230
if err != nil {
197-
return nil, fmt.Errorf("open patch file failed: %w", err)
198-
}
199-
r = f
200-
}
201-
202-
files, preamble, err := gitdiff.Parse(r)
203-
if err != nil {
204-
return nil, fmt.Errorf("parsing patch failed: %w", err)
205-
}
206-
_ = r.Close()
207-
208-
var header *gitdiff.PatchHeader
209-
if len(preamble) > 0 {
210-
header, err = gitdiff.ParsePatchHeader(preamble)
211-
if err != nil {
212-
fmt.Fprintf(os.Stderr, "warning: invalid patch header: %v", err)
231+
return nil, err
213232
}
233+
patches = append(patches, *patch)
214234
}
215235

216236
sourceRepo, err := prepareSourceRepo(ctx, client, opts)
217237
if err != nil {
218238
return nil, err
219239
}
220240

221-
applier := patch2pr.NewApplier(client, sourceRepo, commit)
222-
for _, file := range files {
223-
if _, err := applier.Apply(ctx, file); err != nil {
224-
name := file.NewName
225-
if name == "" {
226-
name = file.OldName
241+
newCommit := commit
242+
for _, patch := range patches {
243+
applier := patch2pr.NewApplier(client, sourceRepo, newCommit)
244+
for _, file := range patch.files {
245+
if _, err := applier.Apply(ctx, file); err != nil {
246+
name := file.NewName
247+
if name == "" {
248+
name = file.OldName
249+
}
250+
return nil, fmt.Errorf("apply failed: %s: %w", name, err)
227251
}
228-
return nil, fmt.Errorf("apply failed: %s: %w", name, err)
229252
}
230-
}
231253

232-
newCommit, err := applier.Commit(ctx, nil, fillHeader(header, patchFile, opts.Message))
233-
if err != nil {
234-
return nil, fmt.Errorf("commit failed: %w", err)
254+
newCommit, err = applier.Commit(ctx, nil, fillHeader(patch.header, patch.path, opts.Message))
255+
if err != nil {
256+
return nil, fmt.Errorf("commit failed: %w", err)
257+
}
235258
}
236259

237260
ref := patch2pr.NewReference(client, sourceRepo, fmt.Sprintf("refs/heads/%s", headBranch))
@@ -458,7 +481,7 @@ func isCode(err error, code int) bool {
458481

459482
func helpText() string {
460483
help := `
461-
Usage: patch2pr [options] [patch]
484+
Usage: patch2pr [options] [patch...]
462485
463486
Create a GitHub pull request from a patch file
464487

0 commit comments

Comments
 (0)