diff --git a/index/server/pkg/server/endpoint.go b/index/server/pkg/server/endpoint.go index 907c49554..060aceb4d 100644 --- a/index/server/pkg/server/endpoint.go +++ b/index/server/pkg/server/endpoint.go @@ -2,7 +2,6 @@ package server import ( "archive/zip" - "context" "encoding/json" "fmt" "io" @@ -20,10 +19,10 @@ import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/parser" "github.com/devfile/library/pkg/devfile/parser/data/v2/common" + "github.com/devfile/registry-support/index/generator/schema" indexSchema "github.com/devfile/registry-support/index/generator/schema" "github.com/devfile/registry-support/index/server/pkg/util" "github.com/gin-gonic/gin" - "github.com/hashicorp/go-getter" "github.com/prometheus/client_golang/prometheus" "gopkg.in/segmentio/analytics-go.v3" ) @@ -157,11 +156,11 @@ func serveDevfileStarterProject(c *gin.Context) { return } else { content, err := parser.ParseFromData(devfileBytes) - filterOptions := common.DevfileOptions{} - // filterOptions := common.DevfileOptions{ - // FilterByName: starterProjectName, - // } + filterOptions := common.DevfileOptions{ + FilterByName: starterProjectName, + } var starterProjects []v1alpha2.StarterProject + var downloadBytes []byte if err != nil { log.Print(err.Error()) @@ -180,140 +179,132 @@ func serveDevfileStarterProject(c *gin.Context) { "status": fmt.Sprintf("problem in reading starter project %s of devfile %s", starterProjectName, devfileName), }) return + } else if len(starterProjects) == 0 { + c.JSON(http.StatusNotFound, gin.H{ + "status": fmt.Sprintf("the starter project named %s does not exist in the devfile of %s", starterProjectName, devfileName), + }) + return } - // ** Temp Filter ** - for _, starterProject := range starterProjects { - if starterProject.Name == starterProjectName { - var downloadBytes []byte - - if starterProject.Git != nil { - downloadTmpLoc := path.Join("/tmp", starterProjectName) - // TODO: Setup go-getter to download subDir and from other remotes - client := &getter.Client{ - Ctx: context.Background(), - Dst: downloadTmpLoc, - Dir: true, - Src: strings.Split(starterProject.Git.Remotes["origin"], "https://")[1], - Mode: getter.ClientModeDir, - Detectors: []getter.Detector{ - &getter.GitHubDetector{}, - }, - Getters: map[string]getter.Getter{ - "git": &getter.GitGetter{}, - }, - } - if err := client.Get(); err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with downloading starter project %s from location: %s", - starterProjectName, client.Src), - }) - return - } - zipFile, err := os.Create(fmt.Sprintf("%s.zip", downloadTmpLoc)) - if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with creating starter project %s zip archive for download", - starterProjectName), - }) - return - } - defer zipFile.Close() - - zipWriter := zip.NewWriter(zipFile) - defer zipWriter.Close() - - err = filepath.Walk(downloadTmpLoc, func(currPath string, info fs.FileInfo, err error) error { - if err != nil { - return err - } else if !info.IsDir() { - srcFile, err := os.Open(currPath) - if err != nil { - return err - } - defer srcFile.Close() - - dstFile, err := zipWriter.Create(path.Join(".", strings.Split(currPath, downloadTmpLoc)[1])) - if err != nil { - return err - } - - if _, err := io.Copy(dstFile, srcFile); err != nil { - return err - } - } - - return nil - }) - if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with populating starter project %s zip archive for download, see error for details", - starterProjectName), - }) - return - } + if starterProject := starterProjects[0]; starterProject.Git != nil { + downloadTmpLoc := path.Join("/tmp", starterProjectName) + gitScheme := schema.Git{ + Remotes: starterProject.Git.Remotes, + RemoteName: "origin", + SubDir: starterProject.SubDir, + } + + if starterProject.Git.CheckoutFrom != nil { + gitScheme.RemoteName = starterProject.Git.CheckoutFrom.Remote + gitScheme.Revision = starterProject.Git.CheckoutFrom.Revision + } + + gitScheme.Url = gitScheme.Remotes[gitScheme.RemoteName] + + if err := library.downloadRemoteStack(&gitScheme, downloadTmpLoc, false); err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with downloading starter project %s from location: %s", + starterProjectName, gitScheme.Url), + }) + return + } - _, err = zipFile.Read(downloadBytes) + zipFile, err := os.Create(fmt.Sprintf("%s.zip", downloadTmpLoc)) + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with creating starter project %s zip archive for download", + starterProjectName), + }) + return + } + defer zipFile.Close() + + zipWriter := zip.NewWriter(zipFile) + defer zipWriter.Close() + + err = filepath.Walk(downloadTmpLoc, func(currPath string, info fs.FileInfo, err error) error { + if err != nil { + return err + } else if !info.IsDir() { + srcFile, err := os.Open(currPath) if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with reading starter project %s zip archive for download", - starterProjectName), - }) - return - } - } else if starterProject.Zip != nil { - client := http.Client{ - CheckRedirect: func(req *http.Request, via []*http.Request) error { - req.URL.Opaque = req.URL.Path - return nil - }, + return err } + defer srcFile.Close() - resp, err := client.Get(starterProject.Zip.Location) + dstFile, err := zipWriter.Create(path.Join(".", strings.Split(currPath, downloadTmpLoc)[1])) if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with downloading starter project %s from location: %s", - starterProjectName, starterProject.Zip.Location), - }) - return + return err } - defer resp.Body.Close() - downloadBytes, err = ioutil.ReadAll(resp.Body) - if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("Problem with reading downloaded starter %s", starterProjectName), - }) - return + if _, err := io.Copy(dstFile, srcFile); err != nil { + return err } - } else { - c.JSON(http.StatusBadRequest, gin.H{ - "status": fmt.Sprintf("Starter project %s has no source to download from", starterProjectName), - }) - return } - c.Data(http.StatusAccepted, "application/zip", downloadBytes) + return nil + }) + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with populating starter project %s zip archive for download, see error for details", + starterProjectName), + }) return } + + _, err = zipFile.Read(downloadBytes) + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with reading starter project %s zip archive for download", + starterProjectName), + }) + return + } + } else if starterProject.Zip != nil { + client := http.Client{ + CheckRedirect: func(req *http.Request, via []*http.Request) error { + req.URL.Opaque = req.URL.Path + return nil + }, + } + + resp, err := client.Get(starterProject.Zip.Location) + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with downloading starter project %s from location: %s", + starterProjectName, starterProject.Zip.Location), + }) + return + } + defer resp.Body.Close() + + downloadBytes, err = ioutil.ReadAll(resp.Body) + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("Problem with reading downloaded starter %s", starterProjectName), + }) + return + } + } else { + c.JSON(http.StatusBadRequest, gin.H{ + "status": fmt.Sprintf("Starter project %s has no source to download from", starterProjectName), + }) + return } - // ***************** - c.JSON(http.StatusNotFound, gin.H{ - "status": fmt.Sprintf("the starter project named %s does not exist in the devfile of %s", starterProjectName, devfileName), - }) + c.Data(http.StatusAccepted, "application/zip", downloadBytes) } }