Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 45 additions & 54 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import (
"github.com/pkg/errors"
)

const collectCodesigningFilesInfo = `To collect available code sign files, we search for installed Provisioning Profiles:"
- which has installed Codesign Identity in your Keychain"
- which can provision your application target's bundle ids"
- which has the project defined Capabilities set"
- which matches to the selected ipa export method"
`

func initExportOutputDir() (string, error) {
confExportOutputDirPath := "./codesigndoc_exports"
absExportOutputDirPath, err := pathutil.AbsPath(confExportOutputDirPath)
Expand Down Expand Up @@ -59,7 +66,7 @@ func analyzeArchive(archive xcarchive.IosArchive, installedCertificates []certif
}, nil
}

func collectIpaExportSelectableCodeSignGroups(archive xcarchive.IosArchive, installedCertificates []certificateutil.CertificateInfoModel, installedProfiles []profileutil.ProvisioningProfileInfoModel) ([]export.SelectableCodeSignGroup, error) {
func collectIpaExportSelectableCodeSignGroups(archive xcarchive.IosArchive, installedCertificates []certificateutil.CertificateInfoModel, installedProfiles []profileutil.ProvisioningProfileInfoModel) []export.SelectableCodeSignGroup {
bundleIDEntitlemenstMap := archive.BundleIDEntitlementsMap()

fmt.Println()
Expand All @@ -83,8 +90,7 @@ func collectIpaExportSelectableCodeSignGroups(archive xcarchive.IosArchive, inst
}

if len(codeSignGroups) == 0 {
log.Errorf("Failed to create codesigning groups for the project")
return []export.SelectableCodeSignGroup{}, nil
return []export.SelectableCodeSignGroup{}
}

codeSignGroups = export.FilterSelectableCodeSignGroups(codeSignGroups,
Expand All @@ -108,11 +114,7 @@ func collectIpaExportSelectableCodeSignGroups(archive xcarchive.IosArchive, inst
log.Debugf(group.String())
}

if len(codeSignGroups) == 0 {
log.Errorf("Failed to create codesigning groups for the project")
}

return codeSignGroups, nil
return codeSignGroups
}

func filterLatestProfiles(profiles []profileutil.ProvisioningProfileInfoModel) []profileutil.ProvisioningProfileInfoModel {
Expand Down Expand Up @@ -145,19 +147,9 @@ func filterLatestProfiles(profiles []profileutil.ProvisioningProfileInfoModel) [
func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, installedCertificates []certificateutil.CertificateInfoModel, installedProfiles []profileutil.ProvisioningProfileInfoModel) ([]export.IosCodeSignGroup, error) {
iosCodeSignGroups := []export.IosCodeSignGroup{}

codeSignGroups, err := collectIpaExportSelectableCodeSignGroups(archive, installedCertificates, installedProfiles)
if err != nil {
return nil, ArchiveError{tool, "failed to collect valid code sign settings: " + err.Error()}
}

codeSignGroups := collectIpaExportSelectableCodeSignGroups(archive, installedCertificates, installedProfiles)
if len(codeSignGroups) == 0 {
fmt.Println()
log.Errorf("No code sign files (Codesign Identities and Provisioning Profiles) are installed to export an ipa")
log.Errorf("To collect available code sign files, we search for installed Provisioning Profiles:")
log.Errorf("- which has installed Codesign Identity in your Keychain")
log.Errorf("- which can provision your application target's bundle ids")
log.Errorf("- which has the project defined Capabilities set")
return nil, ArchiveError{tool, "failed to find code sign files"}
return nil, errors.New("no code sign files (Codesign Identities and Provisioning Profiles) are installed to export an ipa\n" + collectCodesigningFilesInfo)
}

exportMethods := []string{"development", "app-store", "ad-hoc", "enterprise"}
Expand All @@ -166,7 +158,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
fmt.Println()
selectedExportMethod, err := goinp.SelectFromStringsWithDefault("Select the ipa export method", 1, exportMethods)
if err != nil {
return nil, ArchiveError{tool, "failed to select ipa export method: " + err.Error()}
return nil, fmt.Errorf("failed to read input: %s", err)
}
log.Debugf("selected export method: %v", selectedExportMethod)

Expand All @@ -183,20 +175,14 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins

if len(filteredCodeSignGroups) == 0 {
fmt.Println()
log.Errorf("No code sign files (Codesign Identities and Provisioning Profiles) are installed for %s ipa export", selectedExportMethod)
log.Errorf("To collect available code sign files, we search for installed Provisioning Profiles:")
log.Errorf("- which has installed Codesign Identity in your Keychain")
log.Errorf("- which can provision your application target's bundle ids")
log.Errorf("- which has the project defined Capabilities set")
log.Errorf("- which matches to the selected ipa export method")

log.Errorf(collectCodesigningFilesInfo)
fmt.Println()
fmt.Println()
question := "Do you want to collect another ipa export code sign files"
question += "\n(select NO to finish collecting codesign files and continue)"
anotherExport, err := goinp.AskForBoolWithDefault(question, false)
if err != nil {
return nil, fmt.Errorf("failed to ask: %s", err)
return nil, fmt.Errorf("failed to read input: %s", err)
}
if !anotherExport {
break
Expand Down Expand Up @@ -226,7 +212,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
question := fmt.Sprintf("Select the Codesign Indentity for %s ipa export", selectedExportMethod)
selectedCertificateOption, err = goinp.SelectFromStringsWithDefault(question, 1, certificateOptions)
if err != nil {
return nil, ArchiveError{tool, fmt.Sprintf("failed to select Codesign Indentity: %s", err)}
return nil, fmt.Errorf("failed to read input: %s", err)
}
}

Expand All @@ -239,7 +225,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
}
}
if selectedCertificate == nil {
return nil, ArchiveError{tool, "failed to find selected Codesign Indentity"}
return nil, errors.New("failed to find selected Codesign Indentity")
}

// Select Profiles
Expand All @@ -252,7 +238,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
}
}
if len(bundleIDProfilesMap) == 0 {
return nil, ArchiveError{tool, "failed to find Provisioning Profiles for Code Sign Identity"}
return nil, errors.New("failed to find Provisioning Profiles for Code Sign Identity")
}

selectedBundleIDProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{}
Expand All @@ -276,7 +262,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
question := fmt.Sprintf("Select the Provisioning Profile to sign target with bundle ID: %s", bundleID)
selectedProfileOption, err = goinp.SelectFromStringsWithDefault(question, 1, profileOptions)
if err != nil {
return nil, ArchiveError{tool, fmt.Sprintf("failed to select Provisioning Profile: %s", err)}
return nil, fmt.Errorf("failed to read input: %s", err)
}
}

Expand All @@ -288,7 +274,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
}
}
if len(selectedBundleIDProfileMap) != len(bundleIDProfilesMap) {
return nil, ArchiveError{tool, fmt.Sprintf("failed to find Provisioning Profiles for ipa export")}
return nil, fmt.Errorf("failed to find Provisioning Profiles for ipa export")
}

iosCodeSignGroup := export.IosCodeSignGroup{
Expand All @@ -310,7 +296,7 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
question += "\n(select NO to finish collecting codesign files and continue)"
anotherExport, err := goinp.AskForBoolWithDefault(question, false)
if err != nil {
return nil, fmt.Errorf("failed to ask: %s", err)
return nil, fmt.Errorf("failed to read input: %s", err)
}
if !anotherExport {
break
Expand All @@ -323,11 +309,11 @@ func collectIpaExportCodeSignGroups(tool Tool, archive xcarchive.IosArchive, ins
func collectIpaExportCertificate(tool Tool, archiveCertificate certificateutil.CertificateInfoModel, installedCertificates []certificateutil.CertificateInfoModel) (certificateutil.CertificateInfoModel, error) {
fmt.Println()
fmt.Println()
question := fmt.Sprintf(`The Xcode archive used codesigning files of team: %s - %s
question := fmt.Sprintf(`The archive used codesigning files of team: %s - %s
Would you like to use this team to sign your project?`, archiveCertificate.TeamID, archiveCertificate.TeamName)
useArchiveTeam, err := goinp.AskForBoolWithDefault(question, true)
if err != nil {
return certificateutil.CertificateInfoModel{}, fmt.Errorf("failed to ask: %s", err)
return certificateutil.CertificateInfoModel{}, fmt.Errorf("failed to read input: %s", err)
}

selectedTeam := ""
Expand All @@ -342,7 +328,7 @@ Would you like to use this team to sign your project?`, archiveCertificate.TeamI
fmt.Println()
selectedTeam, err = goinp.SelectFromStringsWithDefault("Select the Development team to sign your project", 1, teams)
if err != nil {
return certificateutil.CertificateInfoModel{}, ArchiveError{tool, fmt.Sprintf("failed to select Codesign Indentity: %s", err)}
return certificateutil.CertificateInfoModel{}, fmt.Errorf("failed to read input: %s", err)
}
} else {
selectedTeam = fmt.Sprintf("%s - %s", archiveCertificate.TeamID, archiveCertificate.TeamName)
Expand All @@ -367,7 +353,7 @@ Would you like to use this team to sign your project?`, archiveCertificate.TeamI
Please select a development certificate:`, archiveCertificate.CommonName, archiveCertificate.Serial)
selectedCertificateOption, err := goinp.SelectFromStringsWithDefault(question, 1, certificateOptions)
if err != nil {
return certificateutil.CertificateInfoModel{}, ArchiveError{tool, fmt.Sprintf("failed to select Codesign Indentity: %s", err)}
return certificateutil.CertificateInfoModel{}, fmt.Errorf("failed to read input: %s", err)
}

for _, certInfo := range developmentCertificates {
Expand All @@ -393,7 +379,7 @@ Please select a development certificate:`, archiveCertificate.CommonName, archiv
Please select a distribution certificate:`, archiveCertificate.CommonName, archiveCertificate.Serial)
selectedCertificateOption, err := goinp.SelectFromStringsWithDefault(question, 1, certificateOptions)
if err != nil {
return certificateutil.CertificateInfoModel{}, ArchiveError{tool, fmt.Sprintf("failed to select Codesign Indentity: %s", err)}
return certificateutil.CertificateInfoModel{}, fmt.Errorf("failed to read input: %s", err)
}

for _, certInfo := range distributionCertificates {
Expand Down Expand Up @@ -429,14 +415,14 @@ func collectAndExportProvisioningProfiles(profiles []profileutil.ProvisioningPro
log.Printf("searching for required Provisioning Profile: %s (UUID: %s)", profile.Name, profile.UUID)
_, pth, err := profileutil.FindProvisioningProfileInfo(profile.UUID)
if err != nil {
return errors.Wrap(err, "Failed to find Provisioning Profile")
return errors.Wrap(err, "failed to find Provisioning Profile")
}
profilePathInfoMap[pth] = profile
log.Printf("file found at: %s", pth)
}

if err := exportProvisioningProfiles(profilePathInfoMap, absExportOutputDirPath); err != nil {
return fmt.Errorf("Failed to export the Provisioning Profile into the export directory: %s", err)
return fmt.Errorf("failed to export the Provisioning Profile into the export directory: %s", err)
}

return nil
Expand Down Expand Up @@ -466,11 +452,11 @@ func collectAndExportIdentities(certificates []certificateutil.CertificateInfoMo
log.Printf("searching for Identity: %s", certificate.CommonName)
identityRef, err := osxkeychain.FindAndValidateIdentity(certificate.CommonName)
if err != nil {
return fmt.Errorf("Failed to export, error: %s", err)
return fmt.Errorf("failed to export, error: %s", err)
}

if identityRef == nil {
return errors.New("Identity not found in the keychain, or it was invalid (expired)")
return errors.New("identity not found in the keychain, or it was invalid (expired)")
}

identitiesWithKeychainRefs = append(identitiesWithKeychainRefs, *identityRef)
Expand All @@ -497,7 +483,7 @@ func collectAndExportIdentities(certificates []certificateutil.CertificateInfoMo
fmt.Println()

if err := osxkeychain.ExportFromKeychain(identityKechainRefs, filepath.Join(absExportOutputDirPath, "Identities.p12"), isAskForPassword); err != nil {
return fmt.Errorf("Failed to export from Keychain: %s", err)
return fmt.Errorf("failed to export from Keychain: %s", err)
}

return nil
Expand Down Expand Up @@ -542,7 +528,7 @@ func exportCodesignFiles(tool Tool, archivePath, outputDirPath string) error {
// archive code sign settings
installedCertificates, err := certificateutil.InstalledCodesigningCertificateInfos()
if err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to list installed code signing identities, error: %s", err)}
return fmt.Errorf("failed to list installed code signing identities, error: %s", err)
}
installedCertificates = certificateutil.FilterValidCertificateInfos(installedCertificates)

Expand All @@ -553,7 +539,7 @@ func exportCodesignFiles(tool Tool, archivePath, outputDirPath string) error {

installedProfiles, err := profileutil.InstalledProvisioningProfileInfos(profileutil.ProfileTypeIos)
if err != nil {
return err
return fmt.Errorf("failed to list installed provisioning profiles, error: %s", err)
}

log.Debugf("Installed profiles:")
Expand All @@ -563,16 +549,16 @@ func exportCodesignFiles(tool Tool, archivePath, outputDirPath string) error {

archive, err := xcarchive.NewIosArchive(archivePath)
if err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to analyze archive, error: %s", err)}
return fmt.Errorf("failed to analyze archive, error: %s", err)
}

archiveCodeSignGroup, err := analyzeArchive(archive, installedCertificates)
if err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to analyze the archive, error: %s", err)}
return fmt.Errorf("failed to analyze the archive, error: %s", err)
}

fmt.Println()
log.Infof("Codesign settings used for Xamarin archive:")
log.Infof("Codesign settings used for archive:")
fmt.Println()
printCodesignGroup(archiveCodeSignGroup)

Expand All @@ -594,7 +580,11 @@ func exportCodesignFiles(tool Tool, archivePath, outputDirPath string) error {
} else {
ipaExportCodeSignGroups, err := collectIpaExportCodeSignGroups(tool, archive, installedCertificates, installedProfiles)
if err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to collect ipa export code sign groups, error: %s", err)}
return err
}

if len(ipaExportCodeSignGroups) == 0 {
return errors.New("no ipa export code sign groups collected")
}

codeSignGroups := append(ipaExportCodeSignGroups, archiveCodeSignGroup)
Expand All @@ -605,19 +595,20 @@ func exportCodesignFiles(tool Tool, archivePath, outputDirPath string) error {
}

if err := collectAndExportIdentities(certificatesToExport, outputDirPath); err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to export codesign identities, error: %s", err)}
return err
}

if err := collectAndExportProvisioningProfiles(profilesToExport, outputDirPath); err != nil {
return ArchiveError{tool, fmt.Sprintf("failed to export provisioning profiles, error: %s", err)}
return err
}

fmt.Println()
log.Successf("Exports finished you can find the exported files at: %s", outputDirPath)
if err := command.RunCommand("open", outputDirPath); err != nil {
log.Errorf("Failed to open the export directory in Finder: %s", outputDirPath)
} else {
fmt.Println("Opened the directory in Finder.")
}
fmt.Println("Opened the directory in Finder.")

printFinished(certificatesOnly)

Expand Down
2 changes: 1 addition & 1 deletion cmd/xcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ the one you usually open in Xcode, then hit Enter.
}
}
if err != nil {
return ArchiveError{toolXcode, "failed to run Xcode Archive: " + err.Error()}
return ArchiveError{toolXcode, err.Error()}
}

return exportCodesignFiles("Xcode", archivePath, absExportOutputDirPath)
Expand Down
8 changes: 4 additions & 4 deletions xcode/xcodecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (xccmd CommandModel) GenerateArchive() (string, string, error) {

tmpDir, err := pathutil.NormalizedOSTempDirPath("__codesigndoc__")
if err != nil {
return "", "", fmt.Errorf("Failed to create temp dir for archives, error: %s", err)
return "", "", fmt.Errorf("failed to create temp dir for archives, error: %s", err)
}
tmpArchivePath := filepath.Join(tmpDir, xccmd.Scheme+".xcarchive")

Expand All @@ -54,7 +54,7 @@ func (xccmd CommandModel) GenerateArchive() (string, string, error) {
fmt.Println()

if err != nil {
return "", xcoutput, fmt.Errorf("Failed to Archive, error: %s", err)
return "", xcoutput, err
}
return tmpArchivePath, xcoutput, nil
}
Expand All @@ -65,7 +65,7 @@ func (xccmd CommandModel) xcodeProjectOrWorkspaceParam() (string, error) {
} else if strings.HasSuffix(xccmd.ProjectFilePath, "xcodeproj") {
return "-project", nil
}
return "", fmt.Errorf("Invalid project/workspace file, the extension should be either .xcworkspace or .xcodeproj ; (file path: %s)", xccmd.ProjectFilePath)
return "", fmt.Errorf("invalid project/workspace file, the extension should be either .xcworkspace or .xcodeproj ; (file path: %s)", xccmd.ProjectFilePath)
}

func (xccmd CommandModel) transformToXcodebuildParams(xcodebuildActionArgs ...string) ([]string, error) {
Expand Down Expand Up @@ -99,7 +99,7 @@ func (xccmd CommandModel) RunXcodebuildCommand(xcodebuildActionArgs ...string) (
log.Infof("$ xcodebuild %s", command.PrintableCommandArgs(true, xcodeCmdParamsToRun))
xcoutput, err := command.RunCommandAndReturnCombinedStdoutAndStderr("xcodebuild", xcodeCmdParamsToRun...)
if err != nil {
return xcoutput, fmt.Errorf("Failed to run xcodebuild command, error: %s", err)
return xcoutput, fmt.Errorf("failed to run xcodebuild command, error: %s", err)
}

log.Debugf("xcoutput: %s", xcoutput)
Expand Down