Skip to content

Commit

Permalink
Add reports-only install
Browse files Browse the repository at this point in the history
  • Loading branch information
bamx23 committed Aug 27, 2024
1 parent 29e574a commit 35e137a
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 28 deletions.
16 changes: 16 additions & 0 deletions Samples/Common/Sources/LibraryBridge/InstallBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class InstallBridge: ObservableObject {

@Published public var basePath: BasePath = .default
@Published public var installed: Bool = false
@Published public var installSkipped: Bool = false
@Published public var error: InstallationError?

public init() {
Expand Down Expand Up @@ -97,6 +98,21 @@ public class InstallBridge: ObservableObject {
self.error = .unexpectedError(message)
}
}

public func installReportsOnly() {
do {
try KSCrash.shared.installReportsOnly(withInstallPath: config.installPath)
installSkipped = true
} catch let error as KSCrashInstallError {
let message = error.localizedDescription
Self.logger.error("Failed to install KSCrash: \(message)")
self.error = .kscrashError(message)
} catch {
let message = error.localizedDescription
Self.logger.error("Unexpected error during KSCrash installation: \(message)")
self.error = .unexpectedError(message)
}
}
}

// An utility method to simplify binding of config fields
Expand Down
9 changes: 3 additions & 6 deletions Samples/Common/Sources/SampleUI/SampleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,16 @@ public struct SampleView: View {

@ObservedObject var installBridge = InstallBridge()

@State private var installSkipped = false

public var body: some View {
NavigationView {
if installBridge.installed || installSkipped {
if installBridge.installed || installBridge.installSkipped {
MainView(
installSkipped: $installSkipped
installSkipped: $installBridge.installSkipped
)
.navigationTitle("KSCrash Sample")
} else {
InstallView(
bridge: installBridge,
installSkipped: $installSkipped
bridge: installBridge
)
.navigationTitle("Install KSCrash")
}
Expand Down
4 changes: 1 addition & 3 deletions Samples/Common/Sources/SampleUI/Screens/InstallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ import LibraryBridge
struct InstallView: View {
@ObservedObject var bridge: InstallBridge

@Binding var installSkipped: Bool

@State private var showingInstallAlert = false

var body: some View {
Expand Down Expand Up @@ -82,7 +80,7 @@ struct InstallView: View {
}

Button("Skip install") {
installSkipped = true
bridge.installReportsOnly()
}
.foregroundStyle(Color.red)
}
Expand Down
15 changes: 15 additions & 0 deletions Sources/KSCrashRecording/KSCrash.m
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,21 @@ - (BOOL)installWithConfiguration:(KSCrashConfiguration *)configuration error:(NS
return YES;
}

- (BOOL)installReportsOnlyWithInstallPath:(NSString *)installPath error:(NSError **)error
{
KSCrashInstallErrorCode result =
kscrash_installReports(self.bundleName.UTF8String, (installPath ?: getDefaultInstallPath()).UTF8String);

if (result != KSCrashInstallErrorNone) {
if (error != NULL) {
*error = [self errorForInstallErrorCode:result];
}
return NO;
}

return YES;
}

- (void)sendAllReportsWithCompletion:(KSCrashReportFilterCompletion)onCompletion
{
NSArray *reports = [self allReports];
Expand Down
61 changes: 49 additions & 12 deletions Sources/KSCrashRecording/KSCrashC.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ static const size_t g_monitorMappingCount = sizeof(g_monitorMappings) / sizeof(g

/** True if KSCrash has been installed. */
static volatile bool g_installed = 0;
/** True if the reports store has been installed. */
static volatile bool g_reportsInstalled = 0;

static bool g_shouldAddConsoleLogToReport = false;
static bool g_shouldPrintPreviousLog = false;
Expand Down Expand Up @@ -209,6 +211,21 @@ void handleConfiguration(KSCrashCConfiguration *configuration)
#pragma mark - API -
// ============================================================================

static KSCrashInstallErrorCode installReportsStore(const char *appName, const char *const installPath)
{
char path[KSFU_MAX_PATH_LENGTH];
if (snprintf(path, sizeof(path), "%s/Reports", installPath) >= (int)sizeof(path)) {
KSLOG_ERROR("Reports path is too long.");
return KSCrashInstallErrorPathTooLong;
}
if (ksfu_makePath(path) == false) {
KSLOG_ERROR("Could not create path: %s", path);
return KSCrashInstallErrorCouldNotCreatePath;
}
kscrs_initialize(appName, path);
return KSCrashInstallErrorNone;
}

KSCrashInstallErrorCode kscrash_install(const char *appName, const char *const installPath,
KSCrashCConfiguration configuration)
{
Expand All @@ -226,19 +243,16 @@ KSCrashInstallErrorCode kscrash_install(const char *appName, const char *const i

handleConfiguration(&configuration);

char path[KSFU_MAX_PATH_LENGTH];
if (snprintf(path, sizeof(path), "%s/Reports", installPath) >= (int)sizeof(path)) {
KSLOG_ERROR("Path too long.");
return KSCrashInstallErrorPathTooLong;
}
if (ksfu_makePath(path) == false) {
KSLOG_ERROR("Could not create path: %s", path);
return KSCrashInstallErrorCouldNotCreatePath;
if (g_reportsInstalled == false) {
KSCrashInstallErrorCode result = installReportsStore(appName, installPath);
if (result != KSCrashInstallErrorNone) {
return result;
}
}
kscrs_initialize(appName, installPath, path);

char path[KSFU_MAX_PATH_LENGTH];
if (snprintf(path, sizeof(path), "%s/Data", installPath) >= (int)sizeof(path)) {
KSLOG_ERROR("Path too long.");
KSLOG_ERROR("Data path is too long.");
return KSCrashInstallErrorPathTooLong;
}
if (ksfu_makePath(path) == false) {
Expand All @@ -248,14 +262,14 @@ KSCrashInstallErrorCode kscrash_install(const char *appName, const char *const i
ksmemory_initialize(path);

if (snprintf(path, sizeof(path), "%s/Data/CrashState.json", installPath) >= (int)sizeof(path)) {
KSLOG_ERROR("Path too long.");
KSLOG_ERROR("Crash state path is too long.");
return KSCrashInstallErrorPathTooLong;
}
kscrashstate_initialize(path);

if (snprintf(g_consoleLogPath, sizeof(g_consoleLogPath), "%s/Data/ConsoleLog.txt", installPath) >=
(int)sizeof(g_consoleLogPath)) {
KSLOG_ERROR("Console log path too long.");
KSLOG_ERROR("Console log path is too long.");
return KSCrashInstallErrorPathTooLong;
}
if (g_shouldPrintPreviousLog) {
Expand All @@ -279,6 +293,29 @@ KSCrashInstallErrorCode kscrash_install(const char *appName, const char *const i
return KSCrashInstallErrorNone;
}

KSCrashInstallErrorCode kscrash_installReports(const char *appName, const char *const installPath)
{
KSLOG_DEBUG("Installing reports store.");

if (g_reportsInstalled) {
KSLOG_DEBUG("Crash reporter already installed.");
return KSCrashInstallErrorAlreadyInstalled;
}

if (appName == NULL || installPath == NULL) {
KSLOG_ERROR("Invalid parameters: appName or installPath is NULL.");
return KSCrashInstallErrorInvalidParameter;
}

KSCrashInstallErrorCode result = installReportsStore(appName, installPath);
if (result != KSCrashInstallErrorNone) {
return result;
}

g_reportsInstalled = true;
return KSCrashInstallErrorNone;
}

void kscrash_setUserInfoJSON(const char *const userInfoJSON) { kscrashreport_setUserInfoJSON(userInfoJSON); }

const char *kscrash_getUserInfoJSON(void) { return kscrashreport_getUserInfoJSON(); }
Expand Down
5 changes: 1 addition & 4 deletions Sources/KSCrashRecording/KSCrashReportStore.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ static _Atomic(uint32_t) g_nextUniqueIDLow;
static int64_t g_nextUniqueIDHigh;
static const char *g_appName;
static const char *g_reportsPath;
static const char *g_installPath;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

static int compareInt64(const void *a, const void *b)
Expand Down Expand Up @@ -157,12 +156,10 @@ static void initializeIDs(void)

// Public API

void kscrs_initialize(const char *appName, const char *installPath, const char *reportsPath)
void kscrs_initialize(const char *appName, const char *reportsPath)
{
pthread_mutex_lock(&g_mutex);
g_appName = strdup(appName);
g_installPath = strdup(installPath);
ksfu_makePath(installPath);
g_reportsPath = strdup(reportsPath);
ksfu_makePath(reportsPath);
pruneReports();
Expand Down
3 changes: 1 addition & 2 deletions Sources/KSCrashRecording/KSCrashReportStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ extern "C" {
/** Initialize the report store.
*
* @param appName The application's name.
* @param installPath Full path to directory where the crash system writes files.
* @param reportsPath Full path to directory where the reports are to be stored (path will be created if needed).
*/
void kscrs_initialize(const char *appName, const char *installPath, const char *reportsPath);
void kscrs_initialize(const char *appName, const char *reportsPath);

/** Get the next crash report to be generated.
* Max length for paths is KSCRS_MAX_PATH_LENGTH
Expand Down
4 changes: 4 additions & 0 deletions Sources/KSCrashRecording/include/KSCrash.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)installWithConfiguration:(KSCrashConfiguration *)configuration error:(NSError **)error;

/** TODO: Add docs
*/
- (BOOL)installReportsOnlyWithInstallPath:(nullable NSString *)installPath error:(NSError **)error;

/** Send all outstanding crash reports to the current sink.
* It will only attempt to send the most recent 5 reports. All others will be
* deleted. Once the reports are successfully sent to the server, they may be
Expand Down
4 changes: 4 additions & 0 deletions Sources/KSCrashRecording/include/KSCrashC.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ extern "C" {
KSCrashInstallErrorCode kscrash_install(const char *appName, const char *const installPath,
KSCrashCConfiguration configuration);

/** TODO: Add docs
*/
KSCrashInstallErrorCode kscrash_installReports(const char *appName, const char *const installPath);

/** Set the user-supplied data in JSON format.
*
* @param userInfoJSON Pre-baked JSON containing user-supplied information.
Expand Down
2 changes: 1 addition & 1 deletion Tests/KSCrashRecordingTests/KSCrashReportStore_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ - (void)setUp
- (void)prepareReportStoreWithPathEnd:(NSString *)pathEnd
{
self.reportStorePath = [self.tempPath stringByAppendingPathComponent:pathEnd];
kscrs_initialize(self.appName.UTF8String, self.tempPath.UTF8String, self.reportStorePath.UTF8String);
kscrs_initialize(self.appName.UTF8String, self.reportStorePath.UTF8String);
}

- (NSArray *)getReportIDs
Expand Down

0 comments on commit 35e137a

Please sign in to comment.