Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 75ac146

Browse files
committed
Init
0 parents  commit 75ac146

File tree

6 files changed

+283
-0
lines changed

6 files changed

+283
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea
2+
build

builder/main.go

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package main
2+
3+
import (
4+
"archive/tar"
5+
"compress/gzip"
6+
"github.com/tidwall/gjson"
7+
"io"
8+
"io/ioutil"
9+
"log"
10+
"net/http"
11+
"os"
12+
"path"
13+
"strconv"
14+
"time"
15+
)
16+
17+
const buildTempDir = "./build"
18+
const checkVersionUrl = "https://api.github.com/repos/ix64/unlock-music/releases/latest"
19+
const assetFilename = "modern.tar.gz"
20+
const checksumFilename = "sha256sum.txt"
21+
22+
func main() {
23+
if err := checkTempDirExist(); err != nil {
24+
log.Fatal(err)
25+
}
26+
log.Println("gathering version info: " + checkVersionUrl)
27+
v, err := getLatestVersionInfo()
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
for i := 0; i < 3; i++ {
32+
33+
if !v.checkAssetExist() {
34+
log.Printf("downloading %s to %s\n", v.AssetUrl, v.getAssetPath(""))
35+
if err := v.downloadAsset(); err != nil {
36+
log.Fatal(err)
37+
}
38+
}
39+
log.Printf("gathering checksum info: %s\n", v.ChecksumUrl)
40+
expect, err := v.downloadChecksum()
41+
if err != nil {
42+
log.Fatal(err)
43+
}
44+
log.Printf("checksum of %s should be: %s\n", assetFilename, expect)
45+
46+
actual, err := v.calcAssetChecksum()
47+
if err != nil {
48+
log.Fatal(err)
49+
}
50+
log.Printf("checksum of %s is: %s\n", assetFilename, actual)
51+
52+
if expect != actual {
53+
newFilename := v.getAssetPath("unexpected-" + strconv.FormatInt(time.Now().Unix(), 10) + "-")
54+
if err := os.Rename(v.getAssetPath(""), newFilename); err != nil {
55+
log.Fatal(err)
56+
}
57+
} else {
58+
if err := unArchive(v.getAssetPath(""), path.Join(buildTempDir, "for-build")); err != nil {
59+
log.Fatal(err)
60+
}
61+
return
62+
}
63+
}
64+
log.Fatal("failed for 3 times")
65+
}
66+
67+
func checkTempDirExist() error {
68+
_, err := os.Stat(buildTempDir)
69+
if os.IsNotExist(err) {
70+
err = os.Mkdir(buildTempDir, 0755)
71+
}
72+
return err
73+
}
74+
75+
func getLatestVersionInfo() (info *versionInfo, err error) {
76+
resp, err := http.Get(checkVersionUrl)
77+
if err != nil {
78+
return
79+
}
80+
defer resp.Body.Close()
81+
respBody, err := ioutil.ReadAll(resp.Body)
82+
if err != nil {
83+
return
84+
}
85+
asset := gjson.GetBytes(respBody, "assets.#(name="+assetFilename+")")
86+
checksum := gjson.GetBytes(respBody, "assets.#(name="+checksumFilename+")")
87+
return &versionInfo{
88+
Version: gjson.GetBytes(respBody, "tag_name").String(),
89+
ChecksumUrl: checksum.Get("browser_download_url").String(),
90+
AssetUrl: asset.Get("browser_download_url").String(),
91+
AssetSize: asset.Get("size").Int(),
92+
}, nil
93+
}
94+
func unArchive(source string, destination string) error {
95+
src, err := os.Open(source)
96+
if err != nil {
97+
return nil
98+
}
99+
defer src.Close()
100+
uncompressed, err := gzip.NewReader(src)
101+
if err != nil {
102+
return nil
103+
}
104+
arc := tar.NewReader(uncompressed)
105+
for {
106+
var f *tar.Header
107+
f, err = arc.Next()
108+
if err != nil {
109+
if err != io.EOF {
110+
return err
111+
}
112+
break
113+
}
114+
if f.FileInfo().IsDir() {
115+
err = os.MkdirAll(path.Join(destination, f.Name), 0755)
116+
if err != nil {
117+
return err
118+
}
119+
} else {
120+
dst, err := os.OpenFile(path.Join(destination, f.Name), os.O_WRONLY|os.O_CREATE, 0644)
121+
if err != nil {
122+
return err
123+
}
124+
_, err = io.CopyN(dst, arc, f.Size)
125+
dst.Close()
126+
if err != nil {
127+
return err
128+
}
129+
}
130+
}
131+
return nil
132+
}

builder/version.go

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"crypto/sha256"
6+
"encoding/hex"
7+
"fmt"
8+
"io"
9+
"net/http"
10+
"os"
11+
"path"
12+
"strings"
13+
)
14+
15+
type versionInfo struct {
16+
Version string
17+
ChecksumUrl string
18+
AssetUrl string
19+
AssetSize int64
20+
}
21+
22+
func (v versionInfo) getAssetPath(prefix string) string {
23+
return path.Join(buildTempDir, prefix+v.Version+"_"+assetFilename)
24+
}
25+
26+
func (v versionInfo) checkAssetExist() bool {
27+
_, err := os.Stat(v.getAssetPath(""))
28+
return !os.IsNotExist(err)
29+
}
30+
31+
func (v versionInfo) downloadAsset() (err error) {
32+
file, err := os.OpenFile(v.getAssetPath(""), os.O_WRONLY|os.O_CREATE, 0644)
33+
if err != nil {
34+
return
35+
}
36+
defer file.Close()
37+
38+
resp, err := http.Get(v.AssetUrl)
39+
if err != nil {
40+
return
41+
}
42+
defer resp.Body.Close()
43+
_, err = io.Copy(file, resp.Body)
44+
return err
45+
}
46+
47+
func (v versionInfo) downloadChecksum() (checksum string, err error) {
48+
resp, err := http.Get(v.ChecksumUrl)
49+
if err != nil {
50+
return
51+
}
52+
defer resp.Body.Close()
53+
r := bufio.NewReader(resp.Body)
54+
var line []byte
55+
for err == nil {
56+
line, _, err = r.ReadLine()
57+
lineStr := string(line)
58+
if strings.Contains(lineStr, assetFilename) {
59+
checksum = strings.ToLower(strings.TrimSpace(strings.Split(lineStr, " ")[0]))
60+
return
61+
}
62+
}
63+
return "", fmt.Errorf("checksum for %s not found", assetFilename)
64+
}
65+
66+
func (v versionInfo) calcAssetChecksum() (checksum string, err error) {
67+
file, err := os.Open(v.getAssetPath(""))
68+
if err != nil {
69+
return
70+
}
71+
defer file.Close()
72+
sha := sha256.New()
73+
_, err = io.Copy(sha, file)
74+
if err != nil {
75+
return
76+
}
77+
checksum = hex.EncodeToString(sha.Sum(nil))
78+
return
79+
}

go.mod

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module github.com/unlock-music/simple-server
2+
3+
go 1.16
4+
5+
require (
6+
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
7+
github.com/tidwall/gjson v1.6.3
8+
github.com/tidwall/match v1.0.2 // indirect
9+
)

go.sum

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
2+
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
3+
github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI=
4+
github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
5+
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
6+
github.com/tidwall/match v1.0.2 h1:uuqvHuBGSedK7awZ2YoAtpnimfwBGFjHuWLuLqQj+bU=
7+
github.com/tidwall/match v1.0.2/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
8+
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
9+
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=

main.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"embed"
5+
_ "embed"
6+
"github.com/pkg/browser"
7+
"io/fs"
8+
"log"
9+
"net/http"
10+
"os"
11+
"os/signal"
12+
"path"
13+
)
14+
15+
//go:generate go run ./builder
16+
//go:embed build/for-build
17+
var asset embed.FS
18+
19+
func main() {
20+
pfxFs := WithPrefix(asset, "build/for-build")
21+
go func() {
22+
err := http.ListenAndServe("localhost:6280", http.FileServer(http.FS(pfxFs)))
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
}()
27+
log.Println("you can now open browser with: http://localhost:6280 to access this tool.")
28+
err := browser.OpenURL("http://localhost:6280")
29+
if err != nil {
30+
log.Println("error while opening browser:", err)
31+
}
32+
sign := make(chan os.Signal, 1)
33+
signal.Notify(sign, os.Interrupt, os.Kill)
34+
<-sign
35+
}
36+
37+
type WrappedFS struct {
38+
inner fs.FS
39+
prefix string
40+
}
41+
42+
func (f WrappedFS) Open(p string) (fs.File, error) {
43+
p = path.Join(f.prefix, p)
44+
log.Printf("serving: %s\n", p)
45+
return f.inner.Open(p)
46+
}
47+
48+
// same thing but for ReadFile, Stat, ReadDir, Glob, and maybe Rename, OpenFile?
49+
50+
func WithPrefix(f fs.FS, p string) WrappedFS {
51+
return WrappedFS{f, p}
52+
}

0 commit comments

Comments
 (0)