Skip to content

Commit 3eb98de

Browse files
authored
Remove published: false from template for batch new (#578)
Now that this property isn't required anymore, we can get rid of that part. Honors the feature flag for optional publish values.
1 parent 80d9902 commit 3eb98de

File tree

2 files changed

+104
-80
lines changed

2 files changed

+104
-80
lines changed

cmd/src/batch_new.go

Lines changed: 16 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package main
22

33
import (
4+
"context"
45
"flag"
56
"fmt"
6-
"os"
7-
"os/exec"
8-
"strings"
97

10-
"text/template"
11-
12-
"github.com/pkg/errors"
13-
"github.com/sourcegraph/src-cli/internal/batches"
8+
"github.com/sourcegraph/src-cli/internal/api"
9+
"github.com/sourcegraph/src-cli/internal/batches/service"
10+
"github.com/sourcegraph/src-cli/internal/cmderrors"
1411
)
1512

1613
func init() {
@@ -30,51 +27,33 @@ Examples:
3027
`
3128

3229
flagSet := flag.NewFlagSet("new", flag.ExitOnError)
30+
apiFlags := api.NewFlags(flagSet)
3331

3432
var (
3533
fileFlag = flagSet.String("f", "batch.yaml", "The name of the batch spec file to create.")
3634
)
3735

3836
handler := func(args []string) error {
37+
ctx := context.Background()
38+
3939
if err := flagSet.Parse(args); err != nil {
4040
return err
4141
}
4242

43-
f, err := os.OpenFile(*fileFlag, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
44-
if err != nil {
45-
if os.IsExist(err) {
46-
return fmt.Errorf("file %s already exists", *fileFlag)
47-
}
48-
return errors.Wrapf(err, "failed to create file %s", *fileFlag)
43+
if len(flagSet.Args()) != 0 {
44+
return cmderrors.Usage("additional arguments not allowed")
4945
}
50-
defer f.Close()
5146

52-
tmpl, err := template.New("").Parse(batchSpecTmpl)
53-
if err != nil {
54-
return err
55-
}
47+
svc := service.New(&service.Opts{
48+
Client: cfg.apiClient(apiFlags, flagSet.Output()),
49+
})
5650

57-
author := batches.GitCommitAuthor{
58-
Name: "Sourcegraph",
59-
60-
}
61-
62-
// Try to get better default values from git, ignore any errors.
63-
if err := checkExecutable("git", "version"); err == nil {
64-
var gitAuthorName, gitAuthorEmail string
65-
var err1, err2 error
66-
gitAuthorName, err1 = getGitConfig("user.name")
67-
gitAuthorEmail, err2 = getGitConfig("user.email")
68-
69-
if err1 == nil && err2 == nil && gitAuthorName != "" && gitAuthorEmail != "" {
70-
author.Name = gitAuthorName
71-
author.Email = gitAuthorEmail
72-
}
51+
if err := svc.DetermineFeatureFlags(ctx); err != nil {
52+
return err
7353
}
7454

75-
err = tmpl.Execute(f, map[string]interface{}{"Author": author})
76-
if err != nil {
77-
return errors.Wrap(err, "failed to write batch spec to file")
55+
if err := svc.GenerateExampleSpec(ctx, *fileFlag); err != nil {
56+
return err
7857
}
7958

8059
fmt.Printf("%s created.\n", *fileFlag)
@@ -92,46 +71,3 @@ Examples:
9271
},
9372
})
9473
}
95-
96-
func getGitConfig(attribute string) (string, error) {
97-
cmd := exec.Command("git", "config", "--get", attribute)
98-
out, err := cmd.CombinedOutput()
99-
if err != nil {
100-
return "", err
101-
}
102-
return strings.TrimSpace(string(out)), nil
103-
}
104-
105-
const batchSpecTmpl = `name: NAME-OF-YOUR-BATCH-CHANGE
106-
description: DESCRIPTION-OF-YOUR-BATCH-CHANGE
107-
108-
# "on" specifies on which repositories to execute the "steps".
109-
on:
110-
# Example: find all repositories that contain a README.md file.
111-
- repositoriesMatchingQuery: file:README.md
112-
113-
# "steps" are run in each repository. Each step is run in a Docker container
114-
# with the repository as the working directory. Once complete, each
115-
# repository's resulting diff is captured.
116-
steps:
117-
# Example: append "Hello World" to every README.md
118-
- run: echo "Hello World" | tee -a $(find -name README.md)
119-
container: alpine:3
120-
121-
# "changesetTemplate" describes the changeset (e.g., GitHub pull request) that
122-
# will be created for each repository.
123-
changesetTemplate:
124-
title: Hello World
125-
body: This adds Hello World to the README
126-
127-
branch: BRANCH-NAME-IN-EACH-REPOSITORY # Push the commit to this branch.
128-
129-
commit:
130-
author:
131-
name: {{ .Author.Name }}
132-
email: {{ .Author.Email }}
133-
message: Append Hello World to all README.md files
134-
135-
# Change published to true once you're ready to create changesets on the code host.
136-
published: false
137-
`

internal/batches/service/service.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"html/template"
78
"io"
89
"io/ioutil"
10+
"os"
11+
"os/exec"
912
"path"
1013
"regexp"
1114
"strings"
@@ -273,6 +276,82 @@ func (svc *Service) ParseBatchSpec(in io.Reader) (*batches.BatchSpec, string, er
273276
return spec, string(data), nil
274277
}
275278

279+
const exampleSpecTmpl = `name: NAME-OF-YOUR-BATCH-CHANGE
280+
description: DESCRIPTION-OF-YOUR-BATCH-CHANGE
281+
282+
# "on" specifies on which repositories to execute the "steps".
283+
on:
284+
# Example: find all repositories that contain a README.md file.
285+
- repositoriesMatchingQuery: file:README.md
286+
287+
# "steps" are run in each repository. Each step is run in a Docker container
288+
# with the repository as the working directory. Once complete, each
289+
# repository's resulting diff is captured.
290+
steps:
291+
# Example: append "Hello World" to every README.md
292+
- run: echo "Hello World" | tee -a $(find -name README.md)
293+
container: alpine:3
294+
295+
# "changesetTemplate" describes the changeset (e.g., GitHub pull request) that
296+
# will be created for each repository.
297+
changesetTemplate:
298+
title: Hello World
299+
body: This adds Hello World to the README
300+
301+
branch: BRANCH-NAME-IN-EACH-REPOSITORY # Push the commit to this branch.
302+
303+
commit:
304+
author:
305+
name: {{ .Author.Name }}
306+
email: {{ .Author.Email }}
307+
message: Append Hello World to all README.md files
308+
`
309+
310+
const exampleSpecPublishFlagTmpl = `
311+
# Change published to true once you're ready to create changesets on the code host.
312+
published: false
313+
`
314+
315+
func (svc *Service) GenerateExampleSpec(ctx context.Context, fileName string) error {
316+
// Try to create file. Bail out, if it already exists.
317+
f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
318+
if err != nil {
319+
if os.IsExist(err) {
320+
return fmt.Errorf("file %s already exists", fileName)
321+
}
322+
return errors.Wrapf(err, "failed to create file %s", fileName)
323+
}
324+
defer f.Close()
325+
326+
t := exampleSpecTmpl
327+
if !svc.features.AllowOptionalPublished {
328+
t += exampleSpecPublishFlagTmpl
329+
}
330+
tmpl, err := template.New("").Parse(t)
331+
if err != nil {
332+
return err
333+
}
334+
335+
author := batches.GitCommitAuthor{
336+
Name: "Sourcegraph",
337+
338+
}
339+
// Try to get better default values from git, ignore any errors.
340+
gitAuthorName, err1 := getGitConfig("user.name")
341+
gitAuthorEmail, err2 := getGitConfig("user.email")
342+
if err1 == nil && err2 == nil && gitAuthorName != "" && gitAuthorEmail != "" {
343+
author.Name = gitAuthorName
344+
author.Email = gitAuthorEmail
345+
}
346+
347+
err = tmpl.Execute(f, map[string]interface{}{"Author": author})
348+
if err != nil {
349+
return errors.Wrap(err, "failed to write batch spec to file")
350+
}
351+
352+
return nil
353+
}
354+
276355
const namespaceQuery = `
277356
query NamespaceQuery($name: String!) {
278357
user(username: $name) {
@@ -702,3 +781,12 @@ func (sr *searchResult) UnmarshalJSON(data []byte) error {
702781
return errors.Errorf("unknown GraphQL type %q", tn.Typename)
703782
}
704783
}
784+
785+
func getGitConfig(attribute string) (string, error) {
786+
cmd := exec.Command("git", "config", "--get", attribute)
787+
out, err := cmd.CombinedOutput()
788+
if err != nil {
789+
return "", err
790+
}
791+
return strings.TrimSpace(string(out)), nil
792+
}

0 commit comments

Comments
 (0)