diff --git a/.azuredevops/Pipelines/build.yaml b/.azuredevops/Pipelines/build.yaml index 17a4a2aa..582b474a 100644 --- a/.azuredevops/Pipelines/build.yaml +++ b/.azuredevops/Pipelines/build.yaml @@ -157,32 +157,21 @@ stages: displayName: "Dotnet Publish RepoM" inputs: command: publish - # arguments: "--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/${{ variables.SystemTestsArtifactName }}/bin/Release/publish --no-build --self-contained true" arguments: "--configuration $(buildConfiguration) --output _output/Win/Assemblies" projects: "**/RepoM.App.csproj" publishWebProjects: false modifyOutputPath: false zipAfterPublish: false - - task: DotNetCoreCLI@2 - displayName: "Dotnet Publish grr tool" - inputs: - command: publish - arguments: "--configuration $(buildConfiguration) --output _output/Win/Assemblies --self-contained true --runtime win-x64" - projects: "**/Grr.App.csproj" - publishWebProjects: false - modifyOutputPath: false - zipAfterPublish: false - - - task: DotNetCoreCLI@2 - displayName: "Dotnet Publish grrui tool" - inputs: - command: publish - arguments: "--configuration $(buildConfiguration) --output _output/Win/Assemblies --self-contained true --runtime win-x64" - projects: "**/GrrUi.App.csproj" - publishWebProjects: false - modifyOutputPath: false - zipAfterPublish: false + # - task: DotNetCoreCLI@2 + # displayName: "Dotnet Publish grr tool" + # inputs: + # command: publish + # arguments: "--configuration $(buildConfiguration) --output _output/Win/Assemblies --self-contained true --runtime win-x64" + # projects: "**/Grr.App.csproj" + # publishWebProjects: false + # modifyOutputPath: false + # zipAfterPublish: false - task: DeleteFiles@1 displayName: 'Remove unneeded files' diff --git a/README.md b/README.md index 9680d842..47e686c2 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,19 @@ -# RepoM ~~RepoZ~~ +# RepoM -RepoZ is a zero-conf git repository hub with Windows Explorer- & CLI-enhancements. It uses the git repositories on your machine to create an efficient navigation widget and makes sure you'll never lose track of your work along the way. +RepoM is a minimal-conf git repository hub with Windows Explorer enhancements. It uses the git repositories on your machine to create an efficient navigation widget and makes sure you'll never lose track of your work along the way. It's populating itself as you work with git. It does not get in the way and does not require any user attention to work. -RepoZ will not compete with your favourite git clients, so keep them. It's not about working within a repository: It's a new way to use all of your repositories to make your daily work easier. +Repo< will not compete with your favourite git clients, so keep them. It's not about working within a repository: It's a new way to use all of your repositories to make your daily work easier. πŸ“¦ [Check the Releases page](https://github.com/coenm/RepoM/releases) to **download** the latest version and see **what's new**! -~~🍫 Available on [chocolatey](https://chocolatey.org/packages/repoz) as well, just use `choco install repoz`.~~ - ## The Hub -The hub provides a quick overview of your repositories including their current branch and a short status information. Additionally, it offers some shortcuts like revealing a repository in the Windows Explorer or macOS Finder, opening a command line tool in a given repository and checking out git branches. -RepoZ is available for Windows and macOS. +The hub provides a quick overview of your repositories including their current branch and a short status information. Additionally, it offers some shortcuts like revealing a repository in the Windows Explorer, opening a command line tool in a given repository and checking out git branches. ![Screenshot](https://raw.githubusercontent.com/awaescher/RepoZ/master/_doc/RepoZ-ReadMe-UI-Both.png) - > **"Well ok, that's a neat summary ..."** you might say **"... but how does this help?"**. If you are working on different git repositories throughout the day, you might find yourself wasting time by permanently switching over from one repository to another. If you are like me, you tend to keep all those windows open to be reused later, ending up on a window list which has to be looped through all the time. @@ -26,37 +22,16 @@ With RepoZ, you can instantly jump into a given repository with a file browser o ![Navigation](https://raw.githubusercontent.com/awaescher/RepoZ/master/_doc/QuickNavigation.gif) -For Windows, use the hotkeys Ctrl+Alt+R to show RepoZ. On Mac it's Command+Alt+R*. +For Windows, use the hotkeys Ctrl+Alt+R to show RepoM. To open a file browser, simply press Return on the keyboard once you selected a repository. To open a command prompt instead, hold Ctrl on Windows or Command on macOS while pressing Return. These modifier keys will also work with mouse navigation. -* On Mac you need to give RepoZ access to the [keyboard events in the system privacy settings](http://mizage.com/help/accessibility.html). Once you have done this, you might need to restart the app. - -## Command Line Sidekick -RepoZ is a UI-centered tool but comes with a sidekick app called **grr** to empower the command line hackers. -With **grr**, the information from RepoZ can be brought to any command line tool. - -It supports ... - - listing all repositories found in RepoZ including their branch and status information - - filtering for repository [names, branches or paths](https://github.com/awaescher/RepoZ/issues/68#issuecomment-478764341) (to list or jump) by RegEx patterns, like `grr [M.*]` - - jumping directly to a repository path by adding the `cd` command, like `grr cd MyRepo` - - opening a file browser in a repository from anywhere in your command prompt with `grr open MyRepo` - - list files in a repository following a pattern with `grr list MyRepo *.sln` (add `-r` for recursive search) - - open files in a repository directly with `grr open MyRepo *.sln` (add `-e` for elevated mode, "as Admin") - -See it in action in a ([styled](https://github.com/awaescher/PoshX)) powershell console: - -![Screenshot](https://raw.githubusercontent.com/awaescher/RepoZ/master/_doc/grr-5fps-compressed.gif) - -#### Don't forget to have a look at `grr help` once you get your hands on. - ## Enhanced Windows Explorer Titles + As an extra goodie for Windows users, RepoZ automatically detects open File Explorer windows and adds a status appendix to their title if they are in context of a git repository. ![Screenshot](https://raw.githubusercontent.com/awaescher/RepoZ/master/_doc/RepoZ-ReadMe-Explorer.png) -## Dependencies ⚠︎ -Some user [reported crashes at program start](https://github.com/awaescher/RepoZ/issues/83). Please make sure to install the [.NET Framework Runtime v4.7.2](http://go.microsoft.com/fwlink/?LinkId=863262) if you experience similar issues. - ## Credits -The **grr** app icon was made by Freepik from www.flaticon.com and is licensed by CC 3.0 BY + +RepoM is a fork of the amazing RepoZ, which was created by [Screenshot](https://github.com/awaescher/RepoZ). diff --git a/RepoM.sln b/RepoM.sln index 1d3255e2..5802ec6e 100644 --- a/RepoM.sln +++ b/RepoM.sln @@ -9,12 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.App", "src\RepoM.App\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Specs", "tests\Specs\Specs.csproj", "{C91C3255-637F-45D4-93C0-6A26B4E99FC1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrrUi.App", "src\GrrUi.App\GrrUi.App.csproj", "{350BAB52-335E-4D14-B46A-9A6CF0786519}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Ipc", "src\RepoM.Ipc\RepoM.Ipc.csproj", "{B38E49E8-4691-4D3B-982E-41F8E8B527E3}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grr.App", "src\Grr.App\Grr.App.csproj", "{D5772395-C27C-4BB5-86DA-42DF7388A19B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Api", "src\RepoM.Api\RepoM.Api.csproj", "{699FA61D-A44D-4710-A6DD-52016DAC51D7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.LuceneSearch", "src\RepoM.Plugin.LuceneSearch\RepoM.Plugin.LuceneSearch.csproj", "{409FE957-77C4-40E9-80F2-EBE26676645E}" @@ -25,8 +19,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.WindowsExplore EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{D6E372DC-10D3-4997-9DFC-568B4666635A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.IpcService", "src\RepoM.Plugin.IpcService\RepoM.Plugin.IpcService.csproj", "{01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.EverythingFileSearch", "src\RepoM.Plugin.EverythingFileSearch\RepoM.Plugin.EverythingFileSearch.csproj", "{C85EAF73-3491-4C67-9047-B677CC999184}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.SonarCloud", "src\RepoM.Plugin.SonarCloud\RepoM.Plugin.SonarCloud.csproj", "{F780A2C4-0DAD-4DAA-AF2E-7B35683535EB}" @@ -39,8 +31,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.AzureDevOps.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Api.Tests", "tests\RepoM.Api.Tests\RepoM.Api.Tests.csproj", "{A798CB57-4743-4486-BF0E-93F7563A542B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Ipc.Tests", "tests\RepoM.Ipc.Tests\RepoM.Ipc.Tests.csproj", "{82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Core.Plugin", "src\RepoM.Core.Plugin\RepoM.Core.Plugin.csproj", "{E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}" EndProject Global @@ -117,66 +107,6 @@ Global {C91C3255-637F-45D4-93C0-6A26B4E99FC1}.Release|x64.Build.0 = Release|Any CPU {C91C3255-637F-45D4-93C0-6A26B4E99FC1}.Release|x86.ActiveCfg = Release|Any CPU {C91C3255-637F-45D4-93C0-6A26B4E99FC1}.Release|x86.Build.0 = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|Any CPU.Build.0 = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|ARM.ActiveCfg = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|ARM.Build.0 = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|ARM64.Build.0 = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|x64.ActiveCfg = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|x64.Build.0 = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|x86.ActiveCfg = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Debug|x86.Build.0 = Debug|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|Any CPU.ActiveCfg = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|Any CPU.Build.0 = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|ARM.ActiveCfg = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|ARM.Build.0 = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|ARM64.ActiveCfg = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|ARM64.Build.0 = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|x64.ActiveCfg = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|x64.Build.0 = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|x86.ActiveCfg = Release|Any CPU - {350BAB52-335E-4D14-B46A-9A6CF0786519}.Release|x86.Build.0 = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|ARM.Build.0 = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|ARM64.Build.0 = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|x64.ActiveCfg = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|x64.Build.0 = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|x86.ActiveCfg = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Debug|x86.Build.0 = Debug|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|Any CPU.Build.0 = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|ARM.ActiveCfg = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|ARM.Build.0 = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|ARM64.ActiveCfg = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|ARM64.Build.0 = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|x64.ActiveCfg = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|x64.Build.0 = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|x86.ActiveCfg = Release|Any CPU - {B38E49E8-4691-4D3B-982E-41F8E8B527E3}.Release|x86.Build.0 = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|ARM.Build.0 = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|ARM64.Build.0 = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|x64.ActiveCfg = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|x64.Build.0 = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|x86.ActiveCfg = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Debug|x86.Build.0 = Debug|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|Any CPU.Build.0 = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|ARM.ActiveCfg = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|ARM.Build.0 = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|ARM64.ActiveCfg = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|ARM64.Build.0 = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|x64.ActiveCfg = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|x64.Build.0 = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|x86.ActiveCfg = Release|Any CPU - {D5772395-C27C-4BB5-86DA-42DF7388A19B}.Release|x86.Build.0 = Release|Any CPU {699FA61D-A44D-4710-A6DD-52016DAC51D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {699FA61D-A44D-4710-A6DD-52016DAC51D7}.Debug|Any CPU.Build.0 = Debug|Any CPU {699FA61D-A44D-4710-A6DD-52016DAC51D7}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -257,26 +187,6 @@ Global {6214312F-61F1-4F4C-A9E2-3383987DE266}.Release|x64.Build.0 = Release|Any CPU {6214312F-61F1-4F4C-A9E2-3383987DE266}.Release|x86.ActiveCfg = Release|Any CPU {6214312F-61F1-4F4C-A9E2-3383987DE266}.Release|x86.Build.0 = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|ARM.ActiveCfg = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|ARM.Build.0 = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|ARM64.Build.0 = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|x64.ActiveCfg = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|x64.Build.0 = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|x86.ActiveCfg = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Debug|x86.Build.0 = Debug|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|Any CPU.Build.0 = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|ARM.ActiveCfg = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|ARM.Build.0 = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|ARM64.ActiveCfg = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|ARM64.Build.0 = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|x64.ActiveCfg = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|x64.Build.0 = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|x86.ActiveCfg = Release|Any CPU - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE}.Release|x86.Build.0 = Release|Any CPU {C85EAF73-3491-4C67-9047-B677CC999184}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C85EAF73-3491-4C67-9047-B677CC999184}.Debug|Any CPU.Build.0 = Debug|Any CPU {C85EAF73-3491-4C67-9047-B677CC999184}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -397,26 +307,6 @@ Global {A798CB57-4743-4486-BF0E-93F7563A542B}.Release|x64.Build.0 = Release|Any CPU {A798CB57-4743-4486-BF0E-93F7563A542B}.Release|x86.ActiveCfg = Release|Any CPU {A798CB57-4743-4486-BF0E-93F7563A542B}.Release|x86.Build.0 = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|ARM.ActiveCfg = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|ARM.Build.0 = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|ARM64.Build.0 = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|x64.ActiveCfg = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|x64.Build.0 = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|x86.ActiveCfg = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Debug|x86.Build.0 = Debug|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|Any CPU.Build.0 = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|ARM.ActiveCfg = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|ARM.Build.0 = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|ARM64.ActiveCfg = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|ARM64.Build.0 = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|x64.ActiveCfg = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|x64.Build.0 = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|x86.ActiveCfg = Release|Any CPU - {82F7BFA8-E679-4CD7-BC46-DB53C9C226D2}.Release|x86.Build.0 = Release|Any CPU {E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -445,7 +335,6 @@ Global {409FE957-77C4-40E9-80F2-EBE26676645E} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {48ED60BB-E01F-4395-978E-D25C11C25E52} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {6214312F-61F1-4F4C-A9E2-3383987DE266} = {D6E372DC-10D3-4997-9DFC-568B4666635A} - {01F564A1-BA9F-4BC4-A3AF-D9CDE4B654DE} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {C85EAF73-3491-4C67-9047-B677CC999184} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {F780A2C4-0DAD-4DAA-AF2E-7B35683535EB} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {74B95BAF-0DB4-42C8-92EA-A364E8080809} = {D6E372DC-10D3-4997-9DFC-568B4666635A} diff --git a/RepoM.sln.DotSettings b/RepoM.sln.DotSettings index 64364c71..7f128dd7 100644 --- a/RepoM.sln.DotSettings +++ b/RepoM.sln.DotSettings @@ -2,7 +2,6 @@ True True True - True True True True diff --git a/_setup/RepoM.nsi b/_setup/RepoM.nsi index ef16f536..3fcfb916 100644 --- a/_setup/RepoM.nsi +++ b/_setup/RepoM.nsi @@ -52,7 +52,7 @@ Section "RepoM" File /r ..\_output\win\Assemblies\*.* File ..\_ref\PathEd.exe ; Add PathEd.exe to add the RepoM directory to the system's PATH easily - File ..\_ref\SendKeys.exe ; Add SendKeys.exe to add the RepoM directory for grr and grrui + ; File ..\_ref\SendKeys.exe ; Add SendKeys.exe to add the RepoM directory for grr. File ..\_ref\RepositoryActions.json ; Can be copied in-app for the default settings File ..\_ref\RepositoryActions.yaml ; Can be copied in-app for the default settings CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" $INSTDIR\${PRODUCT_NAME}.exe diff --git a/src/Grr.App/CommandLineOptions.cs b/src/Grr.App/CommandLineOptions.cs deleted file mode 100644 index 91755492..00000000 --- a/src/Grr.App/CommandLineOptions.cs +++ /dev/null @@ -1,144 +0,0 @@ -namespace Grr.App; - -using System; -using System.Linq; -using CommandLine; -using CommandLine.Text; - -[Verb("list", HelpText = "(Default) Lists the repositories found by RepoM including their current branch and the corresponding status. Can be omitted like shown in the examples below.")] -public class ListOptions : RepositoryFilterOptions { } - -[Verb("cd", HelpText = "Causes the command line interface to navigate to the directory of a given repository.")] -public class ChangeDirectoryOptions : RepositoryFilterOptions { } - -[Verb("gd", HelpText = "Returns the main directory of a given repository and puts it into the clipboard")] -public class GetDirectoryOptions : RepositoryFilterOptions { } - -[Verb("open", HelpText = "Opens the directory or a file of a given repository with the operating system's default application.")] -public class OpenDirectoryOptions : RepositoryFilterOptions { } - -partial class CommandLineOptions -{ - public const string LIST_COMMAND = "list"; - public const string CHANGE_DIRECTORY_COMMAND = "cd"; - public const string GET_DIRECTORY_COMMAND = "gd"; - public const string OPEN_DIRECTORY_COMMAND = "open"; - - public const string HELP_COMMAND = "help"; - public const char HELP_COMMAND_CHAR = '?'; - - public static string[] GetKnownCommands() - { - return new string[] - { - LIST_COMMAND, - CHANGE_DIRECTORY_COMMAND, - GET_DIRECTORY_COMMAND, - OPEN_DIRECTORY_COMMAND, - HELP_COMMAND, - HELP_COMMAND_CHAR.ToString(), - }; - } - - public static bool IsKnownArgument(string arg) - { - arg = arg.TrimStart('-').TrimStart('/'); - return GetKnownCommands().Contains(arg, StringComparer.OrdinalIgnoreCase); - } - - public static string GetUsage() - { - var help = new HelpText - { - Heading = HeadingInfo.Default, - Copyright = CopyrightInfo.Default, - AdditionalNewLineAfterOption = true, - AddDashesToOption = false, - MaximumDisplayWidth = 100 - }; - - var knownCommandsPiped = string.Join("|", GetKnownCommands()); - help.AddPreOptionsLine(" "); - help.AddPreOptionsLine(" "); - help.AddPreOptionsLine("USAGE:"); - help.AddPreOptionsLine($" grr [{knownCommandsPiped}] [repository filter or RegEx pattern] [file filter] [file options]"); - help.AddPreOptionsLine(" "); - help.AddPreOptionsLine(" "); - help.AddPreOptionsLine(" "); - - help.AddPreOptionsLine("COMMANDS:"); - help.AddVerbs(typeof(ListOptions), typeof(ChangeDirectoryOptions), typeof(OpenDirectoryOptions)); - - help.AddPostOptionsLine(" "); - help.AddPostOptionsLine("FILTERS:"); - help.AddPostOptionsLine("⁞ Repository filter or RegEx pattern:"); - help.AddPostOptionsLine("⁞ The filter pattern to find matching repositories with a like search."); - help.AddPostOptionsLine("⁞ If a like search is too broad, use a RegEx pattern instead by adding square brackets."); - help.AddPostOptionsLine("⁞ Like [.*Z] for all repositories ending with \"Z\"."); - help.AddPostOptionsLine("⁞ Note that you should put the filter or RegEx pattern in quotes if it contains spaces."); - help.AddPostOptionsLine("⁞"); - help.AddPostOptionsLine("⁞ File name or filter:"); - help.AddPostOptionsLine("⁞ The filter pattern to find matching files of a given repository with a like search."); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("OPTIONS:"); - help.AddPostOptionsLine("⁞ --recursive or -r:"); - help.AddPostOptionsLine("⁞ Enables recursive search in subdirectories of a given Git repository."); - help.AddPostOptionsLine("⁞ Compatible with commands: \"list\" and \"open\""); - help.AddPostOptionsLine("⁞"); - help.AddPostOptionsLine("⁞ --elevated or -e:"); - help.AddPostOptionsLine("⁞ Invokes the UAC dialog to request elevated priviledges for the process to open."); - help.AddPostOptionsLine("⁞ Compatible with commands: \"open\""); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine(""); - - help.AddPostOptionsLine("EXAMPLES:"); - help.AddPostOptionsLine("⁞ (to keep the examples short, \"Repo\" is used as placeholder for a repository name"); - help.AddPostOptionsLine("⁞ like \"RepoM\" or \"NSidekick\", for example)"); - help.AddPostOptionsLine(""); - - help.AddPostOptionsLine("Basics:"); - help.AddPostOptionsLine("⁞ grr \t\t\tLists all repositories found in RepoM including their status"); - help.AddPostOptionsLine("⁞ grr list Repo\tShows the status of a given repository (command \"list\" is optional)"); - help.AddPostOptionsLine("⁞ grr cd Repo\t\tNavigates to the main directory of a given repository"); - help.AddPostOptionsLine("⁞ grr gd Repo\t\tReturns the main directory of a given repository and puts it into the clipboard"); - help.AddPostOptionsLine("⁞ grr open Repo\tOpens the main directory of a given repository (in Windows Explorer)"); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("Predefined filters:"); - help.AddPostOptionsLine("⁞ grr todo\t\tLists repositories with unpushed changes (file changes, stashes and more)"); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("Filter targets:"); - help.AddPostOptionsLine("⁞ grr Repo\t\tBy default, filters are applied to the repository name"); - help.AddPostOptionsLine("⁞ grr \"n Repo\"\t\tThe prefix \"n \" forces RepoM to filter for repository names (optional)"); - help.AddPostOptionsLine("⁞ grr \"b master\"\tThe prefix \"b \" forces RepoM to filter for repository branches"); - help.AddPostOptionsLine("⁞ grr \"p C:\\\"\t\tThe prefix \"p \" forces RepoM to filter for repository paths"); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("File operations in given repositories:"); - help.AddPostOptionsLine("⁞ grr list Repo *.txt\tLists all text files in the given repository matching the filter *.txt"); - help.AddPostOptionsLine("⁞ grr open Repo *.sln\tOpens the Visual Studio solutions in the given repository"); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("RegEx patterns for advanced repository filtering (note the square brackets):"); - help.AddPostOptionsLine("⁞ grr list [.*_.*]\tLists all repositories containing a \"_\""); - help.AddPostOptionsLine("⁞ grr cd [Re.*]\tNavigates to the first repository starting with \"Re\""); - help.AddPostOptionsLine("⁞ grr open [.*Z] *.sln\tOpens each Visual Studio solution in every repository ending with \"Z\""); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("Advanced: grr defines indexes for found repositories. They can be used for the next execution:"); - help.AddPostOptionsLine("⁞ grr list :3 \t\tShows the branch and status of the repository at index 3"); - help.AddPostOptionsLine("⁞ grr open :1 *.sln -e\tOpens the Visual Studio solutions of the repository at index 1 as Admin"); - help.AddPostOptionsLine("⁞ grr list :3 *.* -r\tLists all files of the repository at index 3 recursively"); - help.AddPostOptionsLine("⁞ grr cd :21 \t\tNavigates to the repository at index 21"); - help.AddPostOptionsLine(""); - help.AddPostOptionsLine("Bonus:"); - help.AddPostOptionsLine("⁞ grr cd - \t\tNavigates back to the last path grr was called from"); - help.AddPostOptionsLine(" "); - help.AddPostOptionsLine("Noteworthy:"); - help.AddPostOptionsLine("βžβ€€β€€The parameter \"list\" can be omitted, \"grr [.*_.*]\" has the same effect."); - help.AddPostOptionsLine("βžβ€€β€€Put your filter in quotes if it contains spaces."); - help.AddPostOptionsLine("βžβ€€β€€RepoM has to be running on this system to use grr."); - help.AddPostOptionsLine(""); - - return help.ToString(); - } -} \ No newline at end of file diff --git a/src/Grr.App/ConsoleExtensions.cs b/src/Grr.App/ConsoleExtensions.cs deleted file mode 100644 index d37fad69..00000000 --- a/src/Grr.App/ConsoleExtensions.cs +++ /dev/null @@ -1,155 +0,0 @@ -namespace Grr.App; - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; - -[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")] -internal static class ConsoleExtensions -{ - /// - /// A utility class to determine a process parent. - /// - [SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Not sure if naming can be altered")] - [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Not sure if naming can be altered")] - [StructLayout(LayoutKind.Sequential)] - public struct ParentProcessUtilities - { - // These members must match PROCESS_BASIC_INFORMATION - private IntPtr Reserved1; - private IntPtr PebBaseAddress; - private IntPtr Reserved2_0; - private IntPtr Reserved2_1; - private IntPtr UniqueProcessId; - private IntPtr InheritedFromUniqueProcessId; - - [DllImport("ntdll.dll")] - private static extern int NtQueryInformationProcess( - IntPtr processHandle, - int processInformationClass, - ref ParentProcessUtilities processInformation, - int processInformationLength, - out int returnLength); - - /// - /// Gets the parent process of the current process. - /// - /// An instance of the Process class. - public static Process? GetParentProcess() - { - return GetParentProcess(Process.GetCurrentProcess().Handle); - } - - /// - /// Gets the parent process of specified process. - /// - /// The process id. - /// An instance of the Process class. - public static Process? GetParentProcess(int id) - { - var process = Process.GetProcessById(id); - return GetParentProcess(process.Handle); - } - - /// - /// Climbs up the process tree to find the windowed process where SendKey can send the command keys to - /// - /// The process id - /// First parent in the process tree with window handle - internal static Process? GetWindowedParentProcess(in int id) - { - var process = Process.GetProcessById(id); - - while (process.MainWindowHandle == IntPtr.Zero) - { - Process lastProcess = process; - process = GetParentProcess(process.Handle); - - if (process == null) - { - break; - } - - // Better a result without window handle than an infinite loop - if (lastProcess == process) - { - break; - } - } - - return process; - } - - /// - /// Gets the parent process of a specified process. - /// - /// The process handle. - /// An instance of the Process class. - private static Process? GetParentProcess(IntPtr handle) - { - var pbi = new ParentProcessUtilities(); - var status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out _); - if (status != 0) - { - throw new Win32Exception(status); - } - - try - { - return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); - } - catch (ArgumentException) - { - // not found - return null; - } - } - } - - public static void WriteConsoleInput(Process target, string value, int waitMilliseconds = 0) - { - PrintDebug($"Write {value} to console input {target.ProcessName} ({target.Id})"); - - // Find the first process in the process tree which has a windows handle - Process? parentProcess = ParentProcessUtilities.GetWindowedParentProcess(target.Id); - if (parentProcess == null) - { - // could not find parent to send key press to. - return; - } - - PrintDebug($"Found a process, writing to process {parentProcess.ProcessName} ({parentProcess.Id})"); - - // send CTRL+V with Enter to insert the command - var arguments = "^v{Enter}"; - - arguments = $"-pid:{parentProcess.Id} \"{arguments}\""; - - if (waitMilliseconds > 0) - { - arguments += $" -wait:{waitMilliseconds}"; - } - - var currentPath = Path.GetDirectoryName(Path.Combine(Assembly.GetExecutingAssembly().Location)); - var command = Path.Combine(currentPath ?? string.Empty, "SendKeys.exe"); - - // todo, in future, use IFileSystem - if (File.Exists(command)) - { - Process.Start(new ProcessStartInfo(command, arguments) { UseShellExecute = true, }); - } - else - { - Console.WriteLine(command + " does not exist."); - } - } - - private static void PrintDebug(string value) - { - Debug.WriteLine(value); - } -} \ No newline at end of file diff --git a/src/Grr.App/Grr.App.csproj b/src/Grr.App/Grr.App.csproj deleted file mode 100644 index 153b2dbc..00000000 --- a/src/Grr.App/Grr.App.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - Exe - net6.0 - Andreas WΓ€scher - Git Repositories of RepoM - Command line interface to query repository information from RepoM - https://raw.githubusercontent.com/awaescher/RepoZ/master/grr/grr.ico - grr - - - - - - - - - - - - - - - - ..\..\_ref\SendKeys.exe - true - - - diff --git a/src/Grr.App/History/FileHistoryRepository.cs b/src/Grr.App/History/FileHistoryRepository.cs deleted file mode 100644 index 4f40c070..00000000 --- a/src/Grr.App/History/FileHistoryRepository.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace Grr.App.History; - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using System.Text; -using RepoM.Ipc; - -public class FileHistoryRepository : IHistoryRepository -{ - private readonly IFileSystem _fileSystem; - - public FileHistoryRepository(IFileSystem fileSystem) - { - _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - } - - public void Save(State state) - { - // if multiple repositories were found the last time we ran grr, - // these were written to the last state. - // if the user selects one with an index like "grr cd :2", we want - // to keep the last repositories to enable him to choose another one - // with the same indexes as before. - // so we have to get the old repositories - load and copy them if required - if (!state.OverwriteRepositories) - { - State oldState = Load(); - if (oldState.LastRepositories?.Length > 0) - { - state.LastRepositories = oldState.LastRepositories; - } - } - - var lines = new [] - { - state.LastLocation ?? string.Empty, - Serialize(state.LastRepositories ?? Array.Empty()), - }; - - try - { - _fileSystem.File.WriteAllLines(GetFileName(), lines, Encoding.Default); - } - catch (Exception) - { - /* safely ignore this, saving the state is optional */ - } - } - - public State Load() - { - var lines = Array.Empty(); - - try - { - lines = _fileSystem.File.ReadAllLines(GetFileName(), Encoding.Default); - } - catch - { - /* safely ignore this, reading the state is optional */ - } - - if (lines.Length != 2) - { - return new State() - { - LastLocation = string.Empty, - LastRepositories = Array.Empty(), - }; - } - - return new State() - { - LastLocation = lines[0], - LastRepositories = Deserialize(lines[1]), - }; - } - - private static string GetFileName() - { - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RepoM", "state.grr"); - } - - private static string Serialize(IEnumerable repositories) - { - var names = repositories - .Select(r => r.Name) - .ToArray(); - - if (!names.Any()) - { - return string.Empty; - } - - return string.Join("|", names); - } - - private static Repository[] Deserialize(string repositoryString) - { - if (string.IsNullOrEmpty(repositoryString)) - { - return Array.Empty(); - } - - return repositoryString - .Split(new [] { "|", }, StringSplitOptions.None) - .Select(s => new Repository(s)) - .ToArray(); - } -} \ No newline at end of file diff --git a/src/Grr.App/History/IHistoryRepository.cs b/src/Grr.App/History/IHistoryRepository.cs deleted file mode 100644 index a69f3eaa..00000000 --- a/src/Grr.App/History/IHistoryRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Grr.App.History; - -public interface IHistoryRepository -{ - State Load(); - - void Save(State state); -} \ No newline at end of file diff --git a/src/Grr.App/History/State.cs b/src/Grr.App/History/State.cs deleted file mode 100644 index 165e7f19..00000000 --- a/src/Grr.App/History/State.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Grr.App.History; - -using RepoM.Ipc; - -public class State -{ - public Repository[]? LastRepositories { get; set; } - - public bool OverwriteRepositories { get; set; } - - public string? LastLocation { get; set; } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/ChangeToDirectoryMessage.cs b/src/Grr.App/Messages/ChangeToDirectoryMessage.cs deleted file mode 100644 index 171f8b0e..00000000 --- a/src/Grr.App/Messages/ChangeToDirectoryMessage.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace Grr.App.Messages; - -using System; -using System.Diagnostics; -using System.IO.Abstractions; -using System.Runtime.InteropServices; -using RepoM.Ipc; - -[DebuggerDisplay("{GetRemoteCommand()}")] -public class ChangeToDirectoryMessage : DirectoryMessage -{ - public ChangeToDirectoryMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) { } - - protected override void ExecuteExistingDirectory(string directory) - { - var command = $"cd \"{directory}\""; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // type the path into the console which is hosting grr.exe to change to the directory - TextCopy.ClipboardService.SetText(command); - ConsoleExtensions.WriteConsoleInput(Process.GetCurrentProcess(), command); - } - else - { - TextCopy.ClipboardService.SetText(command); - Console.ForegroundColor = ConsoleColor.Cyan; - Console.WriteLine("The command was copied to the clipboard, paste and execute it manually now.\nChanging directories is not supported on macOS yet, sorry."); - Console.ResetColor(); - } - } - - protected override void ExecuteRepositoryQuery(Repository[] repositories) - { - if (repositories.Length > 1) - { - // only use the first repository when multiple repositories came in - // cd makes no sense with multiple repositories - System.Console.WriteLine(""); - System.Console.WriteLine($"Found multiple repositories, using {repositories[0].Name}."); - System.Console.WriteLine("You can access the others by index now, like:\n grr cd :2"); - base.ExecuteRepositoryQuery(new Repository[] { repositories[0], }); - } - else - { - base.ExecuteRepositoryQuery(repositories); - } - } - - public override bool ShouldWriteRepositories(Repository[] repositories) - { - return true; - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/DirectoryMessage.cs b/src/Grr.App/Messages/DirectoryMessage.cs deleted file mode 100644 index e2e4f9d7..00000000 --- a/src/Grr.App/Messages/DirectoryMessage.cs +++ /dev/null @@ -1,102 +0,0 @@ -namespace Grr.App.Messages; - -using System; -using System.IO.Abstractions; -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public abstract class DirectoryMessage : IMessage -{ - private readonly bool _argumentIsExistingDirectory; - private protected readonly IFileSystem FileSystem; - - protected DirectoryMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - { - Filter = filter ?? throw new ArgumentNullException(nameof(filter)); - FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _argumentIsExistingDirectory = FileSystem.Directory.Exists(Filter.RepositoryFilter); - } - - public void Execute(Repository[] repositories) - { - if (_argumentIsExistingDirectory) - { - ExecuteExistingDirectoryWithSafetyCheck(Filter.RepositoryFilter); - } - else - { - ExecuteRepositoryQuery(repositories); - } - } - - private void ExecuteExistingDirectoryWithSafetyCheck(string? directory) - { - if (directory == null) - { - return; - } - - // use '/' for linux systems and bash command line (will work on cmd and powershell as well) - directory = directory.Replace(@"\", "/"); - ExecuteExistingDirectory(directory); - } - - protected abstract void ExecuteExistingDirectory(string directory); - - protected virtual void ExecuteRepositoryQuery(Repository[] repositories) - { - if (repositories.Length == 0) - { - return; - } - - foreach (Repository repository in repositories) - { - var directory = repository.SafePath; - - if (string.IsNullOrWhiteSpace(directory)) - { - System.Console.WriteLine("Repository path is empty. Aborting."); - return; - } - - if (FileSystem.Directory.Exists(directory)) - { - ExecuteExistingDirectoryWithSafetyCheck(directory); - } - else - { - System.Console.WriteLine("Repository path does not exist:\n" + directory); - } - } - } - - public virtual string? GetRemoteCommand() - { - if (!HasRemoteCommand) - { - return null; - } - - return string.IsNullOrEmpty(Filter?.RepositoryFilter) - ? null /* makes no sense */ - : $"list:{RegexFilter.Get(Filter.RepositoryFilter)}"; - } - - public virtual bool HasRemoteCommand - { - get - { - if (_argumentIsExistingDirectory) - { - return false; - } - - return !string.IsNullOrEmpty(Filter?.RepositoryFilter); - } - } - - public abstract bool ShouldWriteRepositories(Repository[] repositories); - - public RepositoryFilterOptions Filter { get; } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/FileMessage.cs b/src/Grr.App/Messages/FileMessage.cs deleted file mode 100644 index bc69dc13..00000000 --- a/src/Grr.App/Messages/FileMessage.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace Grr.App.Messages; - -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public abstract class FileMessage : DirectoryMessage -{ - protected FileMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) - { - } - - protected override void ExecuteExistingDirectory(string directory) - { - string[] items; - - try - { - items = FindItems(directory, Filter).ToArray(); - } - catch (Exception ex) - { - Console.WriteLine("An error occurred:\n" + ex.ToString()); - return; - } - - if (items.Length == 0) - { - System.Console.WriteLine($"No files found.\n Directory:\t{directory}\n Filter:\t{Filter.FileFilter}"); - return; - } - - ExecuteFound(items); - } - - protected virtual IEnumerable FindItems(string directory, RepositoryFilterOptions filter) - { - SearchOption searchOption = Filter.RecursiveFileFilter - ? SearchOption.AllDirectories - : SearchOption.TopDirectoryOnly; - - return FileSystem.Directory.GetFiles(directory, filter.FileFilter, searchOption) - .OrderBy(i => i); - } - - protected abstract void ExecuteFound(string[] files); -} \ No newline at end of file diff --git a/src/Grr.App/Messages/Filters/GoBackMessageFilter.cs b/src/Grr.App/Messages/Filters/GoBackMessageFilter.cs deleted file mode 100644 index 8f55c84a..00000000 --- a/src/Grr.App/Messages/Filters/GoBackMessageFilter.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Grr.App.Messages.Filters; - -using System; -using Grr.App.History; - -public class GoBackMessageFilter : IMessageFilter -{ - private readonly IHistoryRepository _historyRepository; - - public GoBackMessageFilter(IHistoryRepository historyRepository) - { - _historyRepository = historyRepository ?? throw new ArgumentNullException(nameof(historyRepository)); - } - - public void Filter(RepositoryFilterOptions filter) - { - var filterValue = filter?.RepositoryFilter ?? string.Empty; - - if ("-" == filterValue) - { - State state = _historyRepository.Load(); - if (filter != null) - { - filter.RepositoryFilter = state.LastLocation ?? filterValue; - } - } - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/Filters/IMessageFilter.cs b/src/Grr.App/Messages/Filters/IMessageFilter.cs deleted file mode 100644 index eabcf304..00000000 --- a/src/Grr.App/Messages/Filters/IMessageFilter.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Grr.App.Messages.Filters; - -public interface IMessageFilter -{ - void Filter(RepositoryFilterOptions filter); -} \ No newline at end of file diff --git a/src/Grr.App/Messages/Filters/IndexMessageFilter.cs b/src/Grr.App/Messages/Filters/IndexMessageFilter.cs deleted file mode 100644 index d1a1e6e5..00000000 --- a/src/Grr.App/Messages/Filters/IndexMessageFilter.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace Grr.App.Messages.Filters; - -using System; -using Grr.App.History; - -public class IndexMessageFilter : IMessageFilter -{ - private readonly IHistoryRepository _historyRepository; - - public IndexMessageFilter(IHistoryRepository historyRepository) - { - _historyRepository = historyRepository ?? throw new ArgumentNullException(nameof(historyRepository)); - } - - public void Filter(RepositoryFilterOptions filter) - { - if (filter?.RepositoryFilter == null) - { - return; - } - - if (!filter.RepositoryFilter.StartsWith(":")) - { - return; - } - - var rest = filter.RepositoryFilter[1..]; - if (!int.TryParse(rest, out var index)) - { - return; - } - - index--; // the index visible to the user are 1-based, not 0-based - State state = _historyRepository.Load(); - if (state.LastRepositories == null) - { - return; - } - - if (index >= 0 && state.LastRepositories.Length > index) - { - filter.RepositoryFilter = state.LastRepositories[index]?.Name ?? filter.RepositoryFilter; - } - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/GetDirectoryMessage.cs b/src/Grr.App/Messages/GetDirectoryMessage.cs deleted file mode 100644 index 57758059..00000000 --- a/src/Grr.App/Messages/GetDirectoryMessage.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace Grr.App.Messages; - -using System; -using System.IO.Abstractions; -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public class GetDirectoryMessage : DirectoryMessage -{ - public GetDirectoryMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) - { - } - - protected override void ExecuteExistingDirectory(string directory) - { - directory = $"\"{directory}\""; - - TextCopy.ClipboardService.SetText(directory); - Console.WriteLine(directory); - } - - protected override void ExecuteRepositoryQuery(Repository[] repositories) - { - if (repositories.Length > 1) - { - // only use the first repository when multiple repositories came in - // cd makes no sense with multiple repositories - System.Console.WriteLine(""); - System.Console.WriteLine($"Found multiple repositories, using {repositories[0].Name}."); - System.Console.WriteLine("You can get the others by index now, like:\n grr gd :2"); - base.ExecuteRepositoryQuery(new Repository[] { repositories[0], }); - } - else - { - base.ExecuteRepositoryQuery(repositories); - } - } - - public override bool ShouldWriteRepositories(Repository[] repositories) - { - return (repositories?.Length ?? 0) > 1; - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/IMessage.cs b/src/Grr.App/Messages/IMessage.cs deleted file mode 100644 index fce10713..00000000 --- a/src/Grr.App/Messages/IMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Grr.App.Messages; - -using RepoM.Ipc; - -public interface IMessage -{ - string? GetRemoteCommand(); - - void Execute(Repository[] repositories); - - bool HasRemoteCommand { get; } - - bool ShouldWriteRepositories(Repository[] repositories); -} \ No newline at end of file diff --git a/src/Grr.App/Messages/ListRepositoriesMessage.cs b/src/Grr.App/Messages/ListRepositoriesMessage.cs deleted file mode 100644 index 087b96f2..00000000 --- a/src/Grr.App/Messages/ListRepositoriesMessage.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Grr.App.Messages; - -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public class ListRepositoriesMessage : IMessage -{ - private readonly string _repositoryFilter; - - public ListRepositoriesMessage() - { - _repositoryFilter = string.Empty; - } - - public ListRepositoriesMessage(RepositoryFilterOptions filter) - { - _repositoryFilter = filter?.RepositoryFilter ?? string.Empty; - } - - public void Execute(Repository[] repositories) - { - // nothing to do - } - - public string GetRemoteCommand() - { - return string.IsNullOrEmpty(_repositoryFilter) - ? "list:.*" /* show all with RegEx pattern ".*" */ - : $"list:{RegexFilter.Get(_repositoryFilter)}"; - } - - public bool HasRemoteCommand => true; - - public bool ShouldWriteRepositories(Repository[] repositories) - { - return true; - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/ListRepositoryFilesMessage.cs b/src/Grr.App/Messages/ListRepositoryFilesMessage.cs deleted file mode 100644 index eb611589..00000000 --- a/src/Grr.App/Messages/ListRepositoryFilesMessage.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace Grr.App.Messages; - -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public class ListRepositoryFilesMessage : FileMessage -{ - public ListRepositoryFilesMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) - { - } - - protected override void ExecuteFound(string[] files) - { - foreach (var file in files) - { - System.Console.WriteLine(file); - } - } - - protected override IEnumerable FindItems(string directory, RepositoryFilterOptions filter) - { - SearchOption searchOption = Filter.RecursiveFileFilter - ? SearchOption.AllDirectories - : SearchOption.TopDirectoryOnly; - - if (filter.FileFilter != null) - { - // todo Fix IFileSystem - return /*FileSystem.*/Directory.GetFileSystemEntries(directory, filter.FileFilter, searchOption) - .OrderBy(i => i); - } - - return Enumerable.Empty(); - - } - - public override bool ShouldWriteRepositories(Repository[] repositories) - { - return false; - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/OpenDirectoryMessage.cs b/src/Grr.App/Messages/OpenDirectoryMessage.cs deleted file mode 100644 index db920100..00000000 --- a/src/Grr.App/Messages/OpenDirectoryMessage.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Grr.App.Messages; - -using System.Diagnostics; -using System.IO.Abstractions; -using System.Runtime.InteropServices; -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public class OpenDirectoryMessage : DirectoryMessage -{ - public OpenDirectoryMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) - { - } - - protected override void ExecuteExistingDirectory(string directory) - { - var directoryInQuotes = $"\"{directory}\""; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Process.Start(new ProcessStartInfo(directoryInQuotes) { UseShellExecute = true, }); - } - else - { - Process.Start(new ProcessStartInfo("open", directoryInQuotes)); - } - } - - public override bool ShouldWriteRepositories(Repository[] repositories) - { - return true; - } -} \ No newline at end of file diff --git a/src/Grr.App/Messages/OpenFileMessage.cs b/src/Grr.App/Messages/OpenFileMessage.cs deleted file mode 100644 index 2e8a31a1..00000000 --- a/src/Grr.App/Messages/OpenFileMessage.cs +++ /dev/null @@ -1,92 +0,0 @@ -namespace Grr.App.Messages; - -using System; -using System.Diagnostics; -using System.IO.Abstractions; -using System.Linq; -using System.Runtime.InteropServices; -using RepoM.Ipc; - -[System.Diagnostics.DebuggerDisplay("{GetRemoteCommand()}")] -public class OpenFileMessage : FileMessage -{ - public OpenFileMessage(RepositoryFilterOptions filter, IFileSystem fileSystem) - : base(filter, fileSystem) - { - } - - protected override void ExecuteFound(string[] files) - { - foreach (var file in files) - { - System.Console.WriteLine($"Opening {file} ..."); - - try - { - Process.Start(CreateStartInfo(file)); - } - catch (System.Exception ex) - { - System.Console.WriteLine("An error occurred:\n" + ex.ToString()); - } - } - } - - private ProcessStartInfo CreateStartInfo(string file) - { - var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - if (!Filter.RequestElevation) - { - if (isWindows) - { - return new ProcessStartInfo(file) { UseShellExecute = true, }; - } - else - { - return new ProcessStartInfo("open", file); - } - } - - if (!isWindows) - { - throw new AccessViolationException("Elevation is not supported on this platform."); - } - - var isExecutable = IsExecutable(file); - - // executables can be used directly, whereas files such as *.sln, for example, - // have to been opened with (a hidden) cmd.exe to request elevation. - // command is: cmd.exe /C "C:\Path\Solution.sln" - var executable = isExecutable ? file : "cmd.exe"; - var arguments = isExecutable ? "" : $"/C \"{file}\""; - ProcessWindowStyle windowStyle = isExecutable ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden; - - return new ProcessStartInfo - { - UseShellExecute = true, // this with Verb=runas forces elevation - CreateNoWindow = true, - WindowStyle = windowStyle, - FileName = executable, - Verb = "runas", // this with ShellEx=true forces elevation - Arguments = arguments, - }; - } - - private static bool IsExecutable(string file) - { - var executables = new string[] - { - ".exe", - ".bat", - ".cmd", - ".com", - }; - return executables.Any(e => file.EndsWith(e, System.StringComparison.OrdinalIgnoreCase)); - } - - public override bool ShouldWriteRepositories(Repository[] repositories) - { - return false; - } -} \ No newline at end of file diff --git a/src/Grr.App/Program.cs b/src/Grr.App/Program.cs deleted file mode 100644 index df5f605f..00000000 --- a/src/Grr.App/Program.cs +++ /dev/null @@ -1,262 +0,0 @@ -namespace Grr.App; - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO.Abstractions; -using System.Linq; -using System.Text; -using CommandLine; -using Grr.App.Messages; -using Grr.App.Messages.Filters; -using RepoM.Ipc; - -static class Program -{ - private const int MAX_REPO_NAME_LENGTH = 35; - - private static readonly IFileSystem _fileSystem = new FileSystem(); - - static void Main(string[] args) - { - Console.OutputEncoding = Encoding.UTF8; - - args = PrepareArguments(args); - - if (IsHelpRequested(args)) - { - ShowHelp(); - } - else - { - IMessage? message = TryParseArgumentsToMessage(args); - - if (message != null) - { - IpcClient.Result? result = null; - - if (message.HasRemoteCommand) - { - var client = new IpcClient(new DefaultIpcEndpoint()); - result = client.GetRepositories(message.GetRemoteCommand()); - - if (result.Repositories?.Length > 0) - { - if (message.ShouldWriteRepositories(result.Repositories)) - { - WriteRepositories(result.Repositories); - } - } - else - { - Console.WriteLine(result.Answer); - } - } - - Repository[]? repositories = result?.Repositories; - - if (repositories != null) - { - message?.Execute(repositories); - - WriteHistory(repositories); - } - } - else - { - Console.WriteLine("Could not parse command line arguments."); - } - } - - if (Debugger.IsAttached) - { - Console.ReadKey(); - } - } - - private static IMessage? TryParseArgumentsToMessage(IReadOnlyList args) - { - try - { - ParserResult parseResult = CommandLine.Parser.Default.ParseArguments(args, typeof(ListOptions), typeof(ChangeDirectoryOptions), typeof(GetDirectoryOptions), typeof(OpenDirectoryOptions)); - - if (parseResult.Tag == CommandLine.ParserResultType.NotParsed) - { - return null; - } - - var options = parseResult.GetType()?.GetProperty("Value")?.GetValue(parseResult) as RepositoryFilterOptions; - - // yes, that's a hack. I feel not good about it. The CommandLineParser seems not to be able to parse "cd -" since version 2.3.0 anymore - // and here we are, hacking our way around it ... - if (options != null) - { - if (options.RepositoryFilter == null - && args.Count == 2 - && ("cd".Equals(args[0], StringComparison.OrdinalIgnoreCase) || "gd".Equals(args[0], StringComparison.OrdinalIgnoreCase)) - && args[1] == "-") - { - options.RepositoryFilter = "-"; - } - } - - return options != null - ? GetMessage(options) - : null; - } - catch - { - return null; - } - } - - private static void WriteHistory(Repository[] repositories) - { - var history = new History.State() - { - LastLocation = FindCallerWorkingDirectory(), - LastRepositories = repositories, - OverwriteRepositories = repositories?.Length > 1, /* 0 or 1 repo should not overwrite the last list */ - - // OverwriteRepositories = false?! - // if multiple repositories were found the last time we ran grr, - // these were written to the last state. - // if the user selects one with an index like "grr cd :2", we want - // to keep the last repositories to enable him to choose another one - // with the same indexes as before. - // so we have to get the old repositories - load and copy them if required - }; - - var repository = new History.FileHistoryRepository(_fileSystem); - repository.Save(history); - } - - private static string FindCallerWorkingDirectory() - { - // do NOT use the directory of the grr-assembly - // we need to preserve the context of the calling console - return _fileSystem.Directory.GetCurrentDirectory(); - } - - private static void WriteRepositories(Repository[] repositories) - { - var maxRepoNameLength = Math.Min(MAX_REPO_NAME_LENGTH, repositories.Max(r => r.Name?.Length ?? 0)); - var maxIndexStringLength = repositories.Length.ToString().Length; - var ellipsesSign = "\u2026"; - var writeIndex = repositories.Length > 1; - - for (var i = 0; i < repositories.Length; i++) - { - var userIndex = i + 1; // the index visible to the user are 1-based, not 0-based; - - var repoName = (repositories[i].Name.Length > MAX_REPO_NAME_LENGTH) - ? repositories[i].Name[..MAX_REPO_NAME_LENGTH] + ellipsesSign - : repositories[i].Name; - - Console.Write(" "); - if (writeIndex) - { - Console.Write($" [{userIndex.ToString().PadLeft(maxIndexStringLength)}] "); - } - - Console.Write(repoName.PadRight(maxRepoNameLength + 3)); - Console.Write(repositories[i].BranchWithStatus); - Console.WriteLine(); - } - } - - private static string[] PrepareArguments(string[] args) - { - if (args.Length == 0) - { - args = new string[] { CommandLineOptions.LIST_COMMAND, }; - } - - if (!CommandLineOptions.IsKnownArgument(args.First())) - { - var newArgs = new List(args); - newArgs.Insert(0, CommandLineOptions.LIST_COMMAND); - args = newArgs.ToArray(); - } - - return args; - } - - private static IMessage GetMessage(RepositoryFilterOptions options) - { - // default should be listing all repositories - IMessage message = new ListRepositoriesMessage(); - - ApplyMessageFilters(options); - - if (options is ListOptions) - { - if (options.HasFileFilter) - { - message = new ListRepositoryFilesMessage(options, _fileSystem); - } - else - { - message = new ListRepositoriesMessage(options); - } - } - - if (options is ChangeDirectoryOptions) - { - message = new ChangeToDirectoryMessage(options, _fileSystem); - } - - if (options is GetDirectoryOptions) - { - message = new GetDirectoryMessage(options, _fileSystem); - } - - if (options is OpenDirectoryOptions) - { - if (options.HasFileFilter) - { - message = new OpenFileMessage(options, _fileSystem); - } - else - { - message = new OpenDirectoryMessage(options, _fileSystem); - } - } - - return message; - } - - private static void ApplyMessageFilters(RepositoryFilterOptions filter) - { - var historyRepository = new History.FileHistoryRepository(_fileSystem); - var filters = new IMessageFilter[] - { - new IndexMessageFilter(historyRepository), - new GoBackMessageFilter(historyRepository), - }; - - foreach (IMessageFilter messageFilter in filters) - { - messageFilter.Filter(filter); - } - } - - private static bool IsHelpRequested(IReadOnlyList args) - { - if (args.Count != 1) - { - return false; - } - - var arg = args[0].TrimStart('-').TrimStart('/'); - - return CommandLineOptions.HELP_COMMAND.Equals(arg, StringComparison.OrdinalIgnoreCase) - || - CommandLineOptions.HELP_COMMAND_CHAR.ToString().Equals(arg, StringComparison.OrdinalIgnoreCase); - } - - private static void ShowHelp() - { - Console.WriteLine(CommandLineOptions.GetUsage()); - } -} \ No newline at end of file diff --git a/src/Grr.App/Properties/launchSettings.json b/src/Grr.App/Properties/launchSettings.json deleted file mode 100644 index 977fc4b1..00000000 --- a/src/Grr.App/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "grr": { - "commandName": "Project", - "commandLineArgs": "cd repom" - } - } -} \ No newline at end of file diff --git a/src/Grr.App/RegexFilter.cs b/src/Grr.App/RegexFilter.cs deleted file mode 100644 index d35c91f9..00000000 --- a/src/Grr.App/RegexFilter.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Grr.App; - -using System; -using System.Linq; -using System.Text.RegularExpressions; - -public static class RegexFilter -{ - public static string Get(string value) - { - var usedPrefix = ""; - - // respect filter targets like "n " for name, "b " for branches and "p " for paths - var prefixes = new[] { "b ", "n ", "p ", }; // used in RepositoryView as well - var isPrefixed = prefixes.Any(p => value.StartsWith(p, StringComparison.OrdinalIgnoreCase)); - - if (isPrefixed) - { - usedPrefix = value[..2]; - value = value[2..]; - } - - // square brackets [] define a RegEx to use. If they are not given, use a like search - if (value.StartsWith("[") && value.EndsWith("]")) - { - return $"{usedPrefix}^{value.Substring(1, value.Length - 2)}$"; - } - - return $"{usedPrefix}.*{Regex.Escape(value)}.*"; - } -} \ No newline at end of file diff --git a/src/Grr.App/RepositoryFilterOptions.cs b/src/Grr.App/RepositoryFilterOptions.cs deleted file mode 100644 index b4cdb6ca..00000000 --- a/src/Grr.App/RepositoryFilterOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Grr.App; - -using CommandLine; - -public class RepositoryFilterOptions -{ - [Value(0)] public string? RepositoryFilter { get; set; } - - [Value(1)] public string? FileFilter { get; set; } - - [Option('r', "recursive", Default = false, HelpText = "Defines whether the file filter should be applied recursively or not.")] - public bool RecursiveFileFilter { get; set; } - - [Option('e', "elevated", Default = false, HelpText = "Defines whether the files should be opened in an elevated context or not.")] - public bool RequestElevation { get; set; } - - public bool HasFileFilter => !string.IsNullOrWhiteSpace(FileFilter); -} \ No newline at end of file diff --git a/src/GrrUi.App/GrrUi.App.csproj b/src/GrrUi.App/GrrUi.App.csproj deleted file mode 100644 index 3b0cdf68..00000000 --- a/src/GrrUi.App/GrrUi.App.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - Exe - net6.0 - grrui - - - - - - - - - - - - - - - - - - - - ..\..\_ref\SendKeys.exe - true - - - - diff --git a/src/GrrUi.App/Model/RepositoriesView.cs b/src/GrrUi.App/Model/RepositoriesView.cs deleted file mode 100644 index 6dc627fa..00000000 --- a/src/GrrUi.App/Model/RepositoriesView.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace GrrUi.App.Model; - -using System; -using System.Collections.Generic; -using System.Linq; -using RepoM.Api.Git; -using Repository = RepoM.Ipc.Repository; - -public class RepositoriesView -{ - private const int MAX_REPO_NAME_LENGTH = 35; - private readonly RepositoryView[] _repositoryViews; - - public RepositoriesView(IEnumerable repositories) - { - Repository[] repos = repositories as Repository[] ?? repositories.ToArray(); - - var repositoryCount = repos.Length; - _repositoryViews = new RepositoryView[repositoryCount]; - - var map = new StatusCharacterMap(); - - var maxRepoNameLength = Math.Min(MAX_REPO_NAME_LENGTH, repos.Max(r => r.Name?.Length ?? 0)); - var maxIndexStringLength = repositoryCount.ToString().Length; - var writeIndex = repositoryCount > 1; - - for (var i = 0; i < repositoryCount; i++) - { - var userIndex = i + 1; // the index visible to the user is 1-based, not 0-based; - Repository repository = repos.ElementAt(i); - - var repoName = (repository.Name.Length > MAX_REPO_NAME_LENGTH) - ? repository.Name.Substring(0, MAX_REPO_NAME_LENGTH) + map.EllipsesSign - : repository.Name; - - var index = ""; - if (writeIndex) - { - index = $"[{userIndex.ToString().PadLeft(maxIndexStringLength)}] "; - } - - var name = repoName.PadRight(maxRepoNameLength + 3); - var branch = repository.BranchWithStatus; - - var displayText = index + name + branch; - - _repositoryViews[i] = new RepositoryView(repository, displayText); - } - } - - public RepositoryView[] Repositories => _repositoryViews - .Where(r => r.MatchesFilter(Filter ?? string.Empty)) - .ToArray(); - - public string Filter { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/src/GrrUi.App/Model/RepositoryView.cs b/src/GrrUi.App/Model/RepositoryView.cs deleted file mode 100644 index d94a116f..00000000 --- a/src/GrrUi.App/Model/RepositoryView.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace GrrUi.App.Model; - -using System; -using RepoM.Api.Git; -using Repository = RepoM.Ipc.Repository; - -public class RepositoryView : IRepositoryView -{ - public RepositoryView(Repository repository, string displayText) - { - Repository = repository ?? throw new ArgumentNullException(nameof(repository)); - DisplayText = displayText; - } - - public override string ToString() - { - return DisplayText; - } - - public Repository Repository { get; } - - public string DisplayText { get; } - - public string Name => Repository.Name ?? ""; - - public string CurrentBranch => Repository.BranchWithStatus ?? string.Empty; - - public bool IsPinned { get; } = false; - - public string Path => Repository.Path ?? string.Empty; - - public bool HasUnpushedChanges => Repository.HasUnpushedChanges; -} \ No newline at end of file diff --git a/src/GrrUi.App/Program.cs b/src/GrrUi.App/Program.cs deleted file mode 100644 index 5f62e039..00000000 --- a/src/GrrUi.App/Program.cs +++ /dev/null @@ -1,227 +0,0 @@ -namespace GrrUi.App; - -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using GrrUi.App.Model; -using GrrUi.App.UI; -using NStack; -using RepoM.Ipc; -using Terminal.Gui; - -static class Program -{ - private const int BUTTON_BORDER = 4; // 2 chars to the left, 2 to the right - private const int BUTTON_DISTANCE = 1; - - private static IpcClient _client = null!; - private static ListView? _repositoryList; - private static RepositoriesView? _repositoriesView; - private static TextField? _filterField; - - static void Main(string[] args) - { - _client = new IpcClient(new DefaultIpcEndpoint()); - IpcClient.Result answer = _client.GetRepositories(); - - var repositoryCount = answer.Repositories.Length; - if (repositoryCount == 0) - { - if (!string.IsNullOrEmpty(answer?.Answer)) - { - Console.WriteLine(answer.Answer); - } - else - { - Console.WriteLine("No repositories yet"); - } - - return; - } - - _repositoriesView = new RepositoriesView(answer.Repositories); - - Application.Init(); - - var filterLabel = new Label(1, 1, "Filter: "); - _filterField = new TextField(string.Empty) - { - X = Pos.Right(filterLabel) + 2, - Y = Pos.Top(filterLabel), - Width = Dim.Fill(margin: 1), - }; - _filterField.TextChanged += FilterFieldOnTextChanged; - - _repositoryList = new ListView(_repositoriesView.Repositories) - { - X = Pos.Left(filterLabel), - Y = Pos.Bottom(filterLabel) + 1, - Width = Dim.Fill(margin: 1), - Height = Dim.Fill() - 2, - }; - - var win = new KeyPreviewWindow("grr: Git repositories of RepoM"); - win.Add(filterLabel); - win.Add(_filterField); - win.Add(_repositoryList); - - var buttonX = Pos.Left(filterLabel); - - var navigationButton = new Button("Navigate") - { - X = buttonX, - Y = Pos.AnchorEnd(1), - CanFocus = false, - }; - if (CanNavigate) - { - navigationButton.Clicked += Navigate; - } - else - { - navigationButton.Clicked += CopyNavigationCommandAndQuit; - } - - buttonX = buttonX + navigationButton.Text.Length + BUTTON_BORDER + BUTTON_DISTANCE; - var copyPathButton = new Button("Copy") - { - X = buttonX, - Y = Pos.AnchorEnd(1), - CanFocus = false, - }; - copyPathButton.Clicked += Copy; - - buttonX = buttonX + copyPathButton.Text.Length + BUTTON_BORDER + BUTTON_DISTANCE; - var browseButton = new Button("Browse") - { - - X = buttonX, - Y = Pos.AnchorEnd(1), - CanFocus = false, - }; - browseButton.Clicked += Browse; - - var quitButton = new Button("Quit") - { - X = Pos.AnchorEnd("Quit".Length + BUTTON_BORDER + BUTTON_DISTANCE), - Y = Pos.AnchorEnd(1), - CanFocus = false, - }; - quitButton.Clicked += QuitButtonOnClicked; - - win.Add(navigationButton, copyPathButton, browseButton, quitButton); - - win.DefineKeyAction(Key.Enter, () => _repositoryList.SetFocus()); - win.DefineKeyAction(Key.Esc, () => - { - if (_filterField.HasFocus) - { - SetFilterText(string.Empty); - } - else - { - _filterField.SetFocus(); - } - }); - - if (args.Length > 0) - { - SetFilterText(string.Join(" ", args)); - } - - Application.Top.Add(win); - Application.Run(); - } - - private static void QuitButtonOnClicked() - { - Application.RequestStop(); - } - - private static void SetFilterText(string filter) - { - if (_filterField == null) - { - return; - } - - _filterField.Text = filter; - _filterField.PositionCursor(); - FilterField_Changed(_filterField, NStack.ustring.Empty); - } - - private static void Navigate() - { - ExecuteOnSelectedRepository(r => - { - var command = $"cd \"{r.SafePath}\""; - - // type the path into the console which is hosting grrui.exe to change to the directory - TextCopy.ClipboardService.SetText(command); - Grr.App.ConsoleExtensions.WriteConsoleInput(Process.GetCurrentProcess(), command, waitMilliseconds: 1000); - - Application.RequestStop(); - }); - } - - private static void CopyNavigationCommandAndQuit() - { - ExecuteOnSelectedRepository(r => - { - var command = $"cd \"{r.SafePath}\""; - TextCopy.ClipboardService.SetText(command); - TimelyMessage.ShowMessage("Copied to clipboard. Please paste and run the command manually now.", TimeSpan.FromMilliseconds(1000)); - Application.RequestStop(); - }); - } - - private static void Copy() - { - ExecuteOnSelectedRepository(r => - { - var command = $"\"{r.SafePath}\""; - TextCopy.ClipboardService.SetText(command); - }); - } - - private static void Browse() - { - ExecuteOnSelectedRepository(r => Process.Start(new ProcessStartInfo(r.SafePath) { UseShellExecute = true, })); - } - - private static void ExecuteOnSelectedRepository(Action action) - { - RepositoryView[]? repositories = _repositoriesView?.Repositories; - - if (repositories == null || _repositoryList == null) - { - return; - } - - if (repositories.Length <= _repositoryList.SelectedItem) - { - return; - } - - RepositoryView current = repositories[_repositoryList.SelectedItem]; - action(current.Repository); - } - - private static void FilterFieldOnTextChanged(ustring obj) - { - FilterField_Changed(_filterField, obj); - } - - private static void FilterField_Changed(object? sender, NStack.ustring _) - { - if (_repositoriesView == null) - { - return; - } - - _repositoriesView.Filter = (sender as TextField)?.Text?.ToString() ?? string.Empty; - _repositoryList?.SetSource(_repositoriesView.Repositories); - } - - private static bool CanNavigate => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); -} \ No newline at end of file diff --git a/src/GrrUi.App/UI/KeyPreviewWindow.cs b/src/GrrUi.App/UI/KeyPreviewWindow.cs deleted file mode 100644 index 92826fe6..00000000 --- a/src/GrrUi.App/UI/KeyPreviewWindow.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace GrrUi.App.UI; - -using System; -using System.Collections.Generic; -using Terminal.Gui; - -public class KeyPreviewWindow : Window -{ - private readonly Dictionary _keyActions = new(); - - public KeyPreviewWindow(NStack.ustring title) - : base(title) - { - } - - public KeyPreviewWindow(NStack.ustring title, int padding) - : base(title, padding) - { - } - - public override bool ProcessKey(KeyEvent keyEvent) - { - if (_keyActions.TryGetValue(keyEvent.Key, out Action? action)) - { - action.Invoke(); - } - - return base.ProcessKey(keyEvent); - } - - public void DefineKeyAction(Key key, Action action) - { - _keyActions[key] = action; - } -} \ No newline at end of file diff --git a/src/GrrUi.App/UI/TimelyMessage.cs b/src/GrrUi.App/UI/TimelyMessage.cs deleted file mode 100644 index 8702619f..00000000 --- a/src/GrrUi.App/UI/TimelyMessage.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace GrrUi.App.UI; - -using System; -using System.Threading.Tasks; -using Terminal.Gui; - -public static class TimelyMessage -{ - public static void ShowMessage(string message, TimeSpan duration) - { - var width = message.Length + 6; - var height = 5; - // var lines = Label.MeasureLines(message, width); - - var dialog = new Dialog(null, width, height); - - var label = new Label((width - 4 - message.Length) / 2, 0, message); - dialog.Add(label); - - Task.Delay(duration).ContinueWith(t => dialog.Running = false); - Application.Run(dialog); - } -} \ No newline at end of file diff --git a/src/RepoM.App/App.xaml.cs b/src/RepoM.App/App.xaml.cs index d941f9ff..3f3ab00d 100644 --- a/src/RepoM.App/App.xaml.cs +++ b/src/RepoM.App/App.xaml.cs @@ -27,13 +27,13 @@ namespace RepoM.App; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Deserialization; using RepoM.App.i18n; using RepoM.Core.Plugin; -using RepoM.Ipc; using SimpleInjector; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Serilog; using Serilog.Core; using ILogger = Microsoft.Extensions.Logging.ILogger; +using RepoM.App.Services; /// /// Interaction logic for App.xaml @@ -189,8 +189,6 @@ private static void RegisterLogging(ILoggerFactory loggerFactory) private static void RegisterServices(Container container, IFileSystem fileSystem) { - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); diff --git a/src/RepoM.App/Controls/AcrylicContextMenu.cs b/src/RepoM.App/Controls/AcrylicContextMenu.cs index 1b3bed7e..b730a7cd 100644 --- a/src/RepoM.App/Controls/AcrylicContextMenu.cs +++ b/src/RepoM.App/Controls/AcrylicContextMenu.cs @@ -2,6 +2,7 @@ namespace RepoM.App.Controls; using System.Windows; using System.Windows.Controls; +using RepoM.App.Services; public class AcrylicContextMenu : ContextMenu { diff --git a/src/RepoM.App/Controls/AcrylicMenuItem.cs b/src/RepoM.App/Controls/AcrylicMenuItem.cs index bc0a2caf..33bb1fe2 100644 --- a/src/RepoM.App/Controls/AcrylicMenuItem.cs +++ b/src/RepoM.App/Controls/AcrylicMenuItem.cs @@ -4,6 +4,7 @@ namespace RepoM.App.Controls; using System.Windows; using System.Windows.Controls; using System.Windows.Media; +using RepoM.App.Services; public class AcrylicMenuItem : MenuItem { diff --git a/src/RepoM.App/CustomRepositoryViewSortBehavior.cs b/src/RepoM.App/CustomRepositoryViewSortComparer.cs similarity index 67% rename from src/RepoM.App/CustomRepositoryViewSortBehavior.cs rename to src/RepoM.App/CustomRepositoryViewSortComparer.cs index b415197d..426a6b2b 100644 --- a/src/RepoM.App/CustomRepositoryViewSortBehavior.cs +++ b/src/RepoM.App/CustomRepositoryViewSortComparer.cs @@ -3,11 +3,11 @@ namespace RepoM.App; using System.Collections; using RepoM.Api.Git; -internal class CustomRepositoryViewSortBehavior : IComparer +internal class CustomRepositoryViewSortComparer : IComparer { public int Compare(object? x, object? y) { - if (x is RepositoryView xView && y is RepositoryView yView) + if (x is IRepositoryView xView && y is IRepositoryView yView) { return Compare(xView, yView); } @@ -15,7 +15,7 @@ public int Compare(object? x, object? y) return 0; } - private static int Compare(RepositoryView x, RepositoryView y) + private static int Compare(IRepositoryView x, IRepositoryView y) { if (x.IsPinned == y.IsPinned) { diff --git a/src/RepoM.App/DelegateCommand.cs b/src/RepoM.App/DelegateCommand.cs new file mode 100644 index 00000000..9fa856e9 --- /dev/null +++ b/src/RepoM.App/DelegateCommand.cs @@ -0,0 +1,30 @@ +namespace RepoM.App; + +using System; +using System.Windows.Input; + +/// +/// Simplistic delegate command for the demo. +/// +public class DelegateCommand : ICommand +{ + public Action? CommandAction { get; set; } + + public Func? CanExecuteFunc { get; set; } + + public void Execute(object? parameter) + { + CommandAction?.Invoke(); + } + + public bool CanExecute(object? parameter) + { + return CanExecuteFunc?.Invoke() ?? true; + } + + public event EventHandler? CanExecuteChanged + { + add => CommandManager.RequerySuggested += value; + remove => CommandManager.RequerySuggested -= value; + } +} \ No newline at end of file diff --git a/src/RepoM.App/MainWindow.xaml.cs b/src/RepoM.App/MainWindow.xaml.cs index 102deb3a..7e1cb686 100644 --- a/src/RepoM.App/MainWindow.xaml.cs +++ b/src/RepoM.App/MainWindow.xaml.cs @@ -18,6 +18,7 @@ namespace RepoM.App; using RepoM.Api.Git; using RepoM.Api.IO; using RepoM.App.Controls; +using RepoM.App.Services; using SourceChord.FluentWPF; /// @@ -74,7 +75,7 @@ public MainWindow( var view = (ListCollectionView)CollectionViewSource.GetDefaultView(aggregator.Repositories); ((ICollectionView)view).CollectionChanged += View_CollectionChanged; view.Filter = FilterRepositories; - view.CustomSort = new CustomRepositoryViewSortBehavior(); + view.CustomSort = new CustomRepositoryViewSortComparer(); AssemblyName? appName = Assembly.GetEntryAssembly()?.GetName(); txtHelpCaption.Text = appName?.Name + " " + appName?.Version?.ToString(2); diff --git a/src/RepoM.App/NotifyIconViewModel.cs b/src/RepoM.App/NotifyIconViewModel.cs index 1aa2493c..9ffed5c7 100644 --- a/src/RepoM.App/NotifyIconViewModel.cs +++ b/src/RepoM.App/NotifyIconViewModel.cs @@ -1,8 +1,8 @@ namespace RepoM.App; -using System; using System.Windows; using System.Windows.Input; +using RepoM.App.Services; /// /// Provides bindable properties and commands for the NotifyIcon. In this sample, the @@ -43,30 +43,4 @@ public class NotifyIconViewModel { CommandAction = () => Application.Current.Shutdown(), }; -} - -/// -/// Simplistic delegate command for the demo. -/// -public class DelegateCommand : ICommand -{ - public Action? CommandAction { get; set; } - - public Func? CanExecuteFunc { get; set; } - - public void Execute(object? parameter) - { - CommandAction?.Invoke(); - } - - public bool CanExecute(object? parameter) - { - return CanExecuteFunc?.Invoke() ?? true; - } - - public event EventHandler? CanExecuteChanged - { - add => CommandManager.RequerySuggested += value; - remove => CommandManager.RequerySuggested -= value; - } } \ No newline at end of file diff --git a/src/RepoM.App/RepoM.App.csproj b/src/RepoM.App/RepoM.App.csproj index 4f3020f4..810d07cb 100644 --- a/src/RepoM.App/RepoM.App.csproj +++ b/src/RepoM.App/RepoM.App.csproj @@ -21,11 +21,9 @@ - - @@ -52,8 +50,7 @@ - - + @@ -72,5 +69,9 @@ Settings.Designer.cs + + + + \ No newline at end of file diff --git a/src/RepoM.App/AcrylicHelper.cs b/src/RepoM.App/Services/AcrylicHelper.cs similarity index 93% rename from src/RepoM.App/AcrylicHelper.cs rename to src/RepoM.App/Services/AcrylicHelper.cs index a7256d84..902ad79a 100644 --- a/src/RepoM.App/AcrylicHelper.cs +++ b/src/RepoM.App/Services/AcrylicHelper.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System; using System.Windows; diff --git a/src/RepoM.App/AutoStart.cs b/src/RepoM.App/Services/AutoStart.cs similarity index 97% rename from src/RepoM.App/AutoStart.cs rename to src/RepoM.App/Services/AutoStart.cs index c6f23e68..c3c529ec 100644 --- a/src/RepoM.App/AutoStart.cs +++ b/src/RepoM.App/Services/AutoStart.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System; using System.Reflection; diff --git a/src/RepoM.App/HotKey.cs b/src/RepoM.App/Services/HotKey.cs similarity index 98% rename from src/RepoM.App/HotKey.cs rename to src/RepoM.App/Services/HotKey.cs index a92550fd..620beaf8 100644 --- a/src/RepoM.App/HotKey.cs +++ b/src/RepoM.App/Services/HotKey.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System; using System.Runtime.InteropServices; diff --git a/src/RepoM.App/PluginFinder.cs b/src/RepoM.App/Services/PluginFinder.cs similarity index 82% rename from src/RepoM.App/PluginFinder.cs rename to src/RepoM.App/Services/PluginFinder.cs index 082eb738..54c88928 100644 --- a/src/RepoM.App/PluginFinder.cs +++ b/src/RepoM.App/Services/PluginFinder.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System.Collections.Generic; using System.IO; @@ -7,14 +7,8 @@ namespace RepoM.App; internal static class PluginFinder { - // private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public static IEnumerable FindPluginAssemblies(string baseDirectory,IFileSystem fileSystem) { - // Guard.NotNullOrWhiteSpace(baseDirectory, nameof(baseDirectory)); - - // Logger.Debug(() => $"Plugin base directory {baseDirectory}"); - IEnumerable assemblies = GetPluginAssembliesInDirectory(baseDirectory); foreach (var dir in GetPluginDirectories(baseDirectory, fileSystem)) @@ -22,8 +16,6 @@ public static IEnumerable FindPluginAssemblies(string baseDirectory,IF assemblies = assemblies.Concat(GetPluginAssembliesInDirectory(dir)); } - // LogFoundAssemblies(assemblies); - return assemblies; } diff --git a/src/RepoM.App/TaskBarLocator.cs b/src/RepoM.App/Services/TaskBarLocator.cs similarity index 96% rename from src/RepoM.App/TaskBarLocator.cs rename to src/RepoM.App/Services/TaskBarLocator.cs index f7f27cd9..762098bd 100644 --- a/src/RepoM.App/TaskBarLocator.cs +++ b/src/RepoM.App/Services/TaskBarLocator.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System.Windows.Forms; diff --git a/src/RepoM.App/WindowsCompositionHelper.cs b/src/RepoM.App/Services/WindowsCompositionHelper.cs similarity index 98% rename from src/RepoM.App/WindowsCompositionHelper.cs rename to src/RepoM.App/Services/WindowsCompositionHelper.cs index 0c3af9c0..155e9ba7 100644 --- a/src/RepoM.App/WindowsCompositionHelper.cs +++ b/src/RepoM.App/Services/WindowsCompositionHelper.cs @@ -1,4 +1,4 @@ -namespace RepoM.App; +namespace RepoM.App.Services; using System; using System.Drawing.Printing; diff --git a/src/RepoM.Ipc/DefaultIpcEndpoint.cs b/src/RepoM.Ipc/DefaultIpcEndpoint.cs deleted file mode 100644 index 9eb33f84..00000000 --- a/src/RepoM.Ipc/DefaultIpcEndpoint.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace RepoM.Ipc; - -public class DefaultIpcEndpoint : IIpcEndpoint -{ - public string Address => "tcp://localhost:18181"; -} \ No newline at end of file diff --git a/src/RepoM.Ipc/IIpcEndpoint.cs b/src/RepoM.Ipc/IIpcEndpoint.cs deleted file mode 100644 index 1e60b307..00000000 --- a/src/RepoM.Ipc/IIpcEndpoint.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace RepoM.Ipc; - -public interface IIpcEndpoint -{ - string Address { get; } -} \ No newline at end of file diff --git a/src/RepoM.Ipc/IRepositorySource.cs b/src/RepoM.Ipc/IRepositorySource.cs deleted file mode 100644 index 0effd22f..00000000 --- a/src/RepoM.Ipc/IRepositorySource.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace RepoM.Ipc; - -public interface IRepositorySource -{ - Repository[] GetMatchingRepositories(string repositoryNamePattern); -} \ No newline at end of file diff --git a/src/RepoM.Ipc/IpcClient.cs b/src/RepoM.Ipc/IpcClient.cs deleted file mode 100644 index 974a5377..00000000 --- a/src/RepoM.Ipc/IpcClient.cs +++ /dev/null @@ -1,92 +0,0 @@ -namespace RepoM.Ipc; - -using System; -using System.Diagnostics; -using System.Linq; -using System.Text; -using NetMQ; -using NetMQ.Sockets; - -public class IpcClient -{ - private string? _answer; - private Repository[]? _repositories; - - public IpcClient(IIpcEndpoint endpointProvider) - { - EndpointProvider = endpointProvider ?? throw new ArgumentNullException(nameof(endpointProvider)); - } - - public Result GetRepositories() - { - return GetRepositories("list:.*"); - } - - public Result GetRepositories(string? query) - { - query ??= string.Empty; - var watch = Stopwatch.StartNew(); - - _answer = null; - _repositories = null; - - using (var client = new RequestSocket()) - { - client.Connect(EndpointProvider.Address); - - var load = Encoding.UTF8.GetBytes(query); - client.SendFrame(load); - client.ReceiveReady += ClientOnReceiveReady; - - client.Poll(TimeSpan.FromMilliseconds(3000)); - - client.ReceiveReady -= ClientOnReceiveReady; - client.Disconnect(EndpointProvider.Address); - } - - watch.Stop(); - - return new Result( - _answer ?? GetErrorMessage(), - watch.ElapsedMilliseconds, - _repositories); - } - - private string GetErrorMessage() - { - var isRepoMRunning = Process.GetProcessesByName("RepoM").Any(); - return isRepoMRunning - ? $"RepoM seems to be running but does not answer.\nIt seems that it could not listen on {EndpointProvider.Address}.\nI don't know anything better than recommending a reboot. Sorry." - : "RepoM seems not to be running :("; - } - - private void ClientOnReceiveReady(object sender, NetMQSocketEventArgs e) - { - _answer = Encoding.UTF8.GetString(e.Socket.ReceiveFrameBytes()); - - _repositories = _answer.Split(new string[] { Environment.NewLine, }, StringSplitOptions.None) - .Select(s => Repository.FromString(s)) - .Where(r => r != null) - .Cast() - .OrderBy(r => r.Name) - .ToArray(); - } - - public IIpcEndpoint EndpointProvider { get; } - - public class Result - { - public Result(string answer, long durationMilliseconds, Repository[]? repositories) - { - Answer = answer; - DurationMilliseconds = durationMilliseconds; - Repositories = repositories ?? Array.Empty(); - } - - public string Answer { get; } - - public long DurationMilliseconds { get; } - - public Repository[] Repositories { get; } - } -} \ No newline at end of file diff --git a/src/RepoM.Ipc/RepoM.Ipc.csproj b/src/RepoM.Ipc/RepoM.Ipc.csproj deleted file mode 100644 index 90d874cb..00000000 --- a/src/RepoM.Ipc/RepoM.Ipc.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - netstandard2.0 - - - - - - - - - - - - \ No newline at end of file diff --git a/src/RepoM.Ipc/Repository.cs b/src/RepoM.Ipc/Repository.cs deleted file mode 100644 index e90ed286..00000000 --- a/src/RepoM.Ipc/Repository.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace RepoM.Ipc; - -using System; - -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class Repository -{ - public Repository(string name) - { - Name = name; - } - - public static Repository? FromString(string value) - { - var parts = value.Split(new string[] { "::", }, System.StringSplitOptions.None); - var partsCount = parts.Length; - - var validFormat = partsCount is 3 or 4; - if (!validFormat) - { - return null; - } - - return new Repository(parts[0]) - { - BranchWithStatus = parts[1], - Path = parts[2], - HasUnpushedChanges = parts.Length > 3 && parts[3] == "1", - }; - } - - public override string ToString() - { - if (string.IsNullOrEmpty(Name) || string.IsNullOrEmpty(BranchWithStatus) || string.IsNullOrEmpty(Path)) - { - return ""; - } - - return $"{Name}::{BranchWithStatus}::{Path}::{(HasUnpushedChanges ? "1" : "0")}"; - } - - public string Name { get; } - - public string? BranchWithStatus { get; set; } - - public string? Path { get; set; } - - public bool HasUnpushedChanges { get; set; } - - public string SafePath => Path?.Replace(@"\", "/") ?? string.Empty; - - public string[] ReadAllBranches() - { - return Array.Empty(); - } -} \ No newline at end of file diff --git a/src/RepoM.Ipc/RepositorySource.cs b/src/RepoM.Ipc/RepositorySource.cs deleted file mode 100644 index 96775ba9..00000000 --- a/src/RepoM.Ipc/RepositorySource.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace RepoM.Ipc; - -using System.Linq; -using RepoM.Api.Git; - -public class RepositorySource : IRepositorySource -{ - private readonly IRepositoryInformationAggregator _repositoryInformationAggregator; - - public RepositorySource(IRepositoryInformationAggregator repositoryInformationAggregator) - { - _repositoryInformationAggregator = repositoryInformationAggregator; - } - - public Repository[] GetMatchingRepositories(string repositoryNamePattern) - { - return _repositoryInformationAggregator - .Repositories - .Where(r => r.MatchesRegexFilter(repositoryNamePattern)) - .Select(r => new Repository(r.Name) - { - BranchWithStatus = r.BranchWithStatus, - HasUnpushedChanges = r.HasUnpushedChanges, - Path = r.Path, - }) - .ToArray(); - } -} \ No newline at end of file diff --git a/src/RepoM.Plugin.IpcService/IpcServer.cs b/src/RepoM.Plugin.IpcService/IpcServer.cs deleted file mode 100644 index a65bfdc8..00000000 --- a/src/RepoM.Plugin.IpcService/IpcServer.cs +++ /dev/null @@ -1,85 +0,0 @@ -namespace RepoM.Plugin.IpcService; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using NetMQ; -using NetMQ.Sockets; -using RepoM.Ipc; - -internal class IpcServer : IDisposable -{ - private ResponseSocket? _socketServer; - private readonly IIpcEndpoint _endpointProvider; - private readonly IRepositorySource _repositorySource; - - public IpcServer(IIpcEndpoint endpointProvider, IRepositorySource repositorySource) - { - _endpointProvider = endpointProvider ?? throw new ArgumentNullException(nameof(endpointProvider)); - _repositorySource = repositorySource ?? throw new ArgumentNullException(nameof(repositorySource)); - } - - public void Start() - { - Task.Run(() => StartInternal()); - } - - private void StartInternal() - { - _socketServer = new ResponseSocket(_endpointProvider.Address); - - while (true) - { - var load = _socketServer.ReceiveFrameBytes(out var hasMore); - - var message = Encoding.UTF8.GetString(load); - - if (string.IsNullOrEmpty(message)) - { - return; - } - - if (message.StartsWith("list:", StringComparison.Ordinal)) - { - var repositoryNamePattern = message.Substring("list:".Length); - - var answer = "(no repositories found)"; - try - { - Repository[] repos = _repositorySource.GetMatchingRepositories(repositoryNamePattern); - if (repos.Any()) - { - IEnumerable serializedRepositories = repos - .Where(r => r != null) - .Select(r => r.ToString()); - - answer = string.Join(Environment.NewLine, serializedRepositories); - } - } - catch (Exception ex) - { - answer = ex.Message; - } - - _socketServer.SendFrame(Encoding.UTF8.GetBytes(answer)); - } - - Thread.Sleep(100); - } - } - - public void Stop() - { - Dispose(); - } - - public void Dispose() - { - _socketServer?.Disconnect(_endpointProvider.Address); - _socketServer?.Dispose(); - _socketServer = null; - } -} \ No newline at end of file diff --git a/src/RepoM.Plugin.IpcService/IpcServerModule.cs b/src/RepoM.Plugin.IpcService/IpcServerModule.cs deleted file mode 100644 index 145c9085..00000000 --- a/src/RepoM.Plugin.IpcService/IpcServerModule.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace RepoM.Plugin.IpcService; - -using System; -using System.Threading.Tasks; -using JetBrains.Annotations; -using RepoM.Core.Plugin; - -[UsedImplicitly] -internal class IpcServerModule : IModule, IDisposable -{ - private readonly IpcServer _server; - - public IpcServerModule(IpcServer server) - { - _server = server ?? throw new ArgumentNullException(nameof(server)); - } - - public Task StartAsync() - { - _server.Start(); - return Task.CompletedTask; - } - - public Task StopAsync() - { - _server.Stop(); - return Task.CompletedTask; - } - - public void Dispose() - { - _server.Dispose(); - } -} \ No newline at end of file diff --git a/src/RepoM.Plugin.IpcService/IpcServicePackage.cs b/src/RepoM.Plugin.IpcService/IpcServicePackage.cs deleted file mode 100644 index 1bf9b8a0..00000000 --- a/src/RepoM.Plugin.IpcService/IpcServicePackage.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace RepoM.Plugin.IpcService; - -using JetBrains.Annotations; -using RepoM.Core.Plugin; -using RepoM.Ipc; -using SimpleInjector; -using SimpleInjector.Packaging; - -[UsedImplicitly] -public class IpcServicePackage : IPackage -{ - public void RegisterServices(Container container) - { - //IRepositorySource - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Collection.Append(Lifestyle.Singleton); - } -} \ No newline at end of file diff --git a/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj b/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj deleted file mode 100644 index 1d503cb2..00000000 --- a/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj +++ /dev/null @@ -1,25 +0,0 @@ -ο»Ώ - - - netstandard2.0 - - - - - - - - - - - - - - - - - <_Parameter1>RepoM.Ipc.Tests - - - - diff --git a/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj b/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj index d72ec92e..9233b3c2 100644 --- a/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj +++ b/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj @@ -15,7 +15,6 @@ - diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample1.verified.txt index 112e6b7c..00e57bae 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample1.verified.txt @@ -1,30 +1,25 @@ ο»Ώ{ Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false }, { - $type: Variable, Name: work_repo_2, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: false }, { - $type: Variable, Name: is_private_repo, Value: false }, { - $type: Variable, Name: x, Value: y } @@ -32,13 +27,11 @@ TagsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -46,17 +39,14 @@ ], Tags: [ { - $type: RepositoryActionTag, Tag: work, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt index 92ad51cf..e5b5fe5f 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt @@ -1,30 +1,25 @@ ο»Ώ{ Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false }, { - $type: Variable, Name: work_repo_2, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: false }, { - $type: Variable, Name: is_private_repo, Value: false }, { - $type: Variable, Name: x, Value: y } @@ -32,13 +27,11 @@ TagsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -46,17 +39,14 @@ ], Tags: [ { - $type: RepositoryActionTag, Tag: work, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag } ] @@ -64,13 +54,11 @@ ActionsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -85,7 +73,6 @@ MultiSelectEnabled: true, Variables: [ { - $type: Variable, Name: name, Value: {StringContains({Repository.SafePath}, "abc")} } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt index e901f7af..13296a66 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt @@ -1,52 +1,43 @@ ο»Ώ{ RepositorySpecificEnvironmentFiles: [ { - $type: FileReference, Filename: ab1.env, When: false }, { - $type: FileReference, Filename: ab.env } ], RepositorySpecificConfigFiles: [ { - $type: FileReference, Filename: {Repostitory.Path}\RepositoryActions.json, When: false }, { - $type: FileReference, Filename: {Repostitory.Path}\.git\RepositoryActions.json } ], Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false }, { - $type: Variable, Name: work_repo_2, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: false }, { - $type: Variable, Name: is_private_repo, Value: false }, { - $type: Variable, Name: x, Value: y } @@ -54,13 +45,11 @@ TagsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -68,17 +57,14 @@ ], Tags: [ { - $type: RepositoryActionTag, Tag: work, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag } ] @@ -86,13 +72,11 @@ ActionsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -107,7 +91,6 @@ MultiSelectEnabled: true, Variables: [ { - $type: Variable, Name: name, Value: {StringContains({Repository.SafePath}, "abc")} } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithLatestTags_WhenContentHasDoubleTags.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithLatestTags_WhenContentHasDoubleTags.verified.txt index 74746156..b8718ddd 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithLatestTags_WhenContentHasDoubleTags.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithLatestTags_WhenContentHasDoubleTags.verified.txt @@ -2,17 +2,14 @@ TagsCollection: { Tags: [ { - $type: RepositoryActionTag, Tag: work1, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private1, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag1 } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt index 08053044..03e41708 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt @@ -10,7 +10,6 @@ MultiSelectEnabled: true, Variables: [ { - $type: Variable, Name: name, Value: {StringContains({Repository.SafePath}, "abc")} } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt index 8dd8ea3e..9a38f9b1 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt @@ -3,13 +3,11 @@ ActionsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -25,7 +23,6 @@ MultiSelectEnabled: true, Variables: [ { - $type: Variable, Name: name, Value: {StringContains({Repository.SafePath}, "abc")} } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags1.verified.txt index 109c9a18..5366c5a4 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags1.verified.txt @@ -2,17 +2,14 @@ TagsCollection: { Tags: [ { - $type: RepositoryActionTag, Tag: work, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags3.verified.txt index 67fd5bf5..27bcaf7c 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryTags_WhenContentIsRepositoryTags3.verified.txt @@ -2,13 +2,11 @@ TagsCollection: { Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false @@ -16,17 +14,14 @@ ], Tags: [ { - $type: RepositoryActionTag, Tag: work, When: {StringContains({Repository.SafePath}, "work")} }, { - $type: RepositoryActionTag, Tag: private, When: {StringContains({Repository.SafePath}, "Private")} }, { - $type: RepositoryActionTag, Tag: always-tag } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithVariables_WhenContentIsVariablesOnly.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithVariables_WhenContentIsVariablesOnly.verified.txt index 19ef0e17..8887d590 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithVariables_WhenContentIsVariablesOnly.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithVariables_WhenContentIsVariablesOnly.verified.txt @@ -1,30 +1,25 @@ ο»Ώ{ Variables: [ { - $type: Variable, Name: work_repo, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: true }, { - $type: Variable, Name: work_repo_1, Value: true, Enabled: false }, { - $type: Variable, Name: work_repo_2, Value: {StringContains({Repository.SafePath}, "work")}, Enabled: false }, { - $type: Variable, Name: is_private_repo, Value: false }, { - $type: Variable, Name: x, Value: y } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificConfigFile1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificConfigFile1.verified.txt index 82f1a35f..7323a4dd 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificConfigFile1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificConfigFile1.verified.txt @@ -1,12 +1,10 @@ ο»Ώ{ RepositorySpecificConfigFiles: [ { - $type: FileReference, Filename: ab1.env, When: false }, { - $type: FileReference, Filename: ab.env } ], diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificEnvFile1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificEnvFile1.verified.txt index 4d610c84..01f67e1d 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificEnvFile1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObject_WhenContentIsRepositorySpecificEnvFile1.verified.txt @@ -1,12 +1,10 @@ ο»Ώ{ RepositorySpecificEnvironmentFiles: [ { - $type: FileReference, Filename: ab1.env, When: false }, { - $type: FileReference, Filename: ab.env } ], diff --git a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj index 252dd815..77c1125d 100644 --- a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj +++ b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj @@ -14,12 +14,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/tests/RepoM.Api.Tests/TestFramework/VerifierInitializer.cs b/tests/RepoM.Api.Tests/TestFramework/VerifierInitializer.cs index b467d94b..f34cddd8 100644 --- a/tests/RepoM.Api.Tests/TestFramework/VerifierInitializer.cs +++ b/tests/RepoM.Api.Tests/TestFramework/VerifierInitializer.cs @@ -1,7 +1,7 @@ namespace RepoM.Api.Tests.TestFramework; using System.Runtime.CompilerServices; -using Newtonsoft.Json; +using Argon; using VerifyTests; public static class VerifierInitializer diff --git a/tests/RepoM.Ipc.Tests/Internals/TestIpcEndpoint.cs b/tests/RepoM.Ipc.Tests/Internals/TestIpcEndpoint.cs deleted file mode 100644 index 6d36ea37..00000000 --- a/tests/RepoM.Ipc.Tests/Internals/TestIpcEndpoint.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace RepoM.Ipc.Tests.Internals; - -using RepoM.Ipc; - -internal class TestIpcEndpoint : IIpcEndpoint -{ - public string Address => "tcp://localhost:18182"; -} \ No newline at end of file diff --git a/tests/RepoM.Ipc.Tests/Internals/VerifierInitializer.cs b/tests/RepoM.Ipc.Tests/Internals/VerifierInitializer.cs deleted file mode 100644 index 121d89bf..00000000 --- a/tests/RepoM.Ipc.Tests/Internals/VerifierInitializer.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace RepoM.Ipc.Tests.Internals; - -using System.Runtime.CompilerServices; -using Newtonsoft.Json; -using VerifyTests; - -public static class VerifierInitializer -{ - [ModuleInitializer] - public static void Initialize() - { - VerifierSettings.DisableRequireUniquePrefix(); - VerifierSettings.AddExtraSettings(serializerSettings => serializerSettings.TypeNameHandling = TypeNameHandling.Auto); - } -} \ No newline at end of file diff --git a/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj b/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj deleted file mode 100644 index 1fb2aefe..00000000 --- a/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net6.0 - - - - - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - diff --git a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.GetMatchingRepositories_ShouldReturnExpected.verified.txt b/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.GetMatchingRepositories_ShouldReturnExpected.verified.txt deleted file mode 100644 index 7dde9420..00000000 --- a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.GetMatchingRepositories_ShouldReturnExpected.verified.txt +++ /dev/null @@ -1,10 +0,0 @@ -ο»Ώ[ - { - $type: Repository, - Name: N, - BranchWithStatus: B, - Path: P, - HasUnpushedChanges: false, - SafePath: P - } -] \ No newline at end of file diff --git a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs b/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs deleted file mode 100644 index 6edb4bb7..00000000 --- a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -namespace RepoM.Ipc.Tests; - -using System; -using System.Threading; -using System.Threading.Tasks; -using FakeItEasy; -using FluentAssertions; -using RepoM.Ipc; -using RepoM.Ipc.Tests.Internals; -using RepoM.Plugin.IpcService; -using VerifyXunit; -using Xunit; - -[UsesVerify] -public class RepoMIpcClientTests : IDisposable -{ - private readonly IRepositorySource _repositorySource; - private readonly IpcClient _client; - private readonly IpcServer _server; - - public RepoMIpcClientTests() - { - _repositorySource = A.Fake(); - var endpoint = new TestIpcEndpoint(); - _client = new IpcClient(endpoint); - _server = new IpcServer(endpoint, _repositorySource); - } - - public void Dispose() - { - _server.Stop(); - _server.Dispose(); - } - - [Fact] - public void GetRepositories_SHouldReturnErrorMessage_WhenServerUnreachable() - { - // arrange - _server.Stop(); - - // act - IpcClient.Result result = _client.GetRepositories(); - - // assert - result.Answer.Should().StartWith("RepoM seems"); // ... to be running but ... -> indicates an error - } - - [Fact] - public async Task GetMatchingRepositories_ShouldReturnExpected() - { - // arrange - A.CallTo(() => _repositorySource.GetMatchingRepositories(A._)) - .Returns(new Repository[] - { - new Repository("N") - { - BranchWithStatus = "B", - Path = "P", - }, - }); - _server.Start(); - - // act - IpcClient.Result result = _client.GetRepositories(); - - // assert - await Verifier.Verify(result.Repositories); - } - - [Fact] - public void Stop_ShouldNotThrow_WhenAlreadyStopped() - { - // arrange - _server.Start(); - // just to be sure, slee[p for two seconds. Normally, this is not okay but accepted for now. - Thread.Sleep(2000); - _server.Stop(); - - // act - Action act = () => _server.Stop(); - - // assert - act.Should().NotThrow(); - } -} \ No newline at end of file diff --git a/tests/RepoM.Ipc.Tests/RepositoryTests.cs b/tests/RepoM.Ipc.Tests/RepositoryTests.cs deleted file mode 100644 index cc82613d..00000000 --- a/tests/RepoM.Ipc.Tests/RepositoryTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -namespace RepoM.Ipc.Tests; - -using FluentAssertions; -using RepoM.Ipc; -using Xunit; - -public class RepositoryTests -{ - [Fact] - public void Deserializes_With_Three_Arguments() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch::Path")!; - - // assert - result.Name.Should().Be("Name"); - result.BranchWithStatus.Should().Be("Branch"); - result.Path.Should().Be("Path"); - result.HasUnpushedChanges.Should().BeFalse(); - } - - [Fact] - public void Deserializes_With_Four_Arguments() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch::Path::1")!; - - // assert - result.Name.Should().Be("Name"); - result.BranchWithStatus.Should().Be("Branch"); - result.Path.Should().Be("Path"); - result.HasUnpushedChanges.Should().BeTrue(); - } - - [Fact] - public void Returns_Null_For_Less_Than_Three_Arguments() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch"); - - // assert - result.Should().BeNull(); - } - - [Fact] - public void Returns_Null_For_Too_Much_Arguments() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch::Path::1::Mode"); - - // assert - result.Should().BeNull(); - } - - [Fact] - public void Serializes_With_Four_Arguments() - { - // arrange - - // act - var result = new Repository("N") - { - BranchWithStatus = "B", - Path = "P", - }; - - // assert - result.ToString().Should().Be("N::B::P::0"); // 0 is "HasUnpushedChanges" - } - - [Fact] - public void Returns_Null_For_Less_Than_Mandatory_Arguments() - { - // arrange - - // act - var result = new Repository("N") { BranchWithStatus = "B", }; - - // assert - result.ToString().Should().Be(""); - } - - [Fact] - public void Replaces_Backslashes_With_Slashes() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch::C:\\Users\\doe")!; - - // assert - result.SafePath.Should().Be("C:/Users/doe"); - } - - [Fact] - public void Returns_Empty_String_For_Null_Path() - { - // arrange - - // act - var result = Repository.FromString("Name::Branch::C:\\Users\\doe")!; - - // assert - result.Path = null!; - result.SafePath.Should().Be(""); - } -} diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj index 3cbf4884..d2eba2e5 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj @@ -16,12 +16,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/TestFramework/VerifierInitializer.cs b/tests/RepoM.Plugin.AzureDevOps.Tests/TestFramework/VerifierInitializer.cs index 6108ce14..2303643f 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/TestFramework/VerifierInitializer.cs +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/TestFramework/VerifierInitializer.cs @@ -1,7 +1,7 @@ namespace RepoM.Plugin.AzureDevOps.Tests.TestFramework; using System.Runtime.CompilerServices; -using Newtonsoft.Json; +using Argon; using VerifyTests; public static class VerifierInitializer diff --git a/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj b/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj index 32300513..929fdef9 100644 --- a/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj +++ b/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj @@ -10,7 +10,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj index 5e6df265..b6f59eff 100644 --- a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj +++ b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj @@ -16,12 +16,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/tests/RepoM.Plugin.SonarCloud.Tests/TestFramework/VerifierInitializer.cs b/tests/RepoM.Plugin.SonarCloud.Tests/TestFramework/VerifierInitializer.cs index 28442519..2b5786dc 100644 --- a/tests/RepoM.Plugin.SonarCloud.Tests/TestFramework/VerifierInitializer.cs +++ b/tests/RepoM.Plugin.SonarCloud.Tests/TestFramework/VerifierInitializer.cs @@ -1,7 +1,7 @@ namespace RepoM.Plugin.SonarCloud.Tests.TestFramework; using System.Runtime.CompilerServices; -using Newtonsoft.Json; +using Argon; using VerifyTests; public static class VerifierInitializer diff --git a/tests/Specs/Specs.csproj b/tests/Specs/Specs.csproj index 999d41ac..4bcd9b97 100644 --- a/tests/Specs/Specs.csproj +++ b/tests/Specs/Specs.csproj @@ -12,13 +12,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/tests/Tests/Tests.csproj b/tests/Tests/Tests.csproj index 4a210a51..a6cf0245 100644 --- a/tests/Tests/Tests.csproj +++ b/tests/Tests/Tests.csproj @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - +