Skip to content

Commit 2fdf063

Browse files
Get rid of CartonHelpers dependency from carton driver (#502)
1 parent c44dda0 commit 2fdf063

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+399
-470
lines changed

Package.swift

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ let package = Package(
3434
name: "CartonDriver",
3535
dependencies: [
3636
"SwiftToolchain",
37-
"CartonHelpers"
3837
]
3938
),
4039
.executableTarget(
@@ -125,7 +124,7 @@ let package = Package(
125124
.target(
126125
name: "SwiftToolchain",
127126
dependencies: [
128-
"CartonHelpers",
127+
"CartonCore",
129128
],
130129
exclude: ["Utilities/README.md"]
131130
),
@@ -166,8 +165,7 @@ let package = Package(
166165
name: "carton-release",
167166
dependencies: [
168167
.product(name: "ArgumentParser", package: "swift-argument-parser"),
169-
"CartonHelpers",
170-
"WasmTransformer",
168+
"CartonCore",
171169
]
172170
),
173171
.testTarget(

Sources/CartonCore/CartonCoreError.swift

-6
This file was deleted.

Sources/CartonHelpers/FileSystem+traverseRecursively.swift renamed to Sources/CartonCore/FileSystem+traverseRecursively.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ extension String {
1818
public var isAbsolutePath: Bool { first == "/" }
1919
}
2020

21-
extension FileSystem {
22-
public func traverseRecursively(_ traversalRoot: AbsolutePath) throws -> [AbsolutePath] {
21+
extension FileManager {
22+
public func traverseRecursively(_ traversalRoot: URL) throws -> [URL] {
2323
var isDirectory: ObjCBool = false
2424
guard
25-
FileManager.default.fileExists(atPath: traversalRoot.pathString, isDirectory: &isDirectory)
25+
FileManager.default.fileExists(atPath: traversalRoot.path, isDirectory: &isDirectory)
2626
else {
2727
return []
2828
}
@@ -33,18 +33,18 @@ extension FileSystem {
3333
return result
3434
}
3535

36-
let enumerator = FileManager.default.enumerator(atPath: traversalRoot.pathString)
36+
let enumerator = FileManager.default.enumerator(atPath: traversalRoot.path)
3737

3838
while let element = enumerator?.nextObject() as? String {
39-
let path = try traversalRoot.appending(RelativePath(validating: element))
39+
let path = traversalRoot.appendingPathComponent(element)
4040
result.append(path)
4141
}
4242

4343
return result
4444
}
4545

46-
public func resourcesDirectoryNames(relativeTo buildDirectory: AbsolutePath) throws -> [String] {
47-
try FileManager.default.contentsOfDirectory(atPath: buildDirectory.pathString).filter {
46+
public func resourcesDirectoryNames(relativeTo buildDirectory: URL) throws -> [String] {
47+
try FileManager.default.contentsOfDirectory(atPath: buildDirectory.path).filter {
4848
$0.hasSuffix(".resources")
4949
}
5050
}

Sources/CartonCore/FoundationProcessEx.swift

+17
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,21 @@ extension Foundation.Process {
8686
forwardExit: forwardExit
8787
)
8888
}
89+
90+
public static func which(_ executable: String) throws -> URL {
91+
let pathSeparator: Character
92+
#if os(Windows)
93+
pathSeparator = ";"
94+
#else
95+
pathSeparator = ":"
96+
#endif
97+
let paths = ProcessInfo.processInfo.environment["PATH"]!.split(separator: pathSeparator)
98+
for path in paths {
99+
let url = URL(fileURLWithPath: String(path)).appendingPathComponent(executable)
100+
if FileManager.default.isExecutableFile(atPath: url.path) {
101+
return url
102+
}
103+
}
104+
throw CartonCoreError("Executable \(executable) not found in PATH")
105+
}
89106
}
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
4+
Licensed under Apache License v2.0 with Runtime Library Exception
5+
See http://swift.org/LICENSE.txt for license information
6+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
7+
*/
8+
9+
import Foundation
10+
11+
#if os(Android) || canImport(Musl)
12+
public typealias FILEPointer = OpaquePointer
13+
#else
14+
public typealias FILEPointer = UnsafeMutablePointer<FILE>
15+
#endif
16+
17+
/// Implements file output stream for local file system.
18+
public final class _LocalFileOutputByteStream {
19+
20+
/// The pointer to the file.
21+
let filePointer: FILEPointer
22+
23+
public static let stdout = _LocalFileOutputByteStream(filePointer: Foundation.stdout)
24+
public static let stderr = _LocalFileOutputByteStream(filePointer: Foundation.stderr)
25+
26+
/// Instantiate using the file pointer.
27+
public init(filePointer: FILEPointer) {
28+
self.filePointer = filePointer
29+
}
30+
31+
@discardableResult
32+
public func send(_ value: CustomStringConvertible) -> _LocalFileOutputByteStream {
33+
var contents = [UInt8](value.description.utf8)
34+
while true {
35+
let n = fwrite(&contents, 1, contents.count, filePointer)
36+
if n < 0 {
37+
if errno == EINTR { continue }
38+
} else if n != contents.count {
39+
continue
40+
}
41+
break
42+
}
43+
return self
44+
}
45+
46+
public func flush() {
47+
fflush(filePointer)
48+
}
49+
}
50+
51+
/// This class is used to write on the underlying stream.
52+
///
53+
/// If underlying stream is a not tty, the string will be written in without any
54+
/// formatting.
55+
public final class InteractiveWriter {
56+
/// The standard error writer.
57+
public static let stderr = InteractiveWriter(stream: .stderr)
58+
59+
/// The standard output writer.
60+
public static let stdout = InteractiveWriter(stream: .stdout)
61+
62+
/// The terminal controller, if present.
63+
private let term: TerminalController?
64+
65+
/// The output byte stream reference.
66+
private let stream: _LocalFileOutputByteStream
67+
68+
/// Create an instance with the given stream.
69+
public init(stream: _LocalFileOutputByteStream) {
70+
term = TerminalController(stream: stream)
71+
self.stream = stream
72+
}
73+
74+
/// Write the string to the contained terminal or stream.
75+
public func write(
76+
_ string: String,
77+
inColor color: TerminalController.Color = .noColor,
78+
bold: Bool = false
79+
) {
80+
if let term = term {
81+
term.write(string, inColor: color, bold: bold)
82+
} else {
83+
stream.send(string)
84+
stream.flush()
85+
}
86+
}
87+
88+
public func clearLine() {
89+
if let term = term {
90+
term.clearLine()
91+
} else {
92+
stream.send("\n")
93+
stream.flush()
94+
}
95+
}
96+
97+
public func saveCursor() {
98+
term?.write("\u{001B}[s")
99+
}
100+
101+
public func revertCursorAndClear() {
102+
term?.write("\u{001B}[u\u{001B}[2J\u{001B}H")
103+
}
104+
105+
public func logLookup<T>(_ description: String, _ target: T, newline: Bool = false)
106+
where T: CustomStringConvertible {
107+
write(description)
108+
write("\(target)\n", inColor: .cyan, bold: true)
109+
if newline {
110+
write("\n")
111+
}
112+
}
113+
}

Sources/CartonHelpers/DefaultToolchain.swift renamed to Sources/CartonCore/Misc.swift

+9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
public struct CartonCoreError: Error & CustomStringConvertible {
16+
public init(_ description: String) {
17+
self.description = description
18+
}
19+
public var description: String
20+
}
21+
22+
public let cartonVersion = "1.1.2"
23+
1524
#if compiler(>=6.0)
1625
public let defaultToolchainVersion = "wasm-6.0.2-RELEASE"
1726
#elseif compiler(>=5.10)

Sources/CartonHelpers/Basics/TerminalController.swift renamed to Sources/CartonCore/TerminalController.swift

+13-20
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public final class TerminalController {
6262
}
6363

6464
/// Pointer to output stream to operate on.
65-
private var stream: WritableByteStream
65+
private var stream: _LocalFileOutputByteStream
6666

6767
/// Width of the terminal.
6868
public var width: Int {
@@ -84,13 +84,9 @@ public final class TerminalController {
8484
private let boldString = "\u{001B}[1m"
8585

8686
/// Constructs the instance if the stream is a tty.
87-
public init?(stream: WritableByteStream) {
88-
let realStream = (stream as? ThreadSafeOutputByteStream)?.stream ?? stream
89-
87+
public init?(stream: _LocalFileOutputByteStream) {
9088
// Make sure it is a file stream and it is tty.
91-
guard let fileStream = realStream as? LocalFileOutputByteStream,
92-
TerminalController.isTTY(fileStream)
93-
else {
89+
guard TerminalController.isTTY(stream) else {
9490
return nil
9591
}
9692

@@ -109,14 +105,14 @@ public final class TerminalController {
109105
}
110106

111107
/// Checks if passed file stream is tty.
112-
public static func isTTY(_ stream: LocalFileOutputByteStream) -> Bool {
108+
public static func isTTY(_ stream: _LocalFileOutputByteStream) -> Bool {
113109
return terminalType(stream) == .tty
114110
}
115111

116112
/// Computes the terminal type of the stream.
117-
public static func terminalType(_ stream: LocalFileOutputByteStream) -> TerminalType {
113+
public static func terminalType(_ stream: _LocalFileOutputByteStream) -> TerminalType {
118114
#if !os(Windows)
119-
if ProcessEnv.block["TERM"] == "dumb" {
115+
if ProcessInfo.processInfo.environment["TERM"] == "dumb" {
120116
return .dumb
121117
}
122118
#endif
@@ -138,7 +134,7 @@ public final class TerminalController {
138134
return Int(csbi.srWindow.Right - csbi.srWindow.Left) + 1
139135
#else
140136
// Try to get from environment.
141-
if let columns = ProcessEnv.block["COLUMNS"], let width = Int(columns) {
137+
if let columns = ProcessInfo.processInfo.environment["COLUMNS"], let width = Int(columns) {
142138
return width
143139
}
144140

@@ -181,7 +177,7 @@ public final class TerminalController {
181177

182178
/// Writes a string to the stream.
183179
public func write(_ string: String, inColor color: Color = .noColor, bold: Bool = false) {
184-
writeWrapped(string, inColor: color, bold: bold, stream: stream)
180+
stream.send(writeWrapped(string, inColor: color, bold: bold))
185181
flush()
186182
}
187183

@@ -193,19 +189,16 @@ public final class TerminalController {
193189

194190
/// Wraps the string into the color mentioned.
195191
public func wrap(_ string: String, inColor color: Color, bold: Bool = false) -> String {
196-
let stream = BufferedOutputByteStream()
197-
writeWrapped(string, inColor: color, bold: bold, stream: stream)
198-
return stream.bytes.description
192+
return writeWrapped(string, inColor: color, bold: bold)
199193
}
200194

201195
private func writeWrapped(
202-
_ string: String, inColor color: Color, bold: Bool = false, stream: WritableByteStream
203-
) {
196+
_ string: String, inColor color: Color, bold: Bool = false
197+
) -> String {
204198
// Don't wrap if string is empty or color is no color.
205199
guard !string.isEmpty && color != .noColor else {
206-
stream.send(string)
207-
return
200+
return string
208201
}
209-
stream.send(color.string).send(bold ? boldString : "").send(string).send(resetString)
202+
return color.string + (bold ? boldString : "") + string + resetString
210203
}
211204
}

Sources/CartonDriver/CartonDriverCommand.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
// This executable should be eventually removed once SwiftPM provides a way to express those requirements.
3232

3333
import CartonCore
34-
import CartonHelpers
3534
import Foundation
3635
import SwiftToolchain
3736

@@ -134,31 +133,32 @@ func pluginSubcommand(subcommand: String, argv0: String, arguments: [String]) as
134133
}
135134

136135
let terminal = InteractiveWriter.stdout
137-
let toolchainSystem = try ToolchainSystem(fileSystem: localFileSystem)
136+
let toolchainSystem = try ToolchainSystem(fileSystem: .default)
138137
let swiftPath = try await toolchainSystem.inferSwiftPath(terminal)
139138
let extraArguments = arguments
140139

141-
let swiftExec = URL(fileURLWithPath: swiftPath.swift.pathString)
142140
let pluginArguments = try derivePackageCommandArguments(
143-
swiftExec: swiftExec,
141+
swiftExec: swiftPath.swift,
144142
subcommand: subcommand,
145143
scratchPath: scratchPath.path,
146144
extraArguments: extraArguments
147145
)
148146

149147
var env: [String: String] = ProcessInfo.processInfo.environment
150148
if ToolchainSystem.isSnapshotVersion(swiftPath.version),
151-
swiftPath.toolchain.extension == "xctoolchain"
149+
swiftPath.toolchain.pathExtension == "xctoolchain"
152150
{
153-
env["DYLD_LIBRARY_PATH"] = swiftPath.toolchain.appending(
154-
components: ["usr", "lib", "swift", "macosx"]
155-
).pathString
151+
env["DYLD_LIBRARY_PATH"] = swiftPath.toolchain
152+
.appendingPathComponent("usr")
153+
.appendingPathComponent("lib")
154+
.appendingPathComponent("swift")
155+
.appendingPathComponent("macosx")
156+
.path
156157
}
157158

158159
try Foundation.Process.checkRun(
159-
swiftExec,
160+
swiftPath.swift,
160161
arguments: pluginArguments,
161-
environment: env,
162162
forwardExit: true
163163
)
164164
}
@@ -185,11 +185,11 @@ public func main(arguments: [String]) async throws {
185185
subcommand: subcommand, argv0: argv0, arguments: Array(arguments.dropFirst()))
186186
case "package":
187187
let terminal = InteractiveWriter.stdout
188-
let toolchainSystem = try ToolchainSystem(fileSystem: localFileSystem)
188+
let toolchainSystem = try ToolchainSystem(fileSystem: .default)
189189
let swiftPath = try await toolchainSystem.inferSwiftPath(terminal)
190190

191191
try Foundation.Process.checkRun(
192-
URL(fileURLWithPath: swiftPath.swift.pathString),
192+
swiftPath.swift,
193193
arguments: ["package"] + arguments.dropFirst(),
194194
forwardExit: true
195195
)

Sources/CartonFrontend/CartonFrontendCommand.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// limitations under the License.
1414

1515
import ArgumentParser
16-
import CartonHelpers
16+
import CartonCore
1717

1818
public struct CartonFrontendCommand: AsyncParsableCommand {
1919
public static let configuration = CommandConfiguration(

Sources/CartonFrontend/Commands/CartonFrontendDevCommand.swift

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import ArgumentParser
1616
import CartonHelpers
17+
import CartonCore
1718
import CartonKit
1819
import Foundation
1920

Sources/CartonFrontend/Commands/TestRunners/BrowserTestRunner.swift

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
import CartonHelpers
16+
import CartonCore
1617
import CartonKit
1718
import Foundation
1819
import NIOCore

0 commit comments

Comments
 (0)