cmd/gogio: group buildInfo related code

Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
This commit is contained in:
Walter Werner SCHNEIDER
2020-11-11 23:16:33 +02:00
committed by Elias Naur
parent 7eb32360e5
commit 3c739323cb
7 changed files with 197 additions and 138 deletions
+3 -3
View File
@@ -111,7 +111,7 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
"CGO_ENABLED=1",
),
}
pkgs, err := packages.Load(cfg, bi.pkg)
pkgs, err := packages.Load(cfg, bi.pkgPath)
if err != nil {
return err
}
@@ -205,7 +205,7 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
"-buildmode=c-shared",
"-tags", bi.tags,
"-o", libFile,
bi.pkg,
bi.pkgPath,
)
cmd.Env = append(
os.Environ(),
@@ -352,7 +352,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
}
icon := *iconPath
if icon == "" {
icon = filepath.Join(bi.dir, "appicon.png")
icon = filepath.Join(bi.pkgDir, "appicon.png")
}
iconSnip := ""
if _, err := os.Stat(icon); err == nil {
+143
View File
@@ -0,0 +1,143 @@
package main
import (
"flag"
"fmt"
"os/exec"
"path"
"path/filepath"
"strings"
)
type buildInfo struct {
appID string
archs []string
ldflags string
minsdk int
name string
pkgDir string
pkgPath string
tags string
target string
version int
}
func newBuildInfo(pkgAbsPath string) (*buildInfo, error) {
pkgMetadata, err := getPkgMetadata(pkgAbsPath)
if err != nil {
return nil, err
}
appID := getAppID(pkgMetadata)
bi := &buildInfo{
appID: appID,
archs: getArchs(),
ldflags: getLdFlags(appID),
minsdk: *minsdk,
name: getPkgName(pkgMetadata),
pkgDir: pkgMetadata.Dir,
pkgPath: pkgAbsPath,
tags: *extraTags,
target: *target,
version: *version,
}
return bi, nil
}
func getPkgAbsPath() string {
absPath, _ := filepath.Abs(flag.Arg(0))
return absPath
}
func getArchs() []string {
if *archNames != "" {
return strings.Split(*archNames, ",")
}
switch *target {
case "js":
return []string{"wasm"}
case "ios", "tvos":
// Only 64-bit support.
return []string{"arm64", "amd64"}
case "android":
return []string{"arm", "arm64", "386", "amd64"}
default:
// TODO: Add flag tests.
panic("The target value has already been validated, this will never execute.")
}
}
func getLdFlags(appID string) string {
var ldflags []string
if extra := *extraLdflags; extra != "" {
ldflags = append(ldflags, strings.Split(extra, " ")...)
}
// Pass appID along, to be used for logging on platforms like Android.
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app/internal/log.appID=%s", appID))
// Pass along all remaining arguments to the app.
if appArgs := flag.Args()[1:]; len(appArgs) > 0 {
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app.extraArgs=%s", strings.Join(appArgs, "|")))
}
if m := *linkMode; m != "" {
ldflags = append(ldflags, "-linkmode="+m)
}
return strings.Join(ldflags, " ")
}
type packageMetadata struct {
PkgPath string
Dir string
}
func getPkgMetadata(absPath string) (*packageMetadata, error) {
pkgImportPath, err := runCmd(exec.Command("go", "list", "-f", "{{.ImportPath}}", absPath))
if err != nil {
return nil, err
}
pkgDir, err := runCmd(exec.Command("go", "list", "-f", "{{.Dir}}", absPath))
if err != nil {
return nil, err
}
return &packageMetadata{
PkgPath: pkgImportPath,
Dir: pkgDir,
}, nil
}
func getAppID(pkgMetadata *packageMetadata) string {
if *appID != "" {
return *appID
}
elems := strings.Split(pkgMetadata.PkgPath, "/")
domain := strings.Split(elems[0], ".")
name := ""
if len(elems) > 1 {
name = "." + elems[len(elems)-1]
}
if len(elems) < 2 && len(domain) < 2 {
name = "." + domain[0]
domain[0] = "localhost"
} else {
for i := 0; i < len(domain)/2; i++ {
opp := len(domain) - 1 - i
domain[i], domain[opp] = domain[opp], domain[i]
}
}
pkgDomain := strings.Join(domain, ".")
appid := []rune(pkgDomain + name)
// a Java-language-style package name may contain upper- and lower-case
// letters and underscores with individual parts separated by '.'.
// https://developer.android.com/guide/topics/manifest/manifest-element
for i, c := range appid {
if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' ||
c == '_' || c == '.') {
appid[i] = '_'
}
}
return string(appid)
}
func getPkgName(pkgMetadata *packageMetadata) string {
return path.Base(pkgMetadata.PkgPath)
}
+32
View File
@@ -0,0 +1,32 @@
package main
import "testing"
type expval struct {
in, out string
}
func TestAppID(t *testing.T) {
t.Parallel()
tests := []expval{
{"example", "localhost.example"},
{"example.com", "com.example"},
{"www.example.com", "com.example.www"},
{"examplecom/app", "examplecom.app"},
{"example.com/app", "com.example.app"},
{"www.example.com/app", "com.example.www.app"},
{"www.en.example.com/app", "com.example.en.www.app"},
{"example.com/dir/app", "com.example.app"},
{"example.com/dir.ext/app", "com.example.app"},
{"example.com/dir/app.ext", "com.example.app.ext"},
{"example-com.net/dir/app", "net.example_com.app"},
}
for i, test := range tests {
got := getAppID(&packageMetadata{PkgPath: test.in})
if exp := test.out; got != exp {
t.Errorf("(%d): expected '%s', got '%s'", i, exp, got)
}
}
}
+2 -2
View File
@@ -224,7 +224,7 @@ int main(int argc, char * argv[]) {
}
icon := *iconPath
if icon == "" {
icon = filepath.Join(bi.dir, "appicon.png")
icon = filepath.Join(bi.pkgDir, "appicon.png")
}
if _, err := os.Stat(icon); err == nil {
assetPlist, err := iosIcons(bi, tmpDir, app, icon)
@@ -440,7 +440,7 @@ func archiveIOS(tmpDir, target, frameworkRoot string, bi *buildInfo) error {
"-buildmode=c-archive",
"-o", lib,
"-tags", tags,
bi.pkg,
bi.pkgPath,
)
lipo.Args = append(lipo.Args, lib)
cflagsLine := strings.Join(cflags, " ")
+1 -1
View File
@@ -24,7 +24,7 @@ func buildJS(bi *buildInfo) error {
"-ldflags="+bi.ldflags,
"-tags="+bi.tags,
"-o", filepath.Join(out, "main.wasm"),
bi.pkg,
bi.pkgPath,
)
cmd.Env = append(
os.Environ(),
+16 -103
View File
@@ -37,36 +37,35 @@ var (
iconPath = flag.String("icon", "", "Specify an icon for iOS and Android")
)
type buildInfo struct {
name string
pkg string
ldflags string
tags string
target string
appID string
version int
dir string
archs []string
minsdk int
}
func main() {
flag.Usage = func() {
fmt.Fprint(os.Stderr, mainUsage)
}
flag.Parse()
if err := mainErr(); err != nil {
if err := flagValidate(); err != nil {
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
os.Exit(1)
}
buildInfo, err := newBuildInfo(getPkgAbsPath())
if err != nil {
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
os.Exit(1)
}
if err := build(buildInfo); err != nil {
fmt.Fprintf(os.Stderr, "gogio: %v\n", err)
os.Exit(1)
}
os.Exit(0)
}
func mainErr() error {
pkg := flag.Arg(0)
if pkg == "" {
func flagValidate() error {
pkgPathArg := flag.Arg(0)
if pkgPathArg == "" {
return errors.New("specify a package")
}
if _, err := filepath.Abs(pkgPathArg); err != nil {
return err
}
if *target == "" {
return errors.New("please specify -target")
}
@@ -80,95 +79,9 @@ func mainErr() error {
default:
return fmt.Errorf("invalid -buildmode %s", *buildMode)
}
// Find package name.
pkgPath, err := runCmd(exec.Command("go", "list", "-f", "{{.ImportPath}}", pkg))
if err != nil {
return err
}
dir, err := runCmd(exec.Command("go", "list", "-f", "{{.Dir}}", pkg))
if err != nil {
return err
}
elems := strings.Split(pkgPath, "/")
name := elems[len(elems)-1]
bi := &buildInfo{
name: name,
pkg: pkg,
target: *target,
appID: *appID,
dir: dir,
version: *version,
minsdk: *minsdk,
tags: *extraTags,
}
if bi.appID == "" {
bi.appID = appIDFromPackage(pkgPath)
}
var ldflags []string
if extra := *extraLdflags; extra != "" {
ldflags = append(ldflags, strings.Split(extra, " ")...)
}
// Pass appID along, to be used for logging on platforms like Android.
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app/internal/log.appID=%s", bi.appID))
switch *target {
case "js":
bi.archs = []string{"wasm"}
case "ios", "tvos":
// Only 64-bit support.
bi.archs = []string{"arm64", "amd64"}
case "android":
bi.archs = []string{"arm", "arm64", "386", "amd64"}
}
if *archNames != "" {
bi.archs = strings.Split(*archNames, ",")
}
if appArgs := flag.Args()[1:]; len(appArgs) > 0 {
// Pass along arguments to the app.
ldflags = append(ldflags, fmt.Sprintf("-X gioui.org/app.extraArgs=%s", strings.Join(appArgs, "|")))
}
if m := *linkMode; m != "" {
ldflags = append(ldflags, "-linkmode="+m)
}
bi.ldflags = strings.Join(ldflags, " ")
if err := build(bi); err != nil {
return err
}
return nil
}
func appIDFromPackage(pkgPath string) string {
elems := strings.Split(pkgPath, "/")
domain := strings.Split(elems[0], ".")
name := ""
if len(elems) > 1 {
name = "." + elems[len(elems)-1]
}
if len(elems) < 2 && len(domain) < 2 {
name = "." + domain[0]
domain[0] = "localhost"
} else {
for i := 0; i < len(domain)/2; i++ {
opp := len(domain) - 1 - i
domain[i], domain[opp] = domain[opp], domain[i]
}
}
pkgDomain := strings.Join(domain, ".")
appid := []rune(pkgDomain + name)
// a Java-language-style package name may contain upper- and lower-case
// letters and underscores with individual parts separated by '.'.
// https://developer.android.com/guide/topics/manifest/manifest-element
for i, c := range appid {
if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' ||
c == '_' || c == '.') {
appid[i] = '_'
}
}
return string(appid)
}
func build(bi *buildInfo) error {
tmpDir, err := ioutil.TempDir("", "gogio-")
if err != nil {
-29
View File
@@ -15,32 +15,3 @@ func TestMain(m *testing.M) {
}
os.Exit(m.Run())
}
type expval struct {
in, out string
}
func TestAppID(t *testing.T) {
t.Parallel()
tests := []expval{
{"example", "localhost.example"},
{"example.com", "com.example"},
{"www.example.com", "com.example.www"},
{"examplecom/app", "examplecom.app"},
{"example.com/app", "com.example.app"},
{"www.example.com/app", "com.example.www.app"},
{"www.en.example.com/app", "com.example.en.www.app"},
{"example.com/dir/app", "com.example.app"},
{"example.com/dir.ext/app", "com.example.app"},
{"example.com/dir/app.ext", "com.example.app.ext"},
{"example-com.net/dir/app", "net.example_com.app"},
}
for i, test := range tests {
got := appIDFromPackage(test.in)
if exp := test.out; got != exp {
t.Errorf("(%d): expected '%s', got '%s'", i, exp, got)
}
}
}