Skip to content

Commit b02dac8

Browse files
committed
Accept more repo fields via flags to repo create
1 parent 9175fc0 commit b02dac8

File tree

3 files changed

+136
-26
lines changed

3 files changed

+136
-26
lines changed

api/queries_repo.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
type Repository struct {
1515
ID string
1616
Name string
17+
URL string
1718
Owner RepositoryOwner
1819

1920
IsPrivate bool
@@ -216,3 +217,43 @@ func ForkRepo(client *Client, repo ghrepo.Interface) (*Repository, error) {
216217
ViewerPermission: "WRITE",
217218
}, nil
218219
}
220+
221+
// RepoCreateInput represents input parameters for RepoCreate
222+
type RepoCreateInput struct {
223+
Name string `json:"name"`
224+
Visibility string `json:"visibility"`
225+
Homepage string `json:"homepage,omitempty"`
226+
Description string `json:"description,omitempty"`
227+
228+
HasIssuesEnabled bool `json:"hasIssuesEnabled"`
229+
HasWikiEnabled bool `json:"hasWikiEnabled"`
230+
}
231+
232+
// RepoCreate creates a new GitHub repository
233+
func RepoCreate(client *Client, input RepoCreateInput) (*Repository, error) {
234+
var response struct {
235+
CreateRepository struct {
236+
Repository Repository
237+
}
238+
}
239+
240+
variables := map[string]interface{}{
241+
"input": input,
242+
}
243+
244+
err := client.GraphQL(`
245+
mutation($input: CreateRepositoryInput!) {
246+
createRepository(input: $input) {
247+
repository {
248+
id
249+
url
250+
}
251+
}
252+
}
253+
`, variables, &response)
254+
if err != nil {
255+
return nil, err
256+
}
257+
258+
return &response.CreateRepository.Repository, nil
259+
}

command/repo.go

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path"
77
"strings"
88

9+
"github.com/cli/cli/api"
910
"github.com/cli/cli/git"
1011
"github.com/cli/cli/internal/ghrepo"
1112
"github.com/cli/cli/utils"
@@ -16,6 +17,10 @@ func init() {
1617
RootCmd.AddCommand(repoCmd)
1718
repoCmd.AddCommand(repoCloneCmd)
1819
repoCmd.AddCommand(repoCreateCmd)
20+
repoCreateCmd.Flags().StringP("description", "d", "", "Description of repository")
21+
repoCreateCmd.Flags().StringP("homepage", "h", "", "Repository home page URL")
22+
repoCreateCmd.Flags().Bool("enable-issues", true, "Enable issues in the new repository")
23+
repoCreateCmd.Flags().Bool("enable-wiki", true, "Enable wiki in the new repository")
1924
repoCreateCmd.Flags().Bool("public", false, "Make the new repository public")
2025
repoCmd.AddCommand(repoViewCmd)
2126
}
@@ -85,46 +90,54 @@ func repoCreate(cmd *cobra.Command, args []string) error {
8590
name = path.Base(dir)
8691
}
8792

88-
visibility := "PRIVATE"
89-
if isPublic, err := cmd.Flags().GetBool("public"); err == nil && isPublic {
90-
visibility = "PUBLIC"
93+
isPublic, err := cmd.Flags().GetBool("public")
94+
if err != nil {
95+
return err
9196
}
92-
93-
ctx := contextForCommand(cmd)
94-
client, err := apiClientForContext(ctx)
97+
hasIssuesEnabled, err := cmd.Flags().GetBool("enable-issues")
98+
if err != nil {
99+
return err
100+
}
101+
hasWikiEnabled, err := cmd.Flags().GetBool("enable-wiki")
102+
if err != nil {
103+
return err
104+
}
105+
description, err := cmd.Flags().GetString("description")
106+
if err != nil {
107+
return err
108+
}
109+
homepage, err := cmd.Flags().GetString("homepage")
95110
if err != nil {
96111
return err
97112
}
98113

99-
variables := map[string]interface{}{
100-
"input": map[string]interface{}{
101-
"name": name,
102-
"visibility": visibility,
103-
},
114+
// TODO: move this into constant within `api`
115+
visibility := "PRIVATE"
116+
if isPublic {
117+
visibility = "PUBLIC"
104118
}
105119

106-
var response struct {
107-
CreateRepository struct {
108-
Repository struct {
109-
URL string
110-
}
111-
}
120+
input := api.RepoCreateInput{
121+
Name: name,
122+
Visibility: visibility,
123+
Description: description,
124+
Homepage: homepage,
125+
HasIssuesEnabled: hasIssuesEnabled,
126+
HasWikiEnabled: hasWikiEnabled,
112127
}
113128

114-
err = client.GraphQL(`
115-
mutation($input: CreateRepositoryInput!) {
116-
createRepository(input: $input) {
117-
repository {
118-
url
119-
}
120-
}
129+
ctx := contextForCommand(cmd)
130+
client, err := apiClientForContext(ctx)
131+
if err != nil {
132+
return err
121133
}
122-
`, variables, &response)
134+
135+
repo, err := api.RepoCreate(client, input)
123136
if err != nil {
124137
return err
125138
}
126139

127-
cmd.Println(response.CreateRepository.Repository.URL)
140+
fmt.Fprintln(cmd.OutOrStdout(), repo.URL)
128141
return nil
129142
}
130143

command/repo_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package command
22

33
import (
4+
"bytes"
5+
"encoding/json"
6+
"io/ioutil"
47
"os/exec"
58
"strings"
69
"testing"
@@ -61,6 +64,59 @@ func TestRepoClone(t *testing.T) {
6164
}
6265
}
6366

67+
func TestRepoCreate(t *testing.T) {
68+
ctx := context.NewBlank()
69+
ctx.SetBranch("master")
70+
initContext = func() context.Context {
71+
return ctx
72+
}
73+
74+
http := initFakeHTTP()
75+
http.StubResponse(200, bytes.NewBufferString(`
76+
{ "data": { "createRepository": {
77+
"repository": {
78+
"id": "REPOID",
79+
"url": "https://github.com/OWNER/REPO"
80+
}
81+
} } }
82+
`))
83+
84+
var seenCmd *exec.Cmd
85+
restoreCmd := utils.SetPrepareCmd(func(cmd *exec.Cmd) utils.Runnable {
86+
seenCmd = cmd
87+
return &outputStub{}
88+
})
89+
defer restoreCmd()
90+
91+
output, err := RunCommand(repoCreateCmd, "repo create REPO")
92+
if err != nil {
93+
t.Errorf("error running command `repo create`: %v", err)
94+
}
95+
96+
eq(t, output.String(), "https://github.com/OWNER/REPO\n")
97+
eq(t, output.Stderr(), "")
98+
99+
if seenCmd != nil {
100+
t.Fatal("expected a command to run")
101+
}
102+
103+
var reqBody struct {
104+
Query string
105+
Variables struct {
106+
Input map[string]interface{}
107+
}
108+
}
109+
110+
bodyBytes, _ := ioutil.ReadAll(http.Requests[0].Body)
111+
json.Unmarshal(bodyBytes, &reqBody)
112+
if repoName := reqBody.Variables.Input["name"].(string); repoName != "REPO" {
113+
t.Errorf("expected %q, got %q", "REPO", repoName)
114+
}
115+
if repoVisibility := reqBody.Variables.Input["visibility"].(string); repoVisibility != "PRIVATE" {
116+
t.Errorf("expected %q, got %q", "PRIVATE", repoVisibility)
117+
}
118+
}
119+
64120
func TestRepoView(t *testing.T) {
65121
initBlankContext("OWNER/REPO", "master")
66122
http := initFakeHTTP()

0 commit comments

Comments
 (0)