From f9e8c550d1289486858548e6f893db16b9fdd7cb Mon Sep 17 00:00:00 2001 From: Taleh Didover Date: Wed, 8 Aug 2018 18:51:50 +0200 Subject: [PATCH] Download examples when slang dir is empty --- cmd/slangd/main.go | 16 +++- pkg/daemon/component_loader.go | 157 ++++++++++++++++++++------------- pkg/daemon/utils.go | 9 ++ 3 files changed, 116 insertions(+), 66 deletions(-) diff --git a/cmd/slangd/main.go b/cmd/slangd/main.go index 2146ef40..3221e8d1 100644 --- a/cmd/slangd/main.go +++ b/cmd/slangd/main.go @@ -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 @@ -69,7 +70,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() @@ -85,10 +86,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) { diff --git a/pkg/daemon/component_loader.go b/pkg/daemon/component_loader.go index 7275a322..c5702051 100644 --- a/pkg/daemon/component_loader.go +++ b/pkg/daemon/component_loader.go @@ -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 { @@ -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 } @@ -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 } @@ -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 { @@ -105,30 +98,40 @@ 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 { @@ -136,7 +139,7 @@ func (dl *SlangComponentLoader) replaceDirContentBy(newDirPath string) error { return err } - _, err := os.Stat(dl.path); + _, err := os.Stat(dl.path) if !(err == nil || os.IsNotExist(err)) { return err } @@ -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))) +} diff --git a/pkg/daemon/utils.go b/pkg/daemon/utils.go index eca7da97..ef00c64f 100644 --- a/pkg/daemon/utils.go +++ b/pkg/daemon/utils.go @@ -3,6 +3,7 @@ package daemon import ( "archive/zip" "io" + "io/ioutil" "net/http" "os" "path/filepath" @@ -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