Init
This commit is contained in:
commit
75ac1466c7
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.idea
|
||||||
|
build
|
132
builder/main.go
Normal file
132
builder/main.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"compress/gzip"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const buildTempDir = "./build"
|
||||||
|
const checkVersionUrl = "https://api.github.com/repos/ix64/unlock-music/releases/latest"
|
||||||
|
const assetFilename = "modern.tar.gz"
|
||||||
|
const checksumFilename = "sha256sum.txt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := checkTempDirExist(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Println("gathering version info: " + checkVersionUrl)
|
||||||
|
v, err := getLatestVersionInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
|
||||||
|
if !v.checkAssetExist() {
|
||||||
|
log.Printf("downloading %s to %s\n", v.AssetUrl, v.getAssetPath(""))
|
||||||
|
if err := v.downloadAsset(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("gathering checksum info: %s\n", v.ChecksumUrl)
|
||||||
|
expect, err := v.downloadChecksum()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Printf("checksum of %s should be: %s\n", assetFilename, expect)
|
||||||
|
|
||||||
|
actual, err := v.calcAssetChecksum()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Printf("checksum of %s is: %s\n", assetFilename, actual)
|
||||||
|
|
||||||
|
if expect != actual {
|
||||||
|
newFilename := v.getAssetPath("unexpected-" + strconv.FormatInt(time.Now().Unix(), 10) + "-")
|
||||||
|
if err := os.Rename(v.getAssetPath(""), newFilename); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := unArchive(v.getAssetPath(""), path.Join(buildTempDir, "for-build")); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Fatal("failed for 3 times")
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkTempDirExist() error {
|
||||||
|
_, err := os.Stat(buildTempDir)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(buildTempDir, 0755)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLatestVersionInfo() (info *versionInfo, err error) {
|
||||||
|
resp, err := http.Get(checkVersionUrl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
respBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asset := gjson.GetBytes(respBody, "assets.#(name="+assetFilename+")")
|
||||||
|
checksum := gjson.GetBytes(respBody, "assets.#(name="+checksumFilename+")")
|
||||||
|
return &versionInfo{
|
||||||
|
Version: gjson.GetBytes(respBody, "tag_name").String(),
|
||||||
|
ChecksumUrl: checksum.Get("browser_download_url").String(),
|
||||||
|
AssetUrl: asset.Get("browser_download_url").String(),
|
||||||
|
AssetSize: asset.Get("size").Int(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
func unArchive(source string, destination string) error {
|
||||||
|
src, err := os.Open(source)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
uncompressed, err := gzip.NewReader(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
arc := tar.NewReader(uncompressed)
|
||||||
|
for {
|
||||||
|
var f *tar.Header
|
||||||
|
f, err = arc.Next()
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if f.FileInfo().IsDir() {
|
||||||
|
err = os.MkdirAll(path.Join(destination, f.Name), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dst, err := os.OpenFile(path.Join(destination, f.Name), os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.CopyN(dst, arc, f.Size)
|
||||||
|
dst.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
79
builder/version.go
Normal file
79
builder/version.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type versionInfo struct {
|
||||||
|
Version string
|
||||||
|
ChecksumUrl string
|
||||||
|
AssetUrl string
|
||||||
|
AssetSize int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v versionInfo) getAssetPath(prefix string) string {
|
||||||
|
return path.Join(buildTempDir, prefix+v.Version+"_"+assetFilename)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v versionInfo) checkAssetExist() bool {
|
||||||
|
_, err := os.Stat(v.getAssetPath(""))
|
||||||
|
return !os.IsNotExist(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v versionInfo) downloadAsset() (err error) {
|
||||||
|
file, err := os.OpenFile(v.getAssetPath(""), os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
resp, err := http.Get(v.AssetUrl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
_, err = io.Copy(file, resp.Body)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v versionInfo) downloadChecksum() (checksum string, err error) {
|
||||||
|
resp, err := http.Get(v.ChecksumUrl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
r := bufio.NewReader(resp.Body)
|
||||||
|
var line []byte
|
||||||
|
for err == nil {
|
||||||
|
line, _, err = r.ReadLine()
|
||||||
|
lineStr := string(line)
|
||||||
|
if strings.Contains(lineStr, assetFilename) {
|
||||||
|
checksum = strings.ToLower(strings.TrimSpace(strings.Split(lineStr, " ")[0]))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("checksum for %s not found", assetFilename)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v versionInfo) calcAssetChecksum() (checksum string, err error) {
|
||||||
|
file, err := os.Open(v.getAssetPath(""))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
sha := sha256.New()
|
||||||
|
_, err = io.Copy(sha, file)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checksum = hex.EncodeToString(sha.Sum(nil))
|
||||||
|
return
|
||||||
|
}
|
9
go.mod
Normal file
9
go.mod
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module github.com/unlock-music/simple-server
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
||||||
|
github.com/tidwall/gjson v1.6.3
|
||||||
|
github.com/tidwall/match v1.0.2 // indirect
|
||||||
|
)
|
9
go.sum
Normal file
9
go.sum
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
||||||
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||||
|
github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI=
|
||||||
|
github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
|
||||||
|
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||||
|
github.com/tidwall/match v1.0.2 h1:uuqvHuBGSedK7awZ2YoAtpnimfwBGFjHuWLuLqQj+bU=
|
||||||
|
github.com/tidwall/match v1.0.2/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||||
|
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||||
|
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
52
main.go
Normal file
52
main.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
_ "embed"
|
||||||
|
"github.com/pkg/browser"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run ./builder
|
||||||
|
//go:embed build/for-build
|
||||||
|
var asset embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pfxFs := WithPrefix(asset, "build/for-build")
|
||||||
|
go func() {
|
||||||
|
err := http.ListenAndServe("localhost:6280", http.FileServer(http.FS(pfxFs)))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Println("you can now open browser with: http://localhost:6280 to access this tool.")
|
||||||
|
err := browser.OpenURL("http://localhost:6280")
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error while opening browser:", err)
|
||||||
|
}
|
||||||
|
sign := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sign, os.Interrupt, os.Kill)
|
||||||
|
<-sign
|
||||||
|
}
|
||||||
|
|
||||||
|
type WrappedFS struct {
|
||||||
|
inner fs.FS
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f WrappedFS) Open(p string) (fs.File, error) {
|
||||||
|
p = path.Join(f.prefix, p)
|
||||||
|
log.Printf("serving: %s\n", p)
|
||||||
|
return f.inner.Open(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// same thing but for ReadFile, Stat, ReadDir, Glob, and maybe Rename, OpenFile?
|
||||||
|
|
||||||
|
func WithPrefix(f fs.FS, p string) WrappedFS {
|
||||||
|
return WrappedFS{f, p}
|
||||||
|
}
|
Reference in New Issue
Block a user