Skip to content

improve example created by package init --type executable #4122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions IntegrationTests/Package.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// swift-tools-version:5.1
// swift-tools-version:5.4

import PackageDescription

let package = Package(
name: "IntegrationTests",
targets: [
.testTarget(name: "IntegrationTests", dependencies: [
"SwiftToolsSupport-auto",
"TSCTestSupport"
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
.product(name: "TSCTestSupport", package: "swift-tools-support-core")
]),
]
)
Expand All @@ -20,6 +20,6 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
]
} else {
package.dependencies += [
.package(path: "../TSC"),
.package(name: "swift-tools-support-core", path: "../TSC"),
]
}
252 changes: 156 additions & 96 deletions IntegrationTests/Tests/IntegrationTests/BasicTests.swift

Large diffs are not rendered by default.

14 changes: 3 additions & 11 deletions IntegrationTests/Tests/IntegrationTests/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ func initGitRepo(
}

func binaryTargetsFixture(_ closure: (AbsolutePath) throws -> Void) throws {
fixture(name: "BinaryTargets") { prefix in
let inputsPath = prefix.appending(component: "Inputs")
let packagePath = prefix.appending(component: "TestBinary")
fixture(name: "BinaryTargets") { fixturePath in
let inputsPath = fixturePath.appending(component: "Inputs")
let packagePath = fixturePath.appending(component: "TestBinary")

// Generating StaticLibrary.xcframework.
try withTemporaryDirectory { tmpDir in
Expand Down Expand Up @@ -343,11 +343,3 @@ extension ProcessResult {
"""
}
}

func swiftcSupportsRenamingMainSymbol() throws -> Bool {
try withTemporaryDirectory { tmpDir in
FileManager.default.createFile(atPath: "\(tmpDir)/foo.swift", contents: Data())
let result = try Process.popen(args: swiftc.pathString, "-c", "-Xfrontend", "-entry-point-function-name", "-Xfrontend", "foo", "\(tmpDir)/foo.swift", "-o", "\(tmpDir)/foo.o")
return try !result.utf8stderrOutput().contains("unknown argument: '-entry-point-function-name'")
}
}
58 changes: 30 additions & 28 deletions IntegrationTests/Tests/IntegrationTests/SwiftPMTests.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
This source file is part of the Swift.org open source project
This source file is part of the Swift.org open source project

Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
Copyright (c) 2014 - 2020 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 Swift project authors
*/
See http://swift.org/LICENSE.txt for license information
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import XCTest
import TSCBasic
Expand All @@ -16,13 +16,13 @@ final class SwiftPMTests: XCTestCase {
func testBinaryTargets() throws {
try XCTSkip("FIXME: ld: warning: dylib (/../BinaryTargets.6YVYK4/TestBinary/.build/x86_64-apple-macosx/debug/SwiftFramework.framework/SwiftFramework) was built for newer macOS version (10.15) than being linked (10.10)")

#if !os(macOS)
try XCTSkip("Test requires macOS")
#endif
#if !os(macOS)
try XCTSkip("Test requires macOS")
#endif

try binaryTargetsFixture { prefix in
try binaryTargetsFixture { fixturePath in
do {
let (stdout, stderr) = try sh(swiftRun, "--package-path", prefix, "exe")
let (stdout, stderr) = try sh(swiftRun, "--package-path", fixturePath, "exe")
XCTAssertNoMatch(stderr, .contains("warning: "))
XCTAssertEqual(stdout, """
SwiftFramework()
Expand All @@ -32,52 +32,54 @@ final class SwiftPMTests: XCTestCase {
}

do {
let (stdout, stderr) = try sh(swiftRun, "--package-path", prefix, "cexe")
let (stdout, stderr) = try sh(swiftRun, "--package-path", fixturePath, "cexe")
XCTAssertNoMatch(stderr, .contains("warning: "))
XCTAssertMatch(stdout, .contains("<CLibrary: "))
}

do {
let invalidPath = prefix.appending(component: "SwiftFramework.xcframework")
let (_, stderr) = try shFails(swiftPackage, "--package-path", prefix, "compute-checksum", invalidPath)
let invalidPath = fixturePath.appending(component: "SwiftFramework.xcframework")
let (_, stderr) = try shFails(swiftPackage, "--package-path", fixturePath, "compute-checksum", invalidPath)
XCTAssertMatch(stderr, .contains("error: unexpected file type; supported extensions are: zip"))

let validPath = prefix.appending(component: "SwiftFramework.zip")
let (stdout, _) = try sh(swiftPackage, "--package-path", prefix, "compute-checksum", validPath)
let validPath = fixturePath.appending(component: "SwiftFramework.zip")
let (stdout, _) = try sh(swiftPackage, "--package-path", fixturePath, "compute-checksum", validPath)
XCTAssertEqual(stdout.spm_chomp(), "d1f202b1bfe04dea30b2bc4038f8059dcd75a5a176f1d81fcaedb6d3597d1158")
}
}
}

func testArchCustomization() throws {
#if !os(macOS)
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

try withTemporaryDirectory { tmpDir in
let foo = tmpDir.appending(component: "foo")
try localFileSystem.createDirectory(foo)
try sh(swiftPackage, "--package-path", foo, "init", "--type", "executable")

try localFileSystem.removeFileTree(foo.appending(RelativePath("Sources/foo/main.swift")))
try localFileSystem.writeFileContents(foo.appending(RelativePath("Sources/foo/main.m"))) {
let packagePath = tmpDir.appending(component: "foo")
try localFileSystem.createDirectory(packagePath)
try sh(swiftPackage, "--package-path", packagePath, "init", "--type", "executable")
// delete any files generated
for entry in try localFileSystem.getDirectoryContents(packagePath.appending(components: "Sources", "foo")) {
try localFileSystem.removeFileTree(packagePath.appending(components: "Sources", "foo", entry))
}
try localFileSystem.writeFileContents(packagePath.appending(RelativePath("Sources/foo/main.m"))) {
$0 <<< "int main() {}"
}
let archs = ["x86_64", "arm64"]

for arch in archs {
try sh(swiftBuild, "--package-path", foo, "--arch", arch)
let fooPath = foo.appending(RelativePath(".build/\(arch)-apple-macosx/debug/foo"))
try sh(swiftBuild, "--package-path", packagePath, "--arch", arch)
let fooPath = packagePath.appending(RelativePath(".build/\(arch)-apple-macosx/debug/foo"))
XCTAssertFileExists(fooPath)
}

let args = [swiftBuild.pathString, "--package-path", foo.pathString] + archs.flatMap{ ["--arch", $0] }
let args = [swiftBuild.pathString, "--package-path", packagePath.pathString] + archs.flatMap{ ["--arch", $0] }
try _sh(args)

let fooPath = foo.appending(RelativePath(".build/apple/Products/Debug/foo"))
let fooPath = packagePath.appending(RelativePath(".build/apple/Products/Debug/foo"))
XCTAssertFileExists(fooPath)

let objectsDir = foo.appending(RelativePath(".build/apple/Intermediates.noindex/foo.build/Debug/foo.build/Objects-normal"))
let objectsDir = packagePath.appending(RelativePath(".build/apple/Intermediates.noindex/foo.build/Debug/foo.build/Objects-normal"))
for arch in archs {
XCTAssertDirectoryExists(objectsDir.appending(component: arch))
}
Expand Down
12 changes: 6 additions & 6 deletions IntegrationTests/Tests/IntegrationTests/XCBuildTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

See http://swift.org/LICENSE.txt for license information
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
*/

import XCTest
import TSCBasic
Expand All @@ -15,7 +15,7 @@ import TSCTestSupport
final class XCBuildTests: XCTestCase {
func testExecutableProducts() throws {
#if !os(macOS)
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

fixture(name: "XCBuild/ExecutableProducts") { path in
Expand Down Expand Up @@ -118,7 +118,7 @@ final class XCBuildTests: XCTestCase {
try XCTSkip("FIXME: /.../XCBuild_TestProducts.551ajO/Foo/.build/apple/Intermediates.noindex/GeneratedModuleMaps/macosx/FooLib.modulemap:2:12: error: header 'FooLib-Swift.h' not found")

#if !os(macOS)
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

fixture(name: "XCBuild/TestProducts") { path in
Expand Down Expand Up @@ -200,7 +200,7 @@ final class XCBuildTests: XCTestCase {

func testLibraryProductsAndTargets() throws {
#if !os(macOS)
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

fixture(name: "XCBuild/Libraries") { path in
Expand Down Expand Up @@ -276,7 +276,7 @@ final class XCBuildTests: XCTestCase {
try XCTSkip("FIXME: ld: warning: ignoring file /../XCBuild_SystemTargets.b38QoO/Inputs/libsys.a, building for macOS-arm64 but attempting to link with file built for unknown-x86_64\n\nUndefined symbols for architecture arm64:\n \"_GetSystemLibName\", referenced from:\n _main in main.o\n\nld: symbol(s) not found for architecture arm64\n\nclang: error: linker command failed with exit code 1 (use -v to see invocation)\n\nBuild cancelled\n")

#if !os(macOS)
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

fixture(name: "XCBuild/SystemTargets") { path in
Expand Down Expand Up @@ -312,7 +312,7 @@ final class XCBuildTests: XCTestCase {
try XCTSkip("FIXME: swift-test invocations are timing out in Xcode and self-hosted CI")

#if !os(macOS) || Xcode
try XCTSkip("Test requires macOS")
try XCTSkip("Test requires macOS")
#endif

fixture(name: "XCBuild/TestProducts") { path in
Expand Down
51 changes: 11 additions & 40 deletions Sources/Workspace/InitPackage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public final class InitPackage {
let moduleDir = sources.appending(component: "\(pkgname)")
try makeDirectories(moduleDir)

let sourceFileName = (packageType == .executable) ? "main.swift" : "\(typeName).swift"
let sourceFileName = "\(typeName).swift"
let sourceFile = moduleDir.appending(RelativePath(sourceFileName))

let content: String
Expand All @@ -303,7 +303,14 @@ public final class InitPackage {
"""
case .executable:
content = """
print("Hello, world!")
@main
public struct \(typeName) {
public private(set) var text = "Hello, World!"

public static func main() {
print(\(typeName)().text)
}
}

"""
case .systemModule, .empty, .manifest, .`extension`:
Expand Down Expand Up @@ -377,50 +384,14 @@ public final class InitPackage {
try writePackageFile(path) { stream in
stream <<< """
import XCTest
import class Foundation.Bundle
@testable import \(moduleName)

final class \(moduleName)Tests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.

// Some of the APIs that we use below are available in macOS 10.13 and above.
guard #available(macOS 10.13, *) else {
return
}

// Mac Catalyst won't have `Process`, but it is supported for executables.
#if !targetEnvironment(macCatalyst)

let fooBinary = productsDirectory.appendingPathComponent("\(pkgname)")

let process = Process()
process.executableURL = fooBinary

let pipe = Pipe()
process.standardOutput = pipe

try process.run()
process.waitUntilExit()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)

XCTAssertEqual(output, "Hello, world!\\n")
#endif
}

/// Returns path to the built products directory.
var productsDirectory: URL {
#if os(macOS)
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
return bundle.bundleURL.deletingLastPathComponent()
}
fatalError("couldn't find the products directory")
#else
return Bundle.main.bundleURL
#endif
XCTAssertEqual(\(typeName)().text, "Hello, World!")
}
}

Expand Down
4 changes: 2 additions & 2 deletions Tests/CommandsTests/PackageToolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ final class PackageToolTests: CommandsTestCase {
XCTAssertMatch(contents, .prefix("// swift-tools-version:\(version < .v5_4 ? "" : " ")\(versionSpecifier)\n"))

XCTAssertFileExists(manifest)
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "Foo")), ["main.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "Foo")), ["Foo.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Tests")).sorted(), ["FooTests"])
}
}
Expand Down Expand Up @@ -705,7 +705,7 @@ final class PackageToolTests: CommandsTestCase {
XCTAssertMatch(contents, .prefix("// swift-tools-version:\(version < .v5_4 ? "" : " ")\(versionSpecifier)\n"))

XCTAssertFileExists(manifest)
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "CustomName")), ["main.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "CustomName")), ["CustomName.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Tests")).sorted(), ["CustomNameTests"])
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/WorkspaceTests/InitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class InitTests: XCTestCase {
let readmeContents: String = try localFileSystem.readFileContents(readme)
XCTAssertMatch(readmeContents, .prefix("# Foo\n"))

XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "Foo")), ["main.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Sources").appending(component: "Foo")), ["Foo.swift"])
XCTAssertEqual(try fs.getDirectoryContents(path.appending(component: "Tests")).sorted(), ["FooTests"])

// If we have a compiler that supports `-entry-point-function-name`, we try building it (we need that flag now).
Expand Down