From 73558ac2f5fcc514ba354d39bd6c8c53866ca25d Mon Sep 17 00:00:00 2001 From: Marcin Karmelita Date: Tue, 9 Feb 2021 22:27:17 +0100 Subject: [PATCH 1/5] Update dependencies - Remove dependency on Ruby - Update pods - Update tests with the latest Quick/Nimble syntax - Update Homebrew dependencies --- .ruby-version | 1 - Brewfile | 3 +- Brewfile.lock.json | 53 +++++++++++++----- Gemfile | 3 -- Gemfile.lock | 90 ------------------------------- Podfile | 2 + Podfile.lock | 12 ++--- Tests/BacktraceWatcherTests.swift | 2 +- Tests/DispatcherTests.swift | 4 +- scripts/install.sh | 6 +-- 10 files changed, 55 insertions(+), 121 deletions(-) delete mode 100644 .ruby-version delete mode 100644 Gemfile delete mode 100644 Gemfile.lock diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 25b001e7..00000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ - 2.7.0 diff --git a/Brewfile b/Brewfile index df6007fa..27c6ca77 100644 --- a/Brewfile +++ b/Brewfile @@ -1 +1,2 @@ -brew "fastlane" \ No newline at end of file +brew "fastlane" +brew 'cocoapods' \ No newline at end of file diff --git a/Brewfile.lock.json b/Brewfile.lock.json index cc0b54eb..bbf27ea5 100644 --- a/Brewfile.lock.json +++ b/Brewfile.lock.json @@ -2,22 +2,51 @@ "entries": { "brew": { "fastlane": { - "version": "2.161.0", + "version": "2.172.0", "bottle": { "cellar": ":any", "prefix": "/usr/local", "files": { + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.big_sur.bottle.tar.gz", + "sha256": "f40121e1c323fecb0c6595761ba15674736863d3a7299d1a4d7440f9bef00277" + }, + "arm64_big_sur": { + "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.arm64_big_sur.bottle.tar.gz", + "sha256": "c04de95af044dd37f4d657d40d27663ca58e24a5b482fffc1fe475586228d5ca" + }, "catalina": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.161.0.catalina.bottle.tar.gz", - "sha256": "fa9092e388bca3b32807eddcc1c6514e92f3e5e20da966f82bd7670c3e0d42d3" + "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.catalina.bottle.tar.gz", + "sha256": "beebe5c5fe53f942437727398218574c9dc7f86e8cd7c73a3164b7fe0ab88dd7" }, "mojave": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.161.0.mojave.bottle.tar.gz", - "sha256": "431e169597585884f93781f00c17c64fd779d6ea311602891567236146473c5f" + "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.mojave.bottle.tar.gz", + "sha256": "eeaeb3dbf3490b81aa0d6a085f5076778e61f566f4876c1d2c87adc022a3a210" + } + } + } + }, + "cocoapods": { + "version": "1.10.1", + "bottle": { + "cellar": "/usr/local/Cellar", + "prefix": "/usr/local", + "files": { + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.big_sur.bottle.tar.gz", + "sha256": "0caa8953926c827f62d53f9767aed0a904604c0425ea0557b24d738240db809a" + }, + "arm64_big_sur": { + "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.arm64_big_sur.bottle.tar.gz", + "sha256": "08794cfd260bf206eed3496805816661da367bffdf9af748cd812b1c40a0de75" }, - "high_sierra": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.161.0.high_sierra.bottle.tar.gz", - "sha256": "39bdfc80e896775b45617f1b7bb9f209cad91b91a5bb0a3cbeae0ed0080f45cc" + "catalina": { + "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.catalina.bottle.tar.gz", + "sha256": "3a05cecba1a15c8cad8baa04b4e6be6eef8159c061b37096012de75132e7cd74" + }, + "mojave": { + "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.mojave.bottle.tar.gz", + "sha256": "0883b18c75e7cade594eced3d828ccacefafbbb3ead61667bca21e1fbc94970d" } } } @@ -27,12 +56,12 @@ "system": { "macos": { "catalina": { - "HOMEBREW_VERSION": "2.5.2", + "HOMEBREW_VERSION": "2.7.7", "HOMEBREW_PREFIX": "/usr/local", - "Homebrew/homebrew-core": "3cc2bc2196267adcdaa2e256cd8af6c30207c049", + "Homebrew/homebrew-core": "7c08a98e781448b9a80c9db887c5cb66839f12c8", "CLT": "1103.0.32.62", - "Xcode": "11.7", - "macOS": "10.15.6" + "Xcode": "12.4", + "macOS": "10.15.7" } } } diff --git a/Gemfile b/Gemfile deleted file mode 100644 index d1bf7c6f..00000000 --- a/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source "https://rubygems.org" - -gem "cocoapods" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 6284077f..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,90 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - CFPropertyList (3.0.2) - activesupport (4.2.11.3) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - algoliasearch (1.27.3) - httpclient (~> 2.8, >= 2.8.3) - json (>= 1.5.1) - atomos (0.1.3) - claide (1.0.3) - cocoapods (1.9.3) - activesupport (>= 4.0.2, < 5) - claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.9.3) - cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 1.2.2, < 2.0) - cocoapods-plugins (>= 1.0.0, < 2.0) - cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.4.0, < 2.0) - cocoapods-try (>= 1.1.0, < 2.0) - colored2 (~> 3.1) - escape (~> 0.0.4) - fourflusher (>= 2.3.0, < 3.0) - gh_inspector (~> 1.0) - molinillo (~> 0.6.6) - nap (~> 1.0) - ruby-macho (~> 1.4) - xcodeproj (>= 1.14.0, < 2.0) - cocoapods-core (1.9.3) - activesupport (>= 4.0.2, < 6) - algoliasearch (~> 1.0) - concurrent-ruby (~> 1.1) - fuzzy_match (~> 2.0.4) - nap (~> 1.0) - netrc (~> 0.11) - typhoeus (~> 1.0) - cocoapods-deintegrate (1.0.4) - cocoapods-downloader (1.4.0) - cocoapods-plugins (1.0.0) - nap - cocoapods-search (1.0.0) - cocoapods-stats (1.1.0) - cocoapods-trunk (1.5.0) - nap (>= 0.8, < 2.0) - netrc (~> 0.11) - cocoapods-try (1.2.0) - colored2 (3.1.2) - concurrent-ruby (1.1.6) - escape (0.0.4) - ethon (0.12.0) - ffi (>= 1.3.0) - ffi (1.13.1) - fourflusher (2.3.1) - fuzzy_match (2.0.4) - gh_inspector (1.1.3) - httpclient (2.8.3) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - json (2.3.1) - minitest (5.14.1) - molinillo (0.6.6) - nanaimo (0.3.0) - nap (1.1.0) - netrc (0.11.0) - ruby-macho (1.4.0) - thread_safe (0.3.6) - typhoeus (1.4.0) - ethon (>= 0.9.0) - tzinfo (1.2.7) - thread_safe (~> 0.1) - xcodeproj (1.17.1) - CFPropertyList (>= 2.3.3, < 4.0) - atomos (~> 0.1.3) - claide (>= 1.0.2, < 2.0) - colored2 (~> 3.1) - nanaimo (~> 0.3.0) - -PLATFORMS - ruby - -DEPENDENCIES - cocoapods - -BUNDLED WITH - 2.1.4 diff --git a/Podfile b/Podfile index aee8f487..fb398a88 100644 --- a/Podfile +++ b/Podfile @@ -1,3 +1,5 @@ +source 'https://cdn.cocoapods.org/' + # Library # Definitions diff --git a/Podfile.lock b/Podfile.lock index 7d15622d..ab089fd7 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,8 +2,8 @@ PODS: - Backtrace (1.5.6): - Backtrace-PLCrashReporter - Backtrace-PLCrashReporter (1.5.4) - - Nimble (8.1.2) - - Quick (3.0.0) + - Nimble (9.0.0) + - Quick (3.1.2) DEPENDENCIES: - Backtrace (from `./Backtrace.podspec`) @@ -24,9 +24,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Backtrace: 90f5a8b6bc9d417a444ce62435bbda0c54fa8d89 Backtrace-PLCrashReporter: 65b9aae5468bb6af6b55b88de22b49e031331054 - Nimble: 3864815b4703c7ebffba875973c70e854489fbae - Quick: 6d9559f40647bc4d510103842ef2fdd882d753e2 + Nimble: 3b4ec3fd40f1dc178058e0981107721c615643d8 + Quick: 60f0ea3b8e0cfc0df3259a5c06a238ad8b3c46e0 -PODFILE CHECKSUM: 62d8c592f7a14dbdbf06ce7cbf47810c1a25075e +PODFILE CHECKSUM: afc46274bf1938dc457973360b3e30ff7b342057 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/Tests/BacktraceWatcherTests.swift b/Tests/BacktraceWatcherTests.swift index 54ec467f..7681500b 100644 --- a/Tests/BacktraceWatcherTests.swift +++ b/Tests/BacktraceWatcherTests.swift @@ -51,7 +51,7 @@ final class BacktraceWatcherTests: QuickSpec { watcher.enable() watcher.resetTimer() - waitUntil(timeout: TimeInterval(dbSettings.retryInterval + 1)) { done in + waitUntil(timeout: .seconds(dbSettings.retryInterval + 1)) { (done) in watcher.configureTimer(with: DispatchWorkItem(block: { done() })) diff --git a/Tests/DispatcherTests.swift b/Tests/DispatcherTests.swift index 95930974..a3c1af6d 100644 --- a/Tests/DispatcherTests.swift +++ b/Tests/DispatcherTests.swift @@ -17,8 +17,8 @@ final class DispatcherTests: QuickSpec { }, completion: { finished = true }) - expect(finished).toEventually(beTrue(), timeout: 5, pollInterval: 0.1) - expect(closureCalled).toEventually(beTrue(), timeout: 5, pollInterval: 0.1) + expect(finished).toEventually(beTrue(), timeout: .seconds(5), pollInterval: .milliseconds(100)) + expect(closureCalled).toEventually(beTrue(), timeout: .seconds(5), pollInterval: .milliseconds(100)) } } } diff --git a/scripts/install.sh b/scripts/install.sh index 4d7f734a..f1f4686a 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,8 +1,4 @@ #!/bin/bash set -ex -brew bundle -gem install bundler:2.1.4 -bundle install -bundle exec pod repo update -bundle exec pod install +brew bundle \ No newline at end of file From 7c6cf6e0c9e35e4b642410305240b37adb26bae9 Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Tue, 16 Feb 2021 11:10:05 +0100 Subject: [PATCH 2/5] Out of memory support (#45) * oom support * Add minimal change to support all platforms * Update OOM support - code review advices * Use let instead of private(set) * Removed if brackets * Reindent class * Code review responses * Code review adjustements * Fix compilation issue - Update DispatchSource memory pressure - Fix linter warnings * Update .travis.yml Co-authored-by: Marcin Karmelita --- .swiftlint.yml | 2 +- .travis.yml | 2 +- Backtrace.xcodeproj/project.pbxproj | 8 + ...S.xcscheme => Backtrace-tvOS-lib.xcscheme} | 0 Brewfile | 3 +- Brewfile.lock.json | 21 ++ .../Attributes/AttributesProvider.swift | 4 + Sources/Features/Attributes/System.swift | 4 +- .../Features/Client/BacktraceOomWatcher.swift | 206 ++++++++++++++++++ .../Features/Client/BacktraceReporter.swift | 98 ++++++++- .../Features/Network/MultipartRequest.swift | 2 - Sources/Public/BacktraceClient.swift | 19 +- .../Public/BacktraceClientConfiguration.swift | 6 +- Sources/Public/BacktraceCrashReporter.swift | 2 + Sources/Public/BacktraceLogger.swift | 16 +- Sources/Public/Internal/SignalContext.swift | 1 + Tests/AttributesTests.swift | 4 +- Tests/BacktraceApiTests.swift | 4 +- Tests/BacktraceClientTests.swift | 4 +- Tests/BacktraceReporterTests.swift | 4 +- Tests/BacktraceWatcherTests.swift | 4 +- Tests/Mocks/UrlSessionMock.swift | 2 +- fastlane/Fastfile | 2 +- scripts/test.sh | 3 +- 24 files changed, 383 insertions(+), 38 deletions(-) rename Backtrace.xcodeproj/xcshareddata/xcschemes/{Backtrace-tvOS.xcscheme => Backtrace-tvOS-lib.xcscheme} (100%) create mode 100644 Sources/Features/Client/BacktraceOomWatcher.swift diff --git a/.swiftlint.yml b/.swiftlint.yml index 292e2e15..6a419cc3 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -28,7 +28,7 @@ force_try: severity: warning # explicitly # rules that have both warning and error levels, can set just the warning level # implicitly -line_length: 120 +line_length: 130 # they can set both implicitly with an array type_body_length: - 300 # warning diff --git a/.travis.yml b/.travis.yml index 5555b5dd..bd641fe1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: swift os: osx -osx_image: xcode11.6 +osx_image: xcode12 script: - sh scripts/install.sh - sh scripts/test.sh diff --git a/Backtrace.xcodeproj/project.pbxproj b/Backtrace.xcodeproj/project.pbxproj index 5206b16e..bb376f92 100644 --- a/Backtrace.xcodeproj/project.pbxproj +++ b/Backtrace.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 0B6B4CFD25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B6B4CFC25CD8331002DA15C /* BacktraceOomWatcher.swift */; }; + 0B6B4CFE25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B6B4CFC25CD8331002DA15C /* BacktraceOomWatcher.swift */; }; + 0B6B4CFF25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B6B4CFC25CD8331002DA15C /* BacktraceOomWatcher.swift */; }; 282C85E7223FD8E70014FE75 /* BacktraceCrashExceptionApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282C85E6223FD8E70014FE75 /* BacktraceCrashExceptionApplication.swift */; }; 282C85EA22419C560014FE75 /* BacktraceWatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282C85E822419BB10014FE75 /* BacktraceWatcherTests.swift */; }; 282C85EB22419C600014FE75 /* BacktraceWatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282C85E822419BB10014FE75 /* BacktraceWatcherTests.swift */; }; @@ -305,6 +308,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0B6B4CFC25CD8331002DA15C /* BacktraceOomWatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BacktraceOomWatcher.swift; sourceTree = ""; }; 0DFF5AC24C0AC4EF3E2F5307 /* Pods-Example-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.release.xcconfig"; path = "Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.release.xcconfig"; sourceTree = ""; }; 266E3F27CBA1D3CE7E2CCCB2 /* Pods_Backtrace_macOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Backtrace_macOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 282C85E6223FD8E70014FE75 /* BacktraceCrashExceptionApplication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BacktraceCrashExceptionApplication.swift; sourceTree = ""; }; @@ -701,6 +705,7 @@ children = ( F28F164521E28441008E4B96 /* BacktraceReporter.swift */, F28162F921EFD6AD00A12B7A /* BacktraceResponse.swift */, + 0B6B4CFC25CD8331002DA15C /* BacktraceOomWatcher.swift */, ); path = Client; sourceTree = ""; @@ -1779,6 +1784,7 @@ 28F95BDB22526088003936E0 /* SignalContext.swift in Sources */, 28F95BD122526068003936E0 /* BacktraceResult.swift in Sources */, 28F95BE7225260B0003936E0 /* Attachment.swift in Sources */, + 0B6B4CFF25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */, 28F95BCB22526045003936E0 /* Dispatching.swift in Sources */, 28F95BDD2252608E003936E0 /* BacktraceReportStatus.swift in Sources */, 28F95BDE22526091003936E0 /* ReportingPolicy.swift in Sources */, @@ -1864,6 +1870,7 @@ F282075C21CEA37A0017367F /* Repository.swift in Sources */, F26EBF3B23F21BC700A64218 /* BacktraceRateLimiter.swift in Sources */, F28F165221E2A08F008E4B96 /* HttpMethod.swift in Sources */, + 0B6B4CFE25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */, F29CD78E21FC6BC700216C59 /* BacktraceFileManager.swift in Sources */, F2D7122221F10C45002D2A26 /* BacktraceClientConfiguration.swift in Sources */, F29CD79221FCC25600216C59 /* BacktraceWatcher.swift in Sources */, @@ -1938,6 +1945,7 @@ F2D7122421F10E78002D2A26 /* BacktraceCredentials.swift in Sources */, F28F164621E28441008E4B96 /* BacktraceReporter.swift in Sources */, F21211A5222348AC000B3692 /* BacktraceCrashReporter.swift in Sources */, + 0B6B4CFD25CD8331002DA15C /* BacktraceOomWatcher.swift in Sources */, F2C1514221F7D8E30014F1B3 /* PersistentRepository.swift in Sources */, F2D8BE3821BD7894007CFEFA /* BacktraceError.swift in Sources */, F282075821CEA31F0017367F /* BacktraceReport.swift in Sources */, diff --git a/Backtrace.xcodeproj/xcshareddata/xcschemes/Backtrace-tvOS.xcscheme b/Backtrace.xcodeproj/xcshareddata/xcschemes/Backtrace-tvOS-lib.xcscheme similarity index 100% rename from Backtrace.xcodeproj/xcshareddata/xcschemes/Backtrace-tvOS.xcscheme rename to Backtrace.xcodeproj/xcshareddata/xcschemes/Backtrace-tvOS-lib.xcscheme diff --git a/Brewfile b/Brewfile index 27c6ca77..b17eeef4 100644 --- a/Brewfile +++ b/Brewfile @@ -1,2 +1,3 @@ brew "fastlane" -brew 'cocoapods' \ No newline at end of file +brew 'cocoapods' +brew 'swiftlint' \ No newline at end of file diff --git a/Brewfile.lock.json b/Brewfile.lock.json index bbf27ea5..137c1002 100644 --- a/Brewfile.lock.json +++ b/Brewfile.lock.json @@ -50,6 +50,27 @@ } } } + }, + "swiftlint": { + "version": "0.42.0", + "bottle": { + "cellar": ":any_skip_relocation", + "prefix": "/usr/local", + "files": { + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.big_sur.bottle.tar.gz", + "sha256": "1a0540f0ff6cac2da0a51672db7963aef71cc58954c34791e9b01dafd63c5898" + }, + "arm64_big_sur": { + "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.arm64_big_sur.bottle.tar.gz", + "sha256": "a9cf09a414fd3b8a5cb3d94e682a725f654a4d1caef19497a500d6dbb926ba7c" + }, + "catalina": { + "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.catalina.bottle.tar.gz", + "sha256": "e9023ed754eb8cb78a9f2b469a90875ca42a7afffd3e96f8142252e81d889793" + } + } + } } } }, diff --git a/Sources/Features/Attributes/AttributesProvider.swift b/Sources/Features/Attributes/AttributesProvider.swift index 8a0627ea..737b366d 100644 --- a/Sources/Features/Attributes/AttributesProvider.swift +++ b/Sources/Features/Attributes/AttributesProvider.swift @@ -39,6 +39,10 @@ extension AttributesProvider: SignalContext { self.faultInfo.faultMessage = faultMessage } + func set(errorType: String?) { + self.attributes["error.type"] = errorType + } + var allAttributes: Attributes { return attributes + defaultAttributes } diff --git a/Sources/Features/Attributes/System.swift b/Sources/Features/Attributes/System.swift index c4a2f67c..46412969 100644 --- a/Sources/Features/Attributes/System.swift +++ b/Sources/Features/Attributes/System.swift @@ -285,9 +285,9 @@ extension Processor { self.nice = Double(nice) / total } - //swiftlint:disable identifier_name large_tuple + // swiftlint:disable identifier_name large_tuple init(cpu_tick: (UInt32, UInt32, UInt32, UInt32)) { - //swiftlint:enable identifier_name large_tuple + // swiftlint:enable identifier_name large_tuple self.init(user: UInt(cpu_tick.0), system: UInt(cpu_tick.1), idle: UInt(cpu_tick.2), diff --git a/Sources/Features/Client/BacktraceOomWatcher.swift b/Sources/Features/Client/BacktraceOomWatcher.swift new file mode 100644 index 00000000..9c69e111 --- /dev/null +++ b/Sources/Features/Client/BacktraceOomWatcher.swift @@ -0,0 +1,206 @@ +import Foundation + +final class BacktraceOomWatcher { + + private var state: ApplicationInfo + + let lowMemoryFilePrefix = "_lowMemory" + private(set) static var oomFilePath: URL? = getStatusFilePath() + + private(set) var crashReporter: CrashReporting + private(set) var attributesProvider: AttributesProvider + private(set) var backtraceApi: BacktraceApi + private let repository: PersistentRepository + + init( + repository: PersistentRepository, + crashReporter: CrashReporting, + attributes: AttributesProvider, + backtraceApi: BacktraceApi) { + self.crashReporter = crashReporter + self.attributesProvider = attributes + self.backtraceApi = backtraceApi + self.repository = repository + + // set default state + state = ApplicationInfo() + + // set status file url + if BacktraceOomWatcher.oomFilePath == nil { + // database path will point out sqlite database path + // oom status should exist in the same directory where database exists. + BacktraceOomWatcher.oomFilePath = self.repository.url.deletingLastPathComponent().absoluteURL + .appendingPathComponent("BacktraceOOMState.plist") + } + } + + internal static func clean() { + if let oomFilePath = BacktraceOomWatcher.oomFilePath { + // ignore errors or use do/catch block to handle errors more gracefully + try? FileManager.default.removeItem(at: oomFilePath) + } + } + + internal static func getAppVersion() -> String { + if let appVersion = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String { + return appVersion + } else { + return "" + } + } + + public func start() { + sendPendingOomReports() + // override previous application state after reading all information + saveState() + } + + internal static func getStatusFilePath() -> URL? { + // oom status file is available in application cache dir - the same dir + // where we store attributes + guard let cacheDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { + return nil + } + return cacheDir.appendingPathComponent("BacktraceOomState.plist") + } + + private func sendPendingOomReports() { + // if oom state file doesn't exist it means that we deleted it to + // prevent sending false oom crashes + if let oomFilePath = BacktraceOomWatcher.oomFilePath, !FileManager.default.fileExists(atPath: oomFilePath.path) { + return + } + + guard let appState = self.loadPreviousState() else { + return + } + + if !shouldReportOom(appState: appState) { + return + } + + reportOom(appState: appState) + BacktraceOomWatcher.clean() + } + + private func shouldReportOom(appState: ApplicationInfo) -> Bool { + // no low memory warning + if appState.resource == nil { + return false + } + + // check if debugger was enabled + if appState.debugger { + // detected debugger in previous session + return false + } + // check system update + if appState.version != ProcessInfo.processInfo.operatingSystemVersionString { + // detected system update + return false + } + + // check application update + if appState.appVersion != BacktraceOomWatcher.getAppVersion() { + // detected app update + return false + } + return true + } + + private func reportOom(appState: ApplicationInfo) { + guard let reportData = appState.resource else { + return + } + + var reportAttributes: Attributes = [:] + if let stateAttributes = appState.attributes, + let attributes = try? JSONSerialization.jsonObject(with: stateAttributes, options: []) as? Attributes { + reportAttributes = attributes ?? [:] + } + + // ok - we detected oom and we should report it + guard let report = try? BacktraceReport(report: reportData, attributes: reportAttributes, attachmentPaths: []) + else { + return + } + do { + _ = try backtraceApi.send(report) + } catch { + BacktraceLogger.error(error) + try? self.repository.save(report) + } + } +} + +extension BacktraceOomWatcher { + /// Describes the current application's state + enum ApplicationState: String, Codable { + /// The app is in the foreground and actively in use. + case active + /// The app is in an inactive state when it is in the foreground but receiving events. + case inactive + /// The app transitions into the background. + case background + } + + //// Describes the current application's information + struct ApplicationInfo: Codable { + var state: ApplicationState = .active + var debugger: Bool = DebuggerChecker.isAttached() + var appVersion: String = BacktraceOomWatcher.getAppVersion() + var version: String = ProcessInfo.processInfo.operatingSystemVersionString + var attributes: Data? + var resource: Data? + } +} + +extension BacktraceOomWatcher { + func appChanedState(_ newState: ApplicationState) { + self.state.state = newState + saveState() + } + + func handleTermination() { + // application terminates correctly - for example: user decide to close app + BacktraceOomWatcher.clean() + NotificationCenter.default.removeObserver(self) + } + + func handleLowMemoryWarning() { + guard let resource = try? crashReporter.generateLiveReport(exception: nil, + attributes: attributesProvider.allAttributes, + attachmentPaths: []) else { + return + } + self.state.resource = resource.reportData + resource.attributes["error.message"] = "Out of memory detected." + resource.attributes["error.type"] = "Low Memory" + resource.attributes["state"] = state.state.rawValue + + self.state.attributes = try? JSONSerialization.data(withJSONObject: resource.attributes) + saveState() + } + + private func loadPreviousState() -> ApplicationInfo? { + let decoder = PropertyListDecoder() + + guard let destPath = BacktraceOomWatcher.oomFilePath, + let data = try? Data(contentsOf: destPath), + let previousAppState = try? decoder.decode(ApplicationInfo.self, from: data) else { return nil } + return previousAppState + } + + private func saveState() { + let encoder = PropertyListEncoder() + if let data = try? encoder.encode(self.state), + let destPath = BacktraceOomWatcher.oomFilePath { + if FileManager.default.fileExists(atPath: destPath.path) { + try? data.write(to: destPath) + } else { + FileManager.default.createFile(atPath: destPath.path, contents: data, attributes: nil) + } + + } + } +} diff --git a/Sources/Features/Client/BacktraceReporter.swift b/Sources/Features/Client/BacktraceReporter.swift index 4d3ce09f..f0851848 100644 --- a/Sources/Features/Client/BacktraceReporter.swift +++ b/Sources/Features/Client/BacktraceReporter.swift @@ -6,8 +6,15 @@ final class BacktraceReporter { private(set) var api: BacktraceApi private let watcher: BacktraceWatcher> private(set) var attributesProvider: SignalContext + private(set) var backtraceOomWatcher: BacktraceOomWatcher let repository: PersistentRepository + #if os(macOS) + lazy var memoryPressureSource: DispatchSourceMemoryPressure = { + DispatchSource.makeMemoryPressureSource(eventMask: [.critical, .warning], queue: .global()) + }() + #endif + init(reporter: CrashReporting, api: BacktraceApi, dbSettings: BacktraceDatabaseSettings, @@ -21,8 +28,14 @@ final class BacktraceReporter { credentials: credentials, repository: try PersistentRepository(settings: dbSettings)) self.repository = try PersistentRepository(settings: dbSettings) - self.attributesProvider = AttributesProvider() - self.reporter.signalContext(&attributesProvider) + let attributesProvider = AttributesProvider() + self.attributesProvider = attributesProvider + self.backtraceOomWatcher = BacktraceOomWatcher( + repository: self.repository, + crashReporter: self.reporter, + attributes: attributesProvider, + backtraceApi: self.api) + self.reporter.signalContext(&self.attributesProvider) } } @@ -90,9 +103,90 @@ extension BacktraceReporter { func generate(exception: NSException? = nil, attachmentPaths: [String] = [], faultMessage: String? = nil) throws -> BacktraceReport { attributesProvider.set(faultMessage: faultMessage) + attributesProvider.set(errorType: "Exception") let resource = try reporter.generateLiveReport(exception: exception, attributes: attributesProvider.allAttributes, attachmentPaths: attachmentPaths) return resource } } + +#if os(iOS) || os(tvOS) +typealias Application = UIApplication +#elseif os(macOS) +typealias Application = NSApplication +#else +#error("Unsupported platform") +#endif + +//// Provides notification interfaces for BacktraceOOMWatcher and Breadcrumbs support +extension BacktraceReporter { + internal func enableOomWatcher() { + self.backtraceOomWatcher.start() + + NotificationCenter.default.addObserver(self, + selector: #selector(handleTermination), + name: Application.willTerminateNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(didBecomeActiveNotification), + name: Application.didBecomeActiveNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(willResignActiveNotification), + name: Application.willResignActiveNotification, + object: nil) + + #if os(iOS) || os(tvOS) + NotificationCenter.default.addObserver(self, + selector: #selector(applicationWillEnterForeground), + name: Application.willEnterForegroundNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(didEnterBackgroundNotification), + name: Application.didEnterBackgroundNotification, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(handleLowMemoryWarning), + name: Application.didReceiveMemoryWarningNotification, + object: nil) + #endif + + #if os(macOS) + self.memoryPressureSource.setEventHandler { [weak self] in + guard let self = self else { return } + if [.warning, .critical].contains(self.memoryPressureSource.mask) { + self.handleLowMemoryWarning() + } + self.memoryPressureSource.resume() + } + #endif + } + + @objc private func applicationWillEnterForeground() { + self.backtraceOomWatcher.appChanedState(.active) + } + + @objc private func didBecomeActiveNotification() { + self.backtraceOomWatcher.appChanedState(.active) + } + + @objc private func willResignActiveNotification() { + self.backtraceOomWatcher.appChanedState(.inactive) + } + + @objc private func didEnterBackgroundNotification() { + self.backtraceOomWatcher.appChanedState(.background) + } + + @objc private func handleTermination() { + self.backtraceOomWatcher.handleTermination() + } + @objc private func handleLowMemoryWarning() { + self.backtraceOomWatcher.handleLowMemoryWarning() + } +} diff --git a/Sources/Features/Network/MultipartRequest.swift b/Sources/Features/Network/MultipartRequest.swift index 1c944f26..ba57aad5 100644 --- a/Sources/Features/Network/MultipartRequest.swift +++ b/Sources/Features/Network/MultipartRequest.swift @@ -66,9 +66,7 @@ extension MultipartRequest { // attachments for attachment in report.attachmentPaths.compactMap(Attachment.init(filePath:)) { body.appendString(boundaryPrefix) - // swiftlint:disable line_length body.appendString("Content-Disposition: form-data; name=\"\(attachment.name)\"; filename=\"\(attachment.name)\"\r\n") - // swiftlint:enable line_length body.appendString("Content-Type: \(attachment.mimeType)\r\n\r\n") body.append(attachment.data) body.appendString("\r\n") diff --git a/Sources/Public/BacktraceClient.swift b/Sources/Public/BacktraceClient.swift index a8ddbb9a..a1341035 100644 --- a/Sources/Public/BacktraceClient.swift +++ b/Sources/Public/BacktraceClient.swift @@ -20,7 +20,8 @@ import Foundation /// - Parameter credentials: Credentials to register in Backtrace services. /// - Parameter crashReporter: Instance of the crash reporter to inject. /// - Throws: throws an error in case of failure. - @objc public convenience init(credentials: BacktraceCredentials, crashReporter: BacktraceCrashReporter = BacktraceCrashReporter()) throws { + @objc public convenience init(credentials: BacktraceCredentials, + crashReporter: BacktraceCrashReporter = BacktraceCrashReporter()) throws { try self.init(configuration: BacktraceClientConfiguration(credentials: credentials), crashReporter: crashReporter) } @@ -31,7 +32,8 @@ import Foundation /// - Parameter credentials: Credentials to register in Backtrace services. /// - Throws: throws an error in case of failure. @objc public convenience init(credentials: BacktraceCredentials) throws { - try self.init(configuration: BacktraceClientConfiguration(credentials: credentials), crashReporter: BacktraceCrashReporter()) + try self.init(configuration: BacktraceClientConfiguration(credentials: credentials), + crashReporter: BacktraceCrashReporter()) } /// Initialize `BacktraceClient` with `BacktraceClientConfiguration` instance. Allows to configure `BacktraceClient` @@ -81,10 +83,10 @@ extension BacktraceClient: BacktraceClientCustomizing { /// The object that acts as the delegate object of the `BacktraceClient`. @objc public var delegate: BacktraceClientDelegate? { - set { - reporter.delegate = newValue - } get { + get { return reporter.delegate + } set { + reporter.delegate = newValue } } @@ -92,8 +94,7 @@ extension BacktraceClient: BacktraceClientCustomizing { @objc public var attributes: Attributes { get { return reporter.attributes - } - set { + } set { reporter.attributes = newValue } } @@ -153,6 +154,10 @@ extension BacktraceClient: BacktraceReporting { return } + if self.configuration.detectOom { + self.reporter.enableOomWatcher() + } + try reporter.enableCrashReporter() dispatcher.dispatch({ [weak self] in guard let self = self else { return } diff --git a/Sources/Public/BacktraceClientConfiguration.swift b/Sources/Public/BacktraceClientConfiguration.swift index 231c0cea..4649cc75 100644 --- a/Sources/Public/BacktraceClientConfiguration.swift +++ b/Sources/Public/BacktraceClientConfiguration.swift @@ -17,6 +17,8 @@ import Foundation /// Flag indicating if the Backtrace client should report reports when the debugger is attached. Default `false`. @objc public var allowsAttachingDebugger: Bool = false + /// Flag responsible for detecting and sending possible OOM cashes + @objc public var detectOom: Bool = false /// Produces Backtrace client configuration settings. /// /// - Parameters: @@ -36,10 +38,12 @@ import Foundation @objc public init(credentials: BacktraceCredentials, dbSettings: BacktraceDatabaseSettings = BacktraceDatabaseSettings(), reportsPerMin: Int = 30, - allowsAttachingDebugger: Bool = false) { + allowsAttachingDebugger: Bool = false, + detectOOM: Bool = false) { self.credentials = credentials self.dbSettings = dbSettings self.reportsPerMin = reportsPerMin self.allowsAttachingDebugger = allowsAttachingDebugger + self.detectOom = detectOOM } } diff --git a/Sources/Public/BacktraceCrashReporter.swift b/Sources/Public/BacktraceCrashReporter.swift index 7229bd92..b9c2b577 100644 --- a/Sources/Public/BacktraceCrashReporter.swift +++ b/Sources/Public/BacktraceCrashReporter.swift @@ -28,7 +28,9 @@ extension BacktraceCrashReporter: CrashReporting { let signalInfo = signalInfoPointer?.pointee else { return } + attributesProvider.set(errorType: "Crash") attributesProvider.set(faultMessage: "siginfo_t.si_signo: \(signalInfo.si_signo)") + BacktraceOomWatcher.clean() try? AttributesStorage.store(attributesProvider.allAttributes, fileName: BacktraceCrashReporter.crashName) } diff --git a/Sources/Public/BacktraceLogger.swift b/Sources/Public/BacktraceLogger.swift index 131da9b9..d8d73301 100644 --- a/Sources/Public/BacktraceLogger.swift +++ b/Sources/Public/BacktraceLogger.swift @@ -41,7 +41,7 @@ import Foundation class func setDestinations(destinations: Set) { self.destinations = destinations } - //swiftlint:disable line_length + // swiftlint:disable line_length class func debug(_ msg: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line) { log(level: .debug, msg: msg, file: file, function: function, line: line) } @@ -64,7 +64,7 @@ import Foundation .filter { $0.shouldLog(level: level) } .forEach { $0.log(level: level, msg: message, file: file, function: function, line: line) } } - //swiftlint:enable line_length + // swiftlint:enable line_length } /// Abstract class that provides logging functionality. @@ -86,7 +86,7 @@ import Foundation func shouldLog(level: BacktraceLogLevel) -> Bool { return self.level.rawValue <= level.rawValue } - //swiftlint:disable line_length + // swiftlint:disable line_length /// An abstract method used to log message to provided destination. /// @@ -99,7 +99,7 @@ import Foundation @objc public func log(level: BacktraceLogLevel, msg: String, file: String = #file, function: String = #function, line: Int = #line) { // abstract } - //swiftlint:enable line_length + // swiftlint:enable line_length } /// Provides logging functionality to IDE console. @@ -114,7 +114,7 @@ import Foundation return formatter } - //swiftlint:disable line_length + // swiftlint:disable line_length /// Logs the event to console destination. Formats log in more verbose way. /// /// - Parameters: @@ -126,13 +126,13 @@ import Foundation override public func log(level: BacktraceLogLevel, msg: String, file: String = #file, function: String = #function, line: Int = #line) { print("\(BacktraceFancyConsoleDestination.dateFormatter.string(from: Date())) [\(level.desc()) Backtrace] [\(URL(fileURLWithPath: file).lastPathComponent)]:\(line) \(function) -> \(msg)") } - //swiftlint:enable line_length + // swiftlint:enable line_length } /// Provides logging functionality to IDE console. @objc final public class BacktraceConsoleDestination: BacktraceBaseDestination { - //swiftlint:disable line_length + // swiftlint:disable line_length /// Logs the event to console destination. /// /// - Parameters: @@ -144,5 +144,5 @@ import Foundation override public func log(level: BacktraceLogLevel, msg: String, file: String = #file, function: String = #function, line: Int = #line) { print("\(Date()) [Backtrace]: \(msg)") } - //swiftlint:enable line_length + // swiftlint:enable line_length } diff --git a/Sources/Public/Internal/SignalContext.swift b/Sources/Public/Internal/SignalContext.swift index 7195f8a4..e72771d2 100644 --- a/Sources/Public/Internal/SignalContext.swift +++ b/Sources/Public/Internal/SignalContext.swift @@ -4,4 +4,5 @@ protocol SignalContext: CustomStringConvertible { var allAttributes: Attributes { get } var attributes: Attributes { get set } func set(faultMessage: String?) + func set(errorType: String?) } diff --git a/Tests/AttributesTests.swift b/Tests/AttributesTests.swift index 5fc55ffb..071bb19d 100644 --- a/Tests/AttributesTests.swift +++ b/Tests/AttributesTests.swift @@ -5,7 +5,7 @@ import Quick @testable import Backtrace final class AttributesTests: QuickSpec { - //swiftlint:disable function_body_length + // swiftlint:disable function_body_length override func spec() { describe("Components") { it("sets processor info") { @@ -102,5 +102,5 @@ final class AttributesTests: QuickSpec { } } } - //swiftlint:enable function_body_length + // swiftlint:enable function_body_length } diff --git a/Tests/BacktraceApiTests.swift b/Tests/BacktraceApiTests.swift index 95d418ca..4bb55ea5 100644 --- a/Tests/BacktraceApiTests.swift +++ b/Tests/BacktraceApiTests.swift @@ -5,7 +5,7 @@ import Quick @testable import Backtrace final class BacktraceApiTests: QuickSpec { - //swiftlint:disable function_body_length + // swiftlint:disable function_body_length override func spec() { describe("Backtrace API") { let crashReporter = BacktraceCrashReporter() @@ -146,5 +146,5 @@ final class BacktraceApiTests: QuickSpec { } } } - //swiftlint:enable function_body_length + // swiftlint:enable function_body_length } diff --git a/Tests/BacktraceClientTests.swift b/Tests/BacktraceClientTests.swift index 287ab67b..ebb4b16e 100644 --- a/Tests/BacktraceClientTests.swift +++ b/Tests/BacktraceClientTests.swift @@ -7,7 +7,7 @@ import Backtrace_PLCrashReporter final class BacktraceClientTests: QuickSpec { - //swiftlint:disable function_body_length + // swiftlint:disable function_body_length override func spec() { describe("Backtrace client") { @@ -68,5 +68,5 @@ final class BacktraceClientTests: QuickSpec { } } } - //swiftlint:enable function_body_length + // swiftlint:enable function_body_length } diff --git a/Tests/BacktraceReporterTests.swift b/Tests/BacktraceReporterTests.swift index c86e7ec7..242d1c33 100644 --- a/Tests/BacktraceReporterTests.swift +++ b/Tests/BacktraceReporterTests.swift @@ -5,7 +5,7 @@ import Quick @testable import Backtrace final class BacktraceReporterTests: QuickSpec { - //swiftlint:disable function_body_length force_try + // swiftlint:disable function_body_length force_try override func spec() { describe("Backtrace reporter") { let urlSession = URLSessionMock() @@ -147,5 +147,5 @@ final class BacktraceReporterTests: QuickSpec { } } } - //swiftlint:enable function_body_length force_try + // swiftlint:enable function_body_length force_try } diff --git a/Tests/BacktraceWatcherTests.swift b/Tests/BacktraceWatcherTests.swift index 7681500b..b01b8f5f 100644 --- a/Tests/BacktraceWatcherTests.swift +++ b/Tests/BacktraceWatcherTests.swift @@ -5,7 +5,7 @@ import Quick @testable import Backtrace final class BacktraceWatcherTests: QuickSpec { - //swiftlint:disable function_body_length + // swiftlint:disable function_body_length override func spec() { describe("Watcher") { let dbSettings = BacktraceDatabaseSettings() @@ -206,7 +206,7 @@ final class BacktraceWatcherTests: QuickSpec { } } } - //swiftlint:enable function_body_length + // swiftlint:enable function_body_length } private static func backtraceReport(for attributes: Attributes) throws -> BacktraceReport { diff --git a/Tests/Mocks/UrlSessionMock.swift b/Tests/Mocks/UrlSessionMock.swift index 6938d49f..ddad8e29 100644 --- a/Tests/Mocks/UrlSessionMock.swift +++ b/Tests/Mocks/UrlSessionMock.swift @@ -4,7 +4,7 @@ import Backtrace typealias VoidClosure = () -> Void -//based on: https://medium.com/@johnsundell/mocking-in-swift-56a913ee7484 +// based on: https://medium.com/@johnsundell/mocking-in-swift-56a913ee7484 final class URLSessionMock: URLSession { typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void // Properties that enable us to set exactly what data or error diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3ef9cc81..1d3fc941 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -32,7 +32,7 @@ end platform :tvos do desc "Run tvOS tests" lane :tests do - common_tests(scheme: "Backtrace-tvOS") + common_tests(scheme: "Backtrace-tvOS-lib") end end diff --git a/scripts/test.sh b/scripts/test.sh index 118d5de1..8681a05e 100644 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -2,4 +2,5 @@ set -ex fastlane ios tests -fastlane mac tests \ No newline at end of file +fastlane mac tests +fastlane tvos tests \ No newline at end of file From 2faf27f50646f68ae6eca63476febb06554e6d36 Mon Sep 17 00:00:00 2001 From: krml19 Date: Thu, 18 Feb 2021 01:53:42 +0100 Subject: [PATCH 3/5] Integrate GitHub actions (#47) * oom support * Add minimal change to support all platforms * Update OOM support - code review advices * Use let instead of private(set) * Removed if brackets * Reindent class * Code review responses * Code review adjustements * Fix compilation issue - Update DispatchSource memory pressure - Fix linter warnings * Update .travis.yml * Add deployment script * Set up GitHub actions * Update test script Co-authored-by: konraddysput --- .github/workflows/deploy.yml | 16 +++++++++++ .github/workflows/test.yml | 15 +++++++++++ Brewfile.lock.json | 52 +++++++++++++++++++++++------------- fastlane/Fastfile | 7 +---- fastlane/README.md | 5 ---- scripts/deploy.sh | 11 ++++++++ scripts/install.sh | 5 +++- scripts/test.sh | 9 +++++-- 8 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/test.yml create mode 100644 scripts/deploy.sh diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..efc5fa55 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,16 @@ +name: Deploy to Cocoapods + +on: + push: + tags: '[0-9]+.[0-9]+.[0-9]+*' + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + + - name: Deploy to Cocoapods + run: sh scripts/deploy.sh + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..c85f906c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,15 @@ +name: Run tests + +on: + push: + branches: + - develop + - master + +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Run tests + run: sh scripts/test.sh \ No newline at end of file diff --git a/Brewfile.lock.json b/Brewfile.lock.json index 137c1002..05797756 100644 --- a/Brewfile.lock.json +++ b/Brewfile.lock.json @@ -2,26 +2,28 @@ "entries": { "brew": { "fastlane": { - "version": "2.172.0", + "version": "2.174.0", "bottle": { + "rebuild": 0, "cellar": ":any", "prefix": "/usr/local", + "root_url": "https://homebrew.bintray.com/bottles", "files": { - "big_sur": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.big_sur.bottle.tar.gz", - "sha256": "f40121e1c323fecb0c6595761ba15674736863d3a7299d1a4d7440f9bef00277" - }, "arm64_big_sur": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.arm64_big_sur.bottle.tar.gz", - "sha256": "c04de95af044dd37f4d657d40d27663ca58e24a5b482fffc1fe475586228d5ca" + "url": "https://homebrew.bintray.com/bottles/fastlane-2.174.0.arm64_big_sur.bottle.tar.gz", + "sha256": "f426b0fb779e80de18de67b52f9552ee666ae8b9d1eac2c0631be59a33429b1b" + }, + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/fastlane-2.174.0.big_sur.bottle.tar.gz", + "sha256": "4eac8c1706c541acbfa838b6aea84cf39b74c242e2aadefd0a09ac185a2f24c9" }, "catalina": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.catalina.bottle.tar.gz", - "sha256": "beebe5c5fe53f942437727398218574c9dc7f86e8cd7c73a3164b7fe0ab88dd7" + "url": "https://homebrew.bintray.com/bottles/fastlane-2.174.0.catalina.bottle.tar.gz", + "sha256": "35c4d2b53eda31363256febf927c9b7a305ec7c27173651cc87adf0b4dc5316e" }, "mojave": { - "url": "https://homebrew.bintray.com/bottles/fastlane-2.172.0.mojave.bottle.tar.gz", - "sha256": "eeaeb3dbf3490b81aa0d6a085f5076778e61f566f4876c1d2c87adc022a3a210" + "url": "https://homebrew.bintray.com/bottles/fastlane-2.174.0.mojave.bottle.tar.gz", + "sha256": "6047bf36c5cd07630d35ee2e12b79782f12550a1b5acdd22badf7c4fcc826cf4" } } } @@ -29,17 +31,19 @@ "cocoapods": { "version": "1.10.1", "bottle": { + "rebuild": 0, "cellar": "/usr/local/Cellar", "prefix": "/usr/local", + "root_url": "https://homebrew.bintray.com/bottles", "files": { - "big_sur": { - "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.big_sur.bottle.tar.gz", - "sha256": "0caa8953926c827f62d53f9767aed0a904604c0425ea0557b24d738240db809a" - }, "arm64_big_sur": { "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.arm64_big_sur.bottle.tar.gz", "sha256": "08794cfd260bf206eed3496805816661da367bffdf9af748cd812b1c40a0de75" }, + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.big_sur.bottle.tar.gz", + "sha256": "0caa8953926c827f62d53f9767aed0a904604c0425ea0557b24d738240db809a" + }, "catalina": { "url": "https://homebrew.bintray.com/bottles/cocoapods-1.10.1.catalina.bottle.tar.gz", "sha256": "3a05cecba1a15c8cad8baa04b4e6be6eef8159c061b37096012de75132e7cd74" @@ -54,17 +58,19 @@ "swiftlint": { "version": "0.42.0", "bottle": { + "rebuild": 0, "cellar": ":any_skip_relocation", "prefix": "/usr/local", + "root_url": "https://homebrew.bintray.com/bottles", "files": { - "big_sur": { - "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.big_sur.bottle.tar.gz", - "sha256": "1a0540f0ff6cac2da0a51672db7963aef71cc58954c34791e9b01dafd63c5898" - }, "arm64_big_sur": { "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.arm64_big_sur.bottle.tar.gz", "sha256": "a9cf09a414fd3b8a5cb3d94e682a725f654a4d1caef19497a500d6dbb926ba7c" }, + "big_sur": { + "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.big_sur.bottle.tar.gz", + "sha256": "1a0540f0ff6cac2da0a51672db7963aef71cc58954c34791e9b01dafd63c5898" + }, "catalina": { "url": "https://homebrew.bintray.com/bottles/swiftlint-0.42.0.catalina.bottle.tar.gz", "sha256": "e9023ed754eb8cb78a9f2b469a90875ca42a7afffd3e96f8142252e81d889793" @@ -83,6 +89,14 @@ "CLT": "1103.0.32.62", "Xcode": "12.4", "macOS": "10.15.7" + }, + "big_sur": { + "HOMEBREW_VERSION": "3.0.1", + "HOMEBREW_PREFIX": "/usr/local", + "Homebrew/homebrew-core": "703451fe242d959d029d867909ffd92f0d522ffd", + "CLT": "12.4.0.0.1.1610135815", + "Xcode": "12.4", + "macOS": "11.2.1" } } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1d3fc941..76622167 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -47,9 +47,4 @@ lane :common_tests do |options| disable_slide_to_type: options[:disable_slide_to_type], disable_concurrent_testing: true ) -end - -desc "Lint pod" -lane :lint_pod do - pod_lib_lint(allow_warnings: true, verbose: true) -end +end \ No newline at end of file diff --git a/fastlane/README.md b/fastlane/README.md index 9887961e..c47bdd0f 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -20,11 +20,6 @@ or alternatively using `brew install fastlane` fastlane common_tests ``` Run tests -### lint_pod -``` -fastlane lint_pod -``` -Lint pod ---- diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100644 index 00000000..7727ccfe --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -o errexit # make your script exit when a command fails +set -o pipefail # to exit when the status of the last command that threw a non-zero exit code is returned +set -o nounset # to exit when your script tries to use undeclared variables +set -o xtrace # to trace what gets executed. Useful for debugging + +sh scripts/test.sh + +# This script requires the `COCOAPODS_TRUNK_TOKEN` env var to be set. +# See more: https://fuller.li/posts/automated-cocoapods-releases-with-ci/. +pod trunk push Backtrace.podspec --allow-warnings \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh index f1f4686a..268930f7 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,4 +1,7 @@ #!/bin/bash -set -ex +set -o errexit # make your script exit when a command fails +set -o pipefail # to exit when the status of the last command that threw a non-zero exit code is returned +set -o nounset # to exit when your script tries to use undeclared variables +set -o xtrace # to trace what gets executed. Useful for debugging brew bundle \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index 8681a05e..0f16f091 100644 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,6 +1,11 @@ #!/bin/bash -set -ex +set -o errexit # make your script exit when a command fails +set -o pipefail # to exit when the status of the last command that threw a non-zero exit code is returned +set -o nounset # to exit when your script tries to use undeclared variables +set -o xtrace # to trace what gets executed. Useful for debugging fastlane ios tests fastlane mac tests -fastlane tvos tests \ No newline at end of file +fastlane tvos tests + +pod lib lint --verbose --allow-warnings --sources='https://cdn.cocoapods.org/' From 99a87667490e0f9fe8441fa8aa472cab2725d57c Mon Sep 17 00:00:00 2001 From: Konrad Dysput Date: Thu, 18 Feb 2021 22:27:19 +0100 Subject: [PATCH 4/5] 1.6.0 update (#49) * Version bump * Update README.md * Update README.md * Update README.md Co-authored-by: Vincent Lussenburg --- Backtrace.podspec | 2 +- README.md | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Backtrace.podspec b/Backtrace.podspec index fc842cf0..3d2994df 100644 --- a/Backtrace.podspec +++ b/Backtrace.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.name = "Backtrace" - s.version = "1.5.6" + s.version = "1.6.0" s.summary = "Backtrace's integration with iOS, macOS and tvOS" s.description = "Reliable crash and hang reporting for iOS, macOS and tvOS." s.homepage = "https://backtrace.io/" diff --git a/README.md b/README.md index da3ad70c..a8189589 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,8 @@ let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://b let configuration = BacktraceClientConfiguration(credentials: backtraceCredentials, dbSettings: BacktraceDatabaseSettings(), reportsPerMin: 10, - allowsAttachingDebugger: false) + allowsAttachingDebugger: false, + detectOOM: true) BacktraceClient.shared = try? BacktraceClient(configuration: configuration) ``` @@ -179,12 +180,19 @@ BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration all initWithCredentials: credentials dbSettings: [[BacktraceDatabaseSettings alloc] init] reportsPerMin: 3 - allowsAttachingDebugger: NO]; + allowsAttachingDebugger: NO + detectOOM: TRUE]; BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil]; ``` -**Note:** Backtrace library will *not* send any reports if the `allowsAttachingDebugger` flag is set to `false`. +**Note on parameters** +- `initWithCredentials` and `BacktraceCredentials` see [here](#documentation-client-initialization) +- `dbSettings` see [here](#documentation-database-settings) +- `reportsPerMin` indicates the upper limit of how many reports per minute should be sent to the Backtrace endpoint +- `allowsAttachingDebugger` if this flag is set to `false` (Swift) or `NO` (ObjC) the Backtrace library will *not* send any reports +- `detectOOM` indicates if detected Low Memory Warnings ([`applicationDidReceiveMemoryWarning`](https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle/responding_to_memory_warnings)) are a trigger for Backtrace to send a report. Backtrace will send reports generated by memory warning on application startup when application exited unexpectedly. + ### Database settings BacktraceClient allows you to customize the initialization of BacktraceDatabase for local storage of error reports by supplying a BacktraceDatabaseSettings parameter, as follows: From a7a030a999db8d9ce3623340ec5b98b66a7eecad Mon Sep 17 00:00:00 2001 From: krml19 Date: Thu, 18 Feb 2021 23:48:19 +0100 Subject: [PATCH 5/5] Add GitHub Actions (#48) - Add GitHub Action's workflow to run the tests on every pull request into `develop` or `master` - Add GitHub Action's workflow to automatically distribute Cocoapod to the main specs repo --- .github/workflows/deploy.yml | 7 +++++-- .github/workflows/test.yml | 6 ++++-- Podfile.lock | 4 ++-- scripts/install.sh | 5 ++++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index efc5fa55..e940b3cd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -9,8 +9,11 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 - + - name: Install dependencies + run: sh scripts/install.sh + - name: Run tests + run: sh scripts/test.sh - name: Deploy to Cocoapods run: sh scripts/deploy.sh env: - COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} \ No newline at end of file + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c85f906c..64b7537e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,7 @@ name: Run tests on: - push: + pull_request: branches: - develop - master @@ -11,5 +11,7 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 + - name: Install dependencies + run: sh scripts/install.sh - name: Run tests - run: sh scripts/test.sh \ No newline at end of file + run: sh scripts/test.sh diff --git a/Podfile.lock b/Podfile.lock index ab089fd7..29ccec7e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Backtrace (1.5.6): + - Backtrace (1.6.0): - Backtrace-PLCrashReporter - Backtrace-PLCrashReporter (1.5.4) - Nimble (9.0.0) @@ -22,7 +22,7 @@ EXTERNAL SOURCES: :path: "./Backtrace.podspec" SPEC CHECKSUMS: - Backtrace: 90f5a8b6bc9d417a444ce62435bbda0c54fa8d89 + Backtrace: 90e82b3be4a6bde054dcb4663511a37113c348a8 Backtrace-PLCrashReporter: 65b9aae5468bb6af6b55b88de22b49e031331054 Nimble: 3b4ec3fd40f1dc178058e0981107721c615643d8 Quick: 60f0ea3b8e0cfc0df3259a5c06a238ad8b3c46e0 diff --git a/scripts/install.sh b/scripts/install.sh index 268930f7..80a85199 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -4,4 +4,7 @@ set -o pipefail # to exit when the status of the last command that threw a non-z set -o nounset # to exit when your script tries to use undeclared variables set -o xtrace # to trace what gets executed. Useful for debugging -brew bundle \ No newline at end of file +# ignore installation errors silently +brew bundle || true + +pod install \ No newline at end of file