Skip to content

Commit 367baac

Browse files
add apps detect command
1 parent 51c4f6b commit 367baac

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

args.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,13 @@ const (
406406

407407
// ArgAlertPolicySlackURLs are the Slack URLs to send alerts to.
408408
ArgAlertPolicySlackURLs = "slack-urls"
409+
410+
// ArgCommitHash are the Git commit hash.
411+
ArgCommitHash = "sha"
412+
// ArgProjectSource is either git, github or gitlab.
413+
ArgProjectSource = "source"
414+
// ArgDeployOnPush allow auto deploy on project update.
415+
ArgDeployOnPush = "deployonpush"
416+
// ArgProjectBrach is git project branch.
417+
ArgProjectBrach = "branch"
409418
)

commands/apps.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net/http"
2323
"net/url"
2424
"os"
25+
"strconv"
2526
"strings"
2627
"time"
2728

@@ -113,6 +114,15 @@ This permanently deletes the app and all its associated deployments.`,
113114
)
114115
AddBoolFlag(deleteApp, doctl.ArgForce, doctl.ArgShortForce, false, "Delete the App without a confirmation prompt")
115116

117+
// output is global flag
118+
detect := CmdBuilder(cmd,
119+
RunAppsDetect, "detect", "Detect functions", "Detect functions project and convert it into apps project by adding the AppSpec.", Writer, aliasOpt("dt"))
120+
AddStringFlag(detect, doctl.ArgProjectSource, "", "", `Project source.`)
121+
AddStringFlag(detect, doctl.ArgCommitHash, "", "", `Git commit hash`) // not sure if need to support commit hash?
122+
AddStringFlag(detect, doctl.ArgProjectName, "", "", `App name to be used`)
123+
AddStringFlag(detect, doctl.ArgProjectBrach, "", "", `Project branch to be used`)
124+
AddBoolFlag(detect, doctl.ArgDeployOnPush, "", *boolPtr(true), `Auto deploy on project update.`)
125+
116126
deploymentCreate := CmdBuilder(
117127
cmd,
118128
RunAppsCreateDeployment,
@@ -393,6 +403,69 @@ func RunAppsDelete(c *CmdConfig) error {
393403
return nil
394404
}
395405

406+
// RunAppsDetect detects an function project and converts it into apps project.
407+
func RunAppsDetect(c *CmdConfig) error {
408+
source, err := c.Doit.GetString(c.NS, doctl.ArgProjectSource)
409+
if err != nil {
410+
return err
411+
}
412+
if len(source) == 0 {
413+
return fmt.Errorf("source cannot be empty")
414+
}
415+
416+
sha, err := c.Doit.GetString(c.NS, doctl.ArgCommitHash)
417+
if err != nil {
418+
return err
419+
}
420+
421+
name, err := c.Doit.GetString(c.NS, doctl.ArgProjectName)
422+
if err != nil {
423+
return err
424+
}
425+
if len(name) == 0 {
426+
return fmt.Errorf("name cannot be empty")
427+
}
428+
429+
branch, err := c.Doit.GetString(c.NS, doctl.ArgProjectBrach)
430+
if err != nil {
431+
return err
432+
}
433+
if len(branch) == 0 {
434+
return fmt.Errorf("branch cannot be empty")
435+
}
436+
437+
// Need to check, How user value will be overrided
438+
autoDeploy, err := c.Doit.GetBool(c.NS, doctl.ArgDeployOnPush)
439+
if err != nil {
440+
return err
441+
}
442+
if len(c.Args) > 0 {
443+
fmt.Println(c.Args[0])
444+
x, err := strconv.ParseBool(c.Args[0])
445+
if err == nil {
446+
autoDeploy = x
447+
} else {
448+
return fmt.Errorf("expected true/false for deployonpush, received : %s", c.Args[0])
449+
}
450+
}
451+
452+
spec, err := c.Apps().Detect(source, sha, name, branch, autoDeploy)
453+
if err != nil {
454+
return err
455+
}
456+
457+
switch Output {
458+
case "json":
459+
e := json.NewEncoder(c.Out)
460+
e.SetIndent("", " ")
461+
return e.Encode(spec)
462+
case "text":
463+
return nil
464+
default:
465+
return fmt.Errorf("unknown output type")
466+
}
467+
}
468+
396469
// RunAppsCreateDeployment creates a deployment for an app.
397470
func RunAppsCreateDeployment(c *CmdConfig) error {
398471
if len(c.Args) < 1 {

do/apps.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package do
1515

1616
import (
1717
"context"
18+
"strings"
1819

1920
"github.com/digitalocean/godo"
2021
)
@@ -26,6 +27,7 @@ type AppsService interface {
2627
List() ([]*godo.App, error)
2728
Update(appID string, req *godo.AppUpdateRequest) (*godo.App, error)
2829
Delete(appID string) error
30+
Detect(source string, sha string, name string, branch string, autoDeploy bool) (*godo.AppSpec, error)
2931
Propose(req *godo.AppProposeRequest) (*godo.AppProposeResponse, error)
3032

3133
CreateDeployment(appID string, forceRebuild bool) (*godo.Deployment, error)
@@ -119,6 +121,86 @@ func (s *appsService) Delete(appID string) error {
119121
return err
120122
}
121123

124+
func (s *appsService) Detect(source string, sha string, name string, branch string, autoDeploy bool) (*godo.AppSpec, error) {
125+
var dr godo.DetectRequest
126+
if strings.Contains(source, "github") {
127+
dr.GitHub = &godo.GitHubSourceSpec{
128+
Repo: verifyGitSource(source, "github"),
129+
Branch: branch,
130+
DeployOnPush: autoDeploy,
131+
}
132+
} else if strings.Contains(source, "gitlab") {
133+
dr.GitLab = &godo.GitLabSourceSpec{
134+
Repo: verifyGitSource(source, "gitlab"),
135+
Branch: branch,
136+
DeployOnPush: autoDeploy,
137+
}
138+
} else {
139+
dr.Git = &godo.GitSourceSpec{
140+
RepoCloneURL: source,
141+
Branch: branch,
142+
}
143+
}
144+
dr.SourceDir = "/"
145+
dr.CommitSHA = sha
146+
147+
resp, _, err := s.client.Apps.Detect(context.Background(), &dr)
148+
if err != nil {
149+
return nil, err
150+
}
151+
152+
var appSpec godo.AppSpec
153+
154+
appSpec.Name = name
155+
var funcSpecArray []*godo.AppFunctionsSpec
156+
for _, component := range resp.Components {
157+
158+
if component.Strategy == "SERVERLESS" {
159+
for _, serverlessPackage := range component.ServerlessPackages {
160+
var functionSpec godo.AppFunctionsSpec
161+
functionSpec.Name = serverlessPackage.Name
162+
if strings.Contains(source, "github") {
163+
functionSpec.GitHub = &godo.GitHubSourceSpec{
164+
Repo: verifyGitSource(source, "github"),
165+
Branch: branch,
166+
DeployOnPush: autoDeploy,
167+
}
168+
} else if strings.Contains(source, "gitlab") {
169+
functionSpec.GitLab = &godo.GitLabSourceSpec{
170+
Repo: verifyGitSource(source, "gitlab"),
171+
Branch: branch,
172+
DeployOnPush: autoDeploy,
173+
}
174+
} else {
175+
functionSpec.Git = &godo.GitSourceSpec{
176+
RepoCloneURL: source,
177+
Branch: branch,
178+
}
179+
}
180+
functionSpec.SourceDir = "/"
181+
functionSpec.Routes = []*godo.AppRouteSpec{
182+
{
183+
Path: "/",
184+
PreservePathPrefix: false,
185+
},
186+
}
187+
funcSpecArray = append(funcSpecArray, &functionSpec)
188+
189+
}
190+
}
191+
appSpec.Functions = funcSpecArray
192+
}
193+
return &appSpec, nil
194+
}
195+
196+
func verifyGitSource(s string, splitter string) string {
197+
x := strings.Split(s, splitter+".com/")
198+
if strings.Contains(x[1], ".git") {
199+
x = strings.Split(x[1], ".")
200+
}
201+
return x[0]
202+
}
203+
122204
func (s *appsService) Propose(req *godo.AppProposeRequest) (*godo.AppProposeResponse, error) {
123205
res, _, err := s.client.Apps.Propose(s.ctx, req)
124206
if err != nil {

0 commit comments

Comments
 (0)