@@ -76,7 +76,7 @@ public protocol ManifestLoaderProtocol {
76
76
}
77
77
78
78
public extension ManifestLoaderProtocol {
79
- var supportedArchiveExtension : String { " zip " }
79
+ var supportedArchiveExtensions : [ String ] { [ " zip " ] }
80
80
}
81
81
82
82
public protocol ManifestLoaderDelegate {
@@ -408,30 +408,69 @@ public final class ManifestLoader: ManifestLoaderProtocol {
408
408
private func validateBinaryTargets( _ manifest: Manifest , observabilityScope: ObservabilityScope ) throws {
409
409
// Check that binary targets point to the right file type.
410
410
for target in manifest. targets where target. type == . binary {
411
- guard let location = URL ( string: target. url ?? target. path ?? " " ) else {
411
+ if target. isLocal {
412
+ guard let path = target. path else {
413
+ observabilityScope. emit ( . invalidBinaryLocation( targetName: target. name) )
414
+ continue
415
+ }
416
+
417
+ guard let path = path. spm_chuzzle ( ) , !path. isEmpty else {
418
+ observabilityScope. emit ( . invalidLocalBinaryPath( path: path, targetName: target. name) )
419
+ continue
420
+ }
421
+
422
+ guard let relativePath = try ? RelativePath ( validating: path) else {
423
+ observabilityScope. emit ( . invalidLocalBinaryPath( path: path, targetName: target. name) )
424
+ continue
425
+ }
426
+
427
+ let validExtensions = self . supportedArchiveExtensions + BinaryTarget. Kind. allCases. filter { $0 != . unknown } . map { $0. fileExtension }
428
+ guard let fileExtension = relativePath. extension, validExtensions. contains ( fileExtension) else {
429
+ observabilityScope. emit ( . unsupportedBinaryLocationExtension(
430
+ targetName: target. name,
431
+ validExtensions: validExtensions
432
+ ) )
433
+ continue
434
+ }
435
+ } else if target. isRemote {
436
+ guard let url = target. url else {
437
+ observabilityScope. emit ( . invalidBinaryLocation( targetName: target. name) )
438
+ continue
439
+ }
440
+
441
+ guard let url = url. spm_chuzzle ( ) , !url. isEmpty else {
442
+ observabilityScope. emit ( . invalidBinaryURL( url: url, targetName: target. name) )
443
+ continue
444
+ }
445
+
446
+ guard let url = URL ( string: url) else {
447
+ observabilityScope. emit ( . invalidBinaryURL( url: url, targetName: target. name) )
448
+ continue
449
+ }
450
+
451
+ let validSchemes = [ " https " ]
452
+ guard url. scheme. map ( { validSchemes. contains ( $0) } ) ?? false else {
453
+ observabilityScope. emit ( . invalidBinaryURLScheme(
454
+ targetName: target. name,
455
+ validSchemes: validSchemes
456
+ ) )
457
+ continue
458
+ }
459
+
460
+ guard self . supportedArchiveExtensions. contains ( url. pathExtension) else {
461
+ observabilityScope. emit ( . unsupportedBinaryLocationExtension(
462
+ targetName: target. name,
463
+ validExtensions: self . supportedArchiveExtensions
464
+ ) )
465
+ continue
466
+ }
467
+
468
+ } else {
412
469
observabilityScope. emit ( . invalidBinaryLocation( targetName: target. name) )
413
470
continue
414
471
}
415
472
416
- let validSchemes = [ " https " ]
417
- if target. isRemote && ( location. scheme. map ( { !validSchemes. contains ( $0) } ) ?? true ) {
418
- observabilityScope. emit ( . invalidBinaryURLScheme(
419
- targetName: target. name,
420
- validSchemes: validSchemes
421
- ) )
422
- }
423
473
424
- var validExtensions = [ self . supportedArchiveExtension]
425
- if target. isLocal {
426
- validExtensions += BinaryTarget . Kind. allCases. filter { $0 != . unknown } . map { $0. fileExtension }
427
- }
428
-
429
- if !validExtensions. contains ( location. pathExtension) {
430
- observabilityScope. emit ( . unsupportedBinaryLocationExtension(
431
- targetName: target. name,
432
- validExtensions: validExtensions
433
- ) )
434
- }
435
474
}
436
475
}
437
476
@@ -1070,6 +1109,14 @@ extension Basics.Diagnostic {
1070
1109
. error( " invalid location for binary target ' \( targetName) ' " )
1071
1110
}
1072
1111
1112
+ static func invalidBinaryURL( url: String , targetName: String ) -> Self {
1113
+ . error( " invalid URL ' \( url) ' for binary target ' \( targetName) ' " )
1114
+ }
1115
+
1116
+ static func invalidLocalBinaryPath( path: String , targetName: String ) -> Self {
1117
+ . error( " invalid local path ' \( path) ' for binary target ' \( targetName) ', path expected to be relative to package root. " )
1118
+ }
1119
+
1073
1120
static func invalidBinaryURLScheme( targetName: String , validSchemes: [ String ] ) -> Self {
1074
1121
. error( " invalid URL scheme for binary target ' \( targetName) '; valid schemes are: ' \( validSchemes. joined ( separator: " ', ' " ) ) ' " )
1075
1122
}
0 commit comments