Skip to content

Commit 91fac80

Browse files
authored
Refactor/versioning (#3237)
* move Versionig back to SwiftPM motivation: the logic in Versioning does not belong in TSC, its a SwiftPM concern changes: * move Versioning/SwiftVersion to Basics module * move Git::convertTagsToVersionMap to its only callsite * adjust call sites * cmake
1 parent 60d6da6 commit 91fac80

16 files changed

+167
-40
lines changed

Sources/Basics/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ add_library(Basics
1515
FileSystem+Extensions.swift
1616
HTPClient+URLSession.swift
1717
HTTPClient.swift
18-
JSON+Extensions.swift)
18+
JSON+Extensions.swift
19+
SwiftVersion.swift)
1920
target_link_libraries(Basics PUBLIC
2021
TSCBasic
2122
TSCUtility)
23+
target_link_libraries(Basics PRIVATE
24+
TSCclibc)
2225
# NOTE(compnerd) workaround for CMake not setting up include flags yet
2326
set_target_properties(Basics PROPERTIES
2427
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})

Sources/Basics/HTTPClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public struct HTTPClient: HTTPClientProtocol {
7979
}
8080
}
8181
if request.options.addUserAgent, !request.headers.contains("User-Agent") {
82-
request.headers.add(name: "User-Agent", value: "SwiftPackageManager/\(Versioning.currentVersion.displayString)")
82+
request.headers.add(name: "User-Agent", value: "SwiftPackageManager/\(SwiftVersion.currentVersion.displayString)")
8383
}
8484
// execute
8585
self._execute(request: request, requestNumber: 0) { result in

Sources/Basics/SwiftVersion.swift

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2021 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
@_implementationOnly import TSCclibc
12+
13+
public struct SwiftVersion {
14+
/// The version number.
15+
public var version: (major: Int, minor: Int, patch: Int)
16+
17+
/// Whether or not this is a development version.
18+
public var isDevelopment: Bool
19+
20+
/// Build information, as an unstructured string.
21+
public var buildIdentifier: String?
22+
23+
/// The major component of the version number.
24+
public var major: Int { return version.major }
25+
/// The minor component of the version number.
26+
public var minor: Int { return version.minor }
27+
/// The patch component of the version number.
28+
public var patch: Int { return version.patch }
29+
30+
/// The version as a readable string.
31+
public var displayString: String {
32+
var result = "\(major).\(minor).\(patch)"
33+
if isDevelopment {
34+
result += "-dev"
35+
}
36+
if let buildIdentifier = self.buildIdentifier {
37+
result += " (" + buildIdentifier + ")"
38+
}
39+
return result
40+
}
41+
42+
/// The complete product version display string (including the name).
43+
public var completeDisplayString: String {
44+
var vendorPrefix = String(cString: SPM_VendorNameString())
45+
if !vendorPrefix.isEmpty {
46+
vendorPrefix += " "
47+
}
48+
return vendorPrefix + "Swift Package Manager - Swift " + displayString
49+
}
50+
51+
/// The list of version specific identifiers to search when attempting to
52+
/// load version specific package or version information, in order of
53+
/// preference.
54+
public var versionSpecificKeys: [String] {
55+
return [
56+
"@swift-\(major).\(minor).\(patch)",
57+
"@swift-\(major).\(minor)",
58+
"@swift-\(major)",
59+
]
60+
}
61+
62+
}
63+
64+
extension SwiftVersion {
65+
/// The current version of the package manager.
66+
public static let currentVersion = SwiftVersion(
67+
version: (5, 4, 0),
68+
isDevelopment: true,
69+
buildIdentifier: getBuildIdentifier())
70+
}
71+
72+
private func getBuildIdentifier() -> String? {
73+
let buildIdentifier = String(cString: SPM_BuildIdentifierString())
74+
return buildIdentifier.isEmpty ? nil : buildIdentifier
75+
}

Sources/Commands/SwiftBuildTool.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
*/
1010

1111
import ArgumentParser
12-
import TSCUtility
13-
import TSCBasic
12+
import Basics
13+
import Build
1414
import PackageGraph
1515
import SPMBuildCore
16-
import Build
16+
import TSCBasic
17+
import TSCUtility
1718

1819
extension BuildSubset {
1920
var argumentName: String {
@@ -79,7 +80,7 @@ public struct SwiftBuildTool: SwiftCommand {
7980
_superCommandName: "swift",
8081
abstract: "Build sources into binary products",
8182
discussion: "SEE ALSO: swift run, swift package, swift test",
82-
version: Versioning.currentVersion.completeDisplayString,
83+
version: SwiftVersion.currentVersion.completeDisplayString,
8384
helpNames: [.short, .long, .customLong("help", withSingleDash: true)])
8485

8586
@OptionGroup()

Sources/Commands/SwiftPackageCollectionsTool.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
import ArgumentParser
12+
import Basics
1213
import Foundation
1314
import PackageCollections
1415
import PackageModel
@@ -42,7 +43,7 @@ public struct SwiftPackageCollectionsTool: ParsableCommand {
4243
_superCommandName: "swift",
4344
abstract: "Interact with package collections",
4445
discussion: "SEE ALSO: swift build, swift package, swift run, swift test",
45-
version: Versioning.currentVersion.completeDisplayString,
46+
version: SwiftVersion.currentVersion.completeDisplayString,
4647
subcommands: [
4748
Add.self,
4849
Describe.self,

Sources/Commands/SwiftPackageTool.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public struct SwiftPackageTool: ParsableCommand {
3030
_superCommandName: "swift",
3131
abstract: "Perform operations on Swift packages",
3232
discussion: "SEE ALSO: swift build, swift run, swift test",
33-
version: Versioning.currentVersion.completeDisplayString,
33+
version: SwiftVersion.currentVersion.completeDisplayString,
3434
subcommands: [
3535
Clean.self,
3636
PurgeCache.self,

Sources/Commands/SwiftRunTool.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

1111
import ArgumentParser
12-
import TSCBasic
12+
import Basics
1313
import Build
14-
import TSCUtility
1514
import PackageGraph
1615
import PackageModel
16+
import TSCBasic
17+
import TSCUtility
1718

1819
/// An enumeration of the errors that can be generated by the run tool.
1920
private enum RunError: Swift.Error {
@@ -86,7 +87,7 @@ public struct SwiftRunTool: SwiftCommand {
8687
_superCommandName: "swift",
8788
abstract: "Build and run an executable product",
8889
discussion: "SEE ALSO: swift build, swift package, swift test",
89-
version: Versioning.currentVersion.completeDisplayString,
90+
version: SwiftVersion.currentVersion.completeDisplayString,
9091
helpNames: [.short, .long, .customLong("help", withSingleDash: true)])
9192

9293
@OptionGroup()

Sources/Commands/SwiftTestTool.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public struct SwiftTestTool: SwiftCommand {
191191
_superCommandName: "swift",
192192
abstract: "Build and run tests",
193193
discussion: "SEE ALSO: swift build, swift run, swift package",
194-
version: Versioning.currentVersion.completeDisplayString,
194+
version: SwiftVersion.currentVersion.completeDisplayString,
195195
helpNames: [.short, .long, .customLong("help", withSingleDash: true)])
196196

197197
@OptionGroup()

Sources/PackageGraph/RepositoryPackageContainer.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,48 @@ public class RepositoryPackageContainerProvider: PackageContainerProvider {
384384
}
385385
}
386386
}
387+
388+
extension Git {
389+
static func convertTagsToVersionMap(_ tags: [String]) -> [Version: [String]] {
390+
// First, check if we need to restrict the tag set to version-specific tags.
391+
var knownVersions: [Version: [String]] = [:]
392+
var versionSpecificKnownVersions: [Version: [String]] = [:]
393+
394+
for tag in tags {
395+
for versionSpecificKey in SwiftVersion.currentVersion.versionSpecificKeys {
396+
if tag.hasSuffix(versionSpecificKey) {
397+
let trimmedTag = String(tag.dropLast(versionSpecificKey.count))
398+
if let version = Version(tag: trimmedTag) {
399+
versionSpecificKnownVersions[version, default: []].append(tag)
400+
}
401+
break
402+
}
403+
}
404+
405+
if let version = Version(tag: tag) {
406+
knownVersions[version, default: []].append(tag)
407+
}
408+
}
409+
// Check if any version specific tags were found.
410+
// If true, then return the version specific tags,
411+
// or else return the version independent tags.
412+
if !versionSpecificKnownVersions.isEmpty {
413+
return versionSpecificKnownVersions
414+
} else {
415+
return knownVersions
416+
}
417+
}
418+
}
419+
420+
extension Version {
421+
/// Try a version from a git tag.
422+
///
423+
/// - Parameter tag: A version string possibly prepended with "v".
424+
init?(tag: String) {
425+
if tag.first == "v" {
426+
self.init(string: String(tag.dropFirst()))
427+
} else {
428+
self.init(string: tag)
429+
}
430+
}
431+
}

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ public final class ManifestLoader: ManifestLoaderProtocol {
556556
manifestPath: path,
557557
toolsVersion: toolsVersion,
558558
env: ProcessEnv.vars,
559-
swiftpmVersion: Versioning.currentVersion.displayString,
559+
swiftpmVersion: SwiftVersion.currentVersion.displayString,
560560
fileSystem: fileSystem
561561
)
562562

Sources/PackageLoading/ToolsVersionLoader.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import TSCBasic
11+
import Basics
12+
import Foundation
1213
import PackageModel
14+
import TSCBasic
1315
import TSCUtility
14-
import Foundation
1516

1617
/// Protocol for the manifest loader interface.
1718
public protocol ToolsVersionLoaderProtocol {
@@ -37,7 +38,7 @@ extension Manifest {
3738
fileSystem: FileSystem
3839
) throws -> AbsolutePath {
3940
// Look for a version-specific manifest.
40-
for versionSpecificKey in Versioning.currentVersionSpecificKeys {
41+
for versionSpecificKey in SwiftVersion.currentVersion.versionSpecificKeys {
4142
let versionSpecificPath = packagePath.appending(component: Manifest.basename + versionSpecificKey + ".swift")
4243
if fileSystem.isFile(versionSpecificPath) {
4344
return versionSpecificPath

Sources/PackageModel/ToolsVersion.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import TSCBasic
12-
11+
import Basics
1312
import Foundation
13+
import TSCBasic
1414
import TSCUtility
1515

1616
/// Tools version represents version of the Swift toolchain.
@@ -27,9 +27,9 @@ public struct ToolsVersion: Equatable, Hashable, Codable {
2727

2828
/// The current tools version in use.
2929
public static let currentToolsVersion = ToolsVersion(string:
30-
"\(Versioning.currentVersion.major)." +
31-
"\(Versioning.currentVersion.minor)." +
32-
"\(Versioning.currentVersion.patch)")!
30+
"\(SwiftVersion.currentVersion.major)." +
31+
"\(SwiftVersion.currentVersion.minor)." +
32+
"\(SwiftVersion.currentVersion.patch)")!
3333

3434
/// The minimum tools version that is required by the package manager.
3535
public static let minimumRequired: ToolsVersion = .v4
@@ -106,7 +106,7 @@ public struct ToolsVersion: Equatable, Hashable, Codable {
106106
packagePath: String
107107
) throws {
108108
// We don't want to throw any error when using the special vNext version.
109-
if Versioning.currentVersion.isDevelopment && self == .vNext {
109+
if SwiftVersion.currentVersion.isDevelopment && self == .vNext {
110110
return
111111
}
112112

Tests/FunctionalTests/VersionSpecificTests.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import XCTest
12-
13-
import TSCBasic
11+
import Basics
1412
import SourceControl
15-
import TSCUtility
16-
1713
import SPMTestSupport
14+
import TSCBasic
15+
import TSCUtility
16+
import XCTest
1817

1918
class VersionSpecificTests: XCTestCase {
2019
/// Functional tests of end-to-end support for version specific dependency resolution.
@@ -112,7 +111,7 @@ class VersionSpecificTests: XCTestCase {
112111
}
113112
try repo.stage(file: "Package.swift")
114113
try repo.commit(message: "OK v1.1.0")
115-
try repo.tag(name: "1.1.0@swift-\(Versioning.currentVersion.major)")
114+
try repo.tag(name: "1.1.0@swift-\(SwiftVersion.currentVersion.major)")
116115

117116
// The build should work now.
118117
_ = try SwiftPMProduct.SwiftPackage.execute(["reset"], packagePath: primaryPath)

Tests/PackageLoadingTests/ManifestLoaderSQLiteCacheTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import Basics
1112
@testable import PackageLoading
1213
import PackageModel
1314
import TSCBasic
@@ -186,7 +187,7 @@ fileprivate func makeMockManifests(fileSystem: FileSystem, rootPath: AbsolutePat
186187
manifestPath: manifestPath,
187188
toolsVersion: ToolsVersion.currentToolsVersion,
188189
env: [:],
189-
swiftpmVersion: Versioning.currentVersion.displayString,
190+
swiftpmVersion: SwiftVersion.currentVersion.displayString,
190191
fileSystem: fileSystem)
191192
manifests[key] = ManifestLoader.ManifestParseResult(compilerOutput: "mock-output-\(index)",
192193
parsedManifest: "{ 'name': 'mock-manifest-\(index)' }")

Tests/PackageLoadingTests/PD4_2LoadingTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import XCTest
12-
13-
import TSCBasic
14-
import TSCUtility
15-
import SPMTestSupport
11+
import Basics
1612
import PackageModel
1713
import PackageLoading
14+
import SPMTestSupport
15+
import TSCBasic
16+
import TSCUtility
17+
import XCTest
1818

1919
class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests {
2020
override var toolsVersion: ToolsVersion {
@@ -327,7 +327,7 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests {
327327
"let package = Package(name: \"Trivial\")"))
328328

329329
// Check at each possible spelling.
330-
let currentVersion = Versioning.currentVersion
330+
let currentVersion = SwiftVersion.currentVersion
331331
let possibleSuffixes = [
332332
"\(currentVersion.major).\(currentVersion.minor).\(currentVersion.patch)",
333333
"\(currentVersion.major).\(currentVersion.minor)",

Tests/PackageLoadingTests/ToolsVersionLoaderTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import XCTest
12-
13-
import TSCBasic
14-
import SPMTestSupport
1511

12+
import Basics
1613
import PackageModel
1714
import PackageLoading
15+
import SPMTestSupport
16+
import TSCBasic
1817
import TSCUtility
18+
import XCTest
1919

2020
class ToolsVersionLoaderTests: XCTestCase {
2121

@@ -674,7 +674,7 @@ class ToolsVersionLoaderTests: XCTestCase {
674674
}
675675

676676
// Test version specific manifests.
677-
let keys = Versioning.currentVersionSpecificKeys
677+
let keys = SwiftVersion.currentVersion.versionSpecificKeys
678678

679679
// In case the count ever changes, we will need to modify this test.
680680
XCTAssertEqual(keys.count, 3)

0 commit comments

Comments
 (0)