11package profileutil
22
33import (
4+ "fmt"
5+ "os"
46 "path/filepath"
57
68 "github.com/bitrise-io/go-utils/fileutil"
@@ -11,22 +13,51 @@ import (
1113// ProfileType ...
1214type ProfileType string
1315
14- // ProfileTypeIos ...
15- const ProfileTypeIos ProfileType = "ios"
16-
17- // ProfileTypeMacOs ...
18- const ProfileTypeMacOs ProfileType = "osx"
19-
20- // ProfileTypeTvOs ...
21- const ProfileTypeTvOs ProfileType = "tvos"
16+ const (
17+ // ProfileTypeIos ...
18+ ProfileTypeIos ProfileType = "ios"
19+ // ProfileTypeMacOs ...
20+ ProfileTypeMacOs ProfileType = "osx"
21+ // ProfileTypeTvOs ...
22+ ProfileTypeTvOs ProfileType = "tvos"
23+ )
2224
2325const (
24- // ProvProfileSystemDirPath ...
25- ProvProfileSystemDirPath = "~/Library/MobileDevice/Provisioning Profiles "
26- // ProvProfileModernPath is used by Xcode 16 and later, but the old path is still supported.
27- ProvProfileModernPath = "~/Library/Developer/Xcode/UserData/Provisioning Profiles "
26+ // IOSExtension is the iOS provisioning profile extension
27+ IOSExtension = ".mobileprovision "
28+ // MacExtension is the macOS provisioning profile extension
29+ MacExtension = ".provisionprofile "
2830)
2931
32+ // ProvisioningProfilesDirPath returns the provisioning profile directory path based on the Xcode major version.
33+ func ProvisioningProfilesDirPath (xcodeMajorVersion int64 ) (string , error ) {
34+ if xcodeMajorVersion >= 16 || xcodeMajorVersion == 0 { // return the modern path used by Xcode 16 and later
35+ return ProvisioningProfilesDirModernPath ()
36+ }
37+
38+ return ProvisioningProfilesDirLegacyPath () // return the legacy path used by Xcode 15 and earlier
39+ }
40+
41+ // ProvisioningProfilesDirModernPath is the absolute path used to store and look up provisioning profiles (used Xcode 16 and later)
42+ func ProvisioningProfilesDirModernPath () (string , error ) {
43+ homeDir , err := os .UserHomeDir ()
44+ if err != nil {
45+ return "" , fmt .Errorf ("failed to get home directory: %w" , err )
46+ }
47+
48+ return filepath .Join (homeDir , "Library" , "Developer" , "Xcode" , "UserData" , "Provisioning Profiles" ), nil
49+ }
50+
51+ // ProvisioningProfilesDirLegacyPath is the absolute path used to store and look up provisioning profiles (used Xcode 15 and earlier)
52+ func ProvisioningProfilesDirLegacyPath () (string , error ) {
53+ homeDir , err := os .UserHomeDir ()
54+ if err != nil {
55+ return "" , fmt .Errorf ("failed to get home directory: %w" , err )
56+ }
57+
58+ return filepath .Join (homeDir , "Library" , "MobileDevice" , "Provisioning Profiles" ), nil
59+ }
60+
3061// ProvisioningProfileFromContent ...
3162func ProvisioningProfileFromContent (content []byte ) (* pkcs7.PKCS7 , error ) {
3263 return pkcs7 .Parse (content )
@@ -43,7 +74,7 @@ func ProvisioningProfileFromFile(pth string) (*pkcs7.PKCS7, error) {
4374
4475// InstalledProvisioningProfiles ...
4576func InstalledProvisioningProfiles (profileType ProfileType ) ([]* pkcs7.PKCS7 , error ) {
46- pths , err := listProfiles (profileType )
77+ pths , err := listAllProfiles (profileType )
4778 if err != nil {
4879 return nil , err
4980 }
@@ -61,73 +92,57 @@ func InstalledProvisioningProfiles(profileType ProfileType) ([]*pkcs7.PKCS7, err
6192
6293// FindProvisioningProfile ...
6394func FindProvisioningProfile (uuid string ) (* pkcs7.PKCS7 , string , error ) {
64- {
65- pths , err := listProfiles (ProfileTypeIos )
66- if err != nil {
67- return nil , "" , err
68- }
69-
70- profileName := uuid + ".mobileprovision"
71- for _ , pth := range pths {
72- if filepath .Base (pth ) == profileName {
73- profile , err := ProvisioningProfileFromFile (pth )
74- if err != nil {
75- return nil , "" , err
76- }
77- return profile , pth , nil
78- }
79- }
95+ paths , err := listProfiles (ProfileTypeIos , uuid )
96+ if err != nil {
97+ return nil , "" , err
98+ }
99+ macOSPaths , err := listProfiles (ProfileTypeMacOs , uuid )
100+ if err != nil {
101+ return nil , "" , err
80102 }
81103
82- {
83- pths , err := listProfiles ( ProfileTypeMacOs )
84- if err != nil {
85- return nil , "" , err
86- }
104+ paths = append ( paths , macOSPaths ... )
105+ if len ( paths ) == 0 {
106+ // ToDo return error of not found, keeping the nil return values for backward compatibility for now
107+ return nil , "" , nil
108+ }
87109
88- profileName := uuid + ".provisionprofile"
89- for _ , pth := range pths {
90- if filepath .Base (pth ) == profileName {
91- profile , err := ProvisioningProfileFromFile (pth )
92- if err != nil {
93- return nil , "" , err
94- }
95- return profile , pth , nil
96- }
97- }
110+ profile , err := ProvisioningProfileFromFile (paths [0 ])
111+ if err != nil {
112+ return nil , "" , err
98113 }
114+ return profile , paths [0 ], nil
115+ }
99116
100- return nil , "" , nil
117+ func listAllProfiles (profileType ProfileType ) ([]string , error ) {
118+ return listProfiles (profileType , "*" )
101119}
102120
103- func listProfiles (profileType ProfileType ) ([]string , error ) {
104- ext := ".mobileprovision"
121+ func listProfiles (profileType ProfileType , uuid string ) ([]string , error ) {
122+ ext := IOSExtension
105123 if profileType == ProfileTypeMacOs {
106- ext = ".provisionprofile"
124+ ext = MacExtension
107125 }
108126
109- absProvProfileDirPath , err := pathutil . AbsPath ( ProvProfileSystemDirPath )
127+ modernDirPath , err := ProvisioningProfilesDirModernPath ( )
110128 if err != nil {
111129 return nil , err
112130 }
113-
114- pattern := filepath .Join (pathutil .EscapeGlobPath (absProvProfileDirPath ), "*" + ext )
115- pths , err := filepath .Glob (pattern )
131+ legacyDirPath , err := ProvisioningProfilesDirLegacyPath ()
116132 if err != nil {
117133 return nil , err
118134 }
119135
120- absProvProfileModernDirPath , err := pathutil .AbsPath (ProvProfileModernPath )
121- if err != nil {
122- return nil , err
123- }
136+ var allProfilePaths []string
137+ for _ , dirPath := range []string {modernDirPath , legacyDirPath } {
138+ pattern := filepath .Join (pathutil .EscapeGlobPath (dirPath ), uuid + ext )
139+ profilePaths , err := filepath .Glob (pattern )
140+ if err != nil {
141+ return nil , err
142+ }
124143
125- pattern = filepath .Join (pathutil .EscapeGlobPath (absProvProfileModernDirPath ), "*" + ext )
126- newPaths , err := filepath .Glob (pattern )
127- if err != nil {
128- return nil , err
144+ allProfilePaths = append (allProfilePaths , profilePaths ... )
129145 }
130146
131- pths = append (pths , newPaths ... )
132- return pths , nil
147+ return allProfilePaths , nil
133148}
0 commit comments