github.com/zaquestion/lab@v0.25.1/cmd/project_create.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/MakeNowJust/heredoc/v2" 8 "github.com/spf13/cobra" 9 "github.com/xanzy/go-gitlab" 10 "github.com/zaquestion/lab/internal/git" 11 lab "github.com/zaquestion/lab/internal/gitlab" 12 ) 13 14 // projectCreateCmd represents the create command 15 var projectCreateCmd = &cobra.Command{ 16 Use: "create [path]", 17 Short: "Create a new project on GitLab", 18 Long: heredoc.Doc(` 19 Create a new project on GitLab. 20 21 "path" refers to the path on GitLab not including the group/namespace. 22 If no path or name is provided and the current directory is a git repo, 23 the name of the current working directory will be used.`), 24 Example: heredoc.Doc(` 25 lab project create myproject 26 lab project create myproject -n "new proj" 27 lab project create myproject -r myupstream 28 lab project create -g mygroup myproject 29 lab project create mygroup/myproject -n "new proj" 30 lab project create myproject --http 31 lab project create myproject --internal 32 lab project create myproject --private 33 lab project create myproject --public`), 34 Args: cobra.MaximumNArgs(1), 35 PersistentPreRun: labPersistentPreRun, 36 Run: func(cmd *cobra.Command, args []string) { 37 var ( 38 name, _ = cmd.Flags().GetString("name") 39 desc, _ = cmd.Flags().GetString("description") 40 group, _ = cmd.Flags().GetString("group") 41 remote, _ = cmd.Flags().GetString("remote") 42 ) 43 44 g, path := determineNamespacePath(args, name) 45 if path == "" && name == "" { 46 log.Fatal("path or name must be set") 47 } 48 if g != "" && group != "" { 49 log.Fatalf("group can be passed by flag or in path, but not both\n%s", labUsageFormat(cmd)) 50 } 51 if g != "" { 52 group = g 53 } 54 55 var namespaceID *int 56 if group != "" { 57 groupObj, err := lab.GroupSearch(group) 58 if err != nil { 59 log.Fatal(err) 60 } 61 namespaceID = &groupObj.ID 62 } 63 64 // set the default visibility 65 visibility := gitlab.PrivateVisibility 66 67 // now override the visibility if the user passed in relevant flags. if 68 // the user passes multiple flags, this will use the "most private" 69 // option given, ignoring the rest 70 switch { 71 case private: 72 visibility = gitlab.PrivateVisibility 73 case internal: 74 visibility = gitlab.InternalVisibility 75 case public: 76 visibility = gitlab.PublicVisibility 77 } 78 79 opts := gitlab.CreateProjectOptions{ 80 // if namespaceID is nil, the project will be created in user's 81 // namespace 82 NamespaceID: namespaceID, 83 Path: gitlab.String(path), 84 Name: gitlab.String(name), 85 Description: gitlab.String(desc), 86 Visibility: &visibility, 87 ApprovalsBeforeMerge: gitlab.Int(0), 88 } 89 p, err := lab.ProjectCreate(&opts) 90 if err != nil { 91 log.Fatal(err) 92 } 93 94 if remote != "" { 95 if git.InsideGitRepo() { 96 urlToRepo := labURLToRepo(p) 97 err = git.RemoteAdd(remote, urlToRepo, ".") 98 if err != nil { 99 log.Fatal(err) 100 } 101 } else { 102 log.Warnf("outside of a git repo. remote '%s' not added\n", remote) 103 } 104 } 105 106 fmt.Println(strings.TrimSuffix(p.HTTPURLToRepo, ".git")) 107 }, 108 } 109 110 func determineNamespacePath(args []string, name string) (string, string) { 111 if len(args) > 0 { 112 ps := strings.Split(args[0], "/") 113 if len(ps) == 1 { 114 return "", ps[0] 115 } 116 return strings.Join(ps[:len(ps)-1], "/"), ps[len(ps)-1] 117 } 118 119 var path string 120 if name == "" && git.InsideGitRepo() { 121 wd, err := git.WorkingDir() 122 if err != nil { 123 log.Fatal(err) 124 } 125 p := strings.Split(wd, "/") 126 path = p[len(p)-1] 127 } 128 return "", path 129 } 130 131 func init() { 132 projectCreateCmd.Flags().StringP("name", "n", "", "name of the new project") 133 projectCreateCmd.Flags().StringP("group", "g", "", "group name (also known as namespace)") 134 projectCreateCmd.Flags().StringP("description", "d", "", "description of the new project") 135 projectCreateCmd.Flags().StringP("remote", "r", "", "add remote referring to the new project") 136 projectCreateCmd.Flags().BoolVarP(&private, "private", "p", false, "make project private: visible only to project members") 137 projectCreateCmd.Flags().BoolVar(&public, "public", false, "make project public: visible without any authentication") 138 projectCreateCmd.Flags().BoolVar(&internal, "internal", false, "make project internal: visible to any authenticated user (default)") 139 projectCreateCmd.Flags().BoolVar(&useHTTP, "http", false, "use HTTP protocol instead of SSH") 140 projectCmd.AddCommand(projectCreateCmd) 141 }