Repository navigation
Expand file tree
/
Copy pathSnapshotIdentity.cs
More file actions
81 lines (73 loc) · 3.1 KB
/
Copy pathSnapshotIdentity.cs
File metadata and controls
81 lines (73 loc) · 3.1 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
75
76
77
78
79
80
81
using CodeMesh.Domain.Contracts;
using CodeMesh.Domain.Graph;
using CodeMesh.Domain.Utilities;
namespace CodeMesh.Ingestion;
internal sealed record ComputedSnapshotIdentity(
string SnapshotId,
string SourceViewHash,
string ScopeFingerprint,
string ParserProfileFingerprint,
string GraphSchemaVersion);
internal static class SnapshotIdentity
{
public const string IdentityFormatVersion = "snapshot-identity-v1";
public const string GraphSchemaVersion = "codemesh-graph-v1";
public const string RedactionProfileVersion = "content-redaction-v1";
public static ComputedSnapshotIdentity Compute(
string projectId,
IngestionRequest request,
ParseResult parseResult,
IReadOnlyList<CodeNode> nodes,
IReadOnlyList<CodeRelationship> relationships,
IReadOnlyList<CodeContent> contents)
{
var sourceViewHash = CodeMeshHash.Sha256Hex(string.Join(
'\n',
nodes.Select(node => $"N\u001f{node.StableKey}\u001f{node.Span.FilePath}\u001f{node.ContentHash}\u001f{CodeMeshFingerprint.ForNode(node)}")
.Concat(relationships.Select(relationship => $"R\u001f{relationship.Id}\u001f{CodeMeshFingerprint.ForRelationship(relationship)}"))
.Concat(contents.Select(content => $"C\u001f{content.Hash}"))
.OrderBy(value => value, StringComparer.Ordinal)));
var scopeFingerprint = CodeMeshHash.StableId(
request.Language,
NormalizeScopePath(request.RepositoryRoot, request.SolutionPath),
NormalizeScopePath(request.RepositoryRoot, request.ProjectPath),
StableOptions(request.Options),
RepositoryPathPolicy.StableFingerprint(request.PathFilter));
var parserProfileFingerprint = CodeMeshHash.StableId(
parseResult.ParserName,
parseResult.Language,
RedactionProfileVersion,
RepositoryPathPolicy.Version);
var snapshotId = $"snp_{CodeMeshHash.StableId(
IdentityFormatVersion,
projectId,
sourceViewHash,
scopeFingerprint,
parserProfileFingerprint,
GraphSchemaVersion)}";
return new ComputedSnapshotIdentity(
snapshotId,
sourceViewHash,
scopeFingerprint,
parserProfileFingerprint,
GraphSchemaVersion);
}
private static string NormalizeScopePath(string repositoryRoot, string? path)
{
if (string.IsNullOrWhiteSpace(path))
{
return string.Empty;
}
var fullRoot = Path.GetFullPath(repositoryRoot);
var fullPath = Path.IsPathRooted(path)
? Path.GetFullPath(path)
: Path.GetFullPath(path, fullRoot);
return Path.GetRelativePath(fullRoot, fullPath).Replace('\\', '/');
}
private static string StableOptions(IReadOnlyDictionary<string, string>? options)
{
return options is null
? string.Empty
: string.Join('\u001e', options.OrderBy(item => item.Key, StringComparer.Ordinal).Select(item => $"{item.Key}\u001d{item.Value}"));
}
}