Skip to content

Commit

Permalink
[RA-3066] Add XCArchive and IPA artifact meta parsing logic (bitrise-…
Browse files Browse the repository at this point in the history
…io#241)

* Add XCArchive and IPA artifact meta parsing logic

* Remove vendor folder and update mockery mock

* Create named error for MacOS project not supported error

* Add missing godoc

* Fix nil pointer issue

* Fix review items

* Revert formatting

* Revert formatting vol.2.
  • Loading branch information
gaborpongracz authored Aug 6, 2024
1 parent f876b48 commit b47f848
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 22 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ require (
github.com/bitrise-io/go-steputils v1.0.5
github.com/bitrise-io/go-steputils/v2 v2.0.0-alpha.18
github.com/bitrise-io/go-utils v1.0.12
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.19
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23
github.com/bitrise-io/go-xcode v1.0.18
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/go-querystring v1.1.0
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/hashicorp/go-version v1.6.0
github.com/ryanuber/go-glob v1.0.0
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
golang.org/x/text v0.12.0
howett.net/plist v1.0.0
)
Expand All @@ -26,9 +26,9 @@ require (
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.11.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
30 changes: 14 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ github.com/bitrise-io/go-steputils/v2 v2.0.0-alpha.18/go.mod h1:/ueNOKnsjcUrlt8C
github.com/bitrise-io/go-utils v1.0.1/go.mod h1:ZY1DI+fEpZuFpO9szgDeICM4QbqoWVt0RSY3tRI1heY=
github.com/bitrise-io/go-utils v1.0.12 h1:iJV1ZpyvSA0NCte/N6x+aIQ9TrNr5sIBlcJBf0dn1dE=
github.com/bitrise-io/go-utils v1.0.12/go.mod h1:ZY1DI+fEpZuFpO9szgDeICM4QbqoWVt0RSY3tRI1heY=
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.19 h1:55as5Iv0N4btuRP3YwRzN+BCMtKO210MnJ8mpxmeI7o=
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.19/go.mod h1:Laih4ji980SQkRgdnMCH0g4u2GZI/5nnbqmYT9UfKFQ=
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23 h1:Dfh4nyZPuEtilBisidejqxBrkx9cWvbOUrpq8VEION0=
github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23/go.mod h1:3XUplo0dOWc3DqT2XA2SeHToDSg7+j1y1HTHibT2H68=
github.com/bitrise-io/go-xcode v1.0.18 h1:guFywV/AwcZuexqIQkL1ixc3QThpbJvA4voa9MqvPto=
github.com/bitrise-io/go-xcode v1.0.18/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
Expand All @@ -27,11 +28,11 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand All @@ -40,6 +41,8 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -48,18 +51,13 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
Expand All @@ -68,8 +66,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
Expand Down
78 changes: 78 additions & 0 deletions metaparser/ipa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package metaparser

import (
"fmt"

"github.com/bitrise-io/go-xcode/v2/artifacts"
"github.com/bitrise-io/go-xcode/v2/zip"
)

// ParseIPAData ...
func (m *Parser) ParseIPAData(pth string) (*ArtifactMetadata, error) {
appInfo, provisioningInfo, err := m.readIPADeploymentMeta(pth)
if err != nil {
return nil, fmt.Errorf("failed to parse deployment info for %s: %w", pth, err)
}

fileSize, err := m.fileManager.FileSizeInBytes(pth)
if err != nil {
m.logger.Warnf("Failed to get apk size, error: %s", err)
}

return &ArtifactMetadata{
AppInfo: appInfo,
FileSizeBytes: fileSize,
ProvisioningInfo: provisioningInfo,
}, nil
}

func (m *Parser) readIPADeploymentMeta(ipaPth string) (Info, ProvisionInfo, error) {
reader, err := zip.NewDefaultReader(ipaPth, m.logger)
if err != nil {
return Info{}, ProvisionInfo{}, err
}
defer func() {
if err := reader.Close(); err != nil {
m.logger.Warnf("%s", err)
}
}()

ipaReader := artifacts.NewIPAReader(reader)
infoPlist, err := ipaReader.AppInfoPlist()
if err != nil {
return Info{}, ProvisionInfo{}, fmt.Errorf("failed to unwrap Info.plist from ipa: %w", err)
}

appTitle, _ := infoPlist.GetString("CFBundleName")
bundleID, _ := infoPlist.GetString("CFBundleIdentifier")
version, _ := infoPlist.GetString("CFBundleShortVersionString")
buildNumber, _ := infoPlist.GetString("CFBundleVersion")
minOSVersion, _ := infoPlist.GetString("MinimumOSVersion")
deviceFamilyList, _ := infoPlist.GetUInt64Array("UIDeviceFamily")

appInfo := Info{
AppTitle: appTitle,
BundleID: bundleID,
Version: version,
BuildNumber: buildNumber,
MinOSVersion: minOSVersion,
DeviceFamilyList: deviceFamilyList,
}

provisioningProfileInfo, err := ipaReader.ProvisioningProfileInfo()
if err != nil {
return Info{}, ProvisionInfo{}, fmt.Errorf("failed to read profile info from ipa: %w", err)
}

provisioningInfo := ProvisionInfo{
CreationDate: provisioningProfileInfo.CreationDate,
ExpireDate: provisioningProfileInfo.ExpirationDate,
DeviceUDIDList: provisioningProfileInfo.ProvisionedDevices,
TeamName: provisioningProfileInfo.TeamName,
ProfileName: provisioningProfileInfo.Name,
ProvisionsAllDevices: provisioningProfileInfo.ProvisionsAllDevices,
IPAExportMethod: provisioningProfileInfo.ExportType,
}

return appInfo, provisioningInfo, nil
}
52 changes: 52 additions & 0 deletions metaparser/metaparser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package metaparser

import (
"time"

"github.com/bitrise-io/go-utils/v2/fileutil"
"github.com/bitrise-io/go-utils/v2/log"
"github.com/bitrise-io/go-xcode/exportoptions"
)

// ArtifactMetadata ...
type ArtifactMetadata struct {
AppInfo Info `json:"app_info"`
FileSizeBytes int64 `json:"file_size_bytes"`
ProvisioningInfo ProvisionInfo `json:"provisioning_info,omitempty"`
Scheme string `json:"scheme,omitempty"`
}

// Info ...
type Info struct {
AppTitle string `json:"app_title"`
BundleID string `json:"bundle_id"`
Version string `json:"version"`
BuildNumber string `json:"build_number"`
MinOSVersion string `json:"min_OS_version"`
DeviceFamilyList []uint64 `json:"device_family_list"`
}

// ProvisionInfo ...
type ProvisionInfo struct {
CreationDate time.Time `json:"creation_date"`
ExpireDate time.Time `json:"expire_date"`
DeviceUDIDList []string `json:"device_UDID_list"`
TeamName string `json:"team_name"`
ProfileName string `json:"profile_name"`
ProvisionsAllDevices bool `json:"provisions_all_devices"`
IPAExportMethod exportoptions.Method `json:"ipa_export_method"`
}

// Parser ...
type Parser struct {
logger log.Logger
fileManager fileutil.FileManager
}

// New ...
func New(logger log.Logger, fileManager fileutil.FileManager) *Parser {
return &Parser{
logger: logger,
fileManager: fileManager,
}
}
82 changes: 82 additions & 0 deletions metaparser/xcarchive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package metaparser

import (
"errors"
"fmt"

"github.com/bitrise-io/go-xcode/v2/artifacts"
"github.com/bitrise-io/go-xcode/v2/zip"
)

// MacOSProjectIsNotSupported ...
var MacOSProjectIsNotSupported = errors.New("macOS project is not supported")

// ParseXCArchiveData ...
func (m *Parser) ParseXCArchiveData(pth string) (*ArtifactMetadata, error) {

appInfo, scheme, err := m.readXCArchiveDeploymentMeta(pth)
if err != nil {
return &ArtifactMetadata{
AppInfo: appInfo,
Scheme: scheme,
}, fmt.Errorf("failed to parse deployment info for %s: %w", pth, err)
}

fileSize, err := m.fileManager.FileSizeInBytes(pth)
if err != nil {
m.logger.Warnf("Failed to get apk size, error: %s", err)
}

return &ArtifactMetadata{
AppInfo: appInfo,
FileSizeBytes: fileSize,
Scheme: scheme,
}, nil
}

func (m *Parser) readXCArchiveDeploymentMeta(pth string) (Info, string, error) {
reader, err := zip.NewDefaultReader(pth, m.logger)
if err != nil {
return Info{}, "", err
}
defer func() {
if err := reader.Close(); err != nil {
m.logger.Warnf("%s", err)
}
}()

xcarchiveReader := artifacts.NewXCArchiveReader(reader)
isMacos := xcarchiveReader.IsMacOS()
if isMacos {
return Info{}, "", MacOSProjectIsNotSupported
}
archiveInfoPlist, err := xcarchiveReader.InfoPlist()
if err != nil {
return Info{}, "", fmt.Errorf("failed to unwrap Info.plist from xcarchive: %w", err)
}

iosXCArchiveReader := artifacts.NewIOSXCArchiveReader(reader)
appInfoPlist, err := iosXCArchiveReader.AppInfoPlist()
if err != nil {
return Info{}, "", fmt.Errorf("failed to unwrap application Info.plist from xcarchive: %w", err)
}

appTitle, _ := appInfoPlist.GetString("CFBundleName")
bundleID, _ := appInfoPlist.GetString("CFBundleIdentifier")
version, _ := appInfoPlist.GetString("CFBundleShortVersionString")
buildNumber, _ := appInfoPlist.GetString("CFBundleVersion")
minOSVersion, _ := appInfoPlist.GetString("MinimumOSVersion")
deviceFamilyList, _ := appInfoPlist.GetUInt64Array("UIDeviceFamily")
scheme, _ := archiveInfoPlist.GetString("SchemeName")

appInfo := Info{
AppTitle: appTitle,
BundleID: bundleID,
Version: version,
BuildNumber: buildNumber,
MinOSVersion: minOSVersion,
DeviceFamilyList: deviceFamilyList,
}

return appInfo, scheme, nil
}
Loading

0 comments on commit b47f848

Please sign in to comment.