diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 78c1ab5..d371583 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,4 +2,12 @@ Version 0.6 introduces table order options ## New features -- Repos in the table can now be sorted either alphabetically or according to their last modification. Ascending as well as descending can be set as options. \ No newline at end of file +### Sorting + +Repos in the table can now be sorted either alphabetically or according to their last modification. +Ascending as well as descending can be set as options. + +### Only show changed + +New option "OnlyShowChanged" allows to only print repos that have either a changed Git status or a HEAD that ponts to a branch that is not default. +Default branches are configurable. \ No newline at end of file diff --git a/src/RepoStatusTable/CellProviders/Cell.cs b/src/RepoStatusTable/CellProviders/Cell.cs index 1d524ef..740e7a6 100644 --- a/src/RepoStatusTable/CellProviders/Cell.cs +++ b/src/RepoStatusTable/CellProviders/Cell.cs @@ -1,11 +1,3 @@ namespace RepoStatusTable.CellProviders; -public class Cell -{ - public Cell( string content ) - { - Content = content; - } - - public string Content { get; } -} \ No newline at end of file +public record Cell( string Content, bool IsChanged = true ); \ No newline at end of file diff --git a/src/RepoStatusTable/CellProviders/GitBranchProvider.cs b/src/RepoStatusTable/CellProviders/GitBranchProvider.cs index a7854f9..afc625c 100644 --- a/src/RepoStatusTable/CellProviders/GitBranchProvider.cs +++ b/src/RepoStatusTable/CellProviders/GitBranchProvider.cs @@ -25,7 +25,13 @@ public Task GetCell( string path ) var branchName = _gitFacade.GetCurrentBranch( path ); return Task.FromResult( new Cell( - branchName + branchName, + IsChanged( branchName ) ) ); } + + private bool IsChanged( string branch ) + { + return _options.DefaultBranches.Contains( branch ); + } } \ No newline at end of file diff --git a/src/RepoStatusTable/CellProviders/GitStatusProvider.cs b/src/RepoStatusTable/CellProviders/GitStatusProvider.cs index 8b778e3..4d2a1a4 100644 --- a/src/RepoStatusTable/CellProviders/GitStatusProvider.cs +++ b/src/RepoStatusTable/CellProviders/GitStatusProvider.cs @@ -25,12 +25,12 @@ public Task GetCell( string directory ) var status = _gitFacade.GetStatus( directory ); return Task.FromResult( - new Cell( GetStatusDescription( status ) ) ); + new Cell( GetStatusDescription( status ), IsStatusChanged( status ) ) ); } private static bool IsStatusChanged( IDictionary status ) { - return !status.All( v => v.Value == 0 ); + return status.Any( v => v.Value != 0 ); } private static string GetStatusDescription( IDictionary status ) diff --git a/src/RepoStatusTable/CellProviders/ICellProvider.cs b/src/RepoStatusTable/CellProviders/ICellProvider.cs index 4461963..879e7f3 100644 --- a/src/RepoStatusTable/CellProviders/ICellProvider.cs +++ b/src/RepoStatusTable/CellProviders/ICellProvider.cs @@ -7,7 +7,6 @@ public interface ICellProvider /// public string Heading { get; } - /// /// Determine whether the output of the cell provider should be shown in the output model /// diff --git a/src/RepoStatusTable/DependencyInjection/OptionsBindings.cs b/src/RepoStatusTable/DependencyInjection/OptionsBindings.cs index 3439232..721df1d 100644 --- a/src/RepoStatusTable/DependencyInjection/OptionsBindings.cs +++ b/src/RepoStatusTable/DependencyInjection/OptionsBindings.cs @@ -28,7 +28,7 @@ private void AddOptionsSections( IConfiguration configurationRoot ) _collection.AddOptions() .Bind( configurationRoot.GetSection( OptionsConstants.Headline ) ) .ValidateDataAnnotations(); - _collection.AddOptions() + _collection.AddOptions() .Bind( configurationRoot.GetSection( OptionsConstants.Table ) ); // Spectre Console diff --git a/src/RepoStatusTable/Model/ITableModel.cs b/src/RepoStatusTable/Model/ITableModel.cs index 2fd0b3d..5a89b0b 100644 --- a/src/RepoStatusTable/Model/ITableModel.cs +++ b/src/RepoStatusTable/Model/ITableModel.cs @@ -18,5 +18,5 @@ public interface ITableModel /// /// Table as a list of rows each containing cells /// - IAsyncEnumerable> GetTableAsync(); + IAsyncEnumerable> GetTableAsync(); } \ No newline at end of file diff --git a/src/RepoStatusTable/Model/TableModel.cs b/src/RepoStatusTable/Model/TableModel.cs index 5d40056..c50504b 100644 --- a/src/RepoStatusTable/Model/TableModel.cs +++ b/src/RepoStatusTable/Model/TableModel.cs @@ -1,4 +1,5 @@ using RepoStatusTable.CellProviders; +using RepoStatusTable.Options; using RepoStatusTable.Utilities; namespace RepoStatusTable.Model; @@ -7,11 +8,14 @@ public class TableModel : ITableModel { private readonly IEnumerable _cellProviders; private readonly IReposDirectoryUtility _reposDirectoryUtility; + private readonly TableOptions _tableOptions; - public TableModel( ICellProviderManager cellProviderManager, IReposDirectoryUtility reposDirectoryUtility ) + public TableModel( ICellProviderManager cellProviderManager, IReposDirectoryUtility reposDirectoryUtility, + IOptions tableOptions ) { _cellProviders = cellProviderManager.GetOrderedListOfEnabledCellProviders(); _reposDirectoryUtility = reposDirectoryUtility; + _tableOptions = tableOptions.Value; } public IEnumerable GetHeadings() @@ -19,22 +23,26 @@ public IEnumerable GetHeadings() return _cellProviders.Select( p => p.Heading ); } - public async IAsyncEnumerable> GetTableAsync() + public async IAsyncEnumerable> GetTableAsync() { if ( !_cellProviders.Any() ) { throw new ArgumentException( "No cell providers are enabled" ); } - foreach ( var dir in _reposDirectoryUtility.GetRepoDirectories() ) yield return GetRowsAsync( dir ); + foreach ( var dir in _reposDirectoryUtility.GetRepoDirectories() ) + { + var row = ( await GetRowAsync( dir ) ).ToList(); + if ( _tableOptions.OnlyShowChanged == false || row.Any( r => r.IsChanged ) ) + { + yield return row.Select( r => r.Content ); + } + } } - private async IAsyncEnumerable GetRowsAsync( string path ) + private async Task> GetRowAsync( string path ) { - foreach ( var provider in _cellProviders ) - { - var cell = await provider.GetCell( path ); - yield return cell.Content; - } + var cellTasks = _cellProviders.Select( p => p.GetCell( path ) ); + return await Task.WhenAll( cellTasks ); } } \ No newline at end of file diff --git a/src/RepoStatusTable/Options/CellProvider/GitBranchProviderOptions.cs b/src/RepoStatusTable/Options/CellProvider/GitBranchProviderOptions.cs index 9fc6700..4c67f4c 100644 --- a/src/RepoStatusTable/Options/CellProvider/GitBranchProviderOptions.cs +++ b/src/RepoStatusTable/Options/CellProvider/GitBranchProviderOptions.cs @@ -4,6 +4,11 @@ namespace RepoStatusTable.Options.CellProvider; [SuppressMessage( "ReSharper", "AutoPropertyCanBeMadeGetOnly.Global" )] public class GitBranchProviderOptions : ICellProviderOptions { + /// + /// List of branches that are considered as not changed + /// + public IEnumerable DefaultBranches { get; set; } = new List(); + /// public bool Enable { get; set; } = true; diff --git a/src/RepoStatusTable/Options/TableViewOptions.cs b/src/RepoStatusTable/Options/TableOptions.cs similarity index 55% rename from src/RepoStatusTable/Options/TableViewOptions.cs rename to src/RepoStatusTable/Options/TableOptions.cs index e737f80..eb1220d 100644 --- a/src/RepoStatusTable/Options/TableViewOptions.cs +++ b/src/RepoStatusTable/Options/TableOptions.cs @@ -1,6 +1,8 @@ namespace RepoStatusTable.Options; -public class TableViewOptions +public class TableOptions { public string RenderMethod { get; set; } = "Spectre Table"; + + public bool OnlyShowChanged { get; set; } = false; } \ No newline at end of file diff --git a/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewDefault.cs b/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewDefault.cs index 3bb09b8..d9f67ab 100644 --- a/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewDefault.cs +++ b/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewDefault.cs @@ -34,7 +34,7 @@ private async Task RenderRows( Table table ) { await foreach ( var row in _tableModel.GetTableAsync() ) { - var tableRow = await row.ToArrayAsync(); + var tableRow = row.ToArray(); table.AddRow( tableRow ); } } diff --git a/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewLive.cs b/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewLive.cs index a429c7c..7f9e46b 100644 --- a/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewLive.cs +++ b/src/RepoStatusTable/View/SpectreConsoleTableView/SpectreConsoleTableViewLive.cs @@ -42,7 +42,7 @@ private async Task RenderRows( Table table, LiveDisplayContext ctx ) { await foreach ( var row in _tableModel.GetTableAsync() ) { - var tableRow = await row.ToArrayAsync(); + var tableRow = row.ToArray(); table.AddRow( tableRow ); ctx.Refresh(); } diff --git a/src/RepoStatusTable/View/TableViewProxy.cs b/src/RepoStatusTable/View/TableViewProxy.cs index 12130e9..da956a6 100644 --- a/src/RepoStatusTable/View/TableViewProxy.cs +++ b/src/RepoStatusTable/View/TableViewProxy.cs @@ -4,10 +4,10 @@ namespace RepoStatusTable.View; public class TableViewProxy : ITableView { - private readonly TableViewOptions _options; + private readonly TableOptions _options; private readonly IEnumerable _tableViewStrategies; - public TableViewProxy( IOptions options, IEnumerable tableViewStrategies ) + public TableViewProxy( IOptions options, IEnumerable tableViewStrategies ) { _tableViewStrategies = tableViewStrategies; _options = options.Value; diff --git a/src/RepoStatusTable/exampleconfig.json b/src/RepoStatusTable/exampleconfig.json index 156df3d..61af680 100644 --- a/src/RepoStatusTable/exampleconfig.json +++ b/src/RepoStatusTable/exampleconfig.json @@ -24,6 +24,7 @@ }, "Table": { "RenderMethod": "Spectre Table Live", + "OnlyShowChanged": false, "SpectreConsoleTable": { "Alignment": "Center", "Border": "Horizontal", @@ -41,7 +42,11 @@ }, "GitBranchProvider": { "Position": 1, - "Enable": true + "Enable": true, + "DefaultBranches": [ + "develop", + "master" + ] }, "FileContentProvider": { "Position": 2, diff --git a/test/RepoStatusTable.IntegrationTests/DependencyInjection/TestServiceProviderBuilder.cs b/test/RepoStatusTable.IntegrationTests/DependencyInjection/TestServiceProviderBuilder.cs index 6486c82..0afdf74 100644 --- a/test/RepoStatusTable.IntegrationTests/DependencyInjection/TestServiceProviderBuilder.cs +++ b/test/RepoStatusTable.IntegrationTests/DependencyInjection/TestServiceProviderBuilder.cs @@ -110,7 +110,7 @@ private void AddOptionsSections( IConfiguration configurationRoot ) _collection.AddOptions() .Bind( configurationRoot.GetSection( OptionsConstants.Headline ) ) .ValidateDataAnnotations(); - _collection.AddOptions() + _collection.AddOptions() .Bind( configurationRoot.GetSection( OptionsConstants.Table ) ); // Spectre Console diff --git a/test/RepoStatusTable.IntegrationTests/ViewAsserters/TableViewAsserter.cs b/test/RepoStatusTable.IntegrationTests/ViewAsserters/TableViewAsserter.cs index 2b052de..8ffceda 100644 --- a/test/RepoStatusTable.IntegrationTests/ViewAsserters/TableViewAsserter.cs +++ b/test/RepoStatusTable.IntegrationTests/ViewAsserters/TableViewAsserter.cs @@ -27,7 +27,7 @@ public async Task RenderAsync() { var headings = _tableModel.GetHeadings().ToList(); var enumTable = await _tableModel.GetTableAsync().ToListAsync(); - var table = await Task.WhenAll( enumTable.Select( async r => await r.ToListAsync() ) ); + var table = enumTable.Select( r => r.ToList() ); AssertHeadings( headings ); AssertTable( table );