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

Add simple language detection and have build for golang projects #10

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 22 additions & 88 deletions deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,23 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"text/template"

"gofr.dev/pkg/gofr"

"kops.dev/internal/templates"
)

const (
golang = "golang"
java = "java"
js = "js"
"kops.dev/internal/build"
"kops.dev/internal/file"
)

var (
errDepKeyNotProvided = errors.New("KOPS_DEPLOYMENT_KEY not provided, " +
"please download the key form https://kops.dev")
errLanguageNotProvided = errors.New("unable to create DockerFile as project " +
"programming language not provided. Please Provide a programming language using -lang=<language>")
errLanguageNotSupported = errors.New("creating DockerFile for provided language is not supported yet")
errDepKeyNotProvided = errors.New("KOPS_DEPLOYMENT_KEY not provided, " +
"please download the key form https://kops.dev")
)

func Deploy(ctx *gofr.Context) (interface{}, error) {
var lang, port string

keyFile := os.Getenv("KOPS_DEPLOYMENT_KEY")
if keyFile == "" {
return nil, errDepKeyNotProvided
Expand All @@ -39,102 +33,42 @@ func Deploy(ctx *gofr.Context) (interface{}, error) {
return nil, err
}

fi, _ := os.Stat("Dockerfile")
if fi != nil {
fmt.Println("Dockerfile present, using already created dockerfile")
} else {
if err := createDockerFile(ctx); err != nil {
return nil, err
}
}

// TODO: build and push the docker image to the Kops API
// Also need to figure out the contract for the API

return "Successful", nil
}

func createDockerFile(ctx *gofr.Context) error {
var content, lang, port string

// removing the cloud-specific logic from cli to hosted service
lang = ctx.Param("lang")
if lang == "" {
lang = detect()
lang = file.Detect()
if lang == "" {
ctx.Logger.Errorf("%v", errLanguageNotProvided)

return errLanguageNotProvided
return nil, errLanguageNotProvided
}

fmt.Println("detected language is", lang)
fmt.Println("Detected language is", lang)
}

port = ctx.Param("p")
if port == "" {
port = "8000"
}

// get the template content for dockerFile based on the language
switch strings.ToLower(lang) {
case golang:
content = templates.Golang
case java:
content = templates.Java
case js:
content = templates.Js
default:
ctx.Logger.Errorf("creating DockerFile for %s is not supported yet,"+
" reach us at https://github.com/kops-dev/kops-cli/issues to know more", lang)

fmt.Printf("creating DockerFile for %s is not supported yet, "+
"reach us at https://github.com/kops-dev/kops-cli/issues to know more\n", lang)
fmt.Println("you can create your own DockerFile and run the kops-cli again.")

return errLanguageNotSupported
}

file, err := os.Create("Dockerfile")
if err != nil {
return err
fi, _ := os.Stat("Dockerfile")
if fi != nil {
fmt.Println("Dockerfile present, using already created dockerfile")
} else {
if er := file.CreateDockerFile(ctx, lang, port); er != nil {
return nil, er
}
}

defer file.Close()

t := template.New(lang)

temp, err := t.Parse(content)
// Build the binary based on the language detected or provided by user
err = build.Build(lang)
if err != nil {
return err
}
ctx.Logger.Errorf("error building for %v, error : %v", lang, err)

if er := temp.Execute(file, port); er != nil {
ctx.Logger.Error("error while creating DockerFile", er)
fmt.Println("unable to create the DockerFile, please check permissions for creating files in the directory")

return er
}

return nil
}

func detect() string {
switch {
case checkFile("go.mod"):
return golang
case checkFile("package.json"):
return js
case checkFile("pom.xml") || checkFile("build.gradle"):
return java
return nil, err
}

return ""
}
// TODO: Need to figure out the contract for the API

func checkFile(fileName string) bool {
if _, err := os.Stat(fileName); err != nil {
return false
}

return true
return "Successful", nil
}
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module kops.dev

go 1.22

require gofr.dev v1.15.0
require (
github.com/stretchr/testify v1.9.0
gofr.dev v1.15.0
)

require (
cloud.google.com/go v0.115.0 // indirect
Expand All @@ -17,6 +20,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eclipse/paho.mqtt.golang v1.4.3 // indirect
Expand Down Expand Up @@ -46,6 +50,7 @@ require (
github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
Expand Down Expand Up @@ -84,6 +89,7 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect
google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.52.1 // indirect
modernc.org/mathutil v1.6.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,12 @@ github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0N
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
Expand Down Expand Up @@ -167,6 +171,8 @@ github.com/redis/go-redis/v9 v9.5.4 h1:vOFYDKKVgrI5u++QvnMT7DksSMYg7Aw/Np4vLJLKL
github.com/redis/go-redis/v9 v9.5.4/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0=
github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
Expand Down Expand Up @@ -368,6 +374,8 @@ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6h
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
45 changes: 45 additions & 0 deletions internal/build/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package build

import (
"fmt"
"os/exec"
)

const (
golang = "golang"
java = "java"
js = "js"
)

// TODO: For every language support do we need to check if that language's compiler exists in the system.
// support - 1. golang(done) 2. Javascript 3. Java

func Build(lang string) error {
switch lang {
case golang:
return buildGolang()
case js:
// TODO: necessary steps for javascript build
break
case java:
// TODO: necessary steps for building java projects
break
}

return nil
}

func buildGolang() error {
fmt.Println("Creating binary for the project")

output, err := exec.Command("sh", "-c", "CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .").CombinedOutput()
if err != nil {
fmt.Println("error occurred while creating binary!", output)

return err
}

fmt.Println("Binary created successfully")

return nil
}
30 changes: 30 additions & 0 deletions internal/file/detection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package file

import "os"

const (
golang = "golang"
java = "java"
js = "js"
)

func Detect() string {
switch {
case checkFile("go.mod"):
return golang
case checkFile("package.json"):
return js
case checkFile("pom.xml") || checkFile("build.gradle"):
return java
}

return ""
}

func checkFile(fileName string) bool {
if _, err := os.Stat(fileName); err != nil {
return false
}

return true
}
52 changes: 52 additions & 0 deletions internal/file/detection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package file

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_DetectGolang(t *testing.T) {
f, err := os.Create("go.mod")
if err != nil {
t.Errorf("error creating go.mod file, err : %v", err)
}

defer os.Remove(f.Name())

out := Detect()

assert.Equal(t, golang, out)
}

func Test_DetectJavaScript(t *testing.T) {
f, err := os.Create("package.json")
if err != nil {
t.Errorf("error creating go.mod file, err : %v", err)
}

defer os.Remove(f.Name())

out := Detect()

assert.Equal(t, js, out)
}

func Test_DetectJava(t *testing.T) {
f, err := os.Create("pom.xml")
if err != nil {
t.Errorf("error creating go.mod file, err : %v", err)
}

defer os.Remove(f.Name())

out := Detect()

assert.Equal(t, java, out)
}

func Test_DetectFail(t *testing.T) {
out := Detect()
assert.Equal(t, "", out)
}
Loading
Loading