Skip to content

Commit 740af34

Browse files
authored
Ssw 2880 profile paths dedup (#316)
feat: Added ProvisioningProfilesDirPath() ProvisioningProfilesDirModernPath() and ProvisioningProfilesDirLegacyPath() for reusable way to get provisioning profile dirs feat: Added IOSExtension and MacExtension constants refactor: removed some duplication in listing logic
1 parent ee60f4c commit 740af34

1 file changed

Lines changed: 77 additions & 62 deletions

File tree

profileutil/util.go

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package profileutil
22

33
import (
4+
"fmt"
5+
"os"
46
"path/filepath"
57

68
"github.com/bitrise-io/go-utils/fileutil"
@@ -11,22 +13,51 @@ import (
1113
// ProfileType ...
1214
type 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

2325
const (
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 ...
3162
func 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 ...
4576
func 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 ...
6394
func 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

Comments
 (0)