[sentry] Add Sentry
This commit is contained in:
parent
2192719650
commit
0ab9a7af4e
|
@ -1,3 +1,5 @@
|
||||||
GH_TOKEN=xxxx
|
GH_TOKEN=xxxx
|
||||||
ENCRYPTION_SECRET=xxxx
|
ENCRYPTION_SECRET=xxxx
|
||||||
CERT_PASSWORD=xxxx
|
CERT_PASSWORD=xxxx
|
||||||
|
SENTRY_AUTH_TOKEN=xxx
|
||||||
|
SENTRY_DSN=xxxx
|
|
@ -18,6 +18,10 @@
|
||||||
B915ED662063B18B004B6630 /* xcproj.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B915ED672063B18B004B6630 /* xcproj.framework */; };
|
B915ED662063B18B004B6630 /* xcproj.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B915ED672063B18B004B6630 /* xcproj.framework */; };
|
||||||
B91834BF207CBCE6008935B4 /* ProjectDescription.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B91834BE207CBCE6008935B4 /* ProjectDescription.framework */; };
|
B91834BF207CBCE6008935B4 /* ProjectDescription.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B91834BE207CBCE6008935B4 /* ProjectDescription.framework */; };
|
||||||
B91834C0207CBCFE008935B4 /* ProjectDescription.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B91834BE207CBCE6008935B4 /* ProjectDescription.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
B91834C0207CBCFE008935B4 /* ProjectDescription.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B91834BE207CBCE6008935B4 /* ProjectDescription.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
B918A22A20935EC800E64FBE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B918A22920935EC800E64FBE /* Sentry.framework */; };
|
||||||
|
B918A22B20935ECF00E64FBE /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B918A22920935EC800E64FBE /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
B918A22C20935ED700E64FBE /* Sentry.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B918A22920935EC800E64FBE /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
B918A22E20935EE900E64FBE /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B918A22D20935EE900E64FBE /* ErrorHandler.swift */; };
|
||||||
B91FF331206AB4E6005EA520 /* xcbuddy in Copy CLI */ = {isa = PBXBuildFile; fileRef = B915ECF6206395DA004B6630 /* xcbuddy */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
B91FF331206AB4E6005EA520 /* xcbuddy in Copy CLI */ = {isa = PBXBuildFile; fileRef = B915ECF6206395DA004B6630 /* xcbuddy */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
B92BF9FE2075608B00EE4EBD /* Data+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B92BF9FD2075608B00EE4EBD /* Data+TestData.swift */; };
|
B92BF9FE2075608B00EE4EBD /* Data+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B92BF9FD2075608B00EE4EBD /* Data+TestData.swift */; };
|
||||||
B94C7FC12062B8A8009BF596 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B94C7FB72062B8A7009BF596 /* Assets.xcassets */; };
|
B94C7FC12062B8A8009BF596 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B94C7FB72062B8A7009BF596 /* Assets.xcassets */; };
|
||||||
|
@ -178,6 +182,7 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
|
B918A22B20935ECF00E64FBE /* Sentry.framework in Embed Frameworks */,
|
||||||
B9E2DCB22087757D0061DF86 /* PathKit.framework in Embed Frameworks */,
|
B9E2DCB22087757D0061DF86 /* PathKit.framework in Embed Frameworks */,
|
||||||
B9E2DCA520876F660061DF86 /* Utility.framework in Embed Frameworks */,
|
B9E2DCA520876F660061DF86 /* Utility.framework in Embed Frameworks */,
|
||||||
B9FB2DC82086516A00BC2FB3 /* clibc.framework in Embed Frameworks */,
|
B9FB2DC82086516A00BC2FB3 /* clibc.framework in Embed Frameworks */,
|
||||||
|
@ -198,6 +203,7 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
|
B918A22C20935ED700E64FBE /* Sentry.framework in Embed Frameworks */,
|
||||||
B9E2DCB3208775860061DF86 /* PathKit.framework in Embed Frameworks */,
|
B9E2DCB3208775860061DF86 /* PathKit.framework in Embed Frameworks */,
|
||||||
B9E2DCAC208775160061DF86 /* clibc.framework in Embed Frameworks */,
|
B9E2DCAC208775160061DF86 /* clibc.framework in Embed Frameworks */,
|
||||||
B9E2DCAD208775160061DF86 /* SPMLibc.framework in Embed Frameworks */,
|
B9E2DCAD208775160061DF86 /* SPMLibc.framework in Embed Frameworks */,
|
||||||
|
@ -225,6 +231,8 @@
|
||||||
B915ED4D2063B04C004B6630 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
B915ED4D2063B04C004B6630 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
B915ED672063B18B004B6630 /* xcproj.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = xcproj.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
B915ED672063B18B004B6630 /* xcproj.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = xcproj.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
B91834BE207CBCE6008935B4 /* ProjectDescription.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ProjectDescription.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
B91834BE207CBCE6008935B4 /* ProjectDescription.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ProjectDescription.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
B918A22920935EC800E64FBE /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sentry.framework; sourceTree = "<group>"; };
|
||||||
|
B918A22D20935EE900E64FBE /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
|
||||||
B9287D0520808FFF002DEFEE /* BuildConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildConfigurationTests.swift; sourceTree = "<group>"; };
|
B9287D0520808FFF002DEFEE /* BuildConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildConfigurationTests.swift; sourceTree = "<group>"; };
|
||||||
B92BF8152073E66200EE4EBD /* MockUpdateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUpdateController.swift; sourceTree = "<group>"; };
|
B92BF8152073E66200EE4EBD /* MockUpdateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUpdateController.swift; sourceTree = "<group>"; };
|
||||||
B92BF9F0207559E600EE4EBD /* MockGraphLoaderCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockGraphLoaderCache.swift; sourceTree = "<group>"; };
|
B92BF9F0207559E600EE4EBD /* MockGraphLoaderCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockGraphLoaderCache.swift; sourceTree = "<group>"; };
|
||||||
|
@ -344,6 +352,7 @@
|
||||||
B9E2DCA420876F490061DF86 /* Utility.framework in Frameworks */,
|
B9E2DCA420876F490061DF86 /* Utility.framework in Frameworks */,
|
||||||
B9FB2DBF2086506E00BC2FB3 /* Basic.framework in Frameworks */,
|
B9FB2DBF2086506E00BC2FB3 /* Basic.framework in Frameworks */,
|
||||||
B91834BF207CBCE6008935B4 /* ProjectDescription.framework in Frameworks */,
|
B91834BF207CBCE6008935B4 /* ProjectDescription.framework in Frameworks */,
|
||||||
|
B918A22A20935EC800E64FBE /* Sentry.framework in Frameworks */,
|
||||||
B9013DD5206FEEDF007B1A34 /* Sparkle.framework in Frameworks */,
|
B9013DD5206FEEDF007B1A34 /* Sparkle.framework in Frameworks */,
|
||||||
B915ED662063B18B004B6630 /* xcproj.framework in Frameworks */,
|
B915ED662063B18B004B6630 /* xcproj.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -371,6 +380,7 @@
|
||||||
B915EC392062EC97004B6630 /* Frameworks */ = {
|
B915EC392062EC97004B6630 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B918A22920935EC800E64FBE /* Sentry.framework */,
|
||||||
B9E2DCAF2087756D0061DF86 /* PathKit.framework */,
|
B9E2DCAF2087756D0061DF86 /* PathKit.framework */,
|
||||||
B9FB2DC22086507700BC2FB3 /* clibc.framework */,
|
B9FB2DC22086507700BC2FB3 /* clibc.framework */,
|
||||||
B9FB2DC42086507700BC2FB3 /* SPMLibc.framework */,
|
B9FB2DC42086507700BC2FB3 /* SPMLibc.framework */,
|
||||||
|
@ -575,6 +585,7 @@
|
||||||
B9553DE92090690000050311 /* Shell.swift */,
|
B9553DE92090690000050311 /* Shell.swift */,
|
||||||
B9553DF02092181500050311 /* Context.swift */,
|
B9553DF02092181500050311 /* Context.swift */,
|
||||||
B9553DF220921AF300050311 /* ResourceLocator.swift */,
|
B9553DF220921AF300050311 /* ResourceLocator.swift */,
|
||||||
|
B918A22D20935EE900E64FBE /* ErrorHandler.swift */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -770,6 +781,7 @@
|
||||||
B9FDBF33206423460010BC33 /* Embed Frameworks */,
|
B9FDBF33206423460010BC33 /* Embed Frameworks */,
|
||||||
B9B80AB0206AAFC30057482B /* Copy CLI */,
|
B9B80AB0206AAFC30057482B /* Copy CLI */,
|
||||||
B91834CF207CEB00008935B4 /* Copy ProjectDescription Framework */,
|
B91834CF207CEB00008935B4 /* Copy ProjectDescription Framework */,
|
||||||
|
B918A22F209365E900E64FBE /* Upload symbols to sentry */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -875,6 +887,20 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "${SRCROOT}/scripts/copy-framework.sh ProjectDescription.framework";
|
shellScript = "${SRCROOT}/scripts/copy-framework.sh ProjectDescription.framework";
|
||||||
};
|
};
|
||||||
|
B918A22F209365E900E64FBE /* Upload symbols to sentry */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Upload symbols to sentry";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "if which sentry-cli >/dev/null; then\nexport SENTRY_ORG=xcbuddy\nexport SENTRY_PROJECT=app\nERROR=$(bin/sentry-cli upload-dsym 2>&1 >/dev/null)\nif [ ! $? -eq 0 ]; then\necho \"warning: sentry-cli - $ERROR\"\nfi\nelse\necho \"warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases\"\nfi";
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
@ -890,6 +916,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B918A22E20935EE900E64FBE /* ErrorHandler.swift in Sources */,
|
||||||
B9B629AC20864E3A00EE9E07 /* FileHandler.swift in Sources */,
|
B9B629AC20864E3A00EE9E07 /* FileHandler.swift in Sources */,
|
||||||
B9553DEA2090690000050311 /* Shell.swift in Sources */,
|
B9553DEA2090690000050311 /* Shell.swift in Sources */,
|
||||||
B95895F3208A2ACF00F00ACF /* ProjectGenerator.swift in Sources */,
|
B95895F3208A2ACF00F00ACF /* ProjectGenerator.swift in Sources */,
|
||||||
|
|
|
@ -24,5 +24,7 @@
|
||||||
<string>Copyright © 2018 ppinera.es. All rights reserved.</string>
|
<string>Copyright © 2018 ppinera.es. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
|
<key>SENTRY_DSN</key>
|
||||||
|
<string>$(SENTRY_DSN)</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -61,7 +61,7 @@ class GraphManifestLoader: GraphManifestLoading {
|
||||||
throw GraphManifestLoaderError.swiftNotFound
|
throw GraphManifestLoaderError.swiftNotFound
|
||||||
}
|
}
|
||||||
let swiftPath = AbsolutePath(swiftOutput)
|
let swiftPath = AbsolutePath(swiftOutput)
|
||||||
let manifestFrameworkPath = try context.resourceLocator.projectDescription(context: context)
|
let manifestFrameworkPath = try context.resourceLocator.projectDescription()
|
||||||
let jsonString: String! = try context.shell.run(swiftPath.asString, "-F", manifestFrameworkPath.parentDirectory.asString, "-framework", "ProjectDescription", path.asString, "--dump").chuzzle()
|
let jsonString: String! = try context.shell.run(swiftPath.asString, "-F", manifestFrameworkPath.parentDirectory.asString, "-framework", "ProjectDescription", path.asString, "--dump").chuzzle()
|
||||||
if jsonString == nil {
|
if jsonString == nil {
|
||||||
throw GraphManifestLoaderError.unexpectedOutput(path)
|
throw GraphManifestLoaderError.unexpectedOutput(path)
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
import Foundation
|
||||||
|
import Sentry
|
||||||
|
|
||||||
|
/// Error handling protocol.
|
||||||
|
protocol ErrorHandling: AnyObject {
|
||||||
|
/// It should be called when a fatal error happens. Depending on the error it
|
||||||
|
/// prints, and reports the error to Sentry.
|
||||||
|
///
|
||||||
|
/// - Parameter error: error.
|
||||||
|
func fatal(error: FatalError)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fatal errors that can be thrown at any point of the execution.
|
||||||
|
///
|
||||||
|
/// - abort: used when something unexpected happens and the user should be alerted.
|
||||||
|
/// - bug: like abort, but it also reports the event to Sentry.
|
||||||
|
/// - abortSilent: like abort, but it doesn't print anything in the console.
|
||||||
|
/// - bugSilent: like bug, but it doesn't print anything in the console.
|
||||||
|
enum FatalError: Error {
|
||||||
|
case abort(Error & CustomStringConvertible)
|
||||||
|
case bug(Error & CustomStringConvertible)
|
||||||
|
case abortSilent(Error)
|
||||||
|
case bugSilent(Error)
|
||||||
|
|
||||||
|
/// Returns the error description
|
||||||
|
var description: String? {
|
||||||
|
switch self {
|
||||||
|
case let .abort(error):
|
||||||
|
return error.description
|
||||||
|
case let .bug(error):
|
||||||
|
return error.description
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a bug to be reported.
|
||||||
|
var bug: Error? {
|
||||||
|
switch self {
|
||||||
|
case let .bug(error): return error
|
||||||
|
case let .bugSilent(error): return error
|
||||||
|
default: return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error handler.
|
||||||
|
final class ErrorHandler: ErrorHandling {
|
||||||
|
/// Printer.
|
||||||
|
let printer: Printing
|
||||||
|
|
||||||
|
/// Sentry client.
|
||||||
|
let client: Client?
|
||||||
|
|
||||||
|
/// Initializes the error handler with its attributes.
|
||||||
|
///
|
||||||
|
/// - Parameter printer: printer.
|
||||||
|
init(printer: Printing = Printer()) {
|
||||||
|
if let sentryDsn = Bundle(for: ErrorHandler.self).infoDictionary?["SENTRY_DSN"] as? String {
|
||||||
|
client = try! Client(dsn: sentryDsn)
|
||||||
|
try! client?.startCrashHandler()
|
||||||
|
} else {
|
||||||
|
client = nil
|
||||||
|
}
|
||||||
|
self.printer = printer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// It should be called when a fatal error happens. Depending on the error it
|
||||||
|
/// prints, and reports the error to Sentry.
|
||||||
|
///
|
||||||
|
/// - Parameter error: error.
|
||||||
|
func fatal(error: FatalError) {
|
||||||
|
if let description = error.description {
|
||||||
|
printer.print(errorMessage: description)
|
||||||
|
}
|
||||||
|
if let bug = error.bug {
|
||||||
|
let event = Event(level: .debug)
|
||||||
|
event.message = bug.localizedDescription
|
||||||
|
let semaphore = DispatchSemaphore(value: 0)
|
||||||
|
client?.send(event: event) { _ in
|
||||||
|
semaphore.signal()
|
||||||
|
}
|
||||||
|
semaphore.wait()
|
||||||
|
}
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,14 +8,14 @@ protocol ResourceLocating: AnyObject {
|
||||||
/// - Parameter context: context.
|
/// - Parameter context: context.
|
||||||
/// - Returns: ProjectDescription.framework path.
|
/// - Returns: ProjectDescription.framework path.
|
||||||
/// - Throws: an error if the framework cannot be found.
|
/// - Throws: an error if the framework cannot be found.
|
||||||
func projectDescription(context: Contexting) throws -> AbsolutePath
|
func projectDescription() throws -> AbsolutePath
|
||||||
|
|
||||||
/// Returns the CLI path.
|
/// Returns the CLI path.
|
||||||
///
|
///
|
||||||
/// - Parameter context: context.
|
/// - Parameter context: context.
|
||||||
/// - Returns: path to the xcbuddy CLI.
|
/// - Returns: path to the xcbuddy CLI.
|
||||||
/// - Throws: an error if the CLI cannot be found.
|
/// - Throws: an error if the CLI cannot be found.
|
||||||
func cliPath(context: Contexting) throws -> AbsolutePath
|
func cliPath() throws -> AbsolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resource locating error.
|
/// Resource locating error.
|
||||||
|
@ -40,18 +40,27 @@ enum ResourceLocatingError: Error, CustomStringConvertible, Equatable {
|
||||||
|
|
||||||
/// Resource locator.
|
/// Resource locator.
|
||||||
final class ResourceLocator: ResourceLocating {
|
final class ResourceLocator: ResourceLocating {
|
||||||
|
/// File handler.
|
||||||
|
private let fileHandler: FileHandling
|
||||||
|
|
||||||
|
/// Initializes the locator with its attributes.
|
||||||
|
///
|
||||||
|
/// - Parameter fileHandler: file handler.
|
||||||
|
init(fileHandler: FileHandling = FileHandler()) {
|
||||||
|
self.fileHandler = fileHandler
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the ProjectDescription.framework path.
|
/// Returns the ProjectDescription.framework path.
|
||||||
///
|
///
|
||||||
/// - Parameter context: context.
|
|
||||||
/// - Returns: ProjectDescription.framework path.
|
/// - Returns: ProjectDescription.framework path.
|
||||||
/// - Throws: an error if the framework cannot be found.
|
/// - Throws: an error if the framework cannot be found.
|
||||||
func projectDescription(context: Contexting) throws -> AbsolutePath {
|
func projectDescription() throws -> AbsolutePath {
|
||||||
let frameworkName = "ProjectDescription.framework"
|
let frameworkName = "ProjectDescription.framework"
|
||||||
let xcbuddyKitPath = AbsolutePath(Bundle(for: GraphManifestLoader.self).bundleURL.path)
|
let xcbuddyKitPath = AbsolutePath(Bundle(for: GraphManifestLoader.self).bundleURL.path)
|
||||||
let parentPath = xcbuddyKitPath.parentDirectory
|
let parentPath = xcbuddyKitPath.parentDirectory
|
||||||
let pathInProducts = parentPath.appending(component: frameworkName)
|
let pathInProducts = parentPath.appending(component: frameworkName)
|
||||||
// Built products directory
|
// Built products directory
|
||||||
if context.fileHandler.exists(pathInProducts) {
|
if fileHandler.exists(pathInProducts) {
|
||||||
return pathInProducts
|
return pathInProducts
|
||||||
}
|
}
|
||||||
// Frameworks directory inside the app bundle.
|
// Frameworks directory inside the app bundle.
|
||||||
|
@ -63,7 +72,7 @@ final class ResourceLocator: ResourceLocating {
|
||||||
throw ResourceLocatingError.notFound(frameworkName)
|
throw ResourceLocatingError.notFound(frameworkName)
|
||||||
}
|
}
|
||||||
let frameworkPath = AbsolutePath(frameworksPath).appending(component: frameworkName)
|
let frameworkPath = AbsolutePath(frameworksPath).appending(component: frameworkName)
|
||||||
if !context.fileHandler.exists(frameworkPath) {
|
if !fileHandler.exists(frameworkPath) {
|
||||||
throw ResourceLocatingError.notFound(frameworkName)
|
throw ResourceLocatingError.notFound(frameworkName)
|
||||||
}
|
}
|
||||||
return frameworkPath
|
return frameworkPath
|
||||||
|
@ -71,16 +80,15 @@ final class ResourceLocator: ResourceLocating {
|
||||||
|
|
||||||
/// Returns the CLI path.
|
/// Returns the CLI path.
|
||||||
///
|
///
|
||||||
/// - Parameter context: context.
|
|
||||||
/// - Returns: path to the xcbuddy CLI.
|
/// - Returns: path to the xcbuddy CLI.
|
||||||
/// - Throws: an error if the CLI cannot be found.
|
/// - Throws: an error if the CLI cannot be found.
|
||||||
func cliPath(context: Contexting) throws -> AbsolutePath {
|
func cliPath() throws -> AbsolutePath {
|
||||||
let toolName = "xcbuddy"
|
let toolName = "xcbuddy"
|
||||||
let xcbuddyKitPath = AbsolutePath(Bundle(for: GraphManifestLoader.self).bundleURL.path)
|
let xcbuddyKitPath = AbsolutePath(Bundle(for: GraphManifestLoader.self).bundleURL.path)
|
||||||
let parentPath = xcbuddyKitPath.parentDirectory
|
let parentPath = xcbuddyKitPath.parentDirectory
|
||||||
let pathInProducts = parentPath.appending(component: toolName)
|
let pathInProducts = parentPath.appending(component: toolName)
|
||||||
// Built products directory
|
// Built products directory
|
||||||
if context.fileHandler.exists(pathInProducts) {
|
if fileHandler.exists(pathInProducts) {
|
||||||
return pathInProducts
|
return pathInProducts
|
||||||
}
|
}
|
||||||
// Frameworks directory inside the app bundle.
|
// Frameworks directory inside the app bundle.
|
||||||
|
@ -92,7 +100,7 @@ final class ResourceLocator: ResourceLocating {
|
||||||
throw ResourceLocatingError.notFound(toolName)
|
throw ResourceLocatingError.notFound(toolName)
|
||||||
}
|
}
|
||||||
let toolPath = AbsolutePath(frameworksPath).appending(component: toolName)
|
let toolPath = AbsolutePath(frameworksPath).appending(component: toolName)
|
||||||
if !context.fileHandler.exists(toolPath) {
|
if !fileHandler.exists(toolPath) {
|
||||||
throw ResourceLocatingError.notFound(toolName)
|
throw ResourceLocatingError.notFound(toolName)
|
||||||
}
|
}
|
||||||
return toolPath
|
return toolPath
|
||||||
|
|
|
@ -3,17 +3,17 @@ import Foundation
|
||||||
|
|
||||||
final class MockResourceLocator: ResourceLocating {
|
final class MockResourceLocator: ResourceLocating {
|
||||||
var projectDescriptionCount: UInt = 0
|
var projectDescriptionCount: UInt = 0
|
||||||
var projectDescriptionStub: ((Contexting) throws -> AbsolutePath)?
|
var projectDescriptionStub: (() throws -> AbsolutePath)?
|
||||||
var cliPathCount: UInt = 0
|
var cliPathCount: UInt = 0
|
||||||
var cliPathStub: ((Contexting) throws -> AbsolutePath)?
|
var cliPathStub: (() throws -> AbsolutePath)?
|
||||||
|
|
||||||
func projectDescription(context: Contexting) throws -> AbsolutePath {
|
func projectDescription() throws -> AbsolutePath {
|
||||||
projectDescriptionCount += 1
|
projectDescriptionCount += 1
|
||||||
return try projectDescriptionStub?(context) ?? AbsolutePath("/")
|
return try projectDescriptionStub?() ?? AbsolutePath("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
func cliPath(context: Contexting) throws -> AbsolutePath {
|
func cliPath() throws -> AbsolutePath {
|
||||||
cliPathCount += 1
|
cliPathCount += 1
|
||||||
return try cliPathStub?(context) ?? AbsolutePath("/")
|
return try cliPathStub?() ?? AbsolutePath("/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const cli = require('../js');
|
||||||
|
const child = require('child_process').spawn(cli.getPath(), process.argv.slice(2), {
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', err => {
|
||||||
|
console.error('error: failed to invoke sentry-cli');
|
||||||
|
console.error(err.stack);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', code => {
|
||||||
|
process.exit(code);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
|
child.kill('SIGTERM');
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
child.kill('SIGINT');
|
||||||
|
});
|
Loading…
Reference in New Issue