Skip to content

Commit a37dfa9

Browse files
Merge pull request #305 from swiftwasm/yt/add-more-didyoumean
PackageToJS: Emit hints for permission denied errors
2 parents fc5d334 + f12b41a commit a37dfa9

File tree

1 file changed

+57
-8
lines changed

1 file changed

+57
-8
lines changed

Plugins/PackageToJS/Sources/PackageToJSPlugin.swift

+57-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
@preconcurrency import class Foundation.Process
66
@preconcurrency import class Foundation.ProcessInfo
77
@preconcurrency import class Foundation.FileManager
8+
@preconcurrency import struct Foundation.CocoaError
89
@preconcurrency import func Foundation.fputs
910
@preconcurrency import func Foundation.exit
1011
@preconcurrency import var Foundation.stderr
@@ -27,10 +28,10 @@ struct PackageToJSPlugin: CommandPlugin {
2728
"swift", "package", "--swift-sdk", "wasm32-unknown-wasi", "js",
2829
] + arguments
2930
return """
30-
Please pass the `--swift-sdk` option to the "swift package" command.
31+
Please pass `--swift-sdk` to "swift package".
3132
32-
Did you mean:
33-
\(didYouMean.joined(separator: " "))
33+
Did you mean this?
34+
\(didYouMean.joined(separator: " "))
3435
"""
3536
}),
3637
(
@@ -67,22 +68,70 @@ struct PackageToJSPlugin: CommandPlugin {
6768
"""
6869
}),
6970
]
71+
72+
private func emitHintMessage(_ message: String) {
73+
printStderr("\n" + "\u{001B}[1m\u{001B}[97mHint:\u{001B}[0m " + message)
74+
}
75+
7076
private func reportBuildFailure(
7177
_ build: PackageManager.BuildResult, _ arguments: [String]
7278
) {
7379
for diagnostic in Self.friendlyBuildDiagnostics {
7480
if let message = diagnostic(build, arguments) {
75-
printStderr("\n" + "\u{001B}[1m\u{001B}[97mHint:\u{001B}[0m " + message)
81+
emitHintMessage(message)
82+
return
7683
}
7784
}
7885
}
7986

8087
func performCommand(context: PluginContext, arguments: [String]) throws {
81-
if arguments.first == "test" {
82-
return try performTestCommand(context: context, arguments: Array(arguments.dropFirst()))
83-
}
88+
do {
89+
if arguments.first == "test" {
90+
return try performTestCommand(context: context, arguments: Array(arguments.dropFirst()))
91+
}
92+
93+
return try performBuildCommand(context: context, arguments: arguments)
94+
} catch let error as CocoaError where error.code == .fileWriteNoPermission {
95+
guard let filePath = error.filePath else { throw error }
8496

85-
return try performBuildCommand(context: context, arguments: arguments)
97+
let packageDir = context.package.directoryURL
98+
printStderr("\n\u{001B}[1m\u{001B}[91merror:\u{001B}[0m \(error.localizedDescription)")
99+
100+
if filePath.hasPrefix(packageDir.path) {
101+
// Emit hint for --allow-writing-to-package-directory if the destination path
102+
// is under the package directory
103+
let didYouMean = [
104+
"swift", "package", "--swift-sdk", "wasm32-unknown-wasi",
105+
"plugin", "--allow-writing-to-package-directory",
106+
"js",
107+
] + arguments
108+
emitHintMessage(
109+
"""
110+
Please pass `--allow-writing-to-package-directory` to "swift package".
111+
112+
Did you mean this?
113+
\(didYouMean.joined(separator: " "))
114+
"""
115+
)
116+
} else {
117+
// Emit hint for --allow-writing-to-directory <directory>
118+
// if the destination path is outside the package directory
119+
let didYouMean = [
120+
"swift", "package", "--swift-sdk", "wasm32-unknown-wasi",
121+
"plugin", "--allow-writing-to-directory", "\(filePath)",
122+
"js",
123+
] + arguments
124+
emitHintMessage(
125+
"""
126+
Please pass `--allow-writing-to-directory <directory>` to "swift package".
127+
128+
Did you mean this?
129+
\(didYouMean.joined(separator: " "))
130+
"""
131+
)
132+
}
133+
exit(1)
134+
}
86135
}
87136

88137
static let JAVASCRIPTKIT_PACKAGE_ID: Package.ID = "javascriptkit"

0 commit comments

Comments
 (0)