Skip to content

Commit e42d0c6

Browse files
authored
Ipa reader (#237)
* Create zip reader using ditto tool * Unify default zip reader and the new ditto reader * Move internal zip package to ziputil * zip.ReadCloser.ReadFile now actualy read the file * Revert zip error type * Introduce IsErrFormat * Add tests for ditto reader * Renam zip to artifacts and ziputil to zip * Fix lint issue * Fix refactor issue * Add IsDittoReaderAvailable * Add some comment to the ditto command * Ditto zip reader: lazy extract archives * Benchmark test default and ditto zip readers * Introduce fallbackReader * Rename defaultRead to stdlibRead * Rename fallbackReader to defaultReader and add tests * Fix lint issues * Move stdlib and ditto zip readers to an internal package * Define ZipReadCloser interface on the client package (artifacts) * Update lint issue * Code cleanup
1 parent 398fbc3 commit e42d0c6

File tree

16 files changed

+469
-411
lines changed

16 files changed

+469
-411
lines changed

_integration_tests/test_helper.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"os"
55
"path/filepath"
66
"strings"
7-
"testing"
87

98
"github.com/bitrise-io/go-utils/command/git"
109
"github.com/stretchr/testify/require"
@@ -14,11 +13,11 @@ const sampleArtifactsRepoURL = "https://github.com/bitrise-io/sample-artifacts.g
1413

1514
var reposToDir map[string]map[string]string
1615

17-
func GetSampleArtifactsRepository(t *testing.T) string {
16+
func GetSampleArtifactsRepository(t require.TestingT) string {
1817
return GetRepository(t, sampleArtifactsRepoURL, "master")
1918
}
2019

21-
func GetRepository(t *testing.T, url, branch string) string {
20+
func GetRepository(t require.TestingT, url, branch string) string {
2221
if repoDir := getRepoDir(url, branch); repoDir != "" {
2322
return repoDir
2423
}
@@ -66,7 +65,7 @@ func saveRepoDir(dir, url, branch string) {
6665
reposToDir[url] = branchToDir
6766
}
6867

69-
func createDirForRepo(t *testing.T, repo, branch string) string {
68+
func createDirForRepo(t require.TestingT, repo, branch string) string {
7069
tmpDir, err := os.MkdirTemp("", "go-xcode")
7170
require.NoError(t, err)
7271

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,105 @@
11
package zip
22

33
import (
4+
"fmt"
45
"path/filepath"
56
"testing"
67

78
"github.com/bitrise-io/go-utils/v2/log"
9+
"github.com/bitrise-io/go-xcode/plistutil"
10+
"github.com/bitrise-io/go-xcode/profileutil"
811
"github.com/bitrise-io/go-xcode/v2/_integration_tests"
12+
"github.com/bitrise-io/go-xcode/v2/artifacts"
13+
internalzip "github.com/bitrise-io/go-xcode/v2/internal/zip"
914
"github.com/bitrise-io/go-xcode/v2/zip"
1015
"github.com/stretchr/testify/require"
1116
)
1217

13-
func TestIPAReader(t *testing.T) {
18+
func TestIPAReader_DefaultZipReader(t *testing.T) {
1419
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
1520
watchTestIPAPath := filepath.Join(sampleArtifactsDir, "ipas", "watch-test.ipa")
1621

17-
r, err := zip.NewReader(watchTestIPAPath, log.NewLogger())
22+
r, err := zip.NewDefaultReader(watchTestIPAPath, log.NewLogger())
1823
require.NoError(t, err)
1924
defer func() {
20-
require.NoError(t, r.Close())
25+
err := r.Close()
26+
require.NoError(t, err)
2127
}()
2228

23-
ipaReader := zip.NewIPAReader(*r)
24-
plist, err := ipaReader.AppInfoPlist()
25-
require.NoError(t, err)
29+
plist, profile := readIPAWithStdlibZipReader(t, watchTestIPAPath)
2630
bundleID, _ := plist.GetString("CFBundleIdentifier")
2731
require.Equal(t, "bitrise.watch-test", bundleID)
32+
require.Equal(t, "XC iOS: *", profile.Name)
33+
}
34+
35+
func TestIPAReader_StdlibZipReader(t *testing.T) {
36+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
37+
watchTestIPAPath := filepath.Join(sampleArtifactsDir, "ipas", "watch-test.ipa")
38+
39+
plist, profile := readIPAWithStdlibZipReader(t, watchTestIPAPath)
40+
bundleID, _ := plist.GetString("CFBundleIdentifier")
41+
require.Equal(t, "bitrise.watch-test", bundleID)
42+
require.Equal(t, "XC iOS: *", profile.Name)
43+
}
44+
45+
func TestIPAReader_DittoZipReader(t *testing.T) {
46+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
47+
watchTestIPAPath := filepath.Join(sampleArtifactsDir, "ipas", "watch-test.ipa")
48+
49+
plist, profile := readIPAWithDittoZipReader(t, watchTestIPAPath)
50+
bundleID, _ := plist.GetString("CFBundleIdentifier")
51+
require.Equal(t, "bitrise.watch-test", bundleID)
52+
require.Equal(t, "XC iOS: *", profile.Name)
53+
}
54+
55+
func Benchmark_ZipReaders(b *testing.B) {
56+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(b)
57+
watchTestIPAPath := filepath.Join(sampleArtifactsDir, "ipas", "watch-test.ipa")
58+
59+
for name, zipFunc := range map[string]readIPAFunc{
60+
"dittoReader": func() (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel) {
61+
return readIPAWithDittoZipReader(b, watchTestIPAPath)
62+
},
63+
"stdlibReader": func() (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel) {
64+
return readIPAWithStdlibZipReader(b, watchTestIPAPath)
65+
},
66+
} {
67+
b.Run(fmt.Sprintf("Benchmarking %s", name), func(b *testing.B) {
68+
_, _ = zipFunc()
69+
})
70+
}
71+
}
72+
73+
type readIPAFunc func() (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel)
74+
75+
func readIPAWithStdlibZipReader(t require.TestingT, archivePth string) (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel) {
76+
r, err := internalzip.NewStdlibRead(archivePth, log.NewLogger())
77+
require.NoError(t, err)
78+
defer func() {
79+
err := r.Close()
80+
require.NoError(t, err)
81+
}()
82+
83+
return readIPA(t, r)
84+
}
85+
86+
func readIPAWithDittoZipReader(t require.TestingT, archivePth string) (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel) {
87+
r := internalzip.NewDittoReader(archivePth, log.NewLogger())
88+
defer func() {
89+
err := r.Close()
90+
require.NoError(t, err)
91+
}()
92+
93+
return readIPA(t, r)
94+
}
95+
96+
func readIPA(t require.TestingT, zipReader artifacts.ZipReadCloser) (plistutil.PlistData, *profileutil.ProvisioningProfileInfoModel) {
97+
ipaReader := artifacts.NewIPAReader(zipReader)
98+
plist, err := ipaReader.AppInfoPlist()
99+
require.NoError(t, err)
28100

29101
profile, err := ipaReader.ProvisioningProfileInfo()
30102
require.NoError(t, err)
31-
require.Equal(t, "XC iOS: *", profile.Name)
103+
104+
return plist, profile
32105
}

_integration_tests/zip/xcarchive_reader_test.go

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,23 @@ import (
66

77
"github.com/bitrise-io/go-utils/v2/log"
88
"github.com/bitrise-io/go-xcode/v2/_integration_tests"
9+
"github.com/bitrise-io/go-xcode/v2/artifacts"
10+
internalzip "github.com/bitrise-io/go-xcode/v2/internal/zip"
911
"github.com/bitrise-io/go-xcode/v2/zip"
1012
"github.com/stretchr/testify/require"
1113
)
1214

13-
func TestXCArchiveReader_MacOSArchive(t *testing.T) {
15+
func TestXCArchiveReader_DefaultReader_MacOSArchive(t *testing.T) {
1416
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
1517
macOSXCArchivePath := filepath.Join(sampleArtifactsDir, "archives", "macos.xcarchive.zip")
1618

17-
r, err := zip.NewReader(macOSXCArchivePath, log.NewLogger())
19+
r, err := zip.NewDefaultReader(macOSXCArchivePath, log.NewLogger())
1820
require.NoError(t, err)
1921
defer func() {
2022
require.NoError(t, r.Close())
2123
}()
2224

23-
xcarchiveReader := zip.NewXCArchiveReader(*r)
25+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
2426
plist, err := xcarchiveReader.InfoPlist()
2527
require.NoError(t, err)
2628
name, _ := plist.GetString("Name")
@@ -30,17 +32,107 @@ func TestXCArchiveReader_MacOSArchive(t *testing.T) {
3032
require.Equal(t, true, xcarchiveReader.IsMacOS())
3133
}
3234

33-
func TestXCArchiveReader_IOSArchive(t *testing.T) {
35+
func TestXCArchiveReader_StdlibZipReader_MacOSArchive(t *testing.T) {
36+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
37+
macOSXCArchivePath := filepath.Join(sampleArtifactsDir, "archives", "macos.xcarchive.zip")
38+
39+
r, err := internalzip.NewStdlibRead(macOSXCArchivePath, log.NewLogger())
40+
require.NoError(t, err)
41+
defer func() {
42+
require.NoError(t, r.Close())
43+
}()
44+
45+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
46+
plist, err := xcarchiveReader.InfoPlist()
47+
require.NoError(t, err)
48+
name, _ := plist.GetString("Name")
49+
require.Equal(t, "ActionExtension", name)
50+
51+
require.NoError(t, err)
52+
require.Equal(t, true, xcarchiveReader.IsMacOS())
53+
}
54+
55+
func TestXCArchiveReader_DittoZipReader_MacOSArchive(t *testing.T) {
56+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
57+
macOSXCArchivePath := filepath.Join(sampleArtifactsDir, "archives", "macos.xcarchive.zip")
58+
59+
r := internalzip.NewDittoReader(macOSXCArchivePath, log.NewLogger())
60+
defer func() {
61+
require.NoError(t, r.Close())
62+
}()
63+
64+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
65+
plist, err := xcarchiveReader.InfoPlist()
66+
require.NoError(t, err)
67+
name, _ := plist.GetString("Name")
68+
require.Equal(t, "ActionExtension", name)
69+
70+
require.NoError(t, err)
71+
require.Equal(t, true, xcarchiveReader.IsMacOS())
72+
}
73+
74+
func TestXCArchiveReader_DefaultZipReader_IOSArchive(t *testing.T) {
75+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
76+
iosXCArchiveIPAPath := filepath.Join(sampleArtifactsDir, "archives", "ios.xcarchive.zip")
77+
78+
r, err := zip.NewDefaultReader(iosXCArchiveIPAPath, log.NewLogger())
79+
require.NoError(t, err)
80+
defer func() {
81+
require.NoError(t, r.Close())
82+
}()
83+
84+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
85+
plist, err := xcarchiveReader.InfoPlist()
86+
require.NoError(t, err)
87+
name, _ := plist.GetString("Name")
88+
require.Equal(t, "code-sign-test", name)
89+
90+
require.NoError(t, err)
91+
require.Equal(t, false, xcarchiveReader.IsMacOS())
92+
93+
iosXCArchiveReader := artifacts.NewIOSXCArchiveReader(r)
94+
appPlist, err := iosXCArchiveReader.AppInfoPlist()
95+
require.NoError(t, err)
96+
name, _ = appPlist.GetString("CFBundleIdentifier")
97+
require.Equal(t, "com.bitrise.code-sign-test", name)
98+
}
99+
100+
func TestXCArchiveReader_StdlibZipReader_IOSArchive(t *testing.T) {
34101
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
35102
iosXCArchiveIPAPath := filepath.Join(sampleArtifactsDir, "archives", "ios.xcarchive.zip")
36103

37-
r, err := zip.NewReader(iosXCArchiveIPAPath, log.NewLogger())
104+
r, err := internalzip.NewStdlibRead(iosXCArchiveIPAPath, log.NewLogger())
105+
require.NoError(t, err)
106+
defer func() {
107+
require.NoError(t, r.Close())
108+
}()
109+
110+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
111+
plist, err := xcarchiveReader.InfoPlist()
112+
require.NoError(t, err)
113+
name, _ := plist.GetString("Name")
114+
require.Equal(t, "code-sign-test", name)
115+
38116
require.NoError(t, err)
117+
require.Equal(t, false, xcarchiveReader.IsMacOS())
118+
119+
iosXCArchiveReader := artifacts.NewIOSXCArchiveReader(r)
120+
appPlist, err := iosXCArchiveReader.AppInfoPlist()
121+
require.NoError(t, err)
122+
name, _ = appPlist.GetString("CFBundleIdentifier")
123+
require.Equal(t, "com.bitrise.code-sign-test", name)
124+
}
125+
126+
func TestXCArchiveReader_DittoZipReader_IOSArchive(t *testing.T) {
127+
sampleArtifactsDir := _integration_tests.GetSampleArtifactsRepository(t)
128+
iosXCArchiveIPAPath := filepath.Join(sampleArtifactsDir, "archives", "ios.xcarchive.zip")
129+
130+
r := internalzip.NewDittoReader(iosXCArchiveIPAPath, log.NewLogger())
39131
defer func() {
40132
require.NoError(t, r.Close())
41133
}()
42134

43-
xcarchiveReader := zip.NewXCArchiveReader(*r)
135+
xcarchiveReader := artifacts.NewXCArchiveReader(r)
44136
plist, err := xcarchiveReader.InfoPlist()
45137
require.NoError(t, err)
46138
name, _ := plist.GetString("Name")
@@ -49,7 +141,7 @@ func TestXCArchiveReader_IOSArchive(t *testing.T) {
49141
require.NoError(t, err)
50142
require.Equal(t, false, xcarchiveReader.IsMacOS())
51143

52-
iosXCArchiveReader := zip.NewIOSXCArchiveReader(*r)
144+
iosXCArchiveReader := artifacts.NewIOSXCArchiveReader(r)
53145
appPlist, err := iosXCArchiveReader.AppInfoPlist()
54146
require.NoError(t, err)
55147
name, _ = appPlist.GetString("CFBundleIdentifier")
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
package zip
1+
package artifacts
22

3-
import "github.com/bitrise-io/go-xcode/plistutil"
3+
import (
4+
"github.com/bitrise-io/go-xcode/plistutil"
5+
)
46

57
// IOSXCArchiveReader ...
68
type IOSXCArchiveReader struct {
7-
zipReader Reader
9+
zipReader ZipReadCloser
810
}
911

1012
// NewIOSXCArchiveReader ...
11-
func NewIOSXCArchiveReader(reader Reader) IOSXCArchiveReader {
13+
func NewIOSXCArchiveReader(reader ZipReadCloser) IOSXCArchiveReader {
1214
return IOSXCArchiveReader{zipReader: reader}
1315
}
1416

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package zip
1+
package artifacts
22

33
import (
44
"fmt"
@@ -9,11 +9,11 @@ import (
99

1010
// IPAReader ...
1111
type IPAReader struct {
12-
zipReader Reader
12+
zipReader ZipReadCloser
1313
}
1414

1515
// NewIPAReader ...
16-
func NewIPAReader(zipReader Reader) IPAReader {
16+
func NewIPAReader(zipReader ZipReadCloser) IPAReader {
1717
return IPAReader{zipReader: zipReader}
1818
}
1919

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
package zip
1+
package artifacts
22

3-
import "github.com/bitrise-io/go-xcode/plistutil"
3+
import (
4+
"github.com/bitrise-io/go-xcode/plistutil"
5+
)
46

57
// XCArchiveReader ...
68
type XCArchiveReader struct {
7-
zipReader Reader
9+
zipReader ZipReadCloser
810
}
911

1012
// NewXCArchiveReader ...
11-
func NewXCArchiveReader(reader Reader) XCArchiveReader {
13+
func NewXCArchiveReader(reader ZipReadCloser) XCArchiveReader {
1214
return XCArchiveReader{zipReader: reader}
1315
}
1416

@@ -24,5 +26,6 @@ func (reader XCArchiveReader) InfoPlist() (plistutil.PlistData, error) {
2426

2527
// IsMacOS ...
2628
func (reader XCArchiveReader) IsMacOS() bool {
27-
return reader.zipReader.IsFileOrDirExistsInZipArchive("*.xcarchive/Products/Applications/*.app/Contents/*")
29+
_, err := reader.zipReader.ReadFile("*.xcarchive/Products/Applications/*.app/Contents/Info.plist")
30+
return err == nil
2831
}

artifacts/zip_reader.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package artifacts
2+
3+
// ZipReadCloser ...
4+
type ZipReadCloser interface {
5+
ReadFile(relPthPattern string) ([]byte, error)
6+
Close() error
7+
}

0 commit comments

Comments
 (0)