initial commit
This commit is contained in:
commit
97a3c7ab71
11
ansi_seq.go
Normal file
11
ansi_seq.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "os"
|
||||
|
||||
func clearEOL() {
|
||||
os.Stdout.Write([]byte{0x1b, 0x5b, 0x4b})
|
||||
}
|
||||
|
||||
func goUp() {
|
||||
os.Stdout.Write([]byte{0x1b, 0x5b, 0x41})
|
||||
}
|
56
compile_config.go
Normal file
56
compile_config.go
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var CompileConfigs = []*CompileConfig{}
|
||||
|
||||
type CompileConfig struct {
|
||||
OS string
|
||||
Arch string
|
||||
FileExt string
|
||||
Compress bool
|
||||
}
|
||||
|
||||
func FillCompileConfigs() error {
|
||||
cmd := exec.Command("go", "tool", "dist", "list")
|
||||
|
||||
systems := strings.Split(*OS, ",")
|
||||
arches := strings.Split(*Arch, ",")
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
splits := strings.Split(line, "/")
|
||||
os, arch := splits[0], splits[1]
|
||||
|
||||
if (*OS != "" && !slices.Contains(systems, os)) || (*Arch != "" && !slices.Contains(arches, arch)) {
|
||||
continue
|
||||
}
|
||||
|
||||
ext := ""
|
||||
if os == "windows" {
|
||||
ext = ".exe"
|
||||
}
|
||||
|
||||
cfg := &CompileConfig{
|
||||
OS: os,
|
||||
Arch: arch,
|
||||
Compress: true,
|
||||
FileExt: ext,
|
||||
}
|
||||
|
||||
CompileConfigs = append(CompileConfigs, cfg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
49
compile_report.go
Normal file
49
compile_report.go
Normal file
@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
type CompileReport struct {
|
||||
Config *CompileConfig
|
||||
State CompileState
|
||||
}
|
||||
|
||||
type CompileState string
|
||||
|
||||
const (
|
||||
StateWaiting CompileState = "waiting"
|
||||
StateCompiling CompileState = "compiling"
|
||||
StateCompressing CompileState = "compressing"
|
||||
StateDone CompileState = "done"
|
||||
|
||||
StateCompileError CompileState = "compile error"
|
||||
StateCompressError CompileState = "compress error"
|
||||
)
|
||||
|
||||
var (
|
||||
ColorWaiting = color.New(color.FgHiBlack, color.Italic)
|
||||
|
||||
ColorError = color.New(color.FgRed, color.Bold)
|
||||
ColorInProgress = color.New(color.FgBlue)
|
||||
ColorDone = color.New(color.FgGreen, color.Bold)
|
||||
)
|
||||
|
||||
func (s CompileState) String() string {
|
||||
switch s {
|
||||
case StateWaiting:
|
||||
return ColorWaiting.Sprint(string(s))
|
||||
case StateCompiling:
|
||||
return ColorInProgress.Sprint(string(s))
|
||||
case StateCompressing:
|
||||
return ColorInProgress.Sprint(string(s))
|
||||
case StateDone:
|
||||
return ColorDone.Sprint(string(s))
|
||||
case StateCompileError:
|
||||
return ColorError.Sprint(string(s))
|
||||
case StateCompressError:
|
||||
return ColorError.Sprint(string(s))
|
||||
default:
|
||||
panic("invalid compile state")
|
||||
}
|
||||
}
|
15
go.mod
Normal file
15
go.mod
Normal file
@ -0,0 +1,15 @@
|
||||
module git.milar.in/milarin/gocc
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
git.milar.in/milarin/channel v0.0.7
|
||||
github.com/fatih/color v1.13.0
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
|
||||
)
|
16
go.sum
Normal file
16
go.sum
Normal file
@ -0,0 +1,16 @@
|
||||
git.milar.in/milarin/channel v0.0.7 h1:cVKtwgH/EE7U+XTHcoFCClJ4LR349KanzjX9xKwRcNg=
|
||||
git.milar.in/milarin/channel v0.0.7/go.mod h1:We83LTI8S7u7II3pD+A2ChCDWJfCkcBUCUqii9HjTtM=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
135
main.go
Normal file
135
main.go
Normal file
@ -0,0 +1,135 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.milar.in/milarin/channel"
|
||||
)
|
||||
|
||||
var ModulePath string
|
||||
var ProjectName string
|
||||
|
||||
var (
|
||||
OS = flag.String("os", "", "comma-separated list of operating systems to compile for (empty for all)")
|
||||
Arch = flag.String("arch", "", "comma-separated list of architectures to compile for (empty for all)")
|
||||
|
||||
Silent = flag.Bool("s", false, "silent mode (no output)")
|
||||
NoCompress = flag.Bool("c", false, "dont compress any executables")
|
||||
NumThreads = flag.Int("t", runtime.NumCPU(), "amount of threads (0 = infinite)")
|
||||
)
|
||||
|
||||
var Runner channel.Runner
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
flag.Parse()
|
||||
|
||||
if err := FillCompileConfigs(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ModulePath, err = filepath.Abs(flag.Arg(0))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ProjectName = filepath.Base(ModulePath)
|
||||
|
||||
ch := make(chan *CompileReport, len(CompileConfigs))
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
doneCh := make(chan struct{})
|
||||
go Watch(ch, doneCh)
|
||||
|
||||
Runner = GetRunner()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for _, cfg := range CompileConfigs {
|
||||
cfg := cfg
|
||||
wg.Add(1)
|
||||
go Runner.Run(func() { Compile(cfg, ch, wg) })
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
close(ch)
|
||||
|
||||
end := time.Now()
|
||||
|
||||
<-doneCh // wait for Watch
|
||||
|
||||
if !*Silent {
|
||||
fmt.Printf("compilation took %s (using %s threads)\n", end.Sub(start), GetThreadCount())
|
||||
}
|
||||
}
|
||||
|
||||
func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
||||
filename := fmt.Sprintf("%s_%s_%s%s", ProjectName, cfg.OS, cfg.Arch, cfg.FileExt)
|
||||
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompiling}
|
||||
|
||||
compileCmd := exec.Command("go", "build", "-o", filename)
|
||||
compileCmd.Dir = ModulePath
|
||||
if err := compileCmd.Start(); err != nil {
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompileError}
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
if err := compileCmd.Wait(); err != nil {
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompileError}
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
|
||||
Compress(filename, cfg, ch, wg)
|
||||
|
||||
// uncomment for independent compile and compress tasks
|
||||
/*
|
||||
ch <- &CompileReport{Config: cfg, State: StateWaiting}
|
||||
go Runner.Run(func() { Compress(filename, cfg, ch, wg) })
|
||||
*/
|
||||
}
|
||||
|
||||
func Compress(filename string, cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompressing}
|
||||
|
||||
if !*NoCompress && cfg.Compress {
|
||||
compressCmd := exec.Command("upx", "--best", filename)
|
||||
compressCmd.Dir = ModulePath
|
||||
|
||||
if err := compressCmd.Start(); err != nil {
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompressError}
|
||||
return
|
||||
}
|
||||
|
||||
if err := compressCmd.Wait(); err != nil {
|
||||
ch <- &CompileReport{Config: cfg, State: StateCompressError}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ch <- &CompileReport{Config: cfg, State: StateDone}
|
||||
}
|
||||
|
||||
func GetRunner() channel.Runner {
|
||||
if *NumThreads <= 0 {
|
||||
return channel.NewUnlimitedRunner()
|
||||
} else {
|
||||
return channel.NewLimitedRunner(*NumThreads)
|
||||
}
|
||||
}
|
||||
|
||||
func GetThreadCount() string {
|
||||
if *NumThreads == 0 {
|
||||
return "infinitely many"
|
||||
}
|
||||
return strconv.Itoa(*NumThreads)
|
||||
}
|
43
watch.go
Normal file
43
watch.go
Normal file
@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Watch(ch <-chan *CompileReport, doneCh chan<- struct{}) {
|
||||
defer close(doneCh)
|
||||
|
||||
states := map[*CompileConfig]CompileState{}
|
||||
for _, cfg := range CompileConfigs {
|
||||
states[cfg] = StateWaiting
|
||||
}
|
||||
|
||||
cleared := false
|
||||
|
||||
for report := range ch {
|
||||
states[report.Config] = report.State
|
||||
if !*Silent {
|
||||
PrintStates(states, cleared)
|
||||
}
|
||||
cleared = true
|
||||
}
|
||||
|
||||
doneCh <- struct{}{}
|
||||
}
|
||||
|
||||
func PrintStates(states map[*CompileConfig]CompileState, clear bool) {
|
||||
if clear {
|
||||
for i := 0; i < len(CompileConfigs); i++ {
|
||||
goUp()
|
||||
clearEOL()
|
||||
}
|
||||
}
|
||||
|
||||
for _, cfg := range CompileConfigs {
|
||||
state, ok := states[cfg]
|
||||
if !ok {
|
||||
fmt.Println()
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%-16s %s\n", fmt.Sprintf("%s/%s:", cfg.OS, cfg.Arch), state)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user