Skip to content

Commit 56392da

Browse files
committed
Cargo Package Manager
1 parent a8d1ce6 commit 56392da

File tree

1 file changed

+82
-75
lines changed

1 file changed

+82
-75
lines changed

CodeEdit/Features/LSP/Registry/PackageManagers/Sources/CargoPackageManager.swift

Lines changed: 82 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,78 +7,85 @@
77

88
import Foundation
99

10-
// final class CargoPackageManager: PackageManagerProtocol {
11-
// private let installationDirectory: URL
12-
//
13-
// let shellClient: ShellClient
14-
//
15-
// init(installationDirectory: URL) {
16-
// self.installationDirectory = installationDirectory
17-
// self.shellClient = .live()
18-
// }
19-
//
20-
// func initialize(in packagePath: URL) async throws {
21-
// do {
22-
// try createDirectoryStructure(for: packagePath)
23-
// } catch {
24-
// throw PackageManagerError.initializationFailed(error.localizedDescription)
25-
// }
26-
//
27-
// guard await isInstalled() else {
28-
// throw PackageManagerError.packageManagerNotInstalled
29-
// }
30-
// }
31-
//
32-
// func install(method: InstallationMethod) async throws {
33-
// guard case .standardPackage(let source) = method else {
34-
// throw PackageManagerError.invalidConfiguration
35-
// }
36-
//
37-
// let packagePath = installationDirectory.appending(path: source.entryName)
38-
// try await initialize(in: packagePath)
39-
//
40-
// do {
41-
// var cargoArgs = ["cargo", "install", "--root", "."]
42-
//
43-
// // If this is a git-based package
44-
// if let gitRef = source.gitReference, let repoUrl = source.repositoryUrl {
45-
// cargoArgs.append(contentsOf: ["--git", repoUrl])
46-
// switch gitRef {
47-
// case .tag(let tag):
48-
// cargoArgs.append(contentsOf: ["--tag", tag])
49-
// case .revision(let rev):
50-
// cargoArgs.append(contentsOf: ["--rev", rev])
51-
// }
52-
// } else {
53-
// cargoArgs.append("\(source.pkgName)@\(source.version)")
54-
// }
55-
//
56-
// if let features = source.options["features"] {
57-
// cargoArgs.append(contentsOf: ["--features", features])
58-
// }
59-
// if source.options["locked"] == "true" {
60-
// cargoArgs.append("--locked")
61-
// }
62-
//
63-
// _ = try await executeInDirectory(in: packagePath.path, cargoArgs)
64-
// } catch {
65-
// throw error
66-
// }
67-
// }
68-
//
69-
// func getBinaryPath(for package: String) -> String {
70-
// return installationDirectory.appending(path: package).appending(path: "bin").path
71-
// }
72-
//
73-
// func isInstalled() async -> Bool {
74-
// do {
75-
// let versionOutput = try await runCommand("cargo --version")
76-
// let output = versionOutput.reduce(into: "") {
77-
// $0 += $1.trimmingCharacters(in: .whitespacesAndNewlines)
78-
// }
79-
// return output.starts(with: "cargo")
80-
// } catch {
81-
// return false
82-
// }
83-
// }
84-
// }
10+
final class CargoPackageManager: PackageManagerProtocol {
11+
private let installationDirectory: URL
12+
13+
let shellClient: ShellClient
14+
15+
init(installationDirectory: URL) {
16+
self.installationDirectory = installationDirectory
17+
self.shellClient = .live()
18+
}
19+
20+
func install(method installationMethod: InstallationMethod) throws -> [PackageManagerInstallStep] {
21+
guard case .standardPackage(let source) = installationMethod else {
22+
throw PackageManagerError.invalidConfiguration
23+
}
24+
let packagePath = installationDirectory.appending(path: source.entryName)
25+
return [
26+
initialize(in: packagePath),
27+
runCargoInstall(source, in: packagePath)
28+
]
29+
}
30+
31+
func isInstalled(method installationMethod: InstallationMethod) -> PackageManagerInstallStep {
32+
PackageManagerInstallStep(
33+
name: "",
34+
confirmation: .none
35+
) { model in
36+
let versionOutput = try await model.runCommand("cargo --version")
37+
let output = versionOutput.reduce(into: "") {
38+
$0 += $1.trimmingCharacters(in: .whitespacesAndNewlines)
39+
}
40+
guard output.starts(with: "cargo") else {
41+
throw PackageManagerError.packageManagerNotInstalled
42+
}
43+
}
44+
}
45+
46+
func getBinaryPath(for package: String) -> String {
47+
return installationDirectory.appending(path: package).appending(path: "bin").path
48+
}
49+
50+
func initialize(in packagePath: URL) -> PackageManagerInstallStep {
51+
PackageManagerInstallStep(name: "Initialize Directory Structure", confirmation: .none) { model in
52+
try await model.createDirectoryStructure(for: packagePath)
53+
}
54+
}
55+
56+
func runCargoInstall(_ source: PackageSource, in packagePath: URL) -> PackageManagerInstallStep {
57+
let qualifiedPackageName = "\(source.pkgName)@\(source.version)"
58+
59+
return PackageManagerInstallStep(
60+
name: "Install Package Using cargo",
61+
confirmation: .required(
62+
message: "This requires the cargo package \(qualifiedPackageName)."
63+
+ "\nAllow CodeEdit to install this package?"
64+
)
65+
) { model in
66+
var cargoArgs = ["cargo", "install", "--root", "."]
67+
68+
// If this is a git-based package
69+
if let gitRef = source.gitReference, let repoUrl = source.repositoryUrl {
70+
cargoArgs.append(contentsOf: ["--git", repoUrl])
71+
switch gitRef {
72+
case .tag(let tag):
73+
cargoArgs.append(contentsOf: ["--tag", tag])
74+
case .revision(let rev):
75+
cargoArgs.append(contentsOf: ["--rev", rev])
76+
}
77+
} else {
78+
cargoArgs.append(qualifiedPackageName)
79+
}
80+
81+
if let features = source.options["features"] {
82+
cargoArgs.append(contentsOf: ["--features", features])
83+
}
84+
if source.options["locked"] == "true" {
85+
cargoArgs.append("--locked")
86+
}
87+
88+
try await model.executeInDirectory(in: packagePath.path(percentEncoded: false), cargoArgs)
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)