Skip to content

Commit

Permalink
add apps detect command
Browse files Browse the repository at this point in the history
  • Loading branch information
pulkit-khullar committed Sep 8, 2022
1 parent 51c4f6b commit 367baac
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
9 changes: 9 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,13 @@ const (

// ArgAlertPolicySlackURLs are the Slack URLs to send alerts to.
ArgAlertPolicySlackURLs = "slack-urls"

// ArgCommitHash are the Git commit hash.
ArgCommitHash = "sha"
// ArgProjectSource is either git, github or gitlab.
ArgProjectSource = "source"
// ArgDeployOnPush allow auto deploy on project update.
ArgDeployOnPush = "deployonpush"
// ArgProjectBrach is git project branch.
ArgProjectBrach = "branch"
)
73 changes: 73 additions & 0 deletions commands/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"

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

// output is global flag
detect := CmdBuilder(cmd,
RunAppsDetect, "detect", "Detect functions", "Detect functions project and convert it into apps project by adding the AppSpec.", Writer, aliasOpt("dt"))
AddStringFlag(detect, doctl.ArgProjectSource, "", "", `Project source.`)
AddStringFlag(detect, doctl.ArgCommitHash, "", "", `Git commit hash`) // not sure if need to support commit hash?
AddStringFlag(detect, doctl.ArgProjectName, "", "", `App name to be used`)
AddStringFlag(detect, doctl.ArgProjectBrach, "", "", `Project branch to be used`)
AddBoolFlag(detect, doctl.ArgDeployOnPush, "", *boolPtr(true), `Auto deploy on project update.`)

deploymentCreate := CmdBuilder(
cmd,
RunAppsCreateDeployment,
Expand Down Expand Up @@ -393,6 +403,69 @@ func RunAppsDelete(c *CmdConfig) error {
return nil
}

// RunAppsDetect detects an function project and converts it into apps project.
func RunAppsDetect(c *CmdConfig) error {
source, err := c.Doit.GetString(c.NS, doctl.ArgProjectSource)
if err != nil {
return err
}
if len(source) == 0 {
return fmt.Errorf("source cannot be empty")
}

sha, err := c.Doit.GetString(c.NS, doctl.ArgCommitHash)
if err != nil {
return err
}

name, err := c.Doit.GetString(c.NS, doctl.ArgProjectName)
if err != nil {
return err
}
if len(name) == 0 {
return fmt.Errorf("name cannot be empty")
}

branch, err := c.Doit.GetString(c.NS, doctl.ArgProjectBrach)
if err != nil {
return err
}
if len(branch) == 0 {
return fmt.Errorf("branch cannot be empty")
}

// Need to check, How user value will be overrided
autoDeploy, err := c.Doit.GetBool(c.NS, doctl.ArgDeployOnPush)
if err != nil {
return err
}
if len(c.Args) > 0 {
fmt.Println(c.Args[0])
x, err := strconv.ParseBool(c.Args[0])
if err == nil {
autoDeploy = x
} else {
return fmt.Errorf("expected true/false for deployonpush, received : %s", c.Args[0])
}
}

spec, err := c.Apps().Detect(source, sha, name, branch, autoDeploy)
if err != nil {
return err
}

switch Output {
case "json":
e := json.NewEncoder(c.Out)
e.SetIndent("", " ")
return e.Encode(spec)
case "text":
return nil
default:
return fmt.Errorf("unknown output type")
}
}

// RunAppsCreateDeployment creates a deployment for an app.
func RunAppsCreateDeployment(c *CmdConfig) error {
if len(c.Args) < 1 {
Expand Down
82 changes: 82 additions & 0 deletions do/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package do

import (
"context"
"strings"

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

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

func (s *appsService) Detect(source string, sha string, name string, branch string, autoDeploy bool) (*godo.AppSpec, error) {
var dr godo.DetectRequest
if strings.Contains(source, "github") {
dr.GitHub = &godo.GitHubSourceSpec{
Repo: verifyGitSource(source, "github"),
Branch: branch,
DeployOnPush: autoDeploy,
}
} else if strings.Contains(source, "gitlab") {
dr.GitLab = &godo.GitLabSourceSpec{
Repo: verifyGitSource(source, "gitlab"),
Branch: branch,
DeployOnPush: autoDeploy,
}
} else {
dr.Git = &godo.GitSourceSpec{
RepoCloneURL: source,
Branch: branch,
}
}
dr.SourceDir = "/"
dr.CommitSHA = sha

resp, _, err := s.client.Apps.Detect(context.Background(), &dr)
if err != nil {
return nil, err
}

var appSpec godo.AppSpec

appSpec.Name = name
var funcSpecArray []*godo.AppFunctionsSpec
for _, component := range resp.Components {

if component.Strategy == "SERVERLESS" {
for _, serverlessPackage := range component.ServerlessPackages {
var functionSpec godo.AppFunctionsSpec
functionSpec.Name = serverlessPackage.Name
if strings.Contains(source, "github") {
functionSpec.GitHub = &godo.GitHubSourceSpec{
Repo: verifyGitSource(source, "github"),
Branch: branch,
DeployOnPush: autoDeploy,
}
} else if strings.Contains(source, "gitlab") {
functionSpec.GitLab = &godo.GitLabSourceSpec{
Repo: verifyGitSource(source, "gitlab"),
Branch: branch,
DeployOnPush: autoDeploy,
}
} else {
functionSpec.Git = &godo.GitSourceSpec{
RepoCloneURL: source,
Branch: branch,
}
}
functionSpec.SourceDir = "/"
functionSpec.Routes = []*godo.AppRouteSpec{
{
Path: "/",
PreservePathPrefix: false,
},
}
funcSpecArray = append(funcSpecArray, &functionSpec)

}
}
appSpec.Functions = funcSpecArray
}
return &appSpec, nil
}

func verifyGitSource(s string, splitter string) string {
x := strings.Split(s, splitter+".com/")
if strings.Contains(x[1], ".git") {
x = strings.Split(x[1], ".")
}
return x[0]
}

func (s *appsService) Propose(req *godo.AppProposeRequest) (*godo.AppProposeResponse, error) {
res, _, err := s.client.Apps.Propose(s.ctx, req)
if err != nil {
Expand Down

0 comments on commit 367baac

Please sign in to comment.