Skip to content

Commit

Permalink
feat: wip: update cmd, check, fetch & extract release asset
Browse files Browse the repository at this point in the history
  • Loading branch information
ojaswa1942 committed Feb 26, 2022
1 parent 03bd334 commit d5d7439
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 15 deletions.
118 changes: 118 additions & 0 deletions cmd/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cmd

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"time"

"github.com/Privado-Inc/privado/pkg/config"
"github.com/Privado-Inc/privado/pkg/utils"
"github.com/spf13/cobra"
"golang.org/x/mod/semver"
)

var updateCmd = &cobra.Command{
Use: "update",
Short: "Check for latest release and update to the latest version Privado CLI",
Long: "Check for latest release and update to the latest version Privado CLI",
Args: cobra.ExactArgs(0),
Run: update,
}

func update(cmd *cobra.Command, args []string) {
version(cmd, args)
fmt.Println()

// if Version == "dev" {
// exit(
// fmt.Sprint("Cannot perform an update on the dev build. Kindly use a release build or update manually\nFor more information, visit ", config.AppConfig.PrivadoRepository),
// false,
// )
// }
fmt.Println("Fetching latest release..")
releaseInfo, err := utils.GetLatestReleaseFromGitHub(config.AppConfig.PrivadoRepositoryName)
if releaseInfo.TagName == "" || releaseInfo.PublishedAt == "" || err != nil {
exit("Could not fetch latest release. Some error occurred", true)
}
// Version = "v0.1"
if semver.Compare(releaseInfo.TagName, Version) < 1 {
exit(fmt.Sprint("You are already using the latest version of Privado CLI: ", Version), false)
}

// timeSinceRelease := int(time.Since(publishedAtTime.Local()).Hours() / 24)

// fmt.Printf("New release found: %s (Released %d days ago)\n", releaseInfo.TagName, timeSinceRelease)
time.Sleep(config.AppConfig.SlowdownTime)

// create temporary directory for update assets
temporaryDirectory, err := ioutil.TempDir("", "privado-update-")
if err != nil {
exit("Could not create temporary download file. Terminating..", true)
}

// get download url
replacer := strings.NewReplacer(
"${REPO_NAME}", config.AppConfig.PrivadoRepositoryName,
"${REPO_TAG}", "latest",
"${REPO_RELEASE_FILE}", config.AppConfig.PrivadoRepositoryReleaseFilename,
)
githubReleaseDownloadURL := replacer.Replace(config.ExtConfig.GitHubReleaseDownloadURL)

// download to file
downloadedFilePath := filepath.Join(temporaryDirectory, config.AppConfig.PrivadoRepositoryReleaseFilename)
err = utils.DownloadToFile(githubReleaseDownloadURL, downloadedFilePath)
if err != nil {
exit(fmt.Sprint("Could not download release asset: ", githubReleaseDownloadURL), true)
}
fmt.Println("Downloaded release asset:", githubReleaseDownloadURL)
time.Sleep(config.AppConfig.SlowdownTime)

// extract .tar.gz
fmt.Println()
fmt.Println("Extracting release asset..")
err = utils.ExtractTarGzFile(downloadedFilePath, temporaryDirectory)
if err != nil {
exit(fmt.Sprint("Could not extract release asset: ", githubReleaseDownloadURL, err), true)
}

fmt.Println("Extracted release asset:", temporaryDirectory)
time.Sleep(config.AppConfig.SlowdownTime)

fmt.Println("githubReleaseFileURL", githubReleaseDownloadURL, temporaryDirectory)

printVersion := Version
if Version == "dev" {
printVersion = "Nightly"
}
fmt.Printf("Privado CLI: Version %s (%s-%s) \n", printVersion, runtime.GOOS, runtime.GOARCH)
fmt.Println("For more information, visit", config.AppConfig.PrivadoRepository)

file, _ := os.Executable()
fmt.Println(file)
final, _ := filepath.EvalSymlinks(file)
fmt.Println(final)

}

func init() {
rootCmd.AddCommand(updateCmd)
}

// update logic
// Check for latest version tag
// Get the latest tag
// Compare if new available
// Prompt user
// if yes: download binary for respective os & arch
// Get location of current binary
// for UNIX:
// Check if permissions available to replace the binary
// If yes, replace
// If not, prompt? or what? sudo ?? > Prompt with command
// for non-UNIX i.e. windows:
// not possible to replace files during runtime
// prompt command
15 changes: 15 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ func version(cmd *cobra.Command, args []string) {
func init() {
rootCmd.AddCommand(versionCmd)
}

// update logic
// Check for latest version tag
// Get the latest tag
// Compare if new available
// Prompt user
// if yes: download binary for respective os & arch
// Get location of current binary
// for UNIX:
// Check if permissions available to replace the binary
// If yes, replace
// If not, prompt? or what? sudo ?? > Prompt with command
// for non-UNIX i.e. windows:
// not possible to replace files during runtime
// prompt command
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ require (
github.com/docker/go-units v0.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/h2non/filetype v1.1.3 // indirect
github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/morikuni/aec v1.0.0 // indirect
Expand All @@ -36,7 +38,9 @@ require (
)

require (
github.com/codeclysm/extract v2.2.0+incompatible
github.com/docker/docker v20.10.12+incompatible
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.5.1
)
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codeclysm/extract v2.2.0+incompatible h1:q3wyckoA30bhUSiwdQezMqVhwd8+WGE64/GL//LtUhI=
github.com/codeclysm/extract v2.2.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
Expand Down Expand Up @@ -434,6 +436,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -490,6 +494,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9 h1:EJHbsNpQyupmMeWTq7inn+5L/WZ7JfzCVPJ+DP9McCQ=
github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9/go.mod h1:TRm7EVGA3mQOqSVcBySRY7a9Y1/gyVhh/WTCnc5sD4U=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
Expand Down Expand Up @@ -833,6 +839,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
55 changes: 40 additions & 15 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"time"

"github.com/mitchellh/go-homedir"
)

var AppConfig *Configuration
var ExtConfig *ExternalConfiguration

type Configuration struct {
HomeDirectory string
DefaultWebPort int
ConfigurationDirectory string
DefaultLicensePath string
PrivacyResultsPathSuffix string
PrivacyReportsDirectorySuffix string
PrivadoRepository string
Container *ContainerConfiguration
HomeDirectory string
DefaultWebPort int
ConfigurationDirectory string
DefaultLicensePath string
PrivacyResultsPathSuffix string
PrivacyReportsDirectorySuffix string
PrivadoRepository string
PrivadoRepositoryName string
PrivadoRepositoryReleaseFilename string
SlowdownTime time.Duration
Container *ContainerConfiguration
}

type ContainerConfiguration struct {
Expand All @@ -29,6 +35,13 @@ type ContainerConfiguration struct {
WebPort string
}

type ExternalConfiguration struct {
GitHubAPIHost string
GitHubReleasesEndpoint string
GitHubReleaseDownloadURL string
}

// init function for AppConfig
func init() {
home, _ := homedir.Dir()

Expand All @@ -44,13 +57,16 @@ func init() {
}

AppConfig = &Configuration{
HomeDirectory: home,
DefaultWebPort: 3000,
ConfigurationDirectory: filepath.Join(home, ".privado"),
DefaultLicensePath: filepath.Join(home, ".privado", licenseFileName),
PrivacyResultsPathSuffix: filepath.Join(".privado", "privacy.json"),
PrivacyReportsDirectorySuffix: filepath.Join(".privado", "reports"),
PrivadoRepository: "https://github.com/Privado-Inc/privado",
HomeDirectory: home,
DefaultWebPort: 3000,
ConfigurationDirectory: filepath.Join(home, ".privado"),
DefaultLicensePath: filepath.Join(home, ".privado", licenseFileName),
PrivacyResultsPathSuffix: filepath.Join(".privado", "privacy.json"),
PrivacyReportsDirectorySuffix: filepath.Join(".privado", "reports"),
PrivadoRepository: "https://github.com/Privado-Inc/privado",
PrivadoRepositoryName: "Privado-Inc/privado",
PrivadoRepositoryReleaseFilename: fmt.Sprintf("privado-%s-%s.tar.gz", runtime.GOOS, runtime.GOARCH),
SlowdownTime: 600 * time.Millisecond,
Container: &ContainerConfiguration{
ImageURL: fmt.Sprintf("public.ecr.aws/privado/cli:%s", imageTag),
SourceCodeVolumeDir: "/app/code",
Expand All @@ -59,3 +75,12 @@ func init() {
},
}
}

// init function for ExtConfig
func init() {
ExtConfig = &ExternalConfiguration{
GitHubAPIHost: "https://api.github.com",
GitHubReleasesEndpoint: "/repos/${REPO_NAME}/releases/latest",
GitHubReleaseDownloadURL: "https://github.com/${REPO_NAME}/releases/download/${REPO_TAG}/${REPO_RELEASE_FILE}",
}
}
97 changes: 97 additions & 0 deletions pkg/utils/update_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package utils

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strings"

"github.com/Privado-Inc/privado/pkg/config"
"github.com/codeclysm/extract"
"github.com/schollz/progressbar/v3"
)

type gitHubReleaseType struct {
TagName string `json:"tag_name"`
PublishedAt string `json:"published_at"`
}

func GetLatestReleaseFromGitHub(repoName string) (*gitHubReleaseType, error) {
endpoint := strings.Replace(config.ExtConfig.GitHubReleasesEndpoint, "${REPO_NAME}", config.AppConfig.PrivadoRepositoryName, 1)
url := fmt.Sprintf("%s%s", config.ExtConfig.GitHubAPIHost, endpoint)

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/vnd.github.v3+json")

defaultClient := &http.Client{}
response, err := defaultClient.Do(req)
if response.StatusCode != 200 || err != nil {
return nil, err
}

responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}

releaseResponse := gitHubReleaseType{}
err = json.Unmarshal(responseData, &releaseResponse)
if err != nil {
return nil, err
}

return &releaseResponse, nil
}

func DownloadToFile(downloadURL, filePath string) error {
req, err := http.NewRequest("GET", downloadURL, nil)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer file.Close()

bar := progressbar.DefaultBytes(
resp.ContentLength,
"Downloading..",
)

_, err = io.Copy(io.MultiWriter(file, bar), resp.Body)
if err != nil {
return err
}

return nil
}

func ExtractTarGzFile(sourceFile, target string) error {
ctx := context.Background()
data, err := ioutil.ReadFile(sourceFile)
if err != nil {
return err
}
buffer := bytes.NewBuffer(data)
err = extract.Gz(ctx, buffer, target, func(s string) string { return s })
if err != nil {
return err
}

return nil
}

0 comments on commit d5d7439

Please sign in to comment.