-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathCurrentChange.swift
More file actions
74 lines (59 loc) · 2.79 KB
/
CurrentChange.swift
File metadata and controls
74 lines (59 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import Foundation
import LanguageServerProtocol
public struct PRChange: Equatable, Codable {
public let uri: DocumentUri
public let path: String
public let baseContent: String
public let headContent: String
public var originalContent: String { headContent }
}
public enum CurrentChangeService {
public static func getPRChanges(
_ repositoryURL: URL,
group: GitDiffGroup,
shouldIncludeFile: (URL) -> Bool
) async -> [PRChange] {
let gitStats = await GitDiff.getDiffFiles(repositoryURL: repositoryURL, group: group)
var changes: [PRChange] = []
for stat in gitStats {
guard shouldIncludeFile(stat.url) else { continue }
guard let content = try? String(contentsOf: stat.url, encoding: .utf8)
else { continue }
let uri = stat.url.absoluteString
let relativePath = Self.getRelativePath(fileURL: stat.url, repositoryURL: repositoryURL)
switch stat.status {
case .untracked, .indexAdded:
changes.append(.init(uri: uri, path: relativePath, baseContent: "", headContent: content))
case .modified:
guard let originalContent = GitShow.showHeadContent(of: relativePath, repositoryURL: repositoryURL) else {
continue
}
changes.append(.init(uri: uri, path: relativePath, baseContent: originalContent, headContent: content))
case .deleted, .indexRenamed:
continue
}
}
// Include untracked files
if group == .workingTree {
let untrackedGitStats = GitStatus.getStatus(repositoryURL: repositoryURL, untrackedFilesOption: .all)
for stat in untrackedGitStats {
guard !changes.contains(where: { $0.uri == stat.url.absoluteString }),
let content = try? String(contentsOf: stat.url, encoding: .utf8)
else { continue }
let relativePath = Self.getRelativePath(fileURL: stat.url, repositoryURL: repositoryURL)
changes.append(
.init(uri: stat.url.absoluteString, path: relativePath, baseContent: "", headContent: content)
)
}
}
return changes
}
// TODO: Handle cases of multi-project and referenced file
private static func getRelativePath(fileURL: URL, repositoryURL: URL) -> String {
var relativePath = fileURL.path.replacingOccurrences(of: repositoryURL.path, with: "")
if relativePath.starts(with: "/") {
relativePath = String(relativePath.dropFirst())
}
return relativePath
}
}