1 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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// detect attempts to autodetect the correct
// values of the environment variables
// used by go_darwin_arm_exec.
// detect shells out to ideviceinfo, a third party program that can
// be obtained by following the instructions at
// https://github.com/libimobiledevice/libimobiledevice.
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
)
func main() {
devID := detectDevID()
fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
udid := detectUDID()
mp := detectMobileProvisionFile(udid)
f, err := ioutil.TempFile("", "go_ios_detect_")
check(err)
fname := f.Name()
defer os.Remove(fname)
out := combinedOutput(parseMobileProvision(mp))
_, err = f.Write(out)
check(err)
check(f.Close())
appID, err := plistExtract(fname, "ApplicationIdentifierPrefix:0")
check(err)
fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
teamID, err := plistExtract(fname, "Entitlements:com.apple.developer.team-identifier")
check(err)
fmt.Printf("export GOIOS_TEAM_ID=%s\n", teamID)
}
func detectDevID() string {
cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v")
lines := getLines(cmd)
for _, line := range lines {
if !bytes.Contains(line, []byte("iPhone Developer")) {
continue
}
if bytes.Contains(line, []byte("REVOKED")) {
continue
}
fields := bytes.Fields(line)
return string(fields[1])
}
fail("no code signing identity found")
panic("unreachable")
}
var udidPrefix = []byte("UniqueDeviceID: ")
func detectUDID() []byte {
cmd := exec.Command("ideviceinfo")
lines := getLines(cmd)
for _, line := range lines {
if bytes.HasPrefix(line, udidPrefix) {
return bytes.TrimPrefix(line, udidPrefix)
}
}
fail("udid not found; is the device connected?")
panic("unreachable")
}
func detectMobileProvisionFile(udid []byte) string {
cmd := exec.Command("mdfind", "-name", ".mobileprovision")
lines := getLines(cmd)
for _, line := range lines {
if len(line) == 0 {
continue
}
xmlLines := getLines(parseMobileProvision(string(line)))
for _, xmlLine := range xmlLines {
if bytes.Contains(xmlLine, udid) {
return string(line)
}
}
}
fail("did not find mobile provision matching device udid %s", udid)
panic("ureachable")
}
func parseMobileProvision(fname string) *exec.Cmd {
return exec.Command("security", "cms", "-D", "-i", string(fname))
}
func plistExtract(fname string, path string) ([]byte, error) {
out, err := exec.Command("/usr/libexec/PlistBuddy", "-c", "Print "+path, fname).CombinedOutput()
if err != nil {
return nil, err
}
return bytes.TrimSpace(out), nil
}
func getLines(cmd *exec.Cmd) [][]byte {
out := combinedOutput(cmd)
return bytes.Split(out, []byte("\n"))
}
func combinedOutput(cmd *exec.Cmd) []byte {
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(strings.Join(cmd.Args, "\n"))
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
return out
}
func check(err error) {
if err != nil {
fail(err.Error())
}
}
func fail(msg string, v ...interface{}) {
fmt.Fprintf(os.Stderr, msg, v...)
fmt.Fprintln(os.Stderr)
os.Exit(1)
}
|