import (
"bytes"
+ "crypto/x509"
"fmt"
"io/ioutil"
"os"
)
func main() {
- devID := detectDevID()
+ udids := getLines(exec.Command("idevice_id", "-l"))
+ if len(udids) == 0 {
+ fail("no udid found; is a device connected?")
+ }
- udid := detectUDID()
- mps := detectMobileProvisionFiles(udid)
+ mps := detectMobileProvisionFiles(udids)
if len(mps) == 0 {
- fail("did not find mobile provision matching device udid %s", udid)
+ fail("did not find mobile provision matching device udids %q", udids)
}
fmt.Println("Available provisioning profiles below.")
fmt.Println("will be overwritten when running Go programs.")
for _, mp := range mps {
fmt.Println()
- fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
f, err := ioutil.TempFile("", "go_ios_detect_")
check(err)
fname := f.Name()
check(err)
check(f.Close())
+ cert, err := plistExtract(fname, "DeveloperCertificates:0")
+ check(err)
+ pcert, err := x509.ParseCertificate(cert)
+ check(err)
+ fmt.Printf("export GOIOS_DEV_ID=\"%s\"\n", pcert.Subject.CommonName)
+
appID, err := plistExtract(fname, "Entitlements:application-identifier")
check(err)
fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
}
}
-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 detectMobileProvisionFiles(udid []byte) []string {
+func detectMobileProvisionFiles(udids [][]byte) []string {
cmd := exec.Command("mdfind", "-name", ".mobileprovision")
lines := getLines(cmd)
continue
}
xmlLines := getLines(parseMobileProvision(string(line)))
- for _, xmlLine := range xmlLines {
- if bytes.Contains(xmlLine, udid) {
- files = append(files, string(line))
+ matches := 0
+ for _, udid := range udids {
+ for _, xmlLine := range xmlLines {
+ if bytes.Contains(xmlLine, udid) {
+ matches++
+ }
}
}
+ if matches == len(udids) {
+ files = append(files, string(line))
+ }
}
return files
}
func getLines(cmd *exec.Cmd) [][]byte {
out := output(cmd)
- return bytes.Split(out, []byte("\n"))
+ lines := bytes.Split(out, []byte("\n"))
+ // Skip the empty line at the end.
+ if len(lines[len(lines)-1]) == 0 {
+ lines = lines[:len(lines)-1]
+ }
+ return lines
}
func output(cmd *exec.Cmd) []byte {