Skip to content

profileutil v2 migration#304

Open
godrei wants to merge 11 commits intomasterfrom
profileutil-v2
Open

profileutil v2 migration#304
godrei wants to merge 11 commits intomasterfrom
profileutil-v2

Conversation

@godrei
Copy link
Contributor

@godrei godrei commented Jan 29, 2026

profileutil V1→V2 Migration Summary

V1→V2 Structural Transformation

Core Types: No Changes

The primary data structures remain identical between v1 and v2:

ProvisioningProfileInfoModel

// V1 and V2 - Structure unchanged
type ProvisioningProfileInfoModel struct {
    UUID                  string
    Name                  string
    TeamName              string
    TeamID                string
    BundleID              string
    ExportType            exportoptions.Method
    ProvisionedDevices    []string
    DeveloperCertificates []certificateutil.CertificateInfoModel
    CreationDate          time.Time
    ExpirationDate        time.Time
    Entitlements          plistutil.PlistData
    ProvisionsAllDevices  bool
    Type                  ProfileType
}

PlistData

// V1 and V2 - Type alias unchanged
type PlistData plistutil.PlistData

ProfileType Constants

// V1 and V2 - Constants unchanged
const (
    ProfileTypeIos   ProfileType = "ios"
    ProfileTypeMacOs ProfileType = "osx"
    ProfileTypeTvOs  ProfileType = "tvos"
)

Key Architectural Changes

The migration introduces struct-based APIs replacing v1's function-based approach, following go-utils v2 patterns for better testability and dependency injection.

V1→V2 Function Migration

1. Profile Reading Functions → ProfileReader Struct

V1: Package-level functions

// v1/profileutil/util.go
func ProvisioningProfileFromFile(pth string) (*pkcs7.PKCS7, error)
func InstalledProvisioningProfiles(profileType ProfileType) ([]*pkcs7.PKCS7, error)
func FindProvisioningProfile(uuid string) (*pkcs7.PKCS7, string, error)

// v1/profileutil/info_model.go
func NewProvisioningProfileInfoFromFile(pth string) (ProvisioningProfileInfoModel, error)
func InstalledProvisioningProfileInfos(profileType ProfileType) ([]ProvisioningProfileInfoModel, error)
func FindProvisioningProfileInfo(uuid string) (ProvisioningProfileInfoModel, string, error)

V2: ProfileReader struct with injected dependencies

// v2/profileutil/profile_reader.go
type ProfileReader struct {
    logger       log.Logger              // v2 logger
    fileManager  fileutil.FileManager    // v2 file operations
    pathModifier pathutil.PathModifier   // v2 path utilities
    pathProvider pathutil.PathProvider   // v2 glob operations
    pathChecker  pathutil.PathChecker    // v2 path checking
}

func NewProfileReader(...) ProfileReader

// Instance methods
func (r ProfileReader) ProvisioningProfileInfoFromFile(pth string) (ProvisioningProfileInfoModel, error)
func (r ProfileReader) InstalledProvisioningProfileInfos(profileType ProfileType) ([]ProvisioningProfileInfoModel, error)

// Private helpers (no longer exposed)
func (r ProfileReader) provisioningProfileFromFile(pth string) (*pkcs7.PKCS7, error)
func (r ProfileReader) installedProvisioningProfiles(profileType ProfileType) ([]*pkcs7.PKCS7, error)

Changes:

  • NewProvisioningProfileInfoFromFile()ProfileReader.ProvisioningProfileInfoFromFile()
  • InstalledProvisioningProfileInfos()ProfileReader.InstalledProvisioningProfileInfos()
  • FindProvisioningProfileInfo() - Removed (unused by consumers)
  • 🔒 ProvisioningProfileFromFile() → private provisioningProfileFromFile()
  • 🔒 InstalledProvisioningProfiles() → private installedProvisioningProfiles()
  • 🔒 FindProvisioningProfile() - Removed (unused)

2. Profile Printing Functions → ProfilePrinter Struct

V1: Method on ProvisioningProfileInfoModel

// v1/profileutil/info_model.go
func (info ProvisioningProfileInfoModel) String(installedCertificates ...certificateutil.CertificateInfoModel) string

V2: ProfilePrinter struct

// v2/profileutil/profile_printer.go
type ProfilePrinter struct {
    logger       log.Logger
    timeProvider TimeProvider
}

func NewProfilePrinter(logger log.Logger, timeProvider TimeProvider) *ProfilePrinter
func (p ProfilePrinter) PrintableProfile(profile ProvisioningProfileInfoModel, installedCertificates ...certificateutil.CertificateInfoModel) string

Changes:

  • info.String(certs...)printer.PrintableProfile(info, certs...)
  • Extracted from model method to separate printer struct
  • Added TimeProvider dependency for testable time-based validation
  • Uses v2 logger instead of v1's global log package

3. Model Constructor Functions

V1 and V2: Similar but with key differences

Changes:

  • ✅ Function signature unchanged
  • Platform detection logic moved from constructor to PlistData.GetProfileType()
  • Changed plist library: howett.net/plistgithub.com/bitrise-io/go-plist
  • Better separation of concerns

V2 Addition:

// New helper function
func NewProvisioningProfileInfoFromPKCS7Content(content []byte) (ProvisioningProfileInfoModel, error)

4. Model Validation Methods

V1: Uses global time.Now()

// v1/profileutil/info_model.go
func (info ProvisioningProfileInfoModel) CheckValidity() error {
    timeNow := time.Now()  // Global time - hard to test
    if !timeNow.Before(info.ExpirationDate) {
        return fmt.Errorf("Provisioning Profile is not valid anymore - validity ended at: %s", info.ExpirationDate)
    }
    return nil
}

V2: Time provider pattern for testability

// v2/profileutil/info_model.go
func (info ProvisioningProfileInfoModel) CheckValidity(currentTime func() time.Time) error {
    timeNow := currentTime()  // Injected time provider
    if !timeNow.Before(info.ExpirationDate) {
        return fmt.Errorf("provisioning profile is not valid anymore, validity ended at: %s", info.ExpirationDate)
    }
    return nil
}

Changes:

  • Method now accepts currentTime func() time.Time parameter
  • Enables time-based testing without mocking global state
  • Use DefaultTimeProvider().Now in production code

Unchanged Model Methods:

// Both V1 and V2 - No changes
func (info ProvisioningProfileInfoModel) IsXcodeManaged() bool
func (info ProvisioningProfileInfoModel) HasInstalledCertificate(installedCertificates []certificateutil.CertificateInfoModel) bool

5. PlistData Methods

V1 and V2: Core methods unchanged

These PlistData methods remain identical between v1 and v2:

func (profile PlistData) GetUUID() string
func (profile PlistData) GetName() string
func (profile PlistData) GetApplicationIdentifier() string
func (profile PlistData) GetBundleIdentifier() string
func (profile PlistData) GetExportMethod() exportoptions.Method
func (profile PlistData) GetProvisionedDevices() []string
func (profile PlistData) GetTeamName() string
func (profile PlistData) GetTeamID() string
func (profile PlistData) GetCreationDate() time.Time
func (profile PlistData) GetExpirationDate() time.Time
func (profile PlistData) GetProvisionsAllDevices() bool
func (profile PlistData) GetEntitlements() plistutil.PlistData
func (profile PlistData) GetDeveloperCertificates() [][]byte  // Returns raw byte arrays

V2 Additions: Extracted from NewProvisioningProfileInfo constructor

Two new methods were added by extracting logic that was previously inline in the v1 constructor:

// V2 only - platform detection extracted from v1's NewProvisioningProfileInfo (info_model.go lines 147-164)
func (profile PlistData) GetProfileType() (ProfileType, error)

// V2 only - certificate parsing extracted from v1's NewProvisioningProfileInfo (info_model.go lines 185-200)
func (profile PlistData) GetDeveloperCertificateInfo() []certificateutil.CertificateInfoModel

Benefits:

  • Simpler, more focused constructor
  • Reusable logic for platform detection and certificate parsing
  • Better separation of concerns
  • Easier to test individual pieces

V1 Function Removed:

// V1 only - removed in V2
func NewPlistDataFromFile(provisioningProfilePth string) (PlistData, error)

Functionality replaced by ProfileReader.ProvisioningProfileInfoFromFile()

6. Utility Functions

V1 and V2: Unchanged

// Both versions identical
func IsXcodeManaged(profileName string) bool
func MatchTargetAndProfileEntitlements(targetEntitlements, profileEntitlements plistutil.PlistData, profileType ProfileType) []string

// Capability maps unchanged
var KnownProfileCapabilitiesMap = map[ProfileType]map[string]bool{...}

7. Time Provider (V2 Addition)

New in V2:

// v2/profileutil/time_provider.go
type TimeProvider struct {
    Now func() time.Time
}

func DefaultTimeProvider() TimeProvider {
    return TimeProvider{Now: time.Now}
}

Used for testable time-dependent operations (e.g., CheckValidity).

V1↔V2 Adapter

For gradual migration, v1_adapter.go provides bidirectional conversion:

// v2/profileutil/v1_adapter.go

// Convert v1 → v2
func V2Profile(model profileutilv1.ProvisioningProfileInfoModel) ProvisioningProfileInfoModel

// Convert v2 → v1
func V1Profile(model ProvisioningProfileInfoModel) profileutilv1.ProvisioningProfileInfoModel
func V1Profiles(models []ProvisioningProfileInfoModel) []profileutilv1.ProvisioningProfileInfoModel

// Generic helpers
func copySlice[T any](src []T) []T
func copyMap[K comparable, V any](src map[K]V) map[K]V

Ensures deep copies and allows mixed v1/v2 usage during transition.

godrei added 11 commits January 29, 2026 11:04
# Conflicts:
#	autocodesign/localcodesignasset/profilelookup.go
#	autocodesign/profiles.go
# Conflicts:
#	autocodesign/profiledownloader/profiledownloader.go
#	autocodesign/profiles.go
#	go.mod
#	go.sum
#	mocks/PathModifier.go
#	mocks/PathProvider.go
@godrei godrei changed the title profileutil v2 init profileutil v2 migration Jan 30, 2026
@godrei godrei marked this pull request as ready for review January 30, 2026 16:10

// PrintableProfile ...
func (printer ProfilePrinter) PrintableProfile(profile ProvisioningProfileInfoModel, installedCertificates ...certificateutil.CertificateInfoModel) string {
printable := map[string]interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
printable := map[string]interface{}{}
printable := map[string]any{}

Since golang 1.18 we can use any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants