Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
main: pull: initial implementation
Browse files Browse the repository at this point in the history
Signed-off-by: brkp <[email protected]>
  • Loading branch information
nullptropy committed Oct 12, 2023
1 parent 3441d6c commit a3bcda3
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
55 changes: 55 additions & 0 deletions cmd/pull.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"os"
"path/filepath"

"github.com/deta/space/cmd/utils"
"github.com/deta/space/internal/api"
"github.com/deta/space/internal/runtime"
"github.com/deta/space/pkg/components/emoji"

"github.com/spf13/cobra"
)

func newCmdPull() *cobra.Command {
cmd := &cobra.Command{
Use: "pull",
Short: "Pull the latest release of your project from Space",
PostRunE: utils.CheckLatestVersion,
RunE: func(cmd *cobra.Command, args []string) error {
projectDir, _ := cmd.Flags().GetString("dir")
projectID, _ := cmd.Flags().GetString("id")
if !cmd.Flags().Changed("id") {
var err error
projectID, err = runtime.GetProjectID(projectDir)
if err != nil {
utils.Logger.Printf("%s Failed to get project id: %s", emoji.ErrorExclamation, err)
return err
}
}

resp, err := utils.Client.GetProjectZipball(&api.GetProjectZipballRequest{ID: projectID})
if err != nil {
return err
}

zipFilePath := filepath.Join(projectDir, resp.Name)
err = os.WriteFile(zipFilePath, resp.Data, 0644)
if err != nil {
utils.Logger.Printf("%s Failed to write zip file: %s", emoji.ErrorExclamation, err)
return err
}

utils.Logger.Printf("%s Project pulled successfully to %s", emoji.Check, zipFilePath)
return nil
},
}

cmd.Flags().StringP("id", "i", "", "`project_id` of project")
cmd.Flags().StringP("dir", "d", "./", "src of project")

cmd.MarkFlagDirname("dir")

return cmd
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Complete documentation available at %s`, utils.DocsUrl),
cmd.AddCommand(newCmdPrintAccessToken())
cmd.AddCommand(newCmdTrigger())
cmd.AddCommand(newCmdBuilder())
cmd.AddCommand(newCmdPull())

// XXX: This will prevent the usage from being displayed when an error occurs
// while calling the Execute function in the main.go file.
Expand Down
52 changes: 52 additions & 0 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"strings"

"github.com/deta/space/internal/auth"
"github.com/deta/space/shared"
Expand Down Expand Up @@ -75,6 +76,57 @@ func (c *DetaClient) GetProject(r *GetProjectRequest) (*GetProjectResponse, erro
return &resp, nil
}

type GetProjectZipballRequest struct {
ID string `json:"id"`
}

type GetProjectZipballResponse struct {
Name string
Data []byte
}

func (c *DetaClient) GetProjectZipball(r *GetProjectZipballRequest) (*GetProjectZipballResponse, error) {
i := &requestInput{
Root: spaceRoot,
Path: fmt.Sprintf("/%s/apps/%s/zipball", version, r.ID),
Method: "GET",
NeedsAuth: true,
}

o, err := c.request(i)
if err != nil {
return nil, err
}

if o.Status == 401 || o.Status == 404 {
return nil, ErrProjectNotFound
}

if o.Status != 200 {
msg := o.Error.Detail
if msg == "" && len(o.Error.Errors) > 0 {
msg = o.Error.Errors[0]
}
return nil, fmt.Errorf("failed to get project zipball: %v", msg)
}

contentDisposition := o.Header.Get("Content-Disposition")
if contentDisposition == "" {
return nil, errors.New("missing Content-Disposition header")
}

parts := strings.Split(contentDisposition, `filename=`)
if len(parts) != 2 {
return nil, errors.New("invalid `Content-Disposition` header format")
}
filename := strings.TrimSuffix(parts[1], `"`)

return &GetProjectZipballResponse{
Name: filename,
Data: o.Body,
}, nil
}

type CreateProjectRequest struct {
Name string `json:"name"`
Alias string `json:"alias"`
Expand Down

0 comments on commit a3bcda3

Please sign in to comment.