diff --git a/Sources/Commands/CMakeLists.txt b/Sources/Commands/CMakeLists.txt index 06453788734..05705f74011 100644 --- a/Sources/Commands/CMakeLists.txt +++ b/Sources/Commands/CMakeLists.txt @@ -40,7 +40,6 @@ add_library(Commands Utilities/DependenciesSerializer.swift Utilities/DescribedPackage.swift Utilities/DOTManifestSerializer.swift - Utilities/GenerateLinuxMain.swift Utilities/MultiRootSupport.swift Utilities/PluginDelegate.swift Utilities/SymbolGraphExtract.swift diff --git a/Sources/Commands/SwiftTestTool.swift b/Sources/Commands/SwiftTestTool.swift index 6de43c73a16..152c646e94b 100644 --- a/Sources/Commands/SwiftTestTool.swift +++ b/Sources/Commands/SwiftTestTool.swift @@ -76,10 +76,6 @@ struct TestToolOptions: ParsableArguments { help: "Lists test methods in specifier format") var _deprecated_shouldListTests: Bool = false - /// Generate LinuxMain entries and exit. - @Flag(name: .customLong("generate-linuxmain"), help: .hidden) - var _deprecated_shouldGenerateLinuxMain: Bool = false - /// If the path of the exported code coverage JSON should be printed. @Flag(name: [.customLong("show-codecov-path"), .customLong("show-code-coverage-path"), .customLong("show-coverage-path")], help: "Print the path of the exported code coverage JSON file") @@ -146,7 +142,6 @@ public struct SwiftTestTool: SwiftCommand { version: SwiftVersion.current.completeDisplayString, subcommands: [ List.self, - GenerateLinuxMain.self ], helpNames: [.short, .long, .customLong("help", withSingleDash: true)]) @@ -181,10 +176,6 @@ public struct SwiftTestTool: SwiftCommand { // backward compatibility 6/2022 for deprecation of flag into a subcommand let command = try List.parse() try command.run(swiftTool) - } else if self.options._deprecated_shouldGenerateLinuxMain { - // backward compatibility 6/2022 for deprecation of flag into a subcommand - let command = try GenerateLinuxMain.parse() - try command.run(swiftTool) } else if !self.options.shouldRunInParallel { let toolchain = try swiftTool.getDestinationToolchain() let testProducts = try buildTestsIfNeeded(swiftTool: swiftTool) @@ -435,10 +426,6 @@ public struct SwiftTestTool: SwiftCommand { } } - if options._deprecated_shouldGenerateLinuxMain { - observabilityScope.emit(warning: "'--generate-linuxmain' option is deprecated; tests are automatically discovered on all platforms") - } - if options._deprecated_shouldListTests { observabilityScope.emit(warning: "'--list-tests' option is deprecated; use 'swift test list' instead") } @@ -540,56 +527,6 @@ extension SwiftTestTool { } } -extension SwiftTestTool { - // this functionality is deprecated as of 12/2020 - // but we are keeping it here for transition purposes - // to be removed in future releases - // deprecation warning is emitted by validateArguments - struct GenerateLinuxMain: SwiftCommand { - static let configuration = CommandConfiguration( - commandName: "generate-linuxmain", - abstract: "Generate LinuxMain.swift (deprecated)" - ) - - @OptionGroup(visibility: .hidden) - var globalOptions: GlobalOptions - - // for deprecated passthrough from SwiftTestTool (parse will fail otherwise) - @Flag(name: .customLong("generate-linuxmain"), help: .hidden) - var _deprecated_passthrough: Bool = false - - func run(_ swiftTool: SwiftTool) throws { - #if os(Linux) - swiftTool.observabilityScope.emit(warning: "can't discover tests on Linux; please use this option on macOS instead") - #endif - let graph = try swiftTool.loadPackageGraph() - let testProducts = try buildTests(swiftTool: swiftTool) - let testSuites = try TestingSupport.getTestSuites( - in: testProducts, - swiftTool: swiftTool, - enableCodeCoverage: false, - sanitizers: globalOptions.build.sanitizers - ) - let allTestSuites = testSuites.values.flatMap { $0 } - let generator = LinuxMainGenerator(graph: graph, testSuites: allTestSuites) - try generator.generate() - } - - private func buildTests(swiftTool: SwiftTool) throws -> [BuiltTestProduct] { - let buildParameters = try swiftTool.buildParametersForTest(enableCodeCoverage: false) - let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters) - - try buildSystem.build(subset: .allIncludingTests) - - guard !buildSystem.builtTestProducts.isEmpty else { - throw TestError.testsExecutableNotFound - } - - return buildSystem.builtTestProducts - } - } -} - /// A structure representing an individual unit test. struct UnitTest { /// The path to the test product containing the test. diff --git a/Sources/Commands/Utilities/GenerateLinuxMain.swift b/Sources/Commands/Utilities/GenerateLinuxMain.swift deleted file mode 100644 index 03a2a41086d..00000000000 --- a/Sources/Commands/Utilities/GenerateLinuxMain.swift +++ /dev/null @@ -1,219 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift open source project -// -// Copyright (c) 2015-2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Basics -import PackageGraph -import PackageModel -import TSCBasic - -/// A utility for generating test entries on linux. -/// -/// This uses input from macOS's test discovery and generates -/// corelibs-xctest compatible test manifests. -/// -/// this functionality is deprecated as of 12/2020 -/// We are keeping it here for transition purposes -/// This class is to be removed in future releases -final class LinuxMainGenerator { - - enum Error: Swift.Error { - case noTestTargets - } - - /// The package graph we're working on. - let graph: PackageGraph - - /// The test suites that we need to write. - let testSuites: [TestSuite] - - init(graph: PackageGraph, testSuites: [TestSuite]) { - self.graph = graph - self.testSuites = testSuites - } - - /// Generate the XCTestManifests.swift and LinuxMain.swift for the package. - func generate() throws { - // Create the module struct from input. - // - // This converts the input test suite into a structure that - // is more suitable for generating linux test entries. - let modulesBuilder = ModulesBuilder() - for suite in testSuites { - modulesBuilder.add(suite.tests) - } - let modules = modulesBuilder.build().sorted(by: { $0.name < $1.name }) - - // Generate manifest file for each test module we got from XCTest discovery. - for module in modules { - guard let target = graph.reachableTargets.first(where: { $0.c99name == module.name }) else { - print("warning: did not find target '\(module.name)'") - continue - } - assert(target.type == .test, "Unexpected target type \(target.type) for \(target)") - - // Write the manifest file for this module. - let testManifest = target.sources.root.appending("XCTestManifests.swift") - let stream = try LocalFileOutputByteStream(testManifest) - - stream <<< "#if !canImport(ObjectiveC)" <<< "\n" - stream <<< "import XCTest" <<< "\n" - for klass in module.classes.lazy.sorted(by: { $0.name < $1.name }) { - stream <<< "\n" - stream <<< "extension " <<< klass.name <<< " {" <<< "\n" - stream <<< indent(4) <<< "// DO NOT MODIFY: This is autogenerated, use:\n" - stream <<< indent(4) <<< "// `swift test --generate-linuxmain`\n" - stream <<< indent(4) <<< "// to regenerate.\n" - stream <<< indent(4) <<< "static let __allTests__\(klass.name) = [" <<< "\n" - for method in klass.methods { - stream <<< indent(8) <<< "(\"\(method)\", \(method))," <<< "\n" - } - stream <<< indent(4) <<< "]" <<< "\n" - stream <<< "}" <<< "\n" - } - - stream <<< - """ - - public func __allTests() -> [XCTestCaseEntry] { - return [ - - """ - - for klass in module.classes { - stream <<< indent(8) <<< "testCase(" <<< klass.name <<< ".__allTests__\(klass.name))," <<< "\n" - } - - stream <<< """ - ] - } - #endif - - """ - stream.flush() - } - - /// Write LinuxMain.swift file. - guard let testTarget = graph.reachableProducts.first(where: { $0.type == .test })?.targets.first else { - throw Error.noTestTargets - } - guard let linuxMainFileName = SwiftTarget.testEntryPointNames.first(where: { $0.lowercased().hasPrefix("linux") }) else { - throw InternalError("Unknown linux main file name") - } - let linuxMain = testTarget.sources.root.parentDirectory.appending(components: linuxMainFileName) - - let stream = try LocalFileOutputByteStream(linuxMain) - stream <<< "import XCTest" <<< "\n\n" - for module in modules { - stream <<< "import " <<< module.name <<< "\n" - } - stream <<< "\n" - stream <<< "var tests = [XCTestCaseEntry]()" <<< "\n" - for module in modules { - stream <<< "tests += \(module.name).__allTests()" <<< "\n" - } - stream <<< "\n" - stream <<< "XCTMain(tests)" <<< "\n" - stream.flush() - } - - private func indent(_ spaces: Int) -> ByteStreamable { - return Format.asRepeating(string: " ", count: spaces) - } -} - -// MARK: - Internal data structure for LinuxMainGenerator. - -private struct Module { - struct Class { - let name: String - let methods: [String] - } - let name: String - let classes: [Class] -} - -private final class ModulesBuilder { - - final class ModuleBuilder { - let name: String - var classes: [ClassBuilder] - - init(_ name: String) { - self.name = name - self.classes = [] - } - - func build() -> Module { - return Module(name: name, classes: classes.map({ $0.build() })) - } - } - - final class ClassBuilder { - let name: String - var methods: [String] - - init(_ name: String) { - self.name = name - self.methods = [] - } - - func build() -> Module.Class { - return .init(name: name, methods: methods) - } - } - - /// The built modules. - private var modules: [ModuleBuilder] = [] - - func add(_ cases: [TestSuite.TestCase]) { - for testCase in cases { - let (module, theKlass) = testCase.name.spm_split(around: ".") - guard let klass = theKlass else { - // Ignore the classes that have zero tests. - if testCase.tests.isEmpty { - continue - } - fatalError("unreachable \(testCase.name)") - } - for method in testCase.tests { - add(module, klass, method) - } - } - } - - private func add(_ moduleName: String, _ klassName: String, _ methodName: String) { - // Find or create the module. - let module: ModuleBuilder - if let theModule = modules.first(where: { $0.name == moduleName }) { - module = theModule - } else { - module = ModuleBuilder(moduleName) - modules.append(module) - } - - // Find or create the class. - let klass: ClassBuilder - if let theKlass = module.classes.first(where: { $0.name == klassName }) { - klass = theKlass - } else { - klass = ClassBuilder(klassName) - module.classes.append(klass) - } - - // Finally, append the method to the class. - klass.methods.append(methodName) - } - - func build() -> [Module] { - return modules.map({ $0.build() }) - } -} diff --git a/Tests/CommandsTests/TestToolTests.swift b/Tests/CommandsTests/TestToolTests.swift index 41e2d0f7fbb..4f3331bb1a9 100644 --- a/Tests/CommandsTests/TestToolTests.swift +++ b/Tests/CommandsTests/TestToolTests.swift @@ -209,63 +209,6 @@ final class TestToolTests: CommandsTestCase { #endif } - func testGenerateLinuxMainDeprecation() throws { - try fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - let (_, stderr) = try SwiftPMProduct.SwiftTest.execute(["--generate-linuxmain"], packagePath: fixturePath) - // test deprecation warning - XCTAssertMatch(stderr, .contains("warning: '--generate-linuxmain' option is deprecated")) - } - } - - func testGenerateLinuxMain() throws { - #if !os(macOS) - try XCTSkipIf(true, "test is only supported on macOS") - #endif - try fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in - _ = try SwiftPMProduct.SwiftTest.execute(["--generate-linuxmain"], packagePath: fixturePath) - - // Check LinuxMain - let linuxMain = fixturePath.appending(components: "Tests", "LinuxMain.swift") - XCTAssertEqual(try localFileSystem.readFileContents(linuxMain), """ - import XCTest - - import SimpleTests - - var tests = [XCTestCaseEntry]() - tests += SimpleTests.__allTests() - - XCTMain(tests) - - """) - - // Check test manifest - let testManifest = fixturePath.appending(components: "Tests", "SimpleTests", "XCTestManifests.swift") - XCTAssertEqual(try localFileSystem.readFileContents(testManifest), """ - #if !canImport(ObjectiveC) - import XCTest - - extension SimpleTests { - // DO NOT MODIFY: This is autogenerated, use: - // `swift test --generate-linuxmain` - // to regenerate. - static let __allTests__SimpleTests = [ - ("test_Example2", test_Example2), - ("testExample1", testExample1), - ("testThrowing", testThrowing), - ] - } - - public func __allTests() -> [XCTestCaseEntry] { - return [ - testCase(SimpleTests.__allTests__SimpleTests), - ] - } - #endif - - """) - } - } - func testList() throws { try fixture(name: "Miscellaneous/TestDiscovery/Simple") { fixturePath in let (stdout, stderr) = try SwiftPMProduct.SwiftTest.execute(["list"], packagePath: fixturePath)