Skip to content

Commit a6d763f

Browse files
PackageToJS: Emit hints for permission denied errors
1 parent fc5d334 commit a6d763f

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

Plugins/PackageToJS/Sources/PackageToJSPlugin.swift

+55-7
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
@@ -29,8 +30,8 @@ struct PackageToJSPlugin: CommandPlugin {
2930
return """
3031
Please pass the `--swift-sdk` option to the "swift package" command.
3132
32-
Did you mean:
33-
\(didYouMean.joined(separator: " "))
33+
Did you mean this?
34+
\(didYouMean.joined(separator: " "))
3435
"""
3536
}),
3637
(
@@ -67,22 +68,69 @@ 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+
if filePath.hasPrefix(packageDir.path) {
99+
// Emit hint for --allow-writing-to-package-directory if the destination path
100+
// is under the package directory
101+
let didYouMean = [
102+
"swift", "package", "--swift-sdk", "wasm32-unknown-wasi",
103+
"plugin", "--allow-writing-to-package-directory",
104+
"js",
105+
] + arguments
106+
emitHintMessage(
107+
"""
108+
Permission denied to write to \(filePath).
109+
Please pass the `--allow-writing-to-package-directory` option to the "swift package" command.
110+
111+
Did you mean this?
112+
\(didYouMean.joined(separator: " "))
113+
"""
114+
)
115+
} else {
116+
// Emit hint for --allow-writing-to-directory <directory>
117+
// if the destination path is outside the package directory
118+
let didYouMean = [
119+
"swift", "package", "--swift-sdk", "wasm32-unknown-wasi",
120+
"plugin", "--allow-writing-to-directory", "\(filePath)",
121+
"js",
122+
] + arguments
123+
emitHintMessage(
124+
"""
125+
Permission denied to write to \(filePath).
126+
Please pass the `--allow-writing-to-directory <directory>` option to the "swift package" command.
127+
128+
Did you mean this?
129+
\(didYouMean.joined(separator: " "))
130+
"""
131+
)
132+
}
133+
}
86134
}
87135

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

0 commit comments

Comments
 (0)