Skip to content

Commit 8acf623

Browse files
mrnuggetLawnGnome
andauthored
Add 'campaigns new' command (#339)
* Add 'campaigns new' command * Print success message * Update cmd/src/campaigns_new.go Co-authored-by: Adam Harvey <[email protected]> * Show current worker goroutine status below progress bar (#338) * First try to add progress with status bars * Refactoring and renaming * Tiny step and refactoring * Get ProgressWithStatusBars working * Change API of progressWithStatusbars * Refactor StatusBar printing * Embed ProgressTTY in ProgressWithStatusBarsTTY * More merging of progressTTY and progressWithStatusbarsTTY * Add simple progress with status bars * Move demo of progress with bars to _examples * Restore overwritten methods * Restore more overwritten methods * Restore another overwritten method * WIP: Wire up status bars with executor * Print status bars below progress bar and add ASCII box characters * WIP1: Introduce campaign progress printer * WIP2: More refactoring of campaign status printing * More cleanup and refactoring * Change styling of progress bar with status * Add time to StatusBar and display right-aligned * Use a const * Add CHANGELOG entry * Ignore invisible characters for text length in progress bar * Update CHANGELOG.md Co-authored-by: Adam Harvey <[email protected]> * Erase previous content with spaces on blank line * Thin box drawing lines * Improve non-TTY output for progress indicators with status bars. Co-authored-by: Adam Harvey <[email protected]> Co-authored-by: Adam Harvey <[email protected]> * Incorporate feedback * Change placeholders in campaign skeleton Co-authored-by: Adam Harvey <[email protected]> Co-authored-by: Adam Harvey <[email protected]>
1 parent 5141363 commit 8acf623

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ All notable changes to `src-cli` are documented in this file.
1414
### Added
1515

1616
- The `published` flag in campaign specs may now be an array, which allows only specific changesets within a campaign to be published based on the repository name. [#294](https://github.com/sourcegraph/src-cli/pull/294)
17+
- A new `src campaign new` command creates a campaign spec YAML file with common values prefilled to make it easier to create a new campaign. [#339](https://github.com/sourcegraph/src-cli/pull/339)
1718

1819
### Changed
1920

cmd/src/campaigns_new.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
"strings"
9+
10+
"text/template"
11+
12+
"github.com/pkg/errors"
13+
"github.com/sourcegraph/src-cli/internal/campaigns"
14+
)
15+
16+
func init() {
17+
usage := `
18+
'src campaigns new' creates a new campaign spec YAML, prefilled with all
19+
required fields.
20+
21+
Usage:
22+
23+
src campaigns new [-f FILE]
24+
25+
Examples:
26+
27+
28+
$ src campaigns new -f campaign.spec.yaml
29+
30+
`
31+
32+
flagSet := flag.NewFlagSet("new", flag.ExitOnError)
33+
34+
var (
35+
fileFlag = flagSet.String("f", "campaign.yaml", "The name of campaign spec file to create.")
36+
)
37+
38+
handler := func(args []string) error {
39+
if err := flagSet.Parse(args); err != nil {
40+
return err
41+
}
42+
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)
49+
}
50+
defer f.Close()
51+
52+
tmpl, err := template.New("").Parse(campaignSpecTmpl)
53+
if err != nil {
54+
return err
55+
}
56+
57+
author := campaigns.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+
66+
gitAuthorName, err = getGitConfig("user.name")
67+
gitAuthorEmail, err = getGitConfig("user.email")
68+
69+
if err == nil && gitAuthorName != "" && gitAuthorEmail != "" {
70+
author.Name = gitAuthorName
71+
author.Email = gitAuthorEmail
72+
}
73+
}
74+
75+
err = tmpl.Execute(f, map[string]interface{}{"Author": author})
76+
if err != nil {
77+
return errors.Wrap(err, "failed to write campaign spec to file")
78+
}
79+
80+
fmt.Printf("%s created.\n", *fileFlag)
81+
return nil
82+
}
83+
84+
campaignsCommands = append(campaignsCommands, &command{
85+
flagSet: flagSet,
86+
aliases: []string{},
87+
handler: handler,
88+
usageFunc: func() {
89+
fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'src campaigns %s':\n", flagSet.Name())
90+
flagSet.PrintDefaults()
91+
fmt.Println(usage)
92+
},
93+
})
94+
}
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 campaignSpecTmpl = `name: NAME-OF-YOUR-CAMPAIGN
106+
description: DESCRIPTION-OF-YOUR-CAMPAIGN
107+
108+
109+
# "on" specifies on which repositories to execute the "steps"
110+
on:
111+
# Example: find all repositories that contain a README.md file.
112+
- repositoriesMatchingQuery: file:README.md
113+
114+
# steps are run in each repository. Each repository's resulting diff is captured.
115+
steps:
116+
# Example: append "Hello World" to every README.md
117+
- run: echo "Hello World" | tee -a $(find -name README.md)
118+
container: alpine:3
119+
120+
# Describe the changeset (e.g., GitHub pull request) you want for each repository.
121+
changesetTemplate:
122+
title: Hello World
123+
body: This adds Hello World to the README
124+
125+
branch: BRANCH-NAME-IN-EACH-REPOSITORY # Push the commit to this branch.
126+
127+
commit:
128+
author:
129+
name: {{ .Author.Name }}
130+
email: {{ .Author.Email }}
131+
message: Append Hello World to all README.md files
132+
133+
# Change published to true once you're ready to create changesets on the code host.
134+
published: false
135+
`

0 commit comments

Comments
 (0)