Skip to content

Commit

Permalink
Merge pull request #158 from Bitspark/autodownload-examples
Browse files Browse the repository at this point in the history
Download examples when slang dir is empty
  • Loading branch information
jm9e authored Aug 8, 2018
2 parents cb5c9ef + f9e8c55 commit dfd2483
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 66 deletions.
16 changes: 13 additions & 3 deletions cmd/slangd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"path/filepath"
"time"

"strconv"

"github.com/Bitspark/browser"
"github.com/Bitspark/slang/pkg/daemon"
"strconv"
)

const PORT = 5149 // sla[n]g == 5149
Expand Down Expand Up @@ -73,7 +74,7 @@ func initEnvironPaths() (*EnvironPaths) {

func (e *EnvironPaths) loadLocalComponents() {
for repoName, dirPath := range map[string]string{"slang-lib": e.SLANG_LIB, "slang-ui": e.SLANG_UI} {
dl := daemon.NewComponentLoader(repoName, dirPath)
dl := daemon.NewComponentLoaderLatestRelease(repoName, dirPath)
if dl.NewerVersionExists() {
localVer := dl.GetLocalReleaseVersion()
latestVer := dl.GetLatestReleaseVersion()
Expand All @@ -89,10 +90,19 @@ func (e *EnvironPaths) loadLocalComponents() {
} else {
localVer := dl.GetLocalReleaseVersion()
log.Printf("Your local %v is up-to-date (%v).", repoName, localVer.String())

}
}

// Load slang examples only when slang is started the first time
if daemon.IsDirEmpty(e.SLANG_DIR) {
dl := daemon.NewComponentLoaderLatestMaster("slang-examples", e.SLANG_DIR)
log.Println("Downloading example operators.")
if err := dl.Load(); err != nil {
log.Fatal(err)
}
log.Printf("Done.")
}

}

func (e *EnvironPaths) loadDaemonServices(srv *daemon.Server) {
Expand Down
157 changes: 94 additions & 63 deletions pkg/daemon/component_loader.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package daemon

import (
"github.com/Bitspark/go-github/github"
"github.com/Bitspark/go-version"
"bufio"
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"bufio"
"strings"

"github.com/Bitspark/go-github/github"
"github.com/Bitspark/go-version"
)

type SlangComponentLoader struct {
Expand All @@ -18,19 +19,33 @@ type SlangComponentLoader struct {
owner string
repo string
path string
latest string
versionFilePath string
}

func NewComponentLoader(repo string, path string) *SlangComponentLoader {
func NewComponentLoaderLatestRelease(repo string, path string) *SlangComponentLoader {
return newComponentLoader(repo, path, "release")

}

func NewComponentLoaderLatestMaster(repo string, path string) *SlangComponentLoader {
return newComponentLoader(repo, path, "master")

}

func newComponentLoader(repo string, path string, latest string) *SlangComponentLoader {
dl := &SlangComponentLoader{
github.NewClient(nil),
nil,
"Bitspark",
repo,
path,
latest,
filepath.Join(path, ".VERSION"),
}
dl.fetchLatestRelease()
if latest == "release" {
dl.fetchLatestRelease()
}
return dl
}

Expand All @@ -43,25 +58,27 @@ func (dl *SlangComponentLoader) NewerVersionExists() bool {
* Downloads & unpacks latest version of a component.
*/
func (dl *SlangComponentLoader) Load() error {
release := dl.latestRelease

if len(release.Assets) == 0 {
return fmt.Errorf("release '%v' needs at least 1 asset which can be downloaded", release.Name)
}

asset := release.Assets[0]

compDir, err := dl.downloadArchive(*asset.BrowserDownloadURL)
if err != nil {
return err
}
if err = dl.replaceDirContentBy(compDir); err != nil {
return err
if dl.latest == "release" {
release := dl.latestRelease

if len(release.Assets) == 0 {
return fmt.Errorf("release '%v' needs at least 1 asset which can be downloaded", release.Name)
}

asset := release.Assets[0]
if err := dl.downloadArchiveAndUnpack(*asset.BrowserDownloadURL); err != nil {
return err
}
if err := dl.updateLocalVersionFile(); err != nil {
return err
}
} else {
// Just download project as archive from master
archiveURL := dl.getLatestArchiveURL()
if err := dl.downloadArchiveAndUnpack(archiveURL); err != nil {
return err
}
}
if err = dl.updateLocalVersionFile(); err != nil {
return err
}

return nil
}

Expand All @@ -71,32 +88,8 @@ func (dl *SlangComponentLoader) fetchLatestRelease() error {
return err
}

func (dl *SlangComponentLoader) GetLatestReleaseVersion() *version.Version {
return toVersion(*dl.latestRelease.TagName)
}

func (dl *SlangComponentLoader) GetLocalReleaseVersion() *version.Version {
_, err := os.Stat(dl.path)

if os.IsNotExist(err) {
return nil
}

versionFile, err := os.Open(dl.versionFilePath)
defer versionFile.Close()

if err != nil {
return nil
}

versionReader := bufio.NewReader(versionFile)
currVersion, _, err := versionReader.ReadLine()

if err != nil {
return nil
}

return toVersion(strings.TrimSpace(string(currVersion)))
func (dl *SlangComponentLoader) getLatestArchiveURL() string {
return fmt.Sprintf("https://api.github.com/repos/%v/%v/zipball/master", dl.owner, dl.repo)
}

func (dl *SlangComponentLoader) updateLocalVersionFile() error {
Expand All @@ -105,38 +98,48 @@ func (dl *SlangComponentLoader) updateLocalVersionFile() error {
return err
}

func (dl *SlangComponentLoader) downloadArchive(url string) (string, error) {
// Download archive file
tmpArchiveFile, err := ioutil.TempFile("", "")
func (dl *SlangComponentLoader) downloadArchiveAndUnpack(archiveURL string) error {
archiveFilePath, err := dl.download(archiveURL)
// Unpack archive into directory
tmpDstDir, err := ioutil.TempDir("", dl.repo)
if err != nil {
return "", err
return err
}
defer os.Remove(tmpArchiveFile.Name())
if _, err := unzip(archiveFilePath, tmpDstDir); err != nil {
return err
}
defer os.Remove(archiveFilePath)
defer os.RemoveAll(tmpDstDir)

if err := download(url, tmpArchiveFile); err != nil {
return "", err
if err != nil {
return err
}
tmpArchiveFile.Close()
if err = dl.replaceDirContentBy(tmpDstDir); err != nil {
return err
}
return nil
}

// Unpack archive into directory
tmpDstDir, err := ioutil.TempDir("", dl.repo)
func (dl *SlangComponentLoader) download(url string) (string, error) {
// Download archive file
tmpDstFile, err := ioutil.TempFile("", "")
if err != nil {
return "", err
}
defer tmpDstFile.Close()

if _, err := unzip(tmpArchiveFile.Name(), tmpDstDir); err != nil {
if err := download(url, tmpDstFile); err != nil {
return "", err
}

return tmpDstDir, nil
return tmpDstFile.Name(), nil
}

func (dl *SlangComponentLoader) replaceDirContentBy(newDirPath string) error {
if _, err := os.Stat(newDirPath); err != nil {
return err
}

_, err := os.Stat(dl.path);
_, err := os.Stat(dl.path)
if !(err == nil || os.IsNotExist(err)) {
return err
}
Expand All @@ -155,3 +158,31 @@ func (dl *SlangComponentLoader) replaceDirContentBy(newDirPath string) error {

return err
}

func (dl *SlangComponentLoader) GetLatestReleaseVersion() *version.Version {
return toVersion(*dl.latestRelease.TagName)
}

func (dl *SlangComponentLoader) GetLocalReleaseVersion() *version.Version {
_, err := os.Stat(dl.path)

if os.IsNotExist(err) {
return nil
}

versionFile, err := os.Open(dl.versionFilePath)
defer versionFile.Close()

if err != nil {
return nil
}

versionReader := bufio.NewReader(versionFile)
currVersion, _, err := versionReader.ReadLine()

if err != nil {
return nil
}

return toVersion(strings.TrimSpace(string(currVersion)))
}
9 changes: 9 additions & 0 deletions pkg/daemon/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package daemon
import (
"archive/zip"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
Expand All @@ -13,6 +14,14 @@ import (
"github.com/Bitspark/go-version"
)

func IsDirEmpty(dir string) bool {
entries, err := ioutil.ReadDir(dir)
if err != nil {
return false
}
return len(entries) == 0
}

func EnsureDirExists(dir string) (string, error) {
err := os.MkdirAll(dir, os.ModePerm)
return dir, err
Expand Down

0 comments on commit dfd2483

Please sign in to comment.