| // 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) |
| } |