Skip to content

Commit

Permalink
feat(lfs): Support building directory structure representation (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
skarllot authored Dec 27, 2024
1 parent 5bf58b5 commit 3509e28
Show file tree
Hide file tree
Showing 13 changed files with 593 additions and 47 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ jobs:
dotnetbuilds.azureedge.net:443
dotnetcli.azureedge.net:443
github.com:443
ingest.codecov.io:443
keybase.io:443
objects.githubusercontent.com:443
production.cloudflare.docker.com:443
registry-1.docker.io:443
storage.googleapis.com:443
- name: 🛒 Checkout
Expand Down Expand Up @@ -86,6 +86,11 @@ jobs:
- name: ✅ Test
run: dotnet test --no-build --verbosity normal -p:CollectCoverage=true -p:CoverletOutputFormat=opencover

- name: ☂️ Upload coverage reports to Codecov
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

- name: ✅ Test Publish
run: |
dotnet publish --no-restore -r ${{ matrix.os }}-${{ matrix.arch }} -c Debug
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
_FlowPair provides automated code review and feedback using CI&T Flow AI through a command-line interface._

[![Build status](https://github.com/skarllot/flow-pair/actions/workflows/dotnet.yml/badge.svg?branch=main)](https://github.com/skarllot/flow-pair/actions)
[![GitHub Release](https://img.shields.io/github/v/release/skarllot/flow-pair)](https://github.com/skarllot/flow-pair/releases)
[![GitHub release](https://img.shields.io/github/v/release/skarllot/flow-pair)](https://github.com/skarllot/flow-pair/releases)
[![Code coverage](https://codecov.io/gh/skarllot/flow-pair/graph/badge.svg?token=XQ7SBGPS89)](https://codecov.io/gh/skarllot/flow-pair)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://raw.githubusercontent.com/skarllot/flow-pair/main/LICENSE)

<hr />
Expand Down
2 changes: 2 additions & 0 deletions src/FlowPair/DependencyInjection/AppContainer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Ciandt.FlowTools.FlowPair.Agent.Infrastructure;
using Ciandt.FlowTools.FlowPair.Flow.Infrastructure;
using Ciandt.FlowTools.FlowPair.Git.Infrastructure;
using Ciandt.FlowTools.FlowPair.LocalFileSystem.Infrastructure;
using Ciandt.FlowTools.FlowPair.Settings.Infrastructure;
using Ciandt.FlowTools.FlowPair.UserSessions.Infrastructure;
using Jab;
Expand All @@ -14,4 +15,5 @@ namespace Ciandt.FlowTools.FlowPair.DependencyInjection;
[Import(typeof(IFlowModule))]
[Import(typeof(IAgentModule))]
[Import(typeof(IExternalModule))]
[Import(typeof(ILocalFileSystemModule))]
public sealed partial class AppContainer;
30 changes: 6 additions & 24 deletions src/FlowPair/Git/GetChanges/GitGetChangesHandler.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Immutable;
using System.IO.Abstractions;
using AutomaticInterface;
using Ciandt.FlowTools.FlowPair.Common;
using Ciandt.FlowTools.FlowPair.LocalFileSystem.Services;
using LibGit2Sharp;
using Spectre.Console;

Expand All @@ -11,20 +11,20 @@ public partial interface IGitGetChangesHandler;

[GenerateAutomaticInterface]
public class GitGetChangesHandler(
IFileSystem fileSystem,
IAnsiConsole console)
IAnsiConsole console,
IWorkingDirectoryWalker workingDirectoryWalker)
: IGitGetChangesHandler
{
public Option<ImmutableList<FileChange>> Extract(string? path, string? commit)
{
path = TryFindRepository(fileSystem, path).UnwrapOrNull();
if (path is null)
var gitRootDir = workingDirectoryWalker.TryFindRepositoryRoot(path).UnwrapOrNull();
if (gitRootDir is null)
{
console.MarkupLine("[red]Error:[/] Could not locate Git repository.");
return None;
}

using var repo = new Repository(path);
using var repo = new Repository(gitRootDir.FullName);
var builder = ImmutableList.CreateBuilder<FileChange>();

if (!string.IsNullOrEmpty(commit))
Expand Down Expand Up @@ -102,22 +102,4 @@ private static void FillChangesFromLastCommit(Repository repo, ImmutableList<Fil
builder.Add(new FileChange(changes.Path, changes.Patch));
}
}

private static Option<string> TryFindRepository(IFileSystem fileSystem, string? path)
{
var currentDirectory = fileSystem.DirectoryInfo.New(path ?? fileSystem.Directory.GetCurrentDirectory());
while (currentDirectory != null)
{
if (currentDirectory
.EnumerateDirectories(".git", SearchOption.TopDirectoryOnly)
.Any())
{
return currentDirectory.FullName;
}

currentDirectory = currentDirectory.Parent;
}

return None;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.Frozen;
using System.Globalization;
using System.IO.Abstractions;
using System.Text;
using AutomaticInterface;

namespace Ciandt.FlowTools.FlowPair.LocalFileSystem.GetDirectoryStructure;

public partial interface IGetDirectoryStructureHandler;

[GenerateAutomaticInterface]
public sealed class GetDirectoryStructureHandler
: IGetDirectoryStructureHandler
{
private static readonly FrozenSet<string> s_ignoreList =
[
"__pycache__", "artifacts", "bin", "blib", "build", "cache", "dist", "node_modules", "obj", "out", "pkg",
"Pods", "project", "publish", "target", "vendor", "venv", "xcuserdata"
];

public string Execute(IDirectoryInfo directoryInfo)
{
var result = new StringBuilder();
FillDirectories(result, directoryInfo, 0);
return result.ToString();
}

private static void FillDirectories(StringBuilder builder, IDirectoryInfo directoryInfo, int level)
{
PrintLevel(builder, level);
builder.Append(CultureInfo.InvariantCulture, $"{directoryInfo.Name}/");

foreach (var item in directoryInfo.EnumerateDirectories().Where(IsUserDirectory))
{
FillDirectories(builder, item, level + 1);
}
}

private static bool IsUserDirectory(IDirectoryInfo x)
{
return !x.Name.StartsWith('.') && !s_ignoreList.Contains(x.Name);
}

private static void PrintLevel(StringBuilder builder, int level)
{
if (level == 0)
return;

builder.AppendLine();
builder.Append(string.Join(null, Enumerable.Repeat("| ", level - 1)));
builder.Append("|-- ");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Ciandt.FlowTools.FlowPair.LocalFileSystem.GetDirectoryStructure;
using Ciandt.FlowTools.FlowPair.LocalFileSystem.Services;
using Jab;

namespace Ciandt.FlowTools.FlowPair.LocalFileSystem.Infrastructure;

[ServiceProviderModule]
[Singleton(typeof(IWorkingDirectoryWalker), typeof(WorkingDirectoryWalker))]
[Singleton(typeof(IGetDirectoryStructureHandler), typeof(GetDirectoryStructureHandler))]
public interface ILocalFileSystemModule;
35 changes: 35 additions & 0 deletions src/FlowPair/LocalFileSystem/Services/WorkingDirectoryWalker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.IO.Abstractions;
using AutomaticInterface;

namespace Ciandt.FlowTools.FlowPair.LocalFileSystem.Services;

public partial interface IWorkingDirectoryWalker;

[GenerateAutomaticInterface]
public sealed class WorkingDirectoryWalker(
IFileSystem fileSystem)
: IWorkingDirectoryWalker
{
public Option<IDirectoryInfo> TryFindRepositoryRoot(string? path)
{
var currentDirectory = fileSystem.DirectoryInfo.New(path ?? fileSystem.Directory.GetCurrentDirectory());
if (!currentDirectory.Exists)
{
return None;
}

while (currentDirectory != null)
{
if (currentDirectory
.EnumerateDirectories(".git", SearchOption.TopDirectoryOnly)
.Any())
{
return Some(currentDirectory);
}

currentDirectory = currentDirectory.Parent;
}

return None;
}
}
4 changes: 4 additions & 0 deletions tests/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageVersion>
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
<PackageVersion Include="FxKit.Testing" Version="0.8.3" />
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="21.1.7" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
44 changes: 24 additions & 20 deletions tests/FlowPair.Tests/FlowPair.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\FlowPair\FlowPair.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" />
<PackageReference Include="coverlet.msbuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" />
<PackageReference Include="coverlet.msbuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="FxKit.Testing" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
Loading

0 comments on commit 3509e28

Please sign in to comment.