@@ -13,6 +13,7 @@ import Foundation
13
13
import TSCBasic
14
14
import Build
15
15
import Commands
16
+ import SourceControl
16
17
import SPMTestSupport
17
18
18
19
final class APIDiffTests : XCTestCase {
@@ -50,7 +51,7 @@ final class APIDiffTests: XCTestCase {
50
51
try localFileSystem. writeFileContents ( packageRoot. appending ( component: " Foo.swift " ) ) {
51
52
$0 <<< " public let foo = 42 "
52
53
}
53
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
54
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
54
55
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
55
56
XCTFail ( " Unexpected error " )
56
57
return
@@ -71,7 +72,7 @@ final class APIDiffTests: XCTestCase {
71
72
try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Qux " , " Qux.swift " ) ) {
72
73
$0 <<< " public class Qux<T, U> { private let x = 1 } "
73
74
}
74
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " -j " , " 2 " ] , packagePath: packageRoot) ) { error in
75
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " -j " , " 2 " ] , packagePath: packageRoot) ) { error in
75
76
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
76
77
XCTFail ( " Unexpected error " )
77
78
return
@@ -99,7 +100,7 @@ final class APIDiffTests: XCTestCase {
99
100
try localFileSystem. writeFileContents ( customAllowlistPath) {
100
101
$0 <<< " API breakage: class Qux has generic signature change from <T> to <T, U> \n "
101
102
}
102
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " -j " , " 2 " ,
103
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " -j " , " 2 " ,
103
104
" --breakage-allowlist-path " , customAllowlistPath. pathString] ,
104
105
packagePath: packageRoot) ) { error in
105
106
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
@@ -132,7 +133,7 @@ final class APIDiffTests: XCTestCase {
132
133
try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Qux " , " Qux.swift " ) ) {
133
134
$0 <<< " public class Qux<T, U> { private let x = 1 } "
134
135
}
135
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
136
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
136
137
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
137
138
XCTFail ( " Unexpected error " )
138
139
return
@@ -168,7 +169,7 @@ final class APIDiffTests: XCTestCase {
168
169
try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Qux " , " Qux.swift " ) ) {
169
170
$0 <<< " public class Qux<T, U> { private let x = 1 } "
170
171
}
171
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " --products " , " One " , " --targets " , " Bar " ] ,
172
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " --products " , " One " , " --targets " , " Bar " ] ,
172
173
packagePath: packageRoot) ) { error in
173
174
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
174
175
XCTFail ( " Unexpected error " )
@@ -188,7 +189,7 @@ final class APIDiffTests: XCTestCase {
188
189
}
189
190
190
191
// Diff a target which didn't have a baseline generated as part of the first invocation
191
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " --targets " , " Baz " ] ,
192
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " --targets " , " Baz " ] ,
192
193
packagePath: packageRoot) ) { error in
193
194
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
194
195
XCTFail ( " Unexpected error " )
@@ -208,7 +209,7 @@ final class APIDiffTests: XCTestCase {
208
209
}
209
210
210
211
// Test diagnostics
211
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " --targets " , " NotATarget " , " Exec " ,
212
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " --targets " , " NotATarget " , " Exec " ,
212
213
" --products " , " NotAProduct " , " Exec " ] ,
213
214
packagePath: packageRoot) ) { error in
214
215
guard case SwiftPMProductError . executionFailure( error: _, output: _, stderr: let stderr) = error else {
@@ -239,7 +240,7 @@ final class APIDiffTests: XCTestCase {
239
240
}
240
241
"""
241
242
}
242
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
243
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ] , packagePath: packageRoot) ) { error in
243
244
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
244
245
XCTFail ( " Unexpected error " )
245
246
return
@@ -249,7 +250,7 @@ final class APIDiffTests: XCTestCase {
249
250
}
250
251
251
252
// Report an error if we explicitly ask to diff a C-family target
252
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " , " --targets " , " Foo " ] , packagePath: packageRoot) ) { error in
253
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " , " --targets " , " Foo " ] , packagePath: packageRoot) ) { error in
253
254
guard case SwiftPMProductError . executionFailure( error: _, output: _, stderr: let stderr) = error else {
254
255
XCTFail ( " Unexpected error " )
255
256
return
@@ -268,7 +269,7 @@ final class APIDiffTests: XCTestCase {
268
269
try localFileSystem. writeFileContents ( packageRoot. appending ( components: " Sources " , " Baz " , " Baz.swift " ) ) {
269
270
$0 <<< " public func bar() -> Int { 100 } "
270
271
}
271
- let ( output, _) = try execute ( [ " experimental -api-diff " , " 1.2.3 " ] , packagePath: packageRoot)
272
+ let ( output, _) = try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ] , packagePath: packageRoot)
272
273
XCTAssertTrue ( output. contains ( " No breaking changes detected in Baz " ) )
273
274
XCTAssertTrue ( output. contains ( " No breaking changes detected in Qux " ) )
274
275
}
@@ -301,7 +302,7 @@ final class APIDiffTests: XCTestCase {
301
302
)
302
303
"""
303
304
}
304
- let ( output, _) = try execute ( [ " experimental -api-diff " , " 1.2.3 " ] , packagePath: packageRoot)
305
+ let ( output, _) = try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ] , packagePath: packageRoot)
305
306
XCTAssertTrue ( output. contains ( " No breaking changes detected in Baz " ) )
306
307
XCTAssertTrue ( output. contains ( " No breaking changes detected in Qux " ) )
307
308
XCTAssertTrue ( output. contains ( " Skipping Foo because it does not exist in the baseline " ) )
@@ -312,12 +313,50 @@ final class APIDiffTests: XCTestCase {
312
313
try skipIfApiDigesterUnsupported ( )
313
314
fixture ( name: " Miscellaneous/APIDiff/ " ) { prefix in
314
315
let packageRoot = prefix. appending ( component: " Foo " )
315
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 7.8.9 " ] , packagePath: packageRoot) ) { error in
316
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 7.8.9 " ] , packagePath: packageRoot) ) { error in
316
317
guard case SwiftPMProductError . executionFailure( error: _, output: _, stderr: let stderr) = error else {
317
318
XCTFail ( " Unexpected error " )
318
319
return
319
320
}
320
- XCTAssertTrue ( stderr. contains ( " error: Couldn’t check out revision ‘7.8.9’ " ) )
321
+ XCTAssertTrue ( stderr. contains ( " error: Couldn’t get revision " ) )
322
+ }
323
+ }
324
+ }
325
+
326
+ func testBranchUpdate( ) throws {
327
+ try skipIfApiDigesterUnsupported ( )
328
+ try withTemporaryDirectory { baselineDir in
329
+ fixture ( name: " Miscellaneous/APIDiff/ " ) { prefix in
330
+ let packageRoot = prefix. appending ( component: " Foo " )
331
+ let repo = GitRepository ( path: packageRoot)
332
+ try repo. checkout ( newBranch: " feature " )
333
+ // Overwrite the existing decl.
334
+ try localFileSystem. writeFileContents ( packageRoot. appending ( component: " Foo.swift " ) ) {
335
+ $0 <<< " public let foo = 42 "
336
+ }
337
+ try repo. stage ( file: " Foo.swift " )
338
+ try repo. commit ( message: " Add foo " )
339
+ XCTAssertThrowsError ( try execute ( [ " diagnose-api-breaking-changes " , " main " , " --baseline-dir " , baselineDir. pathString] ,
340
+ packagePath: packageRoot) ) { error in
341
+ guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
342
+ XCTFail ( " Unexpected error " )
343
+ return
344
+ }
345
+ XCTAssertTrue ( output. contains ( " 1 breaking change detected in Foo " ) )
346
+ XCTAssertTrue ( output. contains ( " 💔 API breakage: func foo() has been removed " ) )
347
+ }
348
+
349
+ // Update `main` and ensure the baseline is regenerated.
350
+ try repo. checkout ( revision: . init( identifier: " main " ) )
351
+ try localFileSystem. writeFileContents ( packageRoot. appending ( component: " Foo.swift " ) ) {
352
+ $0 <<< " public let foo = 42 "
353
+ }
354
+ try repo. stage ( file: " Foo.swift " )
355
+ try repo. commit ( message: " Add foo " )
356
+ try repo. checkout ( revision: . init( identifier: " feature " ) )
357
+ let ( output, _) = try execute ( [ " diagnose-api-breaking-changes " , " main " , " --baseline-dir " , baselineDir. pathString] ,
358
+ packagePath: packageRoot)
359
+ XCTAssertTrue ( output. contains ( " No breaking changes detected in Foo " ) )
321
360
}
322
361
}
323
362
}
@@ -332,8 +371,10 @@ final class APIDiffTests: XCTestCase {
332
371
}
333
372
334
373
let baselineDir = prefix. appending ( component: " Baselines " )
374
+ let repo = GitRepository ( path: packageRoot)
375
+ let revision = try repo. resolveRevision ( identifier: " 1.2.3 " )
335
376
336
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " ,
377
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ,
337
378
" --baseline-dir " , baselineDir. pathString] ,
338
379
packagePath: packageRoot) ) { error in
339
380
guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
@@ -342,7 +383,7 @@ final class APIDiffTests: XCTestCase {
342
383
}
343
384
XCTAssertTrue ( output. contains ( " 1 breaking change detected in Foo " ) )
344
385
XCTAssertTrue ( output. contains ( " 💔 API breakage: func foo() has been removed " ) )
345
- XCTAssertTrue ( localFileSystem. exists ( baselineDir. appending ( components: " 1.2.3 " , " Foo.json " ) ) )
386
+ XCTAssertTrue ( localFileSystem. exists ( baselineDir. appending ( components: revision . identifier , " Foo.json " ) ) )
346
387
}
347
388
}
348
389
}
@@ -356,15 +397,18 @@ final class APIDiffTests: XCTestCase {
356
397
$0 <<< " public let foo = 42 "
357
398
}
358
399
400
+ let repo = GitRepository ( path: packageRoot)
401
+ let revision = try repo. resolveRevision ( identifier: " 1.2.3 " )
402
+
359
403
let baselineDir = prefix. appending ( component: " Baselines " )
360
- let fooBaselinePath = baselineDir. appending ( components: " 1.2.3 " , " Foo.json " )
404
+ let fooBaselinePath = baselineDir. appending ( components: revision . identifier , " Foo.json " )
361
405
362
406
try localFileSystem. createDirectory ( fooBaselinePath. parentDirectory, recursive: true )
363
407
try localFileSystem. writeFileContents ( fooBaselinePath) {
364
408
$0 <<< " Old Baseline "
365
409
}
366
410
367
- XCTAssertThrowsError ( try execute ( [ " experimental -api-diff " , " 1.2.3 " ,
411
+ XCTAssertThrowsError ( try execute ( [ " diagnose -api-breaking-changes " , " 1.2.3 " ,
368
412
" --baseline-dir " , baselineDir. pathString,
369
413
" --regenerate-baseline " ] ,
370
414
packagePath: packageRoot) ) { error in
@@ -379,4 +423,15 @@ final class APIDiffTests: XCTestCase {
379
423
}
380
424
}
381
425
}
426
+
427
+ func testOldName( ) throws {
428
+ XCTAssertThrowsError ( try execute ( [ " experimental-api-diff " , " 1.2.3 " , " --regenerate-baseline " ] ,
429
+ packagePath: nil ) ) { error in
430
+ guard case SwiftPMProductError . executionFailure( error: _, output: let output, stderr: _) = error else {
431
+ XCTFail ( " Unexpected error " )
432
+ return
433
+ }
434
+ XCTAssertTrue ( output. contains ( " `swift package experimental-api-diff` has been renamed to `swift package diagnose-api-breaking-changes` " ) )
435
+ }
436
+ }
382
437
}
0 commit comments