Skip to content
This repository was archived by the owner on Sep 30, 2023. It is now read-only.

Commit cd10b52

Browse files
beeveekunga
authored andcommitted
Add multi-branch force (#50)
* Add multi-branch force * Fix some excellent tests * Normalize your directory separators, please * Fix the most excellent test * Add tests for new functionality * Finally, some documentation
1 parent 0789178 commit cd10b52

12 files changed

+122
-54
lines changed

Commands/ConvertSpec.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ private void ConvertDepsSection(string configuration, List<string> children)
7373
writer.WriteLine(" deps:");
7474
if (deps.Force != null)
7575
{
76-
deps.Force = deps.Force.Replace("%CURRENT_BRANCH%", "$CURRENT_BRANCH");
77-
writer.WriteLine(" - force: " + deps.Force);
76+
deps.Force = deps.Force.Select(x => x.Replace("%CURRENT_BRANCH%", "$CURRENT_BRANCH")).ToArray();
77+
writer.WriteLine(" - force: " + string.Join(",", deps.Force));
7878
}
7979
if (deps.Deps == null)
8080
return;

Common/DepsIniParser.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ private List<Dep> GetDepsFromIni(IniData parsed)
5454
return deps;
5555
}
5656

57-
private string GetForceFromIni(IniData parsed)
57+
private string[] GetForceFromIni(IniData parsed)
5858
{
5959
var force = parsed.GetValue("force", "main");
60-
return force == "" ? null : force;
60+
return force == "" ? null : force.Split(',');
6161
}
6262
}
6363
}

Common/ModuleGetter.cs

+28-20
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void GetDeps()
4444
rootRepoTreeish = rootRepo.CurrentLocalTreeish().Value;
4545

4646
var depsContent = new DepsParser(rootRepo.RepoPath).Get(rootModule.Configuration);
47-
depsContent.Force = Helper.DefineForce(depsContent.Force, rootRepo);
47+
depsContent.Force = depsContent.Force?.Select(f => Helper.DefineForce(f, rootRepo)).ToArray();
4848
Log.Info("OK");
4949

5050
var queue = new DepsQueue();
@@ -74,7 +74,7 @@ private void TakeDepsToProcessFromQueue(DepsQueue queue, IList<DepWithParent> de
7474
}
7575
}
7676

77-
private void GetDeps(string force, DepsQueue queue, ModulesContainer processed)
77+
private void GetDeps(string[] force, DepsQueue queue, ModulesContainer processed)
7878
{
7979
while (!queue.IsEmpty())
8080
{
@@ -95,7 +95,7 @@ private void GetDeps(string force, DepsQueue queue, ModulesContainer processed)
9595
ConsoleWriter.WriteWarning($"Branch '{mergedBranch}' was not merged into some of dependencies");
9696
}
9797

98-
private void ProcessDeps(string force, List<DepWithParent> depsPool)
98+
private void ProcessDeps(string[] force, List<DepWithParent> depsPool)
9999
{
100100
if (depsPool.Any())
101101
Log.Info("Parallel update-deps iteration: " + depsPool.Select(d => d.Dep.ToString() + "(" + d.ParentModule + ")").Aggregate((a, b) => a + " " + b));
@@ -153,12 +153,12 @@ private static DepsContent GetCurrentModuleDeps(Dep dep)
153153
return deps;
154154
}
155155

156-
private void GetModule(Dep dep, string force)
156+
private void GetModule(Dep dep, string[] force)
157157
{
158158
Log.Info($"{"[" + dep.Name + "]",-30}Update '{dep.Treeish ?? "master"}'");
159159
if (dep.Treeish == "$CURRENT_BRANCH")
160160
{
161-
force = Helper.DefineForce(dep.Treeish, rootRepoTreeish);
161+
force = new[] {Helper.DefineForce(dep.Treeish, rootRepoTreeish)};
162162
dep.Treeish = null;
163163
}
164164
ConsoleWriter.WriteProgress(dep.Name + " " + dep.Treeish);
@@ -170,7 +170,7 @@ private void GetModule(Dep dep, string force)
170170
GetFullModule(dep, force);
171171
}
172172

173-
private void GetFullModule(Dep dep, string force)
173+
private void GetFullModule(Dep dep, string[] force)
174174
{
175175
var getInfo = new GetInfo();
176176
var module = modules.FirstOrDefault(m => m.Name.Equals(dep.Name));
@@ -194,7 +194,7 @@ private void GetFullModule(Dep dep, string force)
194194
getInfo.CommitInfo = repo.GetCommitInfo();
195195
if (HooksHelper.InstallHooks(dep.Name))
196196
getInfo.HookUpdated = true;
197-
PrintProcessedModuleInfo(dep, getInfo, getInfo.Forced ? force : dep.Treeish);
197+
PrintProcessedModuleInfo(dep, getInfo, getInfo.Forced ? getInfo.ForcedBranch : dep.Treeish);
198198
WarnIfNotMerged(repo);
199199
}
200200

@@ -287,16 +287,16 @@ private void PrintProcessedModuleInfo(Dep dep, GetInfo getInfo, string treeish)
287287
}
288288
}
289289

290-
private void GetTreeish(GitRepository repo, Dep dep, string force, string treeish, GetInfo getInfo)
290+
private void GetTreeish(GitRepository repo, Dep dep, string[] force, string treeish, GetInfo getInfo)
291291
{
292292
treeish = treeish ?? "master";
293293
Log.Info($"{"[" + dep.Name + "]",-30}Getting treeish '{treeish}'");
294294

295295
var hasRemoteBranch = repo.HasRemoteBranch(treeish);
296-
getInfo.Forced = HaveToForce(dep, force, repo);
296+
getInfo.ForcedBranch = HaveToForce(dep, force, repo);
297297
if (getInfo.Forced)
298298
{
299-
treeish = force;
299+
treeish = getInfo.ForcedBranch;
300300
Log.Info($"{"[" + dep.Name + "]",-30}treeish '{treeish}' was forced");
301301
}
302302

@@ -390,15 +390,22 @@ private static void Reset(GitRepository repo, Dep dep)
390390
}
391391
}
392392

393-
private bool HaveToForce(Dep dep, string force, GitRepository repo)
393+
private string HaveToForce(Dep dep, string[] force, GitRepository repo)
394394
{
395-
if (!localBranchForce && repo.HasLocalBranch(force) && !repo.HasRemoteBranch(force))
396-
{
397-
ConsoleWriter.WriteWarning(
398-
$"Module '{repo.ModuleName}' has local-only branch '{force}' which will not be forced.\nUse --allow-local-branch-force key to force it");
399-
return false;
400-
}
401-
return dep.Treeish == null && force != null && repo.HasRemoteBranch(force);
395+
if (force != null)
396+
foreach (var f in force)
397+
{
398+
if (!localBranchForce && repo.HasLocalBranch(f) && !repo.HasRemoteBranch(f))
399+
{
400+
ConsoleWriter.WriteWarning(
401+
$"Module '{repo.ModuleName}' has local-only branch '{force}' which will not be forced.\nUse --allow-local-branch-force key to force it");
402+
continue;
403+
}
404+
405+
if (dep.Treeish == null && repo.HasRemoteBranch(f))
406+
return f;
407+
}
408+
return null;
402409
}
403410

404411
private LocalChangesAction DefineLocalChangesPolicy(GitRepository repo, string localSha, string remoteSha)
@@ -472,7 +479,8 @@ public enum LocalChangesPolicy
472479
public class GetInfo
473480
{
474481
public bool Cloned;
475-
public bool Forced;
482+
public bool Forced => ForcedBranch != null;
483+
public string ForcedBranch;
476484
public bool Changed;
477485
public bool ForcedLocal;
478486
public bool Pulled;
@@ -483,7 +491,7 @@ public class GetInfo
483491
public GetInfo()
484492
{
485493
Cloned = false;
486-
Forced = false;
494+
ForcedBranch = null;
487495
Changed = false;
488496
ForcedLocal = false;
489497
Pulled = false;

Common/YamlParsers/ConfigurationYamlParser.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ public Dictionary<string, IList<string>> GetConfigurationsHierarchy()
141141

142142
public class DepsContent
143143
{
144-
public string Force { get; set; }
144+
public string[] Force { get; set; }
145145
public List<Dep> Deps { get; set; }
146146

147-
public DepsContent(string force, List<Dep> deps)
147+
public DepsContent(string[] force, List<Dep> deps)
148148
{
149149
Force = force;
150150
Deps = deps;

Common/YamlParsers/DepsYamlParser.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,14 @@ private static DepsContent GetDepsFromSection(Dictionary<string, object> configS
155155
return new DepsContent(null, new List<Dep>());
156156

157157
var deps = new List<Dep>();
158-
string force = null;
158+
string[] force = null;
159159
foreach (var depSection in (List<object>) configSection["deps"])
160160
{
161161
if (depSection is Dictionary<object, object>)
162162
{
163163
var dict = depSection as Dictionary<object, object>;
164164
if (dict.Keys.Count == 1 && (string) dict.Keys.First() == "force")
165-
force = (string) dict.Values.First();
165+
force = ((string) dict.Values.First()).Split(',');
166166
else
167167
deps.Add(GetDepFromDictFormat(dict));
168168
}

README-module.yaml.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ Example:
3434
- topology
3535
# to prefer current branch in deps
3636
- force: $CURRENT_BRANCH
37-
# or use <moduleName>@$CURRENT_BRANCH to prefer current branch in some module
37+
# or use <moduleName>@$CURRENT_BRANCH to prefer current branch in some module;
38+
# you can also choose any specific branch name in deps:
39+
# - force: mybestbranch
40+
# or provide a comma-separated list of preferred branches:
41+
# - force: mybestbranch,notsogoodbranch,leastfavoritebranch
42+
# master branch is always the default option if all forced branches are missing
3843

3944
# information on build of the present module in the present configuration
4045
build:

Tests/CommandsTests/TestConvertSpec.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private static void AddDeps(List<Dep> deps, string configuration = null, string
6363

6464
var readedDeps = new DepsIniParser(new FileInfo(depsFileName)).Get();
6565
CollectionAssert.AreEquivalent(readedDeps.Deps, deps);
66-
Assert.AreEqual(force, readedDeps.Force);
66+
Assert.AreEqual(force, readedDeps.Force?.Single());
6767
}
6868

6969
private static void WriteDeps(List<Dep> deps, string force, string depsFileName)
@@ -105,7 +105,7 @@ public void TestSimpleDepsWithForce()
105105

106106
var yamlDeps = Yaml.DepsParser("module").Get();
107107
CollectionAssert.AreEqual(deps, yamlDeps.Deps);
108-
Assert.AreEqual("$CURRENT_BRANCH", yamlDeps.Force);
108+
Assert.AreEqual("$CURRENT_BRANCH", yamlDeps.Force.Single());
109109
}
110110

111111
[Test]

Tests/CommandsTests/TestGet.cs

+45-9
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void TestGetDepsOneDepWithForce()
113113

114114
env.CreateRepo("A", new Dictionary<string, DepsContent>
115115
{
116-
{"full-build", new DepsContent("new", new List<Dep> {new Dep("B")})}
116+
{"full-build", new DepsContent(new[] {"new"}, new List<Dep> {new Dep("B")})}
117117
});
118118
env.CreateRepo("B", null, new[] {"new"});
119119
env.Get("A");
@@ -122,14 +122,50 @@ public void TestGetDepsOneDepWithForce()
122122
}
123123
}
124124

125+
[Test]
126+
public void TestGetDepsOneDepWithMultipleForce()
127+
{
128+
using (var env = new TestEnvironment())
129+
{
130+
var dir = env.WorkingDirectory.Path;
131+
132+
env.CreateRepo("A", new Dictionary<string, DepsContent>
133+
{
134+
{"full-build", new DepsContent(new[] {"priority", "new"}, new List<Dep> {new Dep("B")})}
135+
});
136+
env.CreateRepo("B", null, new[] {"new", "priority"});
137+
env.Get("A");
138+
Assert.IsTrue(Directory.Exists(Path.Combine(dir, "A")));
139+
Assert.AreEqual("priority", new GitRepository("B", dir, Log).CurrentLocalTreeish().Value);
140+
}
141+
}
142+
143+
[Test]
144+
public void TestGetDepsOneDepWithMultipleForceOneBranchMissing()
145+
{
146+
using (var env = new TestEnvironment())
147+
{
148+
var dir = env.WorkingDirectory.Path;
149+
150+
env.CreateRepo("A", new Dictionary<string, DepsContent>
151+
{
152+
{"full-build", new DepsContent(new[] {"missing", "priority", "new"}, new List<Dep> {new Dep("B")})}
153+
});
154+
env.CreateRepo("B", null, new[] {"new", "priority"});
155+
env.Get("A");
156+
Assert.IsTrue(Directory.Exists(Path.Combine(dir, "A")));
157+
Assert.AreEqual("priority", new GitRepository("B", dir, Log).CurrentLocalTreeish().Value);
158+
}
159+
}
160+
125161
[Test]
126162
public void TestGetDepsOneDepWithResetThrowsDueToPolicy()
127163
{
128164
using (var env = new TestEnvironment())
129165
{
130166
env.CreateRepo("A", new Dictionary<string, DepsContent>
131167
{
132-
{"full-build", new DepsContent("new", new List<Dep> {new Dep("B")})}
168+
{"full-build", new DepsContent(new[] {"new"}, new List<Dep> {new Dep("B")})}
133169
});
134170
env.CreateRepo("B", null, new[] {"new"});
135171
env.Get("A");
@@ -147,7 +183,7 @@ public void TestGetDepsOneDepWithResetChanges()
147183

148184
env.CreateRepo("A", new Dictionary<string, DepsContent>
149185
{
150-
{"full-build", new DepsContent("new", new List<Dep> {new Dep("B")})}
186+
{"full-build", new DepsContent(new[] {"new"}, new List<Dep> {new Dep("B")})}
151187
});
152188
env.CreateRepo("B", null, new[] {"new"});
153189
env.Get("A");
@@ -170,7 +206,7 @@ public void TestGetDepsOneDepWithResetChangesAndCommit()
170206

171207
env.CreateRepo("A", new Dictionary<string, DepsContent>
172208
{
173-
{"full-build", new DepsContent("new", new List<Dep> {new Dep("B")})}
209+
{"full-build", new DepsContent(new[] {"new"}, new List<Dep> {new Dep("B")})}
174210
});
175211
env.CreateRepo("B", null, new[] {"new"});
176212
env.Get("A");
@@ -268,7 +304,7 @@ public void TestGetDepsOneDepWithCurrentBranchForceOldStyle()
268304

269305
env.CreateRepo("A", new Dictionary<string, DepsContent>
270306
{
271-
{"full-build", new DepsContent("%CURRENT_BRANCH%", new List<Dep> {new Dep("B")})}
307+
{"full-build", new DepsContent(new[] {"%CURRENT_BRANCH%"}, new List<Dep> {new Dep("B")})}
272308
}, new[] {"new"}, DepsFormatStyle.Ini);
273309
env.Checkout("A", "new");
274310

@@ -289,7 +325,7 @@ public void TestGetDepsOneDepWithCreatingNewRemoteBranch()
289325

290326
env.CreateRepo("A", new Dictionary<string, DepsContent>
291327
{
292-
{"full-build", new DepsContent("%CURRENT_BRANCH%", new List<Dep> {new Dep("B")})}
328+
{"full-build", new DepsContent(new[] {"%CURRENT_BRANCH%"}, new List<Dep> {new Dep("B")})}
293329
}, new[] {"new"}, DepsFormatStyle.Ini);
294330
env.Checkout("A", "new");
295331

@@ -313,7 +349,7 @@ public void TestGetDepsOneDepWithForceAndTreeish()
313349

314350
env.CreateRepo("A", new Dictionary<string, DepsContent>
315351
{
316-
{"full-build", new DepsContent("new", new List<Dep> {new Dep("B")})}
352+
{"full-build", new DepsContent(new[] {"new"}, new List<Dep> {new Dep("B")})}
317353
}, new[] {"new"}, DepsFormatStyle.Ini);
318354

319355
env.CreateRepo("B", new Dictionary<string, DepsContent>
@@ -339,7 +375,7 @@ public void TestGetDepsOneDepWithCurrentBranchForceNewStyle()
339375

340376
env.CreateRepo("A", new Dictionary<string, DepsContent>
341377
{
342-
{"full-build", new DepsContent("$CURRENT_BRANCH", new List<Dep> {new Dep("B")})}
378+
{"full-build", new DepsContent(new[] {"$CURRENT_BRANCH"}, new List<Dep> {new Dep("B")})}
343379
}, new[] {"new"});
344380
env.Checkout("A", "new");
345381

@@ -680,7 +716,7 @@ public void TestGetDepsWithBranchesClientBuild()
680716
{
681717
{"full-build", new DepsContent(null, new List<Dep>())}
682718
}, new[] { "master", "branch1", "branch2" });
683-
719+
684720
env.Get("A");
685721
Assert.IsTrue(Directory.Exists(Path.Combine(dir, "C")));
686722
Assert.AreEqual("branch2", new GitRepository("C", dir, Log).CurrentLocalTreeish().Value);

Tests/Helpers/TestEnvironment.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private void CreateDepsYamlStyle(string path, Dictionary<string, DepsContent> de
117117
deps:{
118118
(depsByConfig[config]
119119
.Force != null
120-
? "\r\n - force: " + depsByConfig[config].Force
120+
? $"\r\n - force: " + string.Join(",", depsByConfig[config].Force)
121121
: "")
122122
}
123123
", (current, dep) => current +
@@ -144,7 +144,7 @@ private void CreateDepsIniStyle(string path, Dictionary<string, DepsContent> dep
144144
{
145145
content = depsByConfig[config].Force != null
146146
? @"[main]
147-
force = " + depsByConfig[config].Force + "\r\n"
147+
force = " + string.Join(",", depsByConfig[config].Force) + "\r\n"
148148
: "";
149149
foreach (var dep in depsByConfig[config].Deps)
150150
{

0 commit comments

Comments
 (0)