Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(internal): Add packages set to SentrySdkInfo #4598

Closed
wants to merge 13 commits into from
Closed
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

- Track adoption of `enablePersistingTracesWhenCrashing` (#4587)

### Internal

- Add `packages` set to SentrySdkInfo (#4598)
Copy link

Choose a reason for hiding this comment

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

  • 🚫 The changelog entry seems to be part of an already released section ## 8.42.0.
    Consider moving the entry to the ## Unreleased section, please.


## 8.42.0-beta.1

### Features
Expand Down
22 changes: 22 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
15E0A8F22411A45A00F044E3 /* SentrySession.m in Sources */ = {isa = PBXBuildFile; fileRef = 15E0A8F12411A45A00F044E3 /* SentrySession.m */; };
33042A0D29DAF79A00C60085 /* SentryExtraContextProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 33042A0C29DAF79A00C60085 /* SentryExtraContextProvider.m */; };
33042A1729DC2C4300C60085 /* SentryExtraContextProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33042A1629DC2C4300C60085 /* SentryExtraContextProviderTests.swift */; };
33764D522D00AF3E0099E35A /* SentrySdkPackage+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 33764D512D00AF3E0099E35A /* SentrySdkPackage+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
33764D552D00B7920099E35A /* SentrySdkPackage+Equality.m in Sources */ = {isa = PBXBuildFile; fileRef = 33764D542D00B7920099E35A /* SentrySdkPackage+Equality.m */; };
33764D572D00C33F0099E35A /* SentryMetaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33764D562D00C33F0099E35A /* SentryMetaTests.swift */; };
339733E62D0096C100C632F1 /* SentrySdkPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 339733E52D0096C100C632F1 /* SentrySdkPackage.m */; };
339733E82D00972200C632F1 /* SentrySdkPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = 339733E72D00972200C632F1 /* SentrySdkPackage.h */; settings = {ATTRIBUTES = (Private, ); }; };
33EB2A912C3412E4004FED3D /* SentryWithoutUIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 33EB2A8F2C3411AE004FED3D /* SentryWithoutUIKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
33EB2A922C341300004FED3D /* Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 63AA76931EB9C1C200D153DE /* Sentry.h */; settings = {ATTRIBUTES = (Public, ); }; };
51B15F7E2BE88A7C0026A2F2 /* URLSessionTaskHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B15F7D2BE88A7C0026A2F2 /* URLSessionTaskHelper.swift */; };
Expand Down Expand Up @@ -1070,6 +1075,12 @@
33042A0B29DAF5F400C60085 /* SentryExtraContextProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryExtraContextProvider.h; sourceTree = "<group>"; };
33042A0C29DAF79A00C60085 /* SentryExtraContextProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryExtraContextProvider.m; sourceTree = "<group>"; };
33042A1629DC2C4300C60085 /* SentryExtraContextProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryExtraContextProviderTests.swift; sourceTree = "<group>"; };
33764D512D00AF3E0099E35A /* SentrySdkPackage+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentrySdkPackage+Private.h"; sourceTree = "<group>"; };
33764D532D00B7730099E35A /* SentrySdkPackage+Equality.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentrySdkPackage+Equality.h"; sourceTree = "<group>"; };
33764D542D00B7920099E35A /* SentrySdkPackage+Equality.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentrySdkPackage+Equality.m"; sourceTree = "<group>"; };
33764D562D00C33F0099E35A /* SentryMetaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMetaTests.swift; sourceTree = "<group>"; };
339733E52D0096C100C632F1 /* SentrySdkPackage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySdkPackage.m; sourceTree = "<group>"; };
339733E72D00972200C632F1 /* SentrySdkPackage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySdkPackage.h; path = include/SentrySdkPackage.h; sourceTree = "<group>"; };
33EB2A8F2C3411AE004FED3D /* SentryWithoutUIKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryWithoutUIKit.h; path = Public/SentryWithoutUIKit.h; sourceTree = "<group>"; };
51B15F7D2BE88A7C0026A2F2 /* URLSessionTaskHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionTaskHelper.swift; sourceTree = "<group>"; };
51B15F7F2BE88D510026A2F2 /* URLSessionTaskHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionTaskHelperTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2245,6 +2256,11 @@
7BE1E32624F7AE08009D3AD0 /* SentrySession+Private.h */,
7B88F2FD24BC5A4C00ADF90A /* SentrySdkInfo.h */,
7B88F2FF24BC5A7D00ADF90A /* SentrySdkInfo.m */,
339733E72D00972200C632F1 /* SentrySdkPackage.h */,
33764D512D00AF3E0099E35A /* SentrySdkPackage+Private.h */,
339733E52D0096C100C632F1 /* SentrySdkPackage.m */,
33764D532D00B7730099E35A /* SentrySdkPackage+Equality.h */,
33764D542D00B7920099E35A /* SentrySdkPackage+Equality.m */,
7BFC169A2524995700FF6266 /* SentryMessage.h */,
7BFC16A025249A9D00FF6266 /* SentryMessage.m */,
7BB654FA253DC14A00887E87 /* SentryUserFeedback.h */,
Expand Down Expand Up @@ -2900,6 +2916,7 @@
7B3B473D25D6CEA500D01640 /* SentryNSErrorTests.swift */,
7BC6EC13255C415E0059822A /* SentryExceptionTests.swift */,
7BC6EC17255C44540059822A /* SentryDebugMetaTests.swift */,
33764D562D00C33F0099E35A /* SentryMetaTests.swift */,
7B4E375A2582313100059C93 /* SentryAttachmentTests.swift */,
7BE8E8442593313500C4DA1F /* SentryAttachment+Equality.h */,
7BE8E8452593313500C4DA1F /* SentryAttachment+Equality.m */,
Expand Down Expand Up @@ -4066,6 +4083,7 @@
63FE717920DA4C1100CDBAE8 /* SentryCrashReportStore.h in Headers */,
0AAE202128ED9BCC00D0CD80 /* SentryReachability.h in Headers */,
D858FA662A29EAB3002A3503 /* SentryBinaryImageCache.h in Headers */,
339733E82D00972200C632F1 /* SentrySdkPackage.h in Headers */,
A839D89824864B80003B7AFD /* SentrySystemEventBreadcrumbs.h in Headers */,
7B14089624878F090035403D /* SentryCrashStackEntryMapper.h in Headers */,
63FE714920DA4C1100CDBAE8 /* SentryCrashStackCursor_Backtrace.h in Headers */,
Expand Down Expand Up @@ -4134,6 +4152,7 @@
8E564AEF267AF24400FE117D /* SentryNetworkTracker.h in Headers */,
63FE715120DA4C1100CDBAE8 /* SentryCrashDebug.h in Headers */,
63FE70F520DA4C1000CDBAE8 /* SentryCrashMonitor_System.h in Headers */,
33764D522D00AF3E0099E35A /* SentrySdkPackage+Private.h in Headers */,
7B31C291277B04A000337126 /* SentryCrashPlatformSpecificDefines.h in Headers */,
7B77BE3527EC8445003C9020 /* SentryDiscardReasonMapper.h in Headers */,
7B610D602512390E00B0B5D9 /* SentrySDK+Private.h in Headers */,
Expand Down Expand Up @@ -4666,6 +4685,7 @@
63FE711120DA4C1000CDBAE8 /* SentryCrashDebug.c in Sources */,
7B883F49253D714C00879E62 /* SentryCrashUUIDConversion.c in Sources */,
63FE716720DA4C1100CDBAE8 /* SentryCrashCPU.c in Sources */,
339733E62D0096C100C632F1 /* SentrySdkPackage.m in Sources */,
63FE717320DA4C1100CDBAE8 /* SentryCrashC.c in Sources */,
63FE712120DA4C1000CDBAE8 /* SentryCrashSymbolicator.c in Sources */,
63FE70D720DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.c in Sources */,
Expand Down Expand Up @@ -4929,6 +4949,7 @@
63EED6C32237989300E02400 /* SentryOptionsTest.m in Sources */,
7BBD18B22451804C00427C76 /* SentryRetryAfterHeaderParserTests.swift in Sources */,
7BD337E424A356180050DB6E /* SentryCrashIntegrationTests.swift in Sources */,
33764D552D00B7920099E35A /* SentrySdkPackage+Equality.m in Sources */,
62C3168B2B1F865A000D7031 /* SentryTimeSwiftTests.swift in Sources */,
7BD4E8E827FD95900086C410 /* SentryMigrateSessionInitTests.m in Sources */,
7B6CC50224EE5A42001816D7 /* SentryHubTests.swift in Sources */,
Expand Down Expand Up @@ -5078,6 +5099,7 @@
7B965728268321CD00C66E25 /* SentryCrashScopeObserverTests.swift in Sources */,
7BD86ECB264A6DB5005439DB /* TestSysctl.swift in Sources */,
D861301C2BB5A267004C0F5E /* SentrySessionReplayTests.swift in Sources */,
33764D572D00C33F0099E35A /* SentryMetaTests.swift in Sources */,
7B0DC73428869BF40039995F /* NSMutableDictionarySentryTests.swift in Sources */,
7B6ADFCF26A02CAE0076C206 /* SentryCrashReportTests.swift in Sources */,
D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Sources/Resources/Sentry.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ framework module Sentry {
header "SentrySessionReplayIntegration-Hybrid.h"

header "SentrySdkInfo.h"
header "SentrySdkPackage.h"
header "SentryInternalSerializable.h"

export *
Expand Down
6 changes: 6 additions & 0 deletions Sources/Sentry/PrivateSentrySDKOnly.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import <SentryFramesTracker.h>
#import <SentryScope+Private.h>
#import <SentryScreenshot.h>
#import <SentrySdkPackage.h>
#import <SentryUser.h>

#if SENTRY_TARGET_PROFILING_SUPPORTED
Expand Down Expand Up @@ -188,6 +189,11 @@ + (NSString *)getSdkVersionString
return SentryMeta.versionString;
}

+ (void)addSdkPackage:(nonnull NSString *)name version:(nonnull NSString *)version
{
[SentryMeta addSdkPackage:name version:version];
}

+ (NSDictionary *)getExtraContext
{
return [SentryDependencyContainer.sharedInstance.extraContextProvider getExtraContext];
Expand Down
3 changes: 2 additions & 1 deletion Sources/Sentry/SentryClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,8 @@ - (void)setSdk:(SentryEvent *)event
@"name" : SentryMeta.sdkName,
@"version" : SentryMeta.versionString,
@"integrations" : integrations,
@"features" : features
@"features" : features,
@"packages" : [SentryMeta getSdkPackagesSerialized],
};
}

Expand Down
3 changes: 2 additions & 1 deletion Sources/Sentry/SentryEnvelope.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ - (instancetype)initWithId:(nullable SentryId *)eventId
traceContext:(nullable SentryTraceContext *)traceContext
{
SentrySdkInfo *sdkInfo = [[SentrySdkInfo alloc] initWithName:SentryMeta.sdkName
andVersion:SentryMeta.versionString];
andVersion:SentryMeta.versionString
andPackages:[SentryMeta getSdkPackages]];
Comment on lines +34 to +35
Copy link
Member

Choose a reason for hiding this comment

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

h: The SDKInfo of the envelope header is the same as the one from the event payload: see

This can carry the same payload as the sdk interface
in the event payload but can be carried for all events. This means that SDK
information can be carried for minidumps, session data and other submissions. - https://develop.sentry.dev/sdk/data-model/envelopes/#envelope-headers

Now that we touch both SDKInfo for the envelope header and the event payload, I think it would be great to merge the different implementations. To make this easier we could do this in an extra PR before adding the new packages implementation.

self = [self initWithId:eventId sdkInfo:sdkInfo traceContext:traceContext];
return self;
}
Expand Down
50 changes: 50 additions & 0 deletions Sources/Sentry/SentryMeta.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ @implementation SentryMeta
static NSString *versionString = @"8.42.0-beta.2";
static NSString *sdkName = @"sentry.cocoa";

static NSSet<SentrySdkPackage *> *sdkPackages;

+ (NSString *)versionString
{
return versionString;
Expand All @@ -28,4 +30,52 @@ + (void)setSdkName:(NSString *)value
sdkName = value;
}

+ (NSArray<NSDictionary<NSString *, NSString *> *> *)getSdkPackagesSerialized
{
NSMutableArray *serializedPackages = [NSMutableArray array];
for (SentrySdkPackage *package in [self getSdkPackages]) {
[serializedPackages addObject:[package serialize]];
}
return serializedPackages;
}

+ (NSSet<SentrySdkPackage *> *)getSdkPackages
{
@synchronized(self) {
if (sdkPackages == nil) {
[self initializeSdkPackages];
}
return sdkPackages;
}
}

+ (void)addSdkPackage:(NSString *_Nonnull)name version:(NSString *_Nonnull)version
{
@synchronized(self) {
if (sdkPackages == nil) {
[self initializeSdkPackages];
}
sdkPackages = [sdkPackages
setByAddingObject:[[SentrySdkPackage alloc] initWithName:name andVersion:version]];
}
}

+ (void)initializeSdkPackages
{
SentrySdkPackage *sdkPackage = [SentrySdkPackage getSentrySDKPackage];
if (nil == sdkPackage) {
sdkPackages = [NSSet set];
return;
}

sdkPackages = [NSSet setWithObject:sdkPackage];
}

#if TEST
+ (void)clearSdkPackages
{
sdkPackages = nil;
}
#endif

@end
92 changes: 37 additions & 55 deletions Sources/Sentry/SentrySdkInfo.m
Original file line number Diff line number Diff line change
@@ -1,49 +1,32 @@
#import "SentrySdkInfo.h"
#import <Foundation/Foundation.h>

typedef NS_ENUM(NSUInteger, SentryPackageManagerOption) {
SentrySwiftPackageManager,
SentryCocoaPods,
SentryCarthage,
SentryPackageManagerUnkown
};

/**
* This is required to identify the package manager used when installing sentry.
*/
#if SWIFT_PACKAGE
static SentryPackageManagerOption SENTRY_PACKAGE_INFO = SentrySwiftPackageManager;
#elif COCOAPODS
static SentryPackageManagerOption SENTRY_PACKAGE_INFO = SentryCocoaPods;
#elif CARTHAGE_YES
// CARTHAGE is a xcodebuild build setting with value `YES`, we need to convert it into a compiler
// definition to be able to use it.
static SentryPackageManagerOption SENTRY_PACKAGE_INFO = SentryCarthage;
#else
static SentryPackageManagerOption SENTRY_PACKAGE_INFO = SentryPackageManagerUnkown;
#endif

NS_ASSUME_NONNULL_BEGIN

@interface SentrySdkInfo ()

@property (nonatomic) SentryPackageManagerOption packageManager;

@end

@implementation SentrySdkInfo

- (instancetype)initWithName:(NSString *)name andVersion:(NSString *)version
- (instancetype)initWithName:(NSString *)name
andVersion:(NSString *)version
andPackages:(NSSet<SentrySdkPackage *> *)packages
{
if (self = [super init]) {
_name = name ?: @"";
_version = version ?: @"";
_packageManager = SENTRY_PACKAGE_INFO;
_packages = packages ?: [NSSet set];
}

return self;
}

- (instancetype)initWithName:(NSString *)name andVersion:(NSString *)version
{
return [self initWithName:name andVersion:version andPackages:[NSSet set]];
}

- (instancetype)initWithDict:(NSDictionary *)dict
{
return [self initWithDictInternal:dict orDefaults:nil];
Expand All @@ -58,6 +41,7 @@
{
NSString *name = @"";
NSString *version = @"";
NSSet *packages = [NSSet set];

if (nil != dict[@"sdk"] && [dict[@"sdk"] isKindOfClass:[NSDictionary class]]) {
NSDictionary<NSString *, id> *sdkInfoDict = dict[@"sdk"];
Expand All @@ -72,43 +56,41 @@
} else if (info && info.version) {
version = info.version;
}
}

return [self initWithName:name andVersion:version];
}

- (nullable NSString *)getPackageName:(SentryPackageManagerOption)packageManager
{
switch (packageManager) {
case SentrySwiftPackageManager:
return @"spm:getsentry/%@";
case SentryCocoaPods:
return @"cocoapods:getsentry/%@";
case SentryCarthage:
return @"carthage:getsentry/%@";
default:
return nil;
if ([sdkInfoDict[@"packages"] isKindOfClass:[NSArray class]]) {
NSMutableSet *newPackages = [NSMutableSet set];
for (id maybePackageDict in sdkInfoDict[@"packages"]) {
if ([maybePackageDict isKindOfClass:[NSDictionary class]]) {
SentrySdkPackage *package =
[[SentrySdkPackage alloc] initWithDict:maybePackageDict];
if (package != nil) {
[newPackages addObject:package];
}
}
}
packages = newPackages;
} else if (info && info.packages) {
packages = info.packages;

Check warning on line 73 in Sources/Sentry/SentrySdkInfo.m

View check run for this annotation

Codecov / codecov/patch

Sources/Sentry/SentrySdkInfo.m#L73

Added line #L73 was not covered by tests
}
}

return [self initWithName:name andVersion:version andPackages:packages];
}

- (NSDictionary<NSString *, id> *)serialize
{
NSMutableDictionary *sdk = @{
@"name" : self.name,
@"version" : self.version,
}
.mutableCopy;
if (self.packageManager != SentryPackageManagerUnkown) {
NSString *format = [self getPackageName:self.packageManager];
if (format != nil) {
sdk[@"packages"] = @{
@"name" : [NSString stringWithFormat:format, self.name],
@"version" : self.version
};
Comment on lines -104 to -107
Copy link
Member Author

@krystofwoldrich krystofwoldrich Dec 5, 2024

Choose a reason for hiding this comment

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

Based on the development docs this should be an array, I don't know if this value was used anywhere, so I just updated it to the array.

If it's not used I would consider removing it completely and only create packages in SentryClient (same as features, integrations...).

Headers docs: https://develop.sentry.dev/sdk/data-model/envelopes/#envelope-headers

SDK Info interface docs: https://develop.sentry.dev/sdk/data-model/event-payloads/sdk/

}
NSMutableArray *serializedPackages = [NSMutableArray array];
for (SentrySdkPackage *package in self.packages) {
[serializedPackages addObject:[package serialize]];
}

return @{ @"sdk" : sdk };
return @{
@"sdk" : @ {
@"name" : self.name,
@"version" : self.version,
@"packages" : serializedPackages,
},
};
}

@end
Expand Down
13 changes: 13 additions & 0 deletions Sources/Sentry/SentrySdkPackage+Equality.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import "SentrySdkPackage.h"

NS_ASSUME_NONNULL_BEGIN

@interface SentrySdkPackage (Equality)
Copy link
Member

Choose a reason for hiding this comment

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

m: If we use a Swift struct for just the data of SentrySDKPackage you get isEqual for free.


- (BOOL)isEqual:(id _Nullable)object;

- (NSUInteger)hash;

@end

NS_ASSUME_NONNULL_END
35 changes: 35 additions & 0 deletions Sources/Sentry/SentrySdkPackage+Equality.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#import "SentrySdkPackage+Equality.h"

@implementation SentrySdkPackage (Equality)

- (BOOL)isEqual:(id _Nullable)object
{
if (object == self)
return YES;
if ([self class] != [object class])
return NO;

SentrySdkPackage *other = (SentrySdkPackage *)object;

if (![self.name isEqualToString:other.name]) {
return NO;
}

if (![self.version isEqualToString:other.version]) {
return NO;

Check warning on line 19 in Sources/Sentry/SentrySdkPackage+Equality.m

View check run for this annotation

Codecov / codecov/patch

Sources/Sentry/SentrySdkPackage+Equality.m#L19

Added line #L19 was not covered by tests
}

return YES;
}

- (NSUInteger)hash
{
NSUInteger hash = 17;

hash = hash * 23 + [self.name hash];
hash = hash * 23 + [self.version hash];

return hash;
}

@end
Loading
Loading