Skip to content

Commit 56d979a

Browse files
authored
sync: fix GetOutgoingRevisions to use draft phases (#3775)
1 parent 797889b commit 56d979a

4 files changed

Lines changed: 75 additions & 3 deletions

File tree

src/SIL.XForge.Scripture/Services/HgWrapper.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public void BackupRepository(string repository, string backupFile) =>
4747
/// </returns>
4848
public string GetLastPublicRevision(string repository)
4949
{
50-
string ids = RunCommand(repository, "log --rev \"public()\" --template \"{node}\n\"");
51-
string revision = ids.Split(["\n"], StringSplitOptions.RemoveEmptyEntries).LastOrDefault()?.Trim();
50+
string ids = RunCommand(repository, """log --rev "public()" --template "{node}\n" """);
51+
string revision = ids.Split('\n', StringSplitOptions.RemoveEmptyEntries).LastOrDefault()?.Trim();
5252
return revision;
5353
}
5454

@@ -86,6 +86,20 @@ public void RestoreRepository(string destination, string backupFile)
8686
/// <param name="repository">The repository.</param>
8787
public void MarkSharedChangeSetsPublic(string repository) => RunCommand(repository, "phase -p -r 'tip'");
8888

89+
/// <summary>
90+
/// Returns the ids of commits with draft phase.
91+
/// </summary>
92+
public string[] GetDraftRevisions(string repositoryPath)
93+
{
94+
string ids = RunCommand(repositoryPath, """log --rev "draft()" --template "{node}\n" """);
95+
return
96+
[
97+
.. ids.Split('\n', StringSplitOptions.RemoveEmptyEntries)
98+
.Select(id => id.Trim())
99+
.Where(id => id.Length > 0),
100+
];
101+
}
102+
89103
/// <summary> Set the default Mercurial installation. Must be called for all other methods to work. </summary>
90104
public void SetDefault(Hg hgDefault)
91105
{

src/SIL.XForge.Scripture/Services/IHgWrapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ public interface IHgWrapper
1313
string GetLastPublicRevision(string repository);
1414
string GetRepoRevision(string repositoryPath);
1515
void MarkSharedChangeSetsPublic(string repository);
16+
string[] GetDraftRevisions(string repositoryPath);
1617
}

src/SIL.XForge.Scripture/Services/JwtInternetSharedRepositorySource.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ public override void Push(string repository, SharedRepository pushRepo)
136136
/// </summary>
137137
public override string GetHgUri(SharedRepository sharedRepository) => string.Empty;
138138

139+
/// <summary>
140+
/// Returns the ids of unpushed commits. Overriding here since InternetSharedRepositorySource.GetOutgoingRevisions
141+
/// is going to SharedRepositorySource.GetOutgoingRevisions which doesn't work for us because it needs to look at
142+
/// the remote repository. One difference with this implementation is that it looks at commit phase to determine
143+
/// what is pushed. Distinguishing between public and draft commit phase is not something ParatextData uses.
144+
/// </summary>
145+
public override string[] GetOutgoingRevisions(string repository, SharedProject sharedProject) =>
146+
_hgWrapper.GetDraftRevisions(repository);
147+
139148
/// <summary>
140149
/// Retrieve a list of <see cref="SharedRepository" />.
141150
/// </summary>

test/SIL.XForge.Scripture.Tests/Services/JwtInternetSharedRepositorySourceTests.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NSubstitute.Extensions;
55
using NUnit.Framework;
66
using Paratext.Data;
7+
using Paratext.Data.Repository;
78
using Paratext.Data.Users;
89
using SIL.XForge.Scripture.Models;
910
using SIL.XForge.Services;
@@ -13,6 +14,11 @@ namespace SIL.XForge.Scripture.Services;
1314
[TestFixture]
1415
public class JwtInternetSharedRepositorySourceTests
1516
{
17+
private const string RepoPath = "/sync/abc123/target";
18+
private const string ProjectName = "TestProject";
19+
private const string ProjectId = "4011111111111111111111111111111111111111";
20+
private const string NewTipRevision = "bbb2222222222222222222222222222222222222";
21+
1622
[Test]
1723
public void CanUserAuthenticateToPTArchives_Works()
1824
{
@@ -50,10 +56,48 @@ public void CanUserAuthenticateToPTArchives_Works()
5056
);
5157
}
5258

59+
[Test]
60+
public void GetOutgoingRevisions_ReturnsDraftRevisions()
61+
{
62+
var env = new TestEnvironment();
63+
SharedProject sharedProject = new SharedProject
64+
{
65+
SendReceiveId = HexId.FromStr(ProjectId),
66+
ScrTextName = ProjectName,
67+
Repository = TestEnvironment.CreatePushRepo(HexId.FromStr(ProjectId), ProjectName),
68+
};
69+
string[] expectedRevisions = [NewTipRevision];
70+
env.MockHgWrapper.GetDraftRevisions(RepoPath).Returns(expectedRevisions);
71+
72+
// SUT
73+
string[] result = env.RepoSource.GetOutgoingRevisions(RepoPath, sharedProject);
74+
75+
Assert.That(result, Is.EqualTo(expectedRevisions));
76+
}
77+
78+
[Test]
79+
public void GetOutgoingRevisions_NoDraftRevisions_ReturnsEmpty()
80+
{
81+
var env = new TestEnvironment();
82+
SharedProject sharedProject = new SharedProject
83+
{
84+
SendReceiveId = HexId.FromStr(ProjectId),
85+
ScrTextName = ProjectName,
86+
Repository = TestEnvironment.CreatePushRepo(HexId.FromStr(ProjectId), ProjectName),
87+
};
88+
env.MockHgWrapper.GetDraftRevisions(RepoPath).Returns([]);
89+
90+
// SUT
91+
string[] result = env.RepoSource.GetOutgoingRevisions(RepoPath, sharedProject);
92+
93+
Assert.That(result, Is.Empty);
94+
}
95+
5396
private class TestEnvironment
5497
{
5598
public readonly JwtInternetSharedRepositorySource RepoSource;
5699
public readonly IRESTClient MockPTArchivesClient;
100+
public readonly IHgWrapper MockHgWrapper;
57101

58102
public TestEnvironment()
59103
{
@@ -63,16 +107,20 @@ public TestEnvironment()
63107
"applicationName",
64108
"jwtToken"
65109
);
110+
MockHgWrapper = Substitute.For<IHgWrapper>();
66111
RepoSource = Substitute.ForPartsOf<JwtInternetSharedRepositorySource>(
67112
"access-token",
68113
mockPTRegistryClient,
69-
Substitute.For<IHgWrapper>(),
114+
MockHgWrapper,
70115
ptUser,
71116
"sr-server-uri",
72117
new MockLogger<InternetSharedRepositorySourceProvider>()
73118
);
74119
MockPTArchivesClient = Substitute.For<RESTClient>("pt-archives-server.example.com", "product-version-123");
75120
RepoSource.Configure().GetClient().Returns(MockPTArchivesClient);
76121
}
122+
123+
public static SharedRepository CreatePushRepo(HexId ptProjectId, string projectName) =>
124+
new SharedRepository { SendReceiveId = ptProjectId, ScrTextName = projectName };
77125
}
78126
}

0 commit comments

Comments
 (0)