Skip to content

Commit f10d5b9

Browse files
authored
Fix-team-cmdlets (#168)
* Fix the handling of team project references * Add paginator service * Disable caching for scope properties * Use paginator * Add missing parameterset annotation * Fix pipeline handling * Improve ShouldProcess support * Fixes collection parameter handling * Validate release notes * Update release notes * Remove unused field * Update release notes
1 parent 63c04ab commit f10d5b9

24 files changed

+185
-65
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Management.Automation;
2+
using System.Threading.Tasks;
3+
4+
namespace TfsCmdlets.Services
5+
{
6+
public interface IPaginator
7+
{
8+
IEnumerable<T> Paginate<T>(Func<int, int, IEnumerable<T>> enumerable, int pageSize = 100);
9+
10+
IEnumerable<T> Paginate<T>(Func<int, int, Task<IEnumerable<T>>> enumerable, string errorMessage, int pageSize = 100);
11+
12+
// IEnumerable<T> Paginate<T>(Func<int, int, Task<List<T>>> enumerable, string errorMessage, int pageSize = 100);
13+
}
14+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System.Threading.Tasks;
2+
using Microsoft.TeamFoundation.Core.WebApi;
3+
using TfsCmdlets.Models;
4+
5+
namespace TfsCmdlets.Services.Impl
6+
{
7+
[Export(typeof(IPaginator))]
8+
public class Paginator : IPaginator
9+
{
10+
public IEnumerable<T> Paginate<T>(Func<int, int, Task<IEnumerable<T>>> enumerable, string errorMessage, int pageSize)
11+
{
12+
var isReturning = true;
13+
var loop = 0;
14+
int items;
15+
16+
while (isReturning)
17+
{
18+
isReturning = false;
19+
items = 0;
20+
21+
foreach (var result in enumerable(pageSize, loop++ * pageSize).GetResult(errorMessage))
22+
{
23+
items++;
24+
isReturning = true;
25+
yield return result;
26+
}
27+
28+
isReturning = isReturning && (items == pageSize);
29+
}
30+
}
31+
32+
public IEnumerable<T> Paginate<T>(Func<int, int, IEnumerable<T>> enumerable, int pageSize)
33+
{
34+
var isReturning = true;
35+
var loop = 0;
36+
int items;
37+
38+
while (isReturning)
39+
{
40+
isReturning = false;
41+
items = 0;
42+
43+
foreach (var result in enumerable(pageSize, loop++ * pageSize))
44+
{
45+
items++;
46+
isReturning = true;
47+
yield return result;
48+
}
49+
50+
isReturning = isReturning && (items == pageSize);
51+
}
52+
}
53+
}
54+
}

CSharp/TfsCmdlets.SourceGenerators/Generators/Controllers/ControllerInfo.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ private static IEnumerable<GeneratedProperty> GenerateScopeProperty(CmdletScope
173173
{
174174
yield return new GeneratedProperty(scope.ToString(), "object", $@" // {scope}
175175
protected bool Has_{scope} => Parameters.HasParameter(""{scope}"");
176-
private {scopeType} _{scope};
177-
protected {scopeType} {scope} => _{scope} ??= Data.Get{scope}();
176+
protected {scopeType} {scope} => Data.Get{scope}();
178177
179178
") { IsScope = true };
180179
}

CSharp/TfsCmdlets/Cmdlets/Git/GetGitRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace TfsCmdlets.Cmdlets.Git
66
/// <summary>
77
/// Gets information from one or more Git repositories in a team project.
88
/// </summary>
9-
[TfsCmdlet(CmdletScope.Project, OutputType = typeof(GitRepository))]
9+
[TfsCmdlet(CmdletScope.Project, OutputType = typeof(GitRepository), DefaultParameterSetName = "Get by ID or Name")]
1010
partial class GetGitRepository
1111
{
1212
/// <summary>

CSharp/TfsCmdlets/Cmdlets/TeamProject/Avatar/RemoveTeamProjectAvatar.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ namespace TfsCmdlets.Cmdlets.TeamProject.Avatar
33
/// <summary>
44
/// Removes the team project avatar, resetting it to the default.
55
/// </summary>
6-
[TfsCmdlet(CmdletScope.Project, SupportsShouldProcess = true)]
6+
[TfsCmdlet(CmdletScope.Collection, SupportsShouldProcess = true)]
77
partial class RemoveTeamProjectAvatar
88
{
9+
/// <summary>
10+
/// HELP_PARAM_PROJECT
11+
/// </summary>
12+
[Parameter(Mandatory = true, ValueFromPipeline = true)]
13+
public object Project { get; set; }
914
}
1015
}

CSharp/TfsCmdlets/Controllers/Git/Branch/RemoveGitBranchController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ protected override IEnumerable Run()
1616
var projectId = commitUrl.Segments[commitUrl.Segments.Length - 7].Trim('/');
1717
var repo = GetItem<GitRepository>(new { Repository = repoId, Project = projectId });
1818

19-
if (!PowerShell.ShouldProcess($"Git repository '{repo.Name}'", $"Delete branch '{branch.Name}'")) continue;
19+
if (!PowerShell.ShouldProcess($"[Project: {repo.ProjectReference.Name}]/[Repository: {repo.Name}]/[Branch: {branch.Name}]", $"Delete branch")) continue;
2020

2121
try
2222
{

CSharp/TfsCmdlets/Controllers/Git/RemoveGitRepositoryController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ protected override IEnumerable Run()
1111

1212
foreach (var repo in Items)
1313
{
14-
if (!PowerShell.ShouldProcess(Project, $"Delete Git repository '{repo.Name}'")) continue;
14+
if (!PowerShell.ShouldProcess($"[Project: {repo.ProjectReference.Name}]/[Repository: {repo.Name}]", $"Delete repository")) continue;
1515

16-
if (!Force && !PowerShell.ShouldContinue($"Are you sure you want to delete Git repository '{repo.Name}'?")) continue;
16+
if (!(repo.DefaultBranch == null || Force) && !PowerShell.ShouldContinue($"Are you sure you want to delete Git repository '{repo.Name}'?")) continue;
1717

1818
client.DeleteRepositoryAsync(repo.Id).Wait();
1919
}

CSharp/TfsCmdlets/Controllers/Identity/Group/RemoveGroupController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ protected override IEnumerable Run()
1212

1313
foreach (var group in Items)
1414
{
15-
if (!PowerShell.ShouldProcess($"Group '{group.PrincipalName}'", "Remove group")) continue;
15+
if (!PowerShell.ShouldProcess(group.PrincipalName, "Remove group")) continue;
1616

1717
client.DeleteGroupAsync(group.Descriptor)
1818
.Wait($"Error removing group '{group.PrincipalName}'");

CSharp/TfsCmdlets/Controllers/Identity/Group/RemoveGroupMemberController.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ protected override IEnumerable Run()
2424

2525
Logger.Log($"Adding {m.IdentityType} '{m.DisplayName} ({m.UniqueName})' to group '{g.DisplayName}'");
2626

27-
if (!PowerShell.ShouldProcess($"Group '{g.DisplayName}'",
28-
$"Remove member '{m.DisplayName} ({m.UniqueName})'")) return null;
27+
if (!PowerShell.ShouldProcess($"[Group: {g.DisplayName}]/[Member: '{m.DisplayName} ({m.UniqueName})']", "Remove member")) return null;
2928

30-
Logger.Log($"Removing '{m.DisplayName} ({m.UniqueName}))' from group '{g.DisplayName}'");
29+
Logger.Log($"Removing '{m.DisplayName} ({m.UniqueName})' from group '{g.DisplayName}'");
3130

3231
client.RemoveMemberFromGroupAsync(g.Descriptor, m.Descriptor)
3332
.GetResult($"Error removing '{m.DisplayName} ({m.UniqueName}))' from group '{g.DisplayName}'");

CSharp/TfsCmdlets/Controllers/Pipeline/ReleaseManagement/RemoveReleaseDefinitionFolderController.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ protected override IEnumerable Run()
1919

2020
foreach (var f in folders)
2121
{
22-
if (!PowerShell.ShouldProcess(tp, $"Remove release folder '{f.Path}'"))
23-
{
24-
continue;
25-
}
22+
if (!PowerShell.ShouldProcess($"[Project: {tp.Name}]/[Folder: {f.Path}]", "Remove release definition folder")) continue;
2623

2724
if (!recurse)
2825
{

0 commit comments

Comments
 (0)