feat: Add fully commit operation support
This commit is contained in:
parent
db0c95b3e8
commit
4a7c92a979
@ -6,4 +6,8 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Flawless.Core\Flawless.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
using Flawless.Core.Modal;
|
||||
|
||||
namespace Flawless.Communication.Request;
|
||||
|
||||
public class CommitRequest
|
||||
{
|
||||
|
||||
public required string Message { get; set; }
|
||||
|
||||
public required string[] WorkspaceSnapshot { get; set; }
|
||||
public required WorkspaceFile[] WorkspaceSnapshot { get; set; }
|
||||
|
||||
public string[]? RequiredDepots { get; set; }
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ public static class DataTransformer
|
||||
{
|
||||
depotStream.Seek(8, SeekOrigin.Current);
|
||||
var val = depotStream.ReadByte();
|
||||
depotStream.Seek(-9, SeekOrigin.Current);
|
||||
|
||||
if (val < 0) ;
|
||||
|
||||
@ -74,7 +73,7 @@ public static class DataTransformer
|
||||
return depotStream.ReadSlice((long) size);
|
||||
}
|
||||
|
||||
public static async IAsyncEnumerable<DepotFileInfo> ExtractDepotFileInfoMapAsync(ulong fileMapSize, Stream depotStream)
|
||||
public static async IAsyncEnumerable<DepotFileInfo> ExtractDepotFileInfoMapAsync(Stream depotStream, ulong fileMapSize)
|
||||
{
|
||||
var splitor = '$';
|
||||
depotStream.Seek((long) fileMapSize, SeekOrigin.End);
|
||||
@ -87,6 +86,7 @@ public static class DataTransformer
|
||||
var path = string.Empty;
|
||||
var size = 0UL;
|
||||
var offset = 0UL;
|
||||
DateTime modifyTime = default;
|
||||
|
||||
// Read loop
|
||||
while (true)
|
||||
@ -101,11 +101,12 @@ public static class DataTransformer
|
||||
if (c != splitor) builder.Append(c);
|
||||
else
|
||||
{
|
||||
switch ((state = (state + 1) % 3))
|
||||
switch ((state = (state + 1) % 4))
|
||||
{
|
||||
case 0: path = builder.ToString(); break;
|
||||
case 1: size = ulong.Parse(builder.ToString()); break;
|
||||
case 2: offset = ulong.Parse(builder.ToString()); break;
|
||||
case 2: modifyTime = DateTime.FromBinary(long.Parse(builder.ToString())); break;
|
||||
case 3: offset = ulong.Parse(builder.ToString()); break;
|
||||
}
|
||||
|
||||
builder.Clear();
|
||||
@ -119,7 +120,7 @@ public static class DataTransformer
|
||||
|
||||
|
||||
// Do output at here.
|
||||
yield return new DepotFileInfo(offset, size, path);
|
||||
yield return new DepotFileInfo(offset, size, modifyTime, path);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
namespace Flawless.Core.Modal;
|
||||
|
||||
[Serializable]
|
||||
public record struct CommitManifest(Guid ManifestId, DepotLabel Depot, string[] FilePaths);
|
||||
public record struct CommitManifest(Guid ManifestId, DepotLabel Depot, WorkspaceFile[] FilePaths);
|
||||
@ -1,4 +1,4 @@
|
||||
namespace Flawless.Core.Modal;
|
||||
|
||||
[Serializable]
|
||||
public record struct DepotFileInfo(ulong Offset, ulong Size, string Path);
|
||||
public record struct DepotFileInfo(ulong Offset, ulong Size, DateTime ModifyTime, string Path);
|
||||
@ -3,4 +3,4 @@
|
||||
namespace Flawless.Core.Modal;
|
||||
|
||||
[Serializable]
|
||||
public record struct DepotLabel(HashId Id, HashId[] Dependency);
|
||||
public record struct DepotLabel(Guid Id, long Length, Guid[] Dependency);
|
||||
33
Flawless.Core/Modal/WorkspaceFile.cs
Normal file
33
Flawless.Core/Modal/WorkspaceFile.cs
Normal file
@ -0,0 +1,33 @@
|
||||
namespace Flawless.Core.Modal;
|
||||
|
||||
public struct WorkspaceFile : IEquatable<WorkspaceFile>
|
||||
{
|
||||
public required DateTime ModifyTime;
|
||||
|
||||
public required string WorkPath;
|
||||
|
||||
public bool Equals(WorkspaceFile other)
|
||||
{
|
||||
return ModifyTime.Equals(other.ModifyTime) && WorkPath == other.WorkPath;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is WorkspaceFile other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(ModifyTime, WorkPath);
|
||||
}
|
||||
|
||||
public static bool operator ==(WorkspaceFile left, WorkspaceFile right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(WorkspaceFile left, WorkspaceFile right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,11 @@
|
||||
using Flawless.Communication.Request;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Flawless.Communication.Request;
|
||||
using Flawless.Communication.Response;
|
||||
using Flawless.Communication.Shared;
|
||||
using Flawless.Core.BinaryDataFormat;
|
||||
using Flawless.Core.Modal;
|
||||
using Flawless.Server.Models;
|
||||
using Flawless.Server.Services;
|
||||
using Flawless.Server.Utility;
|
||||
@ -15,12 +20,13 @@ namespace Flawless.Server.Controllers;
|
||||
public class RepositoryControl(
|
||||
UserManager<AppUser> userManager,
|
||||
AppDbContext dbContext,
|
||||
PathTransformer transformer) : ControllerBase
|
||||
PathTransformer transformer,
|
||||
JsonSerializerOptions serializerOpt) : ControllerBase
|
||||
{
|
||||
|
||||
public class FormCommitRequest : CommitRequest
|
||||
{
|
||||
public IFormFile Depot { get; set; }
|
||||
public IFormFile? Depot { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@ -36,22 +42,31 @@ public class RepositoryControl(
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("fetch/manifest/{commitId}")]
|
||||
public async Task<IActionResult> DownloadManifestAsync(string userName, string repositoryName, string commitId)
|
||||
private async ValueTask<object> ValidateRepositoryAsync(
|
||||
string userName, string repositoryName, AppUser user, RepositoryRole role)
|
||||
{
|
||||
if (!Guid.TryParse(commitId, out var commitGuid)) return BadRequest(new FailedResponse("Invalid commit id"));
|
||||
var rp = await dbContext.Repositories
|
||||
.Include(r => r.Owner)
|
||||
.Include(r => r.Members)
|
||||
.FirstOrDefaultAsync(r => r.Owner.UserName == userName && r.Name == repositoryName);
|
||||
|
||||
if (rp == null) return NotFound(new FailedResponse($"Could not find repository {repositoryName}"));
|
||||
var u = (await userManager.FindByNameAsync(userName))!;
|
||||
if (UserNotGranted(out var rsp, u, rp, RepositoryRole.Guest)) return rsp!;
|
||||
if (rp == null) return NotFound(new FailedResponse($"Could not find repository {userName}:{repositoryName}"));
|
||||
if (UserNotGranted(out var rsp, user, rp, role)) return rsp!;
|
||||
|
||||
return rp;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("fetch/manifest/{commitId}")]
|
||||
public async Task<IActionResult> DownloadManifestAsync(string userName, string repositoryName, string commitId)
|
||||
{
|
||||
if (!Guid.TryParse(commitId, out var commitGuid)) return BadRequest(new FailedResponse("Invalid commit id"));
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest);
|
||||
if (grantIssue is not Repository rp) return (IActionResult) grantIssue;
|
||||
|
||||
// Start checkout file.
|
||||
var target = transformer.GetCommitManifest(rp.Id, commitGuid);
|
||||
var target = transformer.GetCommitManifestPath(rp.Id, commitGuid);
|
||||
if (System.IO.File.Exists(target)) return File(System.IO.File.OpenRead(target), "application/octet-stream");
|
||||
return NotFound(new FailedResponse($"Could not find commit manifest {target}"));
|
||||
}
|
||||
@ -61,42 +76,258 @@ public class RepositoryControl(
|
||||
public async Task<IActionResult> DownloadDepotAsync(string userName, string repositoryName, string depotId)
|
||||
{
|
||||
if (!Guid.TryParse(depotId, out var depotGuid)) return BadRequest(new FailedResponse("Invalid depot id"));
|
||||
var rp = await dbContext.Repositories
|
||||
.Include(r => r.Owner)
|
||||
.Include(r => r.Members)
|
||||
.FirstOrDefaultAsync(r => r.Owner.UserName == userName && r.Name == repositoryName);
|
||||
|
||||
if (rp == null) return NotFound(new FailedResponse($"Could not find repository {repositoryName}"));
|
||||
var u = (await userManager.FindByNameAsync(userName))!;
|
||||
if (UserNotGranted(out var rsp, u, rp, RepositoryRole.Guest)) return rsp!;
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest);
|
||||
if (grantIssue is not Repository rp) return (IActionResult) grantIssue;
|
||||
|
||||
// Start checkout file.
|
||||
var target = transformer.GetDepotManifest(rp.Id, depotGuid);
|
||||
var target = transformer.GetDepotPath(rp.Id, depotGuid);
|
||||
if (System.IO.File.Exists(target)) return File(System.IO.File.OpenRead(target), "application/octet-stream");
|
||||
return NotFound(new FailedResponse($"Could not find depot {target}"));
|
||||
|
||||
}
|
||||
|
||||
[HttpGet("list/commit")]
|
||||
public async Task<IActionResult> ListCommitsAsync(string userName, string repositoryName)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest);
|
||||
if (grantIssue is not Repository) return (IActionResult) grantIssue;
|
||||
|
||||
var commit = await dbContext.Repositories
|
||||
.Where(r => r.Owner.UserName == userName && r.Name == repositoryName)
|
||||
.SelectMany(r => r.Commits)
|
||||
.Include(r => r.Author)
|
||||
.OrderByDescending(r => r.CommittedOn)
|
||||
.ToArrayAsync();
|
||||
|
||||
// [HttpPost("commit")]
|
||||
// public async Task<IActionResult> CommitAsync([FromForm] FormCommitRequest request)
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// [HttpGet("list/commit")]
|
||||
// public async Task<IActionResult> ListCommitsAsync(string userName, string repositoryName)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// [HttpGet("query/commit/{keyword}")]
|
||||
// public async Task<IActionResult> QueryCommitsAsync(string userName, string repositoryName, string keyword)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// [HttpGet("get/commit/{commitId}")]
|
||||
// public async Task<IActionResult> GetCommitAsync(string userName, string repositoryName, string commitId)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
return Ok(new
|
||||
{
|
||||
Commits = commit
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("peek/commit")]
|
||||
public async Task<IActionResult> PeekCommitAsync(string userName, string repositoryName)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest);
|
||||
if (grantIssue is not Repository rp) return (IActionResult) grantIssue;
|
||||
|
||||
var commit = await dbContext.Repositories
|
||||
.Where(r => r.Owner.UserName == userName && r.Name == repositoryName)
|
||||
.SelectMany(r => r.Commits)
|
||||
.Include(r => r.Author)
|
||||
.OrderByDescending(r => r.CommittedOn)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
Commit = commit?.Id.ToString() ?? string.Empty
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("commit")]
|
||||
public async Task<IActionResult> CommitAsync(string userName, string repositoryName, [FromForm] FormCommitRequest req)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest);
|
||||
if (grantIssue is not Repository rp) return (IActionResult) grantIssue;
|
||||
|
||||
if (req.Depot != null ^ req.MainDepotId != null) return await CommitInternalAsync(rp, user, req);
|
||||
|
||||
// Not valid response
|
||||
if (req.Depot != null) return BadRequest(new FailedResponse("You can not choose a existed depot while upload a new depot!"));
|
||||
return BadRequest(new FailedResponse("You must choose a existed depot upload a new depot as baseline!"));
|
||||
}
|
||||
|
||||
private async Task<IActionResult> CommitInternalAsync(Repository rp, AppUser user, FormCommitRequest req)
|
||||
{
|
||||
var test = new HashSet<WorkspaceFile>(req.WorkspaceSnapshot);
|
||||
var createNewDepot = false;
|
||||
RepositoryDepot mainDepot;
|
||||
DepotLabel depotLabel;
|
||||
|
||||
// Judge if receive new depot or use old one...
|
||||
if (req.Depot == null)
|
||||
{
|
||||
var mainDepotId = Guid.Parse(req.MainDepotId!);
|
||||
var preDepot = await StencilWorkspaceSnapshotViaDatabaseAsync(rp.Id, mainDepotId, test);
|
||||
|
||||
if (preDepot == null)
|
||||
return BadRequest(new FailedResponse("Not a valid main depot!", "NoMainDepot"));
|
||||
|
||||
// If still not able to resolve
|
||||
if (test.Count > 0)
|
||||
return BadRequest(new FailedResponse(test, "DependencyUnsolved"));
|
||||
|
||||
// Set this depot label...
|
||||
mainDepot = preDepot;
|
||||
var deps = mainDepot.Dependencies.Select(d => d.DepotId).ToArray();
|
||||
depotLabel = new DepotLabel(mainDepot.DepotId, mainDepot.Length, deps);
|
||||
}
|
||||
else
|
||||
{
|
||||
var actualRequiredDepots = new HashSet<Guid>();
|
||||
|
||||
// Read and create a new depot
|
||||
using var cacheStream = new MemoryStream(new byte[req.Depot.Length], true);
|
||||
await req.Depot.CopyToAsync(cacheStream, HttpContext.RequestAborted);
|
||||
|
||||
// Look if main depot can do this...
|
||||
await StencilWorkspaceSnapshotAsync(cacheStream, test);
|
||||
|
||||
// Oh no, will we need to load their parents?
|
||||
var unresolvedCount = test.Count;
|
||||
if (unresolvedCount != 0)
|
||||
{
|
||||
// Yes
|
||||
foreach (var subDepot in req.RequiredDepots?.Select(Guid.Parse) ?? [])
|
||||
{
|
||||
await StencilWorkspaceSnapshotViaDatabaseAsync(rp.Id, subDepot, test);
|
||||
|
||||
var rest = test.Count;
|
||||
if (rest == 0)
|
||||
{
|
||||
actualRequiredDepots.Add(subDepot);
|
||||
break;
|
||||
}
|
||||
|
||||
// If test is changed?
|
||||
if (unresolvedCount != rest)
|
||||
{
|
||||
actualRequiredDepots.Add(subDepot);
|
||||
unresolvedCount = rest;
|
||||
}
|
||||
}
|
||||
|
||||
// If still not able to resolve
|
||||
if (unresolvedCount > 0)
|
||||
return BadRequest(new
|
||||
{
|
||||
Reason = "Unable to resolve workspace snapshot! May lost some essential dependency.",
|
||||
Unresolved = test
|
||||
});
|
||||
}
|
||||
|
||||
// Great, a valid depot, so create it in db.
|
||||
mainDepot = new RepositoryDepot { Length = req.Depot.Length };
|
||||
mainDepot.Dependencies.AddRange(
|
||||
await dbContext.Repositories
|
||||
.Where(r => r.Id == rp.Id)
|
||||
.SelectMany(r => r.Depots)
|
||||
.Where(cm => actualRequiredDepots.Contains(cm.DepotId))
|
||||
.ToArrayAsync());
|
||||
|
||||
depotLabel = new DepotLabel(mainDepot.DepotId, mainDepot.Length, actualRequiredDepots.ToArray());
|
||||
rp.Depots.Add(mainDepot);
|
||||
|
||||
// Then write depot into disk
|
||||
var depotPath = transformer.GetDepotPath(rp.Id, mainDepot.DepotId);
|
||||
await using (var depotStream = System.IO.File.Create(depotPath))
|
||||
{
|
||||
cacheStream.Seek(0, SeekOrigin.Begin);
|
||||
await cacheStream.CopyToAsync(depotStream, HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
createNewDepot = true;
|
||||
}
|
||||
|
||||
// Create manifest file and write to disk
|
||||
var commitId = Guid.NewGuid();
|
||||
var manifestPath = transformer.GetCommitManifestPath(rp.Id, commitId);
|
||||
var manifest = new CommitManifest
|
||||
{
|
||||
ManifestId = commitId,
|
||||
Depot = depotLabel,
|
||||
FilePaths = req.WorkspaceSnapshot
|
||||
};
|
||||
|
||||
await using (var manifestStream = System.IO.File.Create(manifestPath))
|
||||
await JsonSerializer.SerializeAsync(manifestStream, manifest, serializerOpt);
|
||||
|
||||
// Create commit info
|
||||
var commit = new RepositoryCommit
|
||||
{
|
||||
Id = commitId,
|
||||
Author = user,
|
||||
CommittedOn = DateTime.UtcNow,
|
||||
MainDepot = mainDepot,
|
||||
Message = manifestPath
|
||||
};
|
||||
|
||||
rp.Commits.Add(commit);
|
||||
|
||||
try
|
||||
{
|
||||
// Write changes into db.
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Revert manifest create operation
|
||||
if (createNewDepot) System.IO.File.Delete(transformer.GetDepotPath(rp.Id, mainDepot.DepotId));
|
||||
System.IO.File.Delete(manifestPath);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
CreatedAt = commit.CommittedOn,
|
||||
CommitId = commit.Id
|
||||
});
|
||||
}
|
||||
|
||||
private static async ValueTask StencilWorkspaceSnapshotAsync(Stream depotStream, HashSet<WorkspaceFile> unresolved)
|
||||
{
|
||||
// Get version
|
||||
var version = DataTransformer.GuessStandardDepotHeaderVersion(depotStream);
|
||||
if (version != 1) throw new InvalidDataException($"Unable to get depot header version, feedback is {version}.");
|
||||
|
||||
// Get header
|
||||
depotStream.Seek(0, SeekOrigin.Begin);
|
||||
var header = DataTransformer.ExtractStandardDepotHeaderV1(depotStream);
|
||||
|
||||
// Start validation
|
||||
depotStream.Seek(0, SeekOrigin.Begin);
|
||||
await foreach (var inf in DataTransformer.ExtractDepotFileInfoMapAsync(depotStream, header.FileMapSize))
|
||||
{
|
||||
var test = new WorkspaceFile
|
||||
{
|
||||
ModifyTime = inf.ModifyTime,
|
||||
WorkPath = inf.Path,
|
||||
};
|
||||
|
||||
unresolved.Remove(test);
|
||||
if (unresolved.Count == 0) break; // Early quit to avoid extra performance loss.
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<RepositoryDepot?> StencilWorkspaceSnapshotViaDatabaseAsync(Guid rpId, Guid depotId, HashSet<WorkspaceFile> unresolved)
|
||||
{
|
||||
var depot = await dbContext.Repositories
|
||||
.SelectMany(r => r.Depots)
|
||||
.Include(r => r.Dependencies)
|
||||
.ThenInclude(repositoryDepot => repositoryDepot.Dependencies)
|
||||
.FirstOrDefaultAsync(r => r.DepotId == depotId);
|
||||
|
||||
await RecurringAsync(transformer, rpId, depot, unresolved);
|
||||
return depot;
|
||||
|
||||
static async ValueTask RecurringAsync(PathTransformer transformer, Guid rpId, RepositoryDepot? depot, HashSet<WorkspaceFile> unresolved)
|
||||
{
|
||||
if (depot == null) return;
|
||||
var path = transformer.GetDepotPath(rpId, depot.DepotId);
|
||||
|
||||
// require do not extend lifetime scope.
|
||||
await using (var fs = new BufferedStream(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
|
||||
await StencilWorkspaceSnapshotAsync(fs, unresolved);
|
||||
|
||||
for (var i = 0; i < depot.Dependencies.Count && unresolved.Count > 0; i++)
|
||||
await RecurringAsync(transformer, rpId, depot.Dependencies[i], unresolved);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,4 +22,6 @@ public class Repository
|
||||
public List<RepositoryMember> Members { get; set; } = new();
|
||||
|
||||
public List<RepositoryCommit> Commits { get; set; } = new();
|
||||
|
||||
public List<RepositoryDepot> Depots { get; set; } = new();
|
||||
}
|
||||
@ -5,16 +5,17 @@ namespace Flawless.Server.Models;
|
||||
public class RepositoryCommit
|
||||
{
|
||||
[Required]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public required Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public required AppUser Author { get; set; }
|
||||
|
||||
[Required]
|
||||
public required DateTime CommittedOn { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Message { get; set; } = String.Empty;
|
||||
public required string Message { get; set; } = String.Empty;
|
||||
|
||||
[Required]
|
||||
public required RepositoryDepot MainDepot { get; set; }
|
||||
|
||||
public RepositoryCommit? Parent { get; set; }
|
||||
}
|
||||
@ -6,8 +6,10 @@ public class RepositoryDepot
|
||||
{
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid DepotId { get; set; }
|
||||
public Guid DepotId { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public long Length { get; set; }
|
||||
|
||||
[Required]
|
||||
public List<RepositoryDepot> Dependencies { get; set; } = new();
|
||||
}
|
||||
@ -16,7 +16,7 @@ public class PathTransformer(IConfiguration config)
|
||||
return Path.Combine(_rootPath, repositoryId.ToString());
|
||||
}
|
||||
|
||||
public string GetCommitManifest(Guid repositoryId, Guid commitId)
|
||||
public string GetCommitManifestPath(Guid repositoryId, Guid commitId)
|
||||
{
|
||||
if (repositoryId == Guid.Empty) throw new ArgumentException(nameof(repositoryId));
|
||||
if (commitId == Guid.Empty) throw new ArgumentException(nameof(commitId));
|
||||
@ -24,7 +24,7 @@ public class PathTransformer(IConfiguration config)
|
||||
return Path.Combine(_rootPath, repositoryId.ToString(), "Manifests", commitId.ToString());
|
||||
}
|
||||
|
||||
public string GetDepotManifest(Guid repositoryId, Guid depotId)
|
||||
public string GetDepotPath(Guid repositoryId, Guid depotId)
|
||||
{
|
||||
if (repositoryId == Guid.Empty) throw new ArgumentException(nameof(repositoryId));
|
||||
if (depotId == Guid.Empty) throw new ArgumentException(nameof(depotId));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user