|
7 | 7 |
|
8 | 8 | import Foundation |
9 | 9 |
|
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