mirror of
https://github.com/livekit/livekit.git
synced 2026-08-26 02:49:49 +00:00
move to mage for build
This commit is contained in:
@@ -8,6 +8,10 @@
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# checksums of file modification time
|
||||
.checksumgo
|
||||
proto/.checksumproto
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
livekit-server
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
|
||||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
|
||||
ifeq (,$(shell go env GOBIN))
|
||||
GOBIN=$(shell go env GOPATH)/bin
|
||||
else
|
||||
GOBIN=$(shell go env GOBIN)
|
||||
endif
|
||||
|
||||
|
||||
build: server client
|
||||
|
||||
client: generate
|
||||
@{ \
|
||||
echo "building client" ;\
|
||||
mkdir -p bin ;\
|
||||
cd cmd/cli ;\
|
||||
go build -i -o ../../bin/livekit-cli ;\
|
||||
}
|
||||
|
||||
server: generate
|
||||
@{ \
|
||||
echo "building server" ;\
|
||||
mkdir -p bin ;\
|
||||
cd cmd/server ;\
|
||||
go build -i -o ../../bin/livekit-server ;\
|
||||
}
|
||||
|
||||
generate: wire mockgen
|
||||
@{ \
|
||||
echo "wiring" ;\
|
||||
cd cmd/server ;\
|
||||
$(WIRE) ;\
|
||||
cd ../.. ;\
|
||||
echo "updating mocks" ;\
|
||||
$(MOCKGEN) -source pkg/rtc/interfaces.go -destination pkg/rtc/mock_test.go -package rtc ;\
|
||||
}
|
||||
|
||||
test: generate
|
||||
go test ./...
|
||||
|
||||
GO_TARGET=proto/livekit
|
||||
proto: protoc protoc-gen-go twirp-gen
|
||||
@{ \
|
||||
mkdir -p $(GO_TARGET) ;\
|
||||
protoc --go_out=$(GO_TARGET) --twirp_out=$(GO_TARGET) \
|
||||
--go_opt=paths=source_relative \
|
||||
--twirp_opt=paths=source_relative \
|
||||
--plugin=$(PROTOC_GEN_GO) \
|
||||
-I=proto \
|
||||
proto/room.proto proto/model.proto ;\
|
||||
protoc --go_out=$(GO_TARGET) \
|
||||
--go_opt=paths=source_relative \
|
||||
-I=proto \
|
||||
proto/rtc.proto ;\
|
||||
}
|
||||
|
||||
protoc:
|
||||
ifeq (, $(shell which protoc))
|
||||
echo "protoc is required, and is not installed"
|
||||
endif
|
||||
|
||||
protoc-gen-go:
|
||||
ifeq (, $(shell which protoc-gen-go))
|
||||
@{ \
|
||||
echo "installing go protobuf plugin" ;\
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go ;\
|
||||
}
|
||||
endif
|
||||
|
||||
twirp-gen:
|
||||
ifeq (, $(shell which protoc-gen-twirp))
|
||||
@{ \
|
||||
echo "installing twirp protobuf plugin" ;\
|
||||
go install github.com/twitchtv/twirp/protoc-gen-twirp ;\
|
||||
}
|
||||
endif
|
||||
|
||||
wire:
|
||||
ifeq (, $(shell which wire))
|
||||
@{ \
|
||||
echo "installing wire" ;\
|
||||
go install github.com/google/wire/cmd/wire ;\
|
||||
}
|
||||
WIRE=$(GOBIN)/wire
|
||||
else
|
||||
WIRE=$(shell which wire)
|
||||
endif
|
||||
|
||||
mockgen:
|
||||
ifeq (, $(shell which mockgen))
|
||||
@{ \
|
||||
echo "installing mockgen" ;\
|
||||
go get github.com/golang/mock/mockgen ;\
|
||||
}
|
||||
MOCKGEN=$(GOBIN)/mockgen
|
||||
else
|
||||
MOCKGEN=$(shell which mockgen)
|
||||
endif
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Ensure Go 1.14+ is installed, and GOPATH/bin is in your PATH.
|
||||
|
||||
Run `make proto && make
|
||||
Run `./bootstrap` to install mage, then `mage` to build the project
|
||||
|
||||
## CLI
|
||||
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /tmp
|
||||
git clone https://github.com/magefile/mage
|
||||
cd mage
|
||||
go run bootstrap.go
|
||||
rm -rf mage
|
||||
|
||||
if ! command -v mage &> /dev/null
|
||||
then
|
||||
echo "Ensure ${GOPATH}/bin is in your \$PATH"
|
||||
fi
|
||||
@@ -5,11 +5,13 @@ go 1.15
|
||||
require (
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/google/subcommands v1.2.0 // indirect
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/google/wire v0.4.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/lithammer/shortuuid/v3 v3.0.4
|
||||
github.com/lunixbochs/vtclean v1.0.0 // indirect
|
||||
github.com/magefile/mage v1.10.0
|
||||
github.com/magiconair/properties v1.8.1
|
||||
github.com/manifoldco/promptui v0.8.0
|
||||
github.com/pion/interceptor v0.0.5
|
||||
@@ -26,7 +28,8 @@ require (
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
github.com/urfave/negroni v1.0.0
|
||||
go.uber.org/zap v1.16.0
|
||||
golang.org/x/tools v0.0.0-20200815165600-90abf76919f3 // indirect
|
||||
golang.org/x/mod v0.4.0 // indirect
|
||||
golang.org/x/tools v0.0.0-20201222163215-f2e330f49058 // indirect
|
||||
google.golang.org/protobuf v1.25.0
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
||||
@@ -143,7 +143,10 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
@@ -225,6 +228,8 @@ github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQN
|
||||
github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
|
||||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
|
||||
@@ -430,6 +435,7 @@ github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
@@ -486,6 +492,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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=
|
||||
@@ -509,6 +517,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7 h1:3uJsdck53FDIpWwLeAXlia9p4C8j0BO2xZrqzKpL0D8=
|
||||
@@ -526,6 +535,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -598,6 +608,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200815165600-90abf76919f3 h1:0aScV/0rLmANzEYIhjCOi2pTvDyhZNduBUMD2q3iqs4=
|
||||
golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201222163215-f2e330f49058 h1:zSPRinxiz6krIAZie/STjID5lW/bkAvl+xz2cquNQEA=
|
||||
golang.org/x/tools v0.0.0-20201222163215-f2e330f49058/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
// +build mage
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/magefile/mage/mg"
|
||||
log "github.com/pion/ion-log"
|
||||
)
|
||||
|
||||
const (
|
||||
protoChecksumFile = ".checksumproto"
|
||||
goChecksumFile = ".checksumgo"
|
||||
)
|
||||
|
||||
// Default target to run when none is specified
|
||||
// If not set, running mage will list available targets
|
||||
var Default = Build
|
||||
var checksummer = NewChecksummer(".", goChecksumFile, ".go")
|
||||
|
||||
func init() {
|
||||
checksummer.IgnoredFiles = []string{
|
||||
"cmd/server/wire_gen.go",
|
||||
"pkg/rtc/mock_test.go",
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly reinstall all deps
|
||||
func Deps() error {
|
||||
return installTools(true)
|
||||
}
|
||||
|
||||
// regenerate protobuf
|
||||
func Proto() error {
|
||||
protoChecksummer := NewChecksummer("proto", protoChecksumFile, ".proto")
|
||||
if !protoChecksummer.IsChanged() {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("generating protobuf")
|
||||
target := "proto/livekit"
|
||||
if err := os.MkdirAll(target, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protoc, err := getToolPath("protoc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protoc_go_path, err := getToolPath("protoc-gen-go")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
twirp_path, err := getToolPath("protoc-gen-twirp")
|
||||
|
||||
// generate model and room
|
||||
cmd := exec.Command(protoc,
|
||||
"--go_out", target,
|
||||
"--twirp_out", target,
|
||||
"--go_opt=paths=source_relative",
|
||||
"--twirp_opt=paths=source_relative",
|
||||
"--plugin=go="+protoc_go_path,
|
||||
"--plugin=twirp="+twirp_path,
|
||||
"-I=proto",
|
||||
"proto/room.proto",
|
||||
"proto/model.proto",
|
||||
)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// generate rtc
|
||||
cmd = exec.Command(protoc,
|
||||
"--go_out", target,
|
||||
"--go_opt=paths=source_relative",
|
||||
"--plugin=go="+protoc_go_path,
|
||||
"-I=proto",
|
||||
"proto/rtc.proto",
|
||||
)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protoChecksummer.WriteChecksum()
|
||||
return nil
|
||||
}
|
||||
|
||||
// builds LiveKit server and cli
|
||||
func Build() error {
|
||||
mg.Deps(Proto, generate)
|
||||
if !checksummer.IsChanged() {
|
||||
fmt.Println("up to date")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("building...")
|
||||
if err := os.MkdirAll("bin", 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command("go", "build", "-i", "-o", "../../bin/livekit-server")
|
||||
cmd.Dir = "cmd/server"
|
||||
connectStd(cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command("go", "build", "-i", "-o", "../../bin/livekit-cli")
|
||||
cmd.Dir = "cmd/cli"
|
||||
connectStd(cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
checksummer.WriteChecksum()
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleans up builds
|
||||
func Clean() {
|
||||
fmt.Println("cleaning...")
|
||||
os.RemoveAll("bin")
|
||||
os.Remove(protoChecksumFile)
|
||||
os.Remove(goChecksumFile)
|
||||
}
|
||||
|
||||
// code generation
|
||||
func generate() error {
|
||||
mg.Deps(installDeps)
|
||||
if !checksummer.IsChanged() {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("wiring...")
|
||||
wire, err := getToolPath("wire")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(wire)
|
||||
cmd.Dir = "cmd/server"
|
||||
connectStd(cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//cmd = exec.Command(wire)
|
||||
//cmd.Dir = "cmd/cli"
|
||||
//connectStd(cmd)
|
||||
//if err := cmd.Run(); err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
fmt.Println("updating mocks...")
|
||||
mockgen, err := getToolPath("mockgen")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command(mockgen, "-source", "pkg/rtc/interfaces.go", "-destination", "pkg/rtc/mock_test.go", "-package", "rtc")
|
||||
connectStd(cmd)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// implicitly install deps
|
||||
func installDeps() error {
|
||||
return installTools(false)
|
||||
}
|
||||
|
||||
func installTools(force bool) error {
|
||||
if _, err := getToolPath("protoc"); err != nil {
|
||||
return fmt.Errorf("protoc is required but is not found")
|
||||
}
|
||||
|
||||
tools := []string{
|
||||
"google.golang.org/protobuf/cmd/protoc-gen-go",
|
||||
"github.com/twitchtv/twirp/protoc-gen-twirp",
|
||||
"github.com/google/wire/cmd/wire",
|
||||
"github.com/golang/mock/mockgen",
|
||||
}
|
||||
for _, t := range tools {
|
||||
if err := installTool(t, force); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func installTool(url string, force bool) error {
|
||||
name := filepath.Base(url)
|
||||
if !force {
|
||||
_, err := getToolPath(name)
|
||||
if err == nil {
|
||||
// already installed
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("installing %s\n", name)
|
||||
cmd := exec.Command("go", "get", "-u", url)
|
||||
connectStd(cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check
|
||||
_, err := getToolPath(name)
|
||||
return err
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
func getToolPath(name string) (string, error) {
|
||||
if p, err := exec.LookPath(name); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
// check under gopath
|
||||
gopath := os.Getenv("GOPATH")
|
||||
if gopath == "" {
|
||||
gopath = build.Default.GOPATH
|
||||
}
|
||||
p := filepath.Join(gopath, "bin", name)
|
||||
if _, err := os.Stat(p); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func connectStd(cmd *exec.Cmd) {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
}
|
||||
|
||||
// A helper checksum library that generates a fast, non-portable checksum over a directory of files
|
||||
// it's designed as a quick way to bypass
|
||||
type Checksummer struct {
|
||||
dir string
|
||||
file string
|
||||
checksum string
|
||||
allExts bool
|
||||
extMap map[string]bool
|
||||
IgnoredFiles []string
|
||||
}
|
||||
|
||||
func NewChecksummer(dir string, checksumfile string, exts ...string) *Checksummer {
|
||||
c := &Checksummer{
|
||||
dir: dir,
|
||||
file: checksumfile,
|
||||
extMap: make(map[string]bool),
|
||||
}
|
||||
if len(exts) == 0 {
|
||||
c.allExts = true
|
||||
} else {
|
||||
for _, ext := range exts {
|
||||
c.extMap[ext] = true
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Checksummer) IsChanged() bool {
|
||||
// default changed
|
||||
if err := c.computeChecksum(); err != nil {
|
||||
log.Errorf("could not compute checksum: %v", err)
|
||||
return true
|
||||
}
|
||||
// read
|
||||
existing, err := c.ReadChecksum()
|
||||
if err != nil {
|
||||
// may not be there
|
||||
return true
|
||||
}
|
||||
|
||||
return existing != c.checksum
|
||||
}
|
||||
|
||||
func (c *Checksummer) ReadChecksum() (string, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join(c.dir, c.file))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func (c *Checksummer) WriteChecksum() error {
|
||||
if err := c.computeChecksum(); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(filepath.Join(c.dir, c.file), []byte(c.checksum), 0644)
|
||||
}
|
||||
|
||||
func (c *Checksummer) computeChecksum() error {
|
||||
if c.checksum != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
entries := make([]string, 0)
|
||||
ignoredMap := make(map[string]bool)
|
||||
for _, f := range c.IgnoredFiles {
|
||||
ignoredMap[f] = true
|
||||
}
|
||||
err := filepath.Walk(c.dir, func(path string, info os.FileInfo, err error) error {
|
||||
if path == c.dir {
|
||||
return nil
|
||||
}
|
||||
if strings.HasPrefix(info.Name(), ".") {
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if info.IsDir() {
|
||||
entries = append(entries, fmt.Sprintf("%s %s", path, info.ModTime().String()))
|
||||
} else if !ignoredMap[path] && (c.allExts || c.extMap[filepath.Ext(info.Name())]) {
|
||||
entries = append(entries, fmt.Sprintf("%s %d %d", path, info.Size(), info.ModTime().Unix()))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.Strings(entries)
|
||||
|
||||
h := sha1.New()
|
||||
for _, e := range entries {
|
||||
h.Write([]byte(e))
|
||||
}
|
||||
c.checksum = fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -59,3 +59,10 @@ message TrackInfo {
|
||||
Type type = 2;
|
||||
string name = 3;
|
||||
}
|
||||
|
||||
message DataMessage {
|
||||
oneof value {
|
||||
string text = 1;
|
||||
bytes binary = 2;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user