refactor and more error messages

This commit is contained in:
Timon Ringwald 2022-08-17 19:18:57 +02:00
parent 003af32f46
commit 29c357bd24
4 changed files with 95 additions and 43 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
output

View File

@ -3,15 +3,23 @@ package main
import ( import (
"fmt" "fmt"
"os/exec" "os/exec"
"path/filepath"
"sync" "sync"
) )
func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) { func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
filename := fmt.Sprintf("%s_%s_%s%s", ProjectName, cfg.OS, cfg.Arch, cfg.FileExt) filePath := filepath.Join(*OutputDir, fmt.Sprintf("%s_%s_%s%s", ProjectName, cfg.OS, cfg.Arch, cfg.FileExt))
filePath, err := filepath.Abs(filePath)
if err != nil {
ch <- &CompileReport{Config: cfg, State: StateCompileError}
wg.Done()
return
}
ch <- &CompileReport{Config: cfg, State: StateCompiling} ch <- &CompileReport{Config: cfg, State: StateCompiling}
compileCmd := exec.Command("go", "build", "-o", filename) compileCmd := exec.Command("go", "build", "-o", filePath)
compileCmd.Dir = ModulePath compileCmd.Dir = ModulePath
if err := compileCmd.Start(); err != nil { if err := compileCmd.Start(); err != nil {
@ -24,24 +32,23 @@ func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
wg.Done() wg.Done()
return return
} }
Compress(filePath, cfg, ch, wg)
Compress(filename, cfg, ch, wg)
// uncomment for independent compile and compress tasks // uncomment for independent compile and compress tasks
// (slightly slower in tests, most likely because of more context switches) // (slightly slower in tests, most likely because of more context switches)
/* /*
ch <- &CompileReport{Config: cfg, State: StateWaiting} ch <- &CompileReport{Config: cfg, State: StateWaiting}
go Runner.Run(func() { Compress(filename, cfg, ch, wg) }) go Runner.Run(func() { Compress(filePath, cfg, ch, wg) })
*/ */
} }
func Compress(filename string, cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) { func Compress(filePath string, cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
ch <- &CompileReport{Config: cfg, State: StateCompressing} ch <- &CompileReport{Config: cfg, State: StateCompressing}
if !*NoCompress && cfg.Compress { if !*NoCompress && cfg.Compress {
compressCmd := exec.Command("upx", "--best", filename) compressCmd := exec.Command("upx", "--best", filePath)
compressCmd.Dir = ModulePath compressCmd.Dir = ModulePath
if err := compressCmd.Start(); err != nil { if err := compressCmd.Start(); err != nil {

65
init.go Normal file
View File

@ -0,0 +1,65 @@
package main
import (
"errors"
"flag"
"fmt"
"os"
"os/exec"
"path/filepath"
)
func Init() {
flag.Parse()
var err error
ModulePath, err = filepath.Abs(flag.Arg(0))
if err != nil {
ColorError.Fprintln(os.Stderr, "determining module path failed")
os.Exit(1)
}
*OutputDir, err = filepath.Abs(*OutputDir)
if err != nil {
ColorError.Fprintln(os.Stderr, "determining output path failed")
os.Exit(1)
}
if _, err := exec.LookPath("go"); err != nil {
ColorError.Fprintln(os.Stderr, "go not found in PATH. compilation not possible")
os.Exit(1)
}
if err := FillCompileConfigs(); err != nil {
ColorError.Fprintln(os.Stderr, fmt.Errorf("target architectures could not be determined: %w", err))
os.Exit(1)
}
if _, err := os.Stat(filepath.Join(ModulePath, "go.mod")); errors.Is(err, os.ErrNotExist) {
ColorError.Fprintf(os.Stderr, "no Go module found at '%s'\n", ModulePath)
os.Exit(1)
}
if err := DetermineProjectName(); err != nil {
ColorError.Fprintln(os.Stderr, fmt.Errorf("project name could not be determined: %w", err))
os.Exit(1)
}
if err := os.MkdirAll(*OutputDir, 0744); err != nil {
ColorError.Fprintln(os.Stderr, fmt.Errorf("output folder '%s' could not be made: %w", *OutputDir, err))
os.Exit(1)
}
if err := CheckDirWritable(*OutputDir); err != nil {
ColorError.Fprintf(os.Stderr, "output folder '%s' has insufficient permissions\n", *OutputDir)
os.Exit(1)
}
if !*NoCompress {
if _, err := exec.LookPath("upx"); err != nil {
ColorWarn.Fprintln(os.Stderr, "upx not found in PATH. file compression not possible")
*NoCompress = true
}
}
}

51
main.go
View File

@ -5,7 +5,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
@ -28,46 +27,14 @@ var (
OS = flag.String("os", "", "comma-separated list of operating systems to compile for (empty for all)") 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)") Arch = flag.String("arch", "", "comma-separated list of architectures to compile for (empty for all)")
OutputDir = flag.String("o", "output", "output directory")
Silent = flag.Bool("s", false, "silent mode (no output)") Silent = flag.Bool("s", false, "silent mode (no output)")
NoCompress = flag.Bool("c", false, "dont compress any executables") NoCompress = flag.Bool("c", false, "dont compress any executables")
NumThreads = flag.Int("t", runtime.NumCPU(), "amount of threads (0 = infinite)") NumThreads = flag.Int("t", runtime.NumCPU(), "amount of threads (0 = infinite)")
) )
func main() { func main() {
var err error Init()
flag.Parse()
ModulePath, err = filepath.Abs(flag.Arg(0))
if err != nil {
panic(err)
}
if _, err := exec.LookPath("go"); err != nil {
ColorError.Fprintln(os.Stderr, "go not found in PATH. compilation not possible")
return
}
if !*NoCompress {
if _, err := exec.LookPath("upx"); err != nil {
ColorWarn.Fprintln(os.Stderr, "upx not found in PATH. file compression not possible")
*NoCompress = true
}
}
if err := FillCompileConfigs(); err != nil {
ColorError.Fprintln(os.Stderr, fmt.Errorf("target architectures could not be determined: %w", err))
return
}
if _, err := os.Stat(filepath.Join(ModulePath, "go.mod")); errors.Is(err, os.ErrNotExist) {
ColorError.Fprintf(os.Stderr, "no Go module found at '%s'\n", ModulePath)
return
}
if err := DetermineProjectName(); err != nil {
ColorError.Fprintln(os.Stderr, fmt.Errorf("project name could not be determined: %w", err))
return
}
ch := make(chan *CompileReport, len(CompileConfigs)) ch := make(chan *CompileReport, len(CompileConfigs))
wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)
@ -90,7 +57,7 @@ func main() {
end := time.Now() end := time.Now()
<-doneCh // wait for Watch <-doneCh // wait for Watch routine
if !*Silent { if !*Silent {
fmt.Printf("compilation took %s (using %s threads)\n", end.Sub(start), GetThreadCountString()) fmt.Printf("compilation took %s (using %s threads)\n", end.Sub(start), GetThreadCountString())
@ -129,3 +96,15 @@ func GetThreadCountString() string {
} }
return strconv.Itoa(*NumThreads) return strconv.Itoa(*NumThreads)
} }
func CheckDirWritable(dir string) error {
path := filepath.Join(*OutputDir, ".gocc")
file, err := os.Create(path)
if err != nil {
return err
}
file.Close()
os.Remove(path)
return nil
}