build.go
86 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package commands
import (
"cmp"
"flag"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
)
const buildUsage = `Build a Congo project for production
Usage:
congo build [flags]
Flags:
--os <os> Target OS (default: current)
--arch <arch> Target architecture (default: current)
--output <path> Output binary path (default: build/<project-name>)
Examples:
congo build
congo build --os linux --arch amd64
congo build --output myapp
`
func Build() {
fs := flag.NewFlagSet("build", flag.ExitOnError)
fs.Usage = func() { fmt.Print(buildUsage) }
targetOS := fs.String("os", "", "Target OS")
targetArch := fs.String("arch", "", "Target architecture")
output := fs.String("output", "", "Output binary path")
fs.Parse(os.Args[2:])
wd, err := os.Getwd()
if err != nil {
log.Fatalf("could not determine working directory: %v", err)
}
name := filepath.Base(wd)
dir := findAppDir()
outPath := cmp.Or(*output, filepath.Join("build", name))
os.MkdirAll(filepath.Dir(outPath), 0755)
env := os.Environ()
if *targetOS != "" {
env = append(env, "GOOS="+*targetOS)
}
if *targetArch != "" {
env = append(env, "GOARCH="+*targetArch)
}
cmd := exec.Command("go", "build", "-o", outPath, "./"+dir)
cmd.Env = env
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Printf("Building ./%s → %s", dir, outPath)
if *targetOS != "" || *targetArch != "" {
fmt.Printf(" (%s/%s)", cmp.Or(*targetOS, "native"), cmp.Or(*targetArch, "native"))
}
fmt.Println()
if err := cmd.Run(); err != nil {
log.Fatalf("Build failed: %v", err)
}
// Show binary size
if info, err := os.Stat(outPath); err == nil {
fmt.Printf("\n %s (%.1f MB)\n", outPath, float64(info.Size())/(1024*1024))
}
fmt.Println("\nNext steps:")
fmt.Printf(" ./%s # run locally\n", outPath)
if _, err := os.Stat("Dockerfile"); err == nil {
fmt.Println(" docker build -t app . # containerize")
}
if _, err := os.Stat("infra.json"); err == nil {
fmt.Println(" congo launch # deploy to server")
}
fmt.Println()
}