diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e1cc88885..b55afb8db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,7 @@ jobs: permissions: contents: write + packages: write defaults: run: @@ -20,7 +21,7 @@ jobs: env: gitHubUserAccount: ${{ github.repository_owner }} - gitHubToken: ${{ secrets.GITHUB_TOKEN }} + gitHubToken: ${{ github.token }} FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true ENABLE_CHOCO_PUSH: false @@ -34,7 +35,10 @@ jobs: run: | ./build.ps1 ` -Target AppVeyorRelease ` - -Configuration Release + -Configuration Release ` + --isDryRun=false ` + --gitHubOwner=${{ github.repository_owner }} ` + --gitHubRepository=git-tfs - name: Upload release artifacts uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index e8a2771c8..db8c3a163 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,42 @@ ## Introduction -[git-tfs](http://git-tfs.com/) is a two-way bridge between TFS (Team Foundation Server) and git, similar to git-svn. +**git-tfs-lfs** is a community-maintained fork of [git-tfs](http://git-tfs.com/) with **full Git LFS support**. + +git-tfs is a two-way bridge between TFS (Team Foundation Server) and git, similar to git-svn. It fetches TFS commits into a git repository, and lets you push your updates back to TFS. -[![git-tfs version](https://img.shields.io/github/release/git-tfs/git-tfs.svg?label=Latest%20Version:)](https://github.com/git-tfs/git-tfs/releases). See the [change history](https://github.com/git-tfs/git-tfs/releases) for details and download. +### What's New in This Fork + +- **Full Git LFS awareness** via filter-process protocol - LFS files are properly handled from initial TFVC clone +- Updated dependencies (libgit2sharp 0.31, StructureMap 4.7.1, xunit 2.7) +- Support for Visual Studio 2019 and 2022 only (VS2015/2017 support dropped) + +### Upstream Status + +This is a fork of the [original git-tfs project](https://github.com/git-tfs/git-tfs) which has been largely dormant since 2024. The upstream maintainers are no longer active TFS users and the project is not actively maintained. This fork aims to maintain the project a little longer, with focus on LFS support and modern dependency updates. If you're having problems, check out the [troubleshooting](doc/TROUBLESHOOTING.md) page. And read [how to report an issue](doc/reporting-issues.md), before doing so ;) -## We need your help +## Get git-tfs-lfs -This project is no more **actively** maintained because we are no more users of TFS. -Thus being very useful, git-tfs is not exempt of not supported use cases. -If you encounter something missing or a problem, please contribute, we will be pleased to help you. +To get a stable version: -And remember: +* Download a binary from the [releases page](https://github.com/lucianm/git-tfs/releases) +* Using Scoop: `scoop install gittfs-lfs` (once the bucket PR is merged) +* Using WinGet: `winget install LucianM.GitTfsLfs` (once the package is approved) ->The fastest way to get an issue fixed is to submit a PR that fixes it. +### Original Upstream Version ->The slowest way to get it fixed is to hope someone else will fix it. +The original git-tfs is available at: +* [Upstream releases](https://github.com/git-tfs/git-tfs/releases) +* Using Chocolatey: `choco install gittfs` - installs the [upstream Chocolatey package](http://chocolatey.org/packages/gittfs) -## Get git-tfs +## Contributing -To get a stable version: +Contributions are welcome! Please submit PRs for bug fixes, features, or improvements. -* Download a binary. Find it on the [release page](https://github.com/git-tfs/git-tfs/releases), -* Using Chocolatey. If [Chocolatey](http://chocolatey.org/) is already installed on your computer, run `choco install gittfs` to install the [Chocolatey package](http://chocolatey.org/packages/gittfs) +>The fastest way to get an issue fixed is to submit a PR that fixes it. To get a development version diff --git a/doc/release-notes/NEXT.md b/doc/release-notes/NEXT.md index d5f525dd7..bb3525530 100644 --- a/doc/release-notes/NEXT.md +++ b/doc/release-notes/NEXT.md @@ -1,4 +1,37 @@ +# git-tfs-lfs - Initial Community Fork with Full LFS Support + +Community-maintained fork of git-tfs with full Git LFS awareness and updated dependencies. + +## Full Git LFS support + +Implemented complete Git LFS awareness using the Git filter-process protocol. + +LFS files are now handled correctly directly from the initial TFVC clone, including: + +* automatic smudge/clean operations, +* transparent pointer-file handling, +* compatibility with standard git-lfs, +* support during fetch and checkout operations. + +## Improvements + +* Updated LibGit2Sharp to v0.31 +* Updated StructureMap to v4.7.1 +* Updated xUnit tooling and test infrastructure +* Refreshed various dependencies for security and compatibility +* Added support for relative paths in .git redirection files + +## Breaking Changes + +* **Dropped Visual Studio 2015 support** - VS2015 project removed from solution +* **Dropped Visual Studio 2017 support** - VS2017 project removed from solution +* Minimum supported Visual Studio versions are now VS2019 and VS2022 + +## Bug Fixes (from upstream) + * fix: read/write of `description` in bare repos ( #1487 by bramborman ) -* chore: target .net v4.8 ( #1490 by @pmiossec ) -* chore: Update libgit2sharp to v0.30 ( #1492 by @pmiossec ) * Fix handling of renamed branches for clone/fetch ( #1493 by @dh2i-sam ) + +## Notes + +This fork maintains full backward compatibility with git-tfs repositories while adding comprehensive LFS support. The LFS filter implementation is based on the Git pkt-line protocol and integrates directly with the local git-lfs installation for all filter operations. diff --git a/doc/release-notes/v0.35.0.md b/doc/release-notes/v0.35.0.md new file mode 100644 index 000000000..bb3525530 --- /dev/null +++ b/doc/release-notes/v0.35.0.md @@ -0,0 +1,37 @@ +# git-tfs-lfs - Initial Community Fork with Full LFS Support + +Community-maintained fork of git-tfs with full Git LFS awareness and updated dependencies. + +## Full Git LFS support + +Implemented complete Git LFS awareness using the Git filter-process protocol. + +LFS files are now handled correctly directly from the initial TFVC clone, including: + +* automatic smudge/clean operations, +* transparent pointer-file handling, +* compatibility with standard git-lfs, +* support during fetch and checkout operations. + +## Improvements + +* Updated LibGit2Sharp to v0.31 +* Updated StructureMap to v4.7.1 +* Updated xUnit tooling and test infrastructure +* Refreshed various dependencies for security and compatibility +* Added support for relative paths in .git redirection files + +## Breaking Changes + +* **Dropped Visual Studio 2015 support** - VS2015 project removed from solution +* **Dropped Visual Studio 2017 support** - VS2017 project removed from solution +* Minimum supported Visual Studio versions are now VS2019 and VS2022 + +## Bug Fixes (from upstream) + +* fix: read/write of `description` in bare repos ( #1487 by bramborman ) +* Fix handling of renamed branches for clone/fetch ( #1493 by @dh2i-sam ) + +## Notes + +This fork maintains full backward compatibility with git-tfs repositories while adding comprehensive LFS support. The LFS filter implementation is based on the Git pkt-line protocol and integrates directly with the local git-lfs installation for all filter operations. diff --git a/src/.paket/Paket.Restore.targets b/src/.paket/Paket.Restore.targets deleted file mode 100644 index bbeec153f..000000000 --- a/src/.paket/Paket.Restore.targets +++ /dev/null @@ -1,560 +0,0 @@ - - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - $(MSBuildVersion) - 15.0.0 - false - true - - true - $(MSBuildThisFileDirectory) - $(MSBuildThisFileDirectory)..\ - $(PaketRootPath)paket-files\paket.restore.cached - $(PaketRootPath)paket.lock - classic - proj - assembly - native - /Library/Frameworks/Mono.framework/Commands/mono - mono - - - $(PaketRootPath)paket.bootstrapper.exe - $(PaketToolsPath)paket.bootstrapper.exe - $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ - - "$(PaketBootStrapperExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" - - - - - true - true - - - True - - - False - - $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) - - - - - - - - - $(PaketRootPath)paket - $(PaketToolsPath)paket - - - - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - - - - - - <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json")) - <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"')) - <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false - - - - - - - - - - - <_PaketCommand>dotnet paket - - - - - - $(PaketToolsPath)paket - $(PaketBootStrapperExeDir)paket - - - paket - - - - - <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)" - <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)" - - - - - - - - - - - - - - - - - - - - - true - $(NoWarn);NU1603;NU1604;NU1605;NU1608 - false - true - - - - - - - - - $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) - - - - - - - $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``)) - $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``)) - - - - - %(PaketRestoreCachedKeyValue.Value) - %(PaketRestoreCachedKeyValue.Value) - - - - - true - false - true - - - - - true - - - - - - - - - - - - - - - - - - - $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached - - $(MSBuildProjectFullPath).paket.references - - $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references - - $(MSBuildProjectDirectory)\paket.references - - false - true - true - references-file-or-cache-not-found - - - - - $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) - $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) - references-file - false - - - - - false - - - - - true - target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) - - - - - - - - - - - false - true - - - - - - - - - - - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[8]) - - - %(PaketReferencesFileLinesInfo.PackageVersion) - All - runtime - $(ExcludeAssets);contentFiles - $(ExcludeAssets);build;buildMultitargeting;buildTransitive - %(PaketReferencesFileLinesInfo.Aliases) - true - true - - - - - - $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools - - - - - - - - - $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) - $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) - - - %(PaketCliToolFileLinesInfo.PackageVersion) - - - - - - - - - - false - - - - - - <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/> - - - - - - $(MSBuildProjectDirectory)/$(MSBuildProjectFile) - true - false - true - false - true - false - true - false - true - false - true - $(PaketIntermediateOutputPath)\$(Configuration) - $(PaketIntermediateOutputPath) - - - - <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/> - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/.paket/paket.exe b/src/.paket/paket.exe deleted file mode 100644 index 1f5be73ef..000000000 Binary files a/src/.paket/paket.exe and /dev/null differ diff --git a/src/.paket/paket.targets b/src/.paket/paket.targets deleted file mode 100644 index e57d15cad..000000000 --- a/src/.paket/paket.targets +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - true - $(MSBuildThisFileDirectory) - $(MSBuildThisFileDirectory)..\ - $(PaketRootPath)paket.lock - $(PaketRootPath)paket-files\paket.restore.cached - /Library/Frameworks/Mono.framework/Commands/mono - mono - - - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - "$(PaketExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - - - - - - $(MSBuildProjectFullPath).paket.references - - - - - $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references - - - - - $(MSBuildProjectDirectory)\paket.references - - - - - - - - - - - - $(PaketCommand) restore --references-file "$(PaketReferences)" - - RestorePackages; $(BuildDependsOn); - - - - true - - - - $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) - $([System.IO.File]::ReadAllText('$(PaketLockFilePath)')) - true - false - true - - - - - diff --git a/src/GitTfs/Commands/CheckinOptions.cs b/src/GitTfs.Core/Commands/CheckinOptions.cs similarity index 97% rename from src/GitTfs/Commands/CheckinOptions.cs rename to src/GitTfs.Core/Commands/CheckinOptions.cs index 1c7de0ec8..261453354 100644 --- a/src/GitTfs/Commands/CheckinOptions.cs +++ b/src/GitTfs.Core/Commands/CheckinOptions.cs @@ -1,10 +1,8 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; using NDesk.Options; -using GitTfs.Util; namespace GitTfs.Commands { - [StructureMapSingleton] public class CheckinOptions { public OptionSet OptionSet => new OptionSet diff --git a/src/GitTfs/Commands/Helpers.cs b/src/GitTfs.Core/Commands/Helpers.cs similarity index 100% rename from src/GitTfs/Commands/Helpers.cs rename to src/GitTfs.Core/Commands/Helpers.cs diff --git a/src/GitTfs/Commands/RemoteOptions.cs b/src/GitTfs.Core/Commands/RemoteOptions.cs similarity index 97% rename from src/GitTfs/Commands/RemoteOptions.cs rename to src/GitTfs.Core/Commands/RemoteOptions.cs index 0039b9e34..26c024fb6 100644 --- a/src/GitTfs/Commands/RemoteOptions.cs +++ b/src/GitTfs.Core/Commands/RemoteOptions.cs @@ -1,9 +1,7 @@ -using GitTfs.Util; using NDesk.Options; namespace GitTfs.Commands { - [StructureMapSingleton] public class RemoteOptions { public OptionSet OptionSet => new OptionSet diff --git a/src/GitTfs/Commands/ShelveList.cs b/src/GitTfs.Core/Commands/ShelveList.cs similarity index 100% rename from src/GitTfs/Commands/ShelveList.cs rename to src/GitTfs.Core/Commands/ShelveList.cs diff --git a/src/GitTfs/ConfigProperties.cs b/src/GitTfs.Core/ConfigProperties.cs similarity index 100% rename from src/GitTfs/ConfigProperties.cs rename to src/GitTfs.Core/ConfigProperties.cs diff --git a/src/GitTfs/Core/Bootstrapper.cs b/src/GitTfs.Core/Core/Bootstrapper.cs similarity index 97% rename from src/GitTfs/Core/Bootstrapper.cs rename to src/GitTfs.Core/Core/Bootstrapper.cs index f329d3985..9e872f2a2 100644 --- a/src/GitTfs/Core/Bootstrapper.cs +++ b/src/GitTfs.Core/Core/Bootstrapper.cs @@ -1,4 +1,5 @@ -using GitTfs.Commands; // ToGitRefName() and RemoteOptions +using GitTfs.Commands; // RemoteOptions +using GitTfs.Util; // ToGitRefName() using System.Diagnostics; namespace GitTfs.Core diff --git a/src/GitTfs/Core/BranchVisitors/BranchTreeContainsPathVisitor.cs b/src/GitTfs.Core/Core/BranchVisitors/BranchTreeContainsPathVisitor.cs similarity index 100% rename from src/GitTfs/Core/BranchVisitors/BranchTreeContainsPathVisitor.cs rename to src/GitTfs.Core/Core/BranchVisitors/BranchTreeContainsPathVisitor.cs diff --git a/src/GitTfs/Core/Changes/Git/Add.cs b/src/GitTfs.Core/Core/Changes/Git/Add.cs similarity index 100% rename from src/GitTfs/Core/Changes/Git/Add.cs rename to src/GitTfs.Core/Core/Changes/Git/Add.cs diff --git a/src/GitTfs/Core/Changes/Git/Delete.cs b/src/GitTfs.Core/Core/Changes/Git/Delete.cs similarity index 100% rename from src/GitTfs/Core/Changes/Git/Delete.cs rename to src/GitTfs.Core/Core/Changes/Git/Delete.cs diff --git a/src/GitTfs/Core/Changes/Git/Modify.cs b/src/GitTfs.Core/Core/Changes/Git/Modify.cs similarity index 100% rename from src/GitTfs/Core/Changes/Git/Modify.cs rename to src/GitTfs.Core/Core/Changes/Git/Modify.cs diff --git a/src/GitTfs/Core/Changes/Git/RenameEdit.cs b/src/GitTfs.Core/Core/Changes/Git/RenameEdit.cs similarity index 100% rename from src/GitTfs/Core/Changes/Git/RenameEdit.cs rename to src/GitTfs.Core/Core/Changes/Git/RenameEdit.cs diff --git a/src/GitTfs/Core/CheckinPolicyEvaluator.cs b/src/GitTfs.Core/Core/CheckinPolicyEvaluator.cs similarity index 100% rename from src/GitTfs/Core/CheckinPolicyEvaluator.cs rename to src/GitTfs.Core/Core/CheckinPolicyEvaluator.cs diff --git a/src/GitTfs/Core/DelimitedReader.cs b/src/GitTfs.Core/Core/DelimitedReader.cs similarity index 100% rename from src/GitTfs/Core/DelimitedReader.cs rename to src/GitTfs.Core/Core/DelimitedReader.cs diff --git a/src/GitTfs/Core/DerivedGitTfsRemote.cs b/src/GitTfs.Core/Core/DerivedGitTfsRemote.cs similarity index 100% rename from src/GitTfs/Core/DerivedGitTfsRemote.cs rename to src/GitTfs.Core/Core/DerivedGitTfsRemote.cs diff --git a/src/GitTfs/Core/DirectoryTidier.cs b/src/GitTfs.Core/Core/DirectoryTidier.cs similarity index 100% rename from src/GitTfs/Core/DirectoryTidier.cs rename to src/GitTfs.Core/Core/DirectoryTidier.cs diff --git a/src/GitTfs/Core/ExportWorkItem.cs b/src/GitTfs.Core/Core/ExportWorkItem.cs similarity index 100% rename from src/GitTfs/Core/ExportWorkItem.cs rename to src/GitTfs.Core/Core/ExportWorkItem.cs diff --git a/src/GitTfs/Core/Ext.cs b/src/GitTfs.Core/Core/Ext.cs similarity index 100% rename from src/GitTfs/Core/Ext.cs rename to src/GitTfs.Core/Core/Ext.cs diff --git a/src/GitTfs/Core/GitChangeInfo.cs b/src/GitTfs.Core/Core/GitChangeInfo.cs similarity index 100% rename from src/GitTfs/Core/GitChangeInfo.cs rename to src/GitTfs.Core/Core/GitChangeInfo.cs diff --git a/src/GitTfs/Core/GitCommandException.cs b/src/GitTfs.Core/Core/GitCommandException.cs similarity index 100% rename from src/GitTfs/Core/GitCommandException.cs rename to src/GitTfs.Core/Core/GitCommandException.cs diff --git a/src/GitTfs/Core/GitCommit.cs b/src/GitTfs.Core/Core/GitCommit.cs similarity index 100% rename from src/GitTfs/Core/GitCommit.cs rename to src/GitTfs.Core/Core/GitCommit.cs diff --git a/src/GitTfs/Core/GitHelpers.cs b/src/GitTfs.Core/Core/GitHelpers.cs similarity index 100% rename from src/GitTfs/Core/GitHelpers.cs rename to src/GitTfs.Core/Core/GitHelpers.cs diff --git a/src/GitTfs/Core/GitObject.cs b/src/GitTfs.Core/Core/GitObject.cs similarity index 100% rename from src/GitTfs/Core/GitObject.cs rename to src/GitTfs.Core/Core/GitObject.cs diff --git a/src/GitTfs/Core/GitRepository.cs b/src/GitTfs.Core/Core/GitRepository.cs similarity index 100% rename from src/GitTfs/Core/GitRepository.cs rename to src/GitTfs.Core/Core/GitRepository.cs diff --git a/src/GitTfs/Core/GitTfsException.cs b/src/GitTfs.Core/Core/GitTfsException.cs similarity index 100% rename from src/GitTfs/Core/GitTfsException.cs rename to src/GitTfs.Core/Core/GitTfsException.cs diff --git a/src/GitTfs/Core/GitTfsGatedCheckinException.cs b/src/GitTfs.Core/Core/GitTfsGatedCheckinException.cs similarity index 100% rename from src/GitTfs/Core/GitTfsGatedCheckinException.cs rename to src/GitTfs.Core/Core/GitTfsGatedCheckinException.cs diff --git a/src/GitTfs/Core/GitTfsRemote.cs b/src/GitTfs.Core/Core/GitTfsRemote.cs similarity index 100% rename from src/GitTfs/Core/GitTfsRemote.cs rename to src/GitTfs.Core/Core/GitTfsRemote.cs diff --git a/src/GitTfs/Core/GitTfsVersionProvider.cs b/src/GitTfs.Core/Core/GitTfsVersionProvider.cs similarity index 100% rename from src/GitTfs/Core/GitTfsVersionProvider.cs rename to src/GitTfs.Core/Core/GitTfsVersionProvider.cs diff --git a/src/GitTfs/Core/GitTreeBuilder.cs b/src/GitTfs.Core/Core/GitTreeBuilder.cs similarity index 100% rename from src/GitTfs/Core/GitTreeBuilder.cs rename to src/GitTfs.Core/Core/GitTreeBuilder.cs diff --git a/src/GitTfs/Core/GitTreeEntry.cs b/src/GitTfs.Core/Core/GitTreeEntry.cs similarity index 100% rename from src/GitTfs/Core/GitTreeEntry.cs rename to src/GitTfs.Core/Core/GitTreeEntry.cs diff --git a/src/GitTfs/Core/IBranchTreeVisitor.cs b/src/GitTfs.Core/Core/IBranchTreeVisitor.cs similarity index 100% rename from src/GitTfs/Core/IBranchTreeVisitor.cs rename to src/GitTfs.Core/Core/IBranchTreeVisitor.cs diff --git a/src/GitTfs/Core/IGitChangedFile.cs b/src/GitTfs.Core/Core/IGitChangedFile.cs similarity index 100% rename from src/GitTfs/Core/IGitChangedFile.cs rename to src/GitTfs.Core/Core/IGitChangedFile.cs diff --git a/src/GitTfs/Core/IGitHelpers.cs b/src/GitTfs.Core/Core/IGitHelpers.cs similarity index 100% rename from src/GitTfs/Core/IGitHelpers.cs rename to src/GitTfs.Core/Core/IGitHelpers.cs diff --git a/src/GitTfs/Core/IGitRepository.cs b/src/GitTfs.Core/Core/IGitRepository.cs similarity index 100% rename from src/GitTfs/Core/IGitRepository.cs rename to src/GitTfs.Core/Core/IGitRepository.cs diff --git a/src/GitTfs/Core/IGitTfsRemote.cs b/src/GitTfs.Core/Core/IGitTfsRemote.cs similarity index 100% rename from src/GitTfs/Core/IGitTfsRemote.cs rename to src/GitTfs.Core/Core/IGitTfsRemote.cs diff --git a/src/GitTfs/Core/IGitTfsVersionProvider.cs b/src/GitTfs.Core/Core/IGitTfsVersionProvider.cs similarity index 100% rename from src/GitTfs/Core/IGitTfsVersionProvider.cs rename to src/GitTfs.Core/Core/IGitTfsVersionProvider.cs diff --git a/src/GitTfs/Core/IGitTreeBuilder.cs b/src/GitTfs.Core/Core/IGitTreeBuilder.cs similarity index 100% rename from src/GitTfs/Core/IGitTreeBuilder.cs rename to src/GitTfs.Core/Core/IGitTreeBuilder.cs diff --git a/src/GitTfs/Core/ITfsChangeset.cs b/src/GitTfs.Core/Core/ITfsChangeset.cs similarity index 100% rename from src/GitTfs/Core/ITfsChangeset.cs rename to src/GitTfs.Core/Core/ITfsChangeset.cs diff --git a/src/GitTfs/Core/ITfsCheckinNote.cs b/src/GitTfs.Core/Core/ITfsCheckinNote.cs similarity index 100% rename from src/GitTfs/Core/ITfsCheckinNote.cs rename to src/GitTfs.Core/Core/ITfsCheckinNote.cs diff --git a/src/GitTfs/Core/ITfsWorkitem.cs b/src/GitTfs.Core/Core/ITfsWorkitem.cs similarity index 100% rename from src/GitTfs/Core/ITfsWorkitem.cs rename to src/GitTfs.Core/Core/ITfsWorkitem.cs diff --git a/src/GitTfs/Core/ITfsWorkspace.cs b/src/GitTfs.Core/Core/ITfsWorkspace.cs similarity index 100% rename from src/GitTfs/Core/ITfsWorkspace.cs rename to src/GitTfs.Core/Core/ITfsWorkspace.cs diff --git a/src/GitTfs/Core/ITreeEntry.cs b/src/GitTfs.Core/Core/ITreeEntry.cs similarity index 100% rename from src/GitTfs/Core/ITreeEntry.cs rename to src/GitTfs.Core/Core/ITreeEntry.cs diff --git a/src/GitTfs/Core/Janitor.cs b/src/GitTfs.Core/Core/Janitor.cs similarity index 92% rename from src/GitTfs/Core/Janitor.cs rename to src/GitTfs.Core/Core/Janitor.cs index 9ceab8d3d..b3e78a8d1 100644 --- a/src/GitTfs/Core/Janitor.cs +++ b/src/GitTfs.Core/Core/Janitor.cs @@ -1,10 +1,7 @@ -using GitTfs.Util; - using System.Diagnostics; namespace GitTfs.Core { - [StructureMapSingleton] public class Janitor : IDisposable { private readonly Queue _actions = new Queue(); diff --git a/src/GitTfs/Core/LogEntry.cs b/src/GitTfs.Core/Core/LogEntry.cs similarity index 100% rename from src/GitTfs/Core/LogEntry.cs rename to src/GitTfs.Core/Core/LogEntry.cs diff --git a/src/GitTfs/Core/Mode.cs b/src/GitTfs.Core/Core/Mode.cs similarity index 100% rename from src/GitTfs/Core/Mode.cs rename to src/GitTfs.Core/Core/Mode.cs diff --git a/src/GitTfs/Core/RemoteConfigConverter.cs b/src/GitTfs.Core/Core/RemoteConfigConverter.cs similarity index 100% rename from src/GitTfs/Core/RemoteConfigConverter.cs rename to src/GitTfs.Core/Core/RemoteConfigConverter.cs diff --git a/src/GitTfs/Core/RemoteInfo.cs b/src/GitTfs.Core/Core/RemoteInfo.cs similarity index 100% rename from src/GitTfs/Core/RemoteInfo.cs rename to src/GitTfs.Core/Core/RemoteInfo.cs diff --git a/src/GitTfs/Core/RequiresValidGitRepositoryAttribute.cs b/src/GitTfs.Core/Core/RequiresValidGitRepositoryAttribute.cs similarity index 100% rename from src/GitTfs/Core/RequiresValidGitRepositoryAttribute.cs rename to src/GitTfs.Core/Core/RequiresValidGitRepositoryAttribute.cs diff --git a/src/GitTfs/Core/TfsChangeset.cs b/src/GitTfs.Core/Core/TfsChangeset.cs similarity index 100% rename from src/GitTfs/Core/TfsChangeset.cs rename to src/GitTfs.Core/Core/TfsChangeset.cs diff --git a/src/GitTfs/Core/TfsChangesetInfo.cs b/src/GitTfs.Core/Core/TfsChangesetInfo.cs similarity index 100% rename from src/GitTfs/Core/TfsChangesetInfo.cs rename to src/GitTfs.Core/Core/TfsChangesetInfo.cs diff --git a/src/GitTfs/Core/TfsCheckinNote.cs b/src/GitTfs.Core/Core/TfsCheckinNote.cs similarity index 100% rename from src/GitTfs/Core/TfsCheckinNote.cs rename to src/GitTfs.Core/Core/TfsCheckinNote.cs diff --git a/src/GitTfs/Core/TfsInterop/IBranch.cs b/src/GitTfs.Core/Core/TfsInterop/IBranch.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IBranch.cs rename to src/GitTfs.Core/Core/TfsInterop/IBranch.cs diff --git a/src/GitTfs/Core/TfsInterop/IChange.cs b/src/GitTfs.Core/Core/TfsInterop/IChange.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IChange.cs rename to src/GitTfs.Core/Core/TfsInterop/IChange.cs diff --git a/src/GitTfs/Core/TfsInterop/IChangeset.cs b/src/GitTfs.Core/Core/TfsInterop/IChangeset.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IChangeset.cs rename to src/GitTfs.Core/Core/TfsInterop/IChangeset.cs diff --git a/src/GitTfs/Core/TfsInterop/ICheckinEvaluationResult.cs b/src/GitTfs.Core/Core/TfsInterop/ICheckinEvaluationResult.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/ICheckinEvaluationResult.cs rename to src/GitTfs.Core/Core/TfsInterop/ICheckinEvaluationResult.cs diff --git a/src/GitTfs/Core/TfsInterop/ICheckinNote.cs b/src/GitTfs.Core/Core/TfsInterop/ICheckinNote.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/ICheckinNote.cs rename to src/GitTfs.Core/Core/TfsInterop/ICheckinNote.cs diff --git a/src/GitTfs/Core/TfsInterop/IIdentity.cs b/src/GitTfs.Core/Core/TfsInterop/IIdentity.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IIdentity.cs rename to src/GitTfs.Core/Core/TfsInterop/IIdentity.cs diff --git a/src/GitTfs/Core/TfsInterop/IItem.cs b/src/GitTfs.Core/Core/TfsInterop/IItem.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IItem.cs rename to src/GitTfs.Core/Core/TfsInterop/IItem.cs diff --git a/src/GitTfs/Core/TfsInterop/IPendingChange.cs b/src/GitTfs.Core/Core/TfsInterop/IPendingChange.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IPendingChange.cs rename to src/GitTfs.Core/Core/TfsInterop/IPendingChange.cs diff --git a/src/GitTfs/Core/TfsInterop/IShelveset.cs b/src/GitTfs.Core/Core/TfsInterop/IShelveset.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IShelveset.cs rename to src/GitTfs.Core/Core/TfsInterop/IShelveset.cs diff --git a/src/GitTfs/Core/TfsInterop/ITfsHelper.cs b/src/GitTfs.Core/Core/TfsInterop/ITfsHelper.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/ITfsHelper.cs rename to src/GitTfs.Core/Core/TfsInterop/ITfsHelper.cs diff --git a/src/GitTfs/Core/TfsInterop/IVersionControlServer.cs b/src/GitTfs.Core/Core/TfsInterop/IVersionControlServer.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IVersionControlServer.cs rename to src/GitTfs.Core/Core/TfsInterop/IVersionControlServer.cs diff --git a/src/GitTfs/Core/TfsInterop/IWorkItemCheckedInfo.cs b/src/GitTfs.Core/Core/TfsInterop/IWorkItemCheckedInfo.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IWorkItemCheckedInfo.cs rename to src/GitTfs.Core/Core/TfsInterop/IWorkItemCheckedInfo.cs diff --git a/src/GitTfs/Core/TfsInterop/IWorkItemCheckinInfo.cs b/src/GitTfs.Core/Core/TfsInterop/IWorkItemCheckinInfo.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IWorkItemCheckinInfo.cs rename to src/GitTfs.Core/Core/TfsInterop/IWorkItemCheckinInfo.cs diff --git a/src/GitTfs/Core/TfsInterop/IWorkspace.cs b/src/GitTfs.Core/Core/TfsInterop/IWorkspace.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/IWorkspace.cs rename to src/GitTfs.Core/Core/TfsInterop/IWorkspace.cs diff --git a/src/GitTfs/Core/TfsInterop/NullIdentity.cs b/src/GitTfs.Core/Core/TfsInterop/NullIdentity.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/NullIdentity.cs rename to src/GitTfs.Core/Core/TfsInterop/NullIdentity.cs diff --git a/src/GitTfs/Core/TfsInterop/README.txt b/src/GitTfs.Core/Core/TfsInterop/README.txt similarity index 100% rename from src/GitTfs/Core/TfsInterop/README.txt rename to src/GitTfs.Core/Core/TfsInterop/README.txt diff --git a/src/GitTfs/Core/TfsInterop/RootBranch.cs b/src/GitTfs.Core/Core/TfsInterop/RootBranch.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/RootBranch.cs rename to src/GitTfs.Core/Core/TfsInterop/RootBranch.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsApiBridge.cs b/src/GitTfs.Core/Core/TfsInterop/TfsApiBridge.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsApiBridge.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsApiBridge.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsChangeType.cs b/src/GitTfs.Core/Core/TfsInterop/TfsChangeType.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsChangeType.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsChangeType.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsCheckinEvaluationOptions.cs b/src/GitTfs.Core/Core/TfsInterop/TfsCheckinEvaluationOptions.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsCheckinEvaluationOptions.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsCheckinEvaluationOptions.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsExt.cs b/src/GitTfs.Core/Core/TfsInterop/TfsExt.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsExt.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsExt.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsItemType.cs b/src/GitTfs.Core/Core/TfsInterop/TfsItemType.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsItemType.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsItemType.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsPlugin.cs b/src/GitTfs.Core/Core/TfsInterop/TfsPlugin.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsPlugin.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsPlugin.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsRecursionType.cs b/src/GitTfs.Core/Core/TfsInterop/TfsRecursionType.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsRecursionType.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsRecursionType.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsShelvingOptions.cs b/src/GitTfs.Core/Core/TfsInterop/TfsShelvingOptions.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsShelvingOptions.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsShelvingOptions.cs diff --git a/src/GitTfs/Core/TfsInterop/TfsWorkItemCheckinAction.cs b/src/GitTfs.Core/Core/TfsInterop/TfsWorkItemCheckinAction.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/TfsWorkItemCheckinAction.cs rename to src/GitTfs.Core/Core/TfsInterop/TfsWorkItemCheckinAction.cs diff --git a/src/GitTfs/Core/TfsInterop/WrapperFor.cs b/src/GitTfs.Core/Core/TfsInterop/WrapperFor.cs similarity index 100% rename from src/GitTfs/Core/TfsInterop/WrapperFor.cs rename to src/GitTfs.Core/Core/TfsInterop/WrapperFor.cs diff --git a/src/GitTfs/Core/TfsLabel.cs b/src/GitTfs.Core/Core/TfsLabel.cs similarity index 100% rename from src/GitTfs/Core/TfsLabel.cs rename to src/GitTfs.Core/Core/TfsLabel.cs diff --git a/src/GitTfs/Core/TfsTreeEntry.cs b/src/GitTfs.Core/Core/TfsTreeEntry.cs similarity index 100% rename from src/GitTfs/Core/TfsTreeEntry.cs rename to src/GitTfs.Core/Core/TfsTreeEntry.cs diff --git a/src/GitTfs/Core/TfsWorkitem.cs b/src/GitTfs.Core/Core/TfsWorkitem.cs similarity index 100% rename from src/GitTfs/Core/TfsWorkitem.cs rename to src/GitTfs.Core/Core/TfsWorkitem.cs diff --git a/src/GitTfs/Core/TfsWorkspace.cs b/src/GitTfs.Core/Core/TfsWorkspace.cs similarity index 100% rename from src/GitTfs/Core/TfsWorkspace.cs rename to src/GitTfs.Core/Core/TfsWorkspace.cs diff --git a/src/GitTfs/Core/TfsWriter.cs b/src/GitTfs.Core/Core/TfsWriter.cs similarity index 100% rename from src/GitTfs/Core/TfsWriter.cs rename to src/GitTfs.Core/Core/TfsWriter.cs diff --git a/src/GitTfs.Core/GitTfs.Core.csproj b/src/GitTfs.Core/GitTfs.Core.csproj new file mode 100644 index 000000000..9edbddd0b --- /dev/null +++ b/src/GitTfs.Core/GitTfs.Core.csproj @@ -0,0 +1,16 @@ + + + + + Properties\CommonAssemblyInfo.cs + + + + + + + + + + + \ No newline at end of file diff --git a/src/GitTfs/GitTfsCommand.cs b/src/GitTfs.Core/GitTfsCommand.cs similarity index 100% rename from src/GitTfs/GitTfsCommand.cs rename to src/GitTfs.Core/GitTfsCommand.cs diff --git a/src/GitTfs/GitTfsConstants.cs b/src/GitTfs.Core/GitTfsConstants.cs similarity index 100% rename from src/GitTfs/GitTfsConstants.cs rename to src/GitTfs.Core/GitTfsConstants.cs diff --git a/src/GitTfs/GitTfsExitCodes.cs b/src/GitTfs.Core/GitTfsExitCodes.cs similarity index 100% rename from src/GitTfs/GitTfsExitCodes.cs rename to src/GitTfs.Core/GitTfsExitCodes.cs diff --git a/src/GitTfs/Globals.cs b/src/GitTfs.Core/Globals.cs similarity index 99% rename from src/GitTfs/Globals.cs rename to src/GitTfs.Core/Globals.cs index 559bcffb3..880f6d470 100644 --- a/src/GitTfs/Globals.cs +++ b/src/GitTfs.Core/Globals.cs @@ -1,11 +1,9 @@ using System.Diagnostics; using NDesk.Options; using GitTfs.Core; -using GitTfs.Util; namespace GitTfs { - [StructureMapSingleton] public class Globals { public OptionSet OptionSet => new OptionSet diff --git a/src/GitTfs/Util/AuthorsFile.cs b/src/GitTfs.Core/Util/AuthorsFile.cs similarity index 98% rename from src/GitTfs/Util/AuthorsFile.cs rename to src/GitTfs.Core/Util/AuthorsFile.cs index 47b2ba876..192de9ae3 100644 --- a/src/GitTfs/Util/AuthorsFile.cs +++ b/src/GitTfs.Core/Util/AuthorsFile.cs @@ -1,4 +1,4 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; using GitTfs.Core; using System.Diagnostics; @@ -35,7 +35,7 @@ public Author(string tfsUserId, string name, string email) #endregion } - [StructureMapSingleton] + public class AuthorsFile { private readonly Dictionary _authorsByTfsUserId = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/GitTfs/Util/Bouncer.cs b/src/GitTfs.Core/Util/Bouncer.cs similarity index 100% rename from src/GitTfs/Util/Bouncer.cs rename to src/GitTfs.Core/Util/Bouncer.cs diff --git a/src/GitTfs/Util/CamelCaseToDelimitedStringConverter.cs b/src/GitTfs.Core/Util/CamelCaseToDelimitedStringConverter.cs similarity index 100% rename from src/GitTfs/Util/CamelCaseToDelimitedStringConverter.cs rename to src/GitTfs.Core/Util/CamelCaseToDelimitedStringConverter.cs diff --git a/src/GitTfs/Util/ChangeSieve.cs b/src/GitTfs.Core/Util/ChangeSieve.cs similarity index 100% rename from src/GitTfs/Util/ChangeSieve.cs rename to src/GitTfs.Core/Util/ChangeSieve.cs diff --git a/src/GitTfs/Util/ConfigPropertyLoader.cs b/src/GitTfs.Core/Util/ConfigPropertyLoader.cs similarity index 97% rename from src/GitTfs/Util/ConfigPropertyLoader.cs rename to src/GitTfs.Core/Util/ConfigPropertyLoader.cs index b07a94872..72de2ec03 100644 --- a/src/GitTfs/Util/ConfigPropertyLoader.cs +++ b/src/GitTfs.Core/Util/ConfigPropertyLoader.cs @@ -1,7 +1,6 @@ namespace GitTfs.Util { // Manages configurable values. - [StructureMapSingleton] public class ConfigPropertyLoader { private readonly Globals _globals; diff --git a/src/GitTfs/Util/ExportMetadatasInitializer.cs b/src/GitTfs.Core/Util/ExportMetadatasInitializer.cs similarity index 100% rename from src/GitTfs/Util/ExportMetadatasInitializer.cs rename to src/GitTfs.Core/Util/ExportMetadatasInitializer.cs diff --git a/src/GitTfs/Util/InspectExtensions.cs b/src/GitTfs.Core/Util/InspectExtensions.cs similarity index 98% rename from src/GitTfs/Util/InspectExtensions.cs rename to src/GitTfs.Core/Util/InspectExtensions.cs index cff82fa2f..c4f453675 100644 --- a/src/GitTfs/Util/InspectExtensions.cs +++ b/src/GitTfs.Core/Util/InspectExtensions.cs @@ -1,7 +1,7 @@ -using System.Collections; +using System.Collections; using System.Text.RegularExpressions; -namespace GitTfs.Extensions +namespace GitTfs.Util { public static class InspectExtensions { diff --git a/src/GitTfs/Util/PathResolver.cs b/src/GitTfs.Core/Util/PathResolver.cs similarity index 100% rename from src/GitTfs/Util/PathResolver.cs rename to src/GitTfs.Core/Util/PathResolver.cs diff --git a/src/GitTfs.Core/Util/StringExtensions.cs b/src/GitTfs.Core/Util/StringExtensions.cs new file mode 100644 index 000000000..7fc59f459 --- /dev/null +++ b/src/GitTfs.Core/Util/StringExtensions.cs @@ -0,0 +1,76 @@ + +using System.Text.RegularExpressions; + +using GitTfs.Core; + +namespace GitTfs.Util +{ + public static class StringExtensions + { + private static readonly Regex ValidTfsPath = new Regex("^\\$/.+"); + public static bool IsValidTfsPath(this string tfsPath) => ValidTfsPath.IsMatch(tfsPath); + + public static void AssertValidTfsPathOrRoot(this string tfsPath) + { + if (tfsPath == GitTfsConstants.TfsRoot) + return; + AssertValidTfsPath(tfsPath); + } + + public static void AssertValidTfsPath(this string tfsPath) + { + if (!ValidTfsPath.IsMatch(tfsPath)) + throw new GitTfsException("TFS repository can not be root and must start with \"$/\".", SuggestPaths(tfsPath)); + } + + private static IEnumerable SuggestPaths(string tfsPath) + { + if (tfsPath == "$" || tfsPath == "$/") + yield return "Cloning an entire TFS repository is not supported. Try using a subdirectory of the root (e.g. $/MyProject)."; + else if (tfsPath.StartsWith("$")) + yield return "Try using $/" + tfsPath.Substring(1); + else + yield return "Try using $/" + tfsPath; + } + + public static string ToGitRefName(this string expectedRefName) + { + expectedRefName = Regex.Replace(expectedRefName, @"[!~$?[*^: \\]", string.Empty); + expectedRefName = expectedRefName.Replace("@{", string.Empty); + expectedRefName = expectedRefName.Replace("..", string.Empty); + expectedRefName = expectedRefName.Replace("//", string.Empty); + expectedRefName = expectedRefName.Replace("/.", "/"); + expectedRefName = expectedRefName.TrimEnd('.', '/'); + return expectedRefName.Trim('/'); + } + + public static string ToGitBranchNameFromTfsRepositoryPath(this string tfsRepositoryPath, bool includeTeamProjectName = false) + { + if (includeTeamProjectName) + { + return tfsRepositoryPath + .Replace("$/", string.Empty) + .ToGitRefName(); + } + + string gitBranchNameExpected = tfsRepositoryPath.IndexOf("$/") == 0 + ? tfsRepositoryPath.Remove(0, tfsRepositoryPath.IndexOf('/', 2) + 1) + : tfsRepositoryPath; + + return gitBranchNameExpected.ToGitRefName(); + } + + public static string ToTfsTeamProjectRepositoryPath(this string tfsRepositoryPath) + { + if (!tfsRepositoryPath.StartsWith("$/")) + { + return tfsRepositoryPath; + } + + var index = tfsRepositoryPath.IndexOf('/', 2); + return index == -1 ? tfsRepositoryPath : tfsRepositoryPath.Remove(index, tfsRepositoryPath.Length - index); + } + + public static string ToLocalGitRef(this string refName) => "refs/heads/" + refName; + } +} diff --git a/src/GitTfs/Util/TemporaryFile.cs b/src/GitTfs.Core/Util/TemporaryFile.cs similarity index 100% rename from src/GitTfs/Util/TemporaryFile.cs rename to src/GitTfs.Core/Util/TemporaryFile.cs diff --git a/src/GitTfs/Util/TemporaryFileStream.cs b/src/GitTfs.Core/Util/TemporaryFileStream.cs similarity index 100% rename from src/GitTfs/Util/TemporaryFileStream.cs rename to src/GitTfs.Core/Util/TemporaryFileStream.cs diff --git a/src/GitTfs/Util/WhenDynamicDoesntWork.cs b/src/GitTfs.Core/Util/WhenDynamicDoesntWork.cs similarity index 100% rename from src/GitTfs/Util/WhenDynamicDoesntWork.cs rename to src/GitTfs.Core/Util/WhenDynamicDoesntWork.cs diff --git a/src/GitTfs/paket.references b/src/GitTfs.Core/paket.references similarity index 100% rename from src/GitTfs/paket.references rename to src/GitTfs.Core/paket.references diff --git a/src/GitTfs.Vs2019/GitTfs.Vs2019.csproj b/src/GitTfs.Vs2019/GitTfs.Vs2019.csproj index 17447a7d7..ec37d1ce8 100644 --- a/src/GitTfs.Vs2019/GitTfs.Vs2019.csproj +++ b/src/GitTfs.Vs2019/GitTfs.Vs2019.csproj @@ -25,10 +25,12 @@ - + - + + + @@ -37,5 +39,4 @@ - \ No newline at end of file diff --git a/src/GitTfs.Vs2019/paket.references b/src/GitTfs.Vs2019/paket.references deleted file mode 100644 index 220c1c82e..000000000 --- a/src/GitTfs.Vs2019/paket.references +++ /dev/null @@ -1,7 +0,0 @@ -structuremap - -group VS2019 -Microsoft.TeamFoundationServer.Client -Microsoft.TeamFoundationServer.ExtendedClient -Microsoft.VisualStudio.Setup.Configuration.Interop -Microsoft.VisualStudio.Settings.15.0 diff --git a/src/GitTfs.Vs2022/GitTfs.Vs2022.csproj b/src/GitTfs.Vs2022/GitTfs.Vs2022.csproj index 17447a7d7..3f5b25977 100644 --- a/src/GitTfs.Vs2022/GitTfs.Vs2022.csproj +++ b/src/GitTfs.Vs2022/GitTfs.Vs2022.csproj @@ -24,11 +24,13 @@ Wrappers.cs + + + - - - - + + + @@ -37,5 +39,4 @@ - \ No newline at end of file diff --git a/src/GitTfs.Vs2022/paket.references b/src/GitTfs.Vs2022/paket.references deleted file mode 100644 index 1cf84437d..000000000 --- a/src/GitTfs.Vs2022/paket.references +++ /dev/null @@ -1,7 +0,0 @@ -structuremap - -group VS2022 -Microsoft.TeamFoundationServer.Client -Microsoft.TeamFoundationServer.ExtendedClient -Microsoft.VisualStudio.Setup.Configuration.Interop -Microsoft.VisualStudio.Settings.15.0 diff --git a/src/GitTfs.VsCommon/TfsHelper.Common.cs b/src/GitTfs.VsCommon/TfsHelper.Common.cs index 987ab670a..0f908dad2 100644 --- a/src/GitTfs.VsCommon/TfsHelper.Common.cs +++ b/src/GitTfs.VsCommon/TfsHelper.Common.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Net; using System.Reflection; using Microsoft.TeamFoundation.Client; @@ -8,7 +8,6 @@ using GitTfs.Commands; using GitTfs.Core; using GitTfs.Core.TfsInterop; -using GitTfs.Extensions; using GitTfs.Util; using StructureMap; using StructureMap.Attributes; diff --git a/src/GitTfs.VsFake/GitTfs.VsFake.csproj b/src/GitTfs.VsFake/GitTfs.VsFake.csproj index 142bc5fcc..2fc21030a 100644 --- a/src/GitTfs.VsFake/GitTfs.VsFake.csproj +++ b/src/GitTfs.VsFake/GitTfs.VsFake.csproj @@ -6,10 +6,9 @@ - + - \ No newline at end of file diff --git a/src/GitTfs.VsFake/paket.references b/src/GitTfs.VsFake/paket.references deleted file mode 100644 index cfcfcec02..000000000 --- a/src/GitTfs.VsFake/paket.references +++ /dev/null @@ -1 +0,0 @@ -structuremap \ No newline at end of file diff --git a/src/GitTfs.sln b/src/GitTfs.sln deleted file mode 100644 index 3e2b5a528..000000000 --- a/src/GitTfs.sln +++ /dev/null @@ -1,81 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.271 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{15A283E3-44EA-47DE-B1BD-B93CC8C08900}" - ProjectSection(SolutionItems) = preProject - paket.dependencies = paket.dependencies - paket.lock = paket.lock - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitTfs", "GitTfs\GitTfs.csproj", "{55C169E0-93CC-488C-9885-1D4EAF4EA236}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitTfsTest", "GitTfsTest\GitTfsTest.csproj", "{DDFB4746-2BCE-4B34-8E45-056324CF140D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitTfs.VsFake", "GitTfs.VsFake\GitTfs.VsFake.csproj", "{20C411E8-49C7-11E1-A776-3FE84824019B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{4A46FEEE-B8A2-4445-B9D1-8160520C7301}" - ProjectSection(SolutionItems) = preProject - ..\doc\release-notes\NEXT.md = ..\doc\release-notes\NEXT.md - ..\README.md = ..\README.md - ..\doc\running-the-unit-tests.md = ..\doc\running-the-unit-tests.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ChocolateyTemplates", "ChocolateyTemplates", "{AC0FE25D-D76B-4EE7-9EA8-470204451C9F}" - ProjectSection(SolutionItems) = preProject - build\ChocolateyTemplates\chocolateyInstall.ps1 = build\ChocolateyTemplates\chocolateyInstall.ps1 - build\ChocolateyTemplates\gittfs.nuspec = build\ChocolateyTemplates\gittfs.nuspec - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7E25ACEF-468A-4E93-9549-8BBFC72294DF}" - ProjectSection(SolutionItems) = preProject - ..\appveyor.yml = ..\appveyor.yml - build.cake = build.cake - build.ps1 = build.ps1 - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NDesk.Options", "NDesk.Options\NDesk.Options.csproj", "{4B6F5E5C-188D-4EA7-B1D0-EC185546F66F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitTfs.Vs2019", "GitTfs.Vs2019\GitTfs.Vs2019.csproj", "{54B4B8B8-F06C-4D2E-B7A3-C17C3850C88B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitTfs.Vs2022", "GitTfs.Vs2022\GitTfs.Vs2022.csproj", "{7853F7AB-87E8-4282-8FDE-6A138B73F9B5}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|AnyCPU = Debug|AnyCPU - Release|AnyCPU = Release|AnyCPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {55C169E0-93CC-488C-9885-1D4EAF4EA236}.Release|AnyCPU.Build.0 = Release|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {DDFB4746-2BCE-4B34-8E45-056324CF140D}.Release|AnyCPU.Build.0 = Release|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {20C411E8-49C7-11E1-A776-3FE84824019B}.Release|AnyCPU.Build.0 = Release|Any CPU - {4B6F5E5C-188D-4EA7-B1D0-EC185546F66F}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {4B6F5E5C-188D-4EA7-B1D0-EC185546F66F}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {4B6F5E5C-188D-4EA7-B1D0-EC185546F66F}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {4B6F5E5C-188D-4EA7-B1D0-EC185546F66F}.Release|AnyCPU.Build.0 = Release|Any CPU - {54B4B8B8-F06C-4D2E-B7A3-C17C3850C88B}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {54B4B8B8-F06C-4D2E-B7A3-C17C3850C88B}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {54B4B8B8-F06C-4D2E-B7A3-C17C3850C88B}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {54B4B8B8-F06C-4D2E-B7A3-C17C3850C88B}.Release|AnyCPU.Build.0 = Release|Any CPU - {7853F7AB-87E8-4282-8FDE-6A138B73F9B5}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU - {7853F7AB-87E8-4282-8FDE-6A138B73F9B5}.Debug|AnyCPU.Build.0 = Debug|Any CPU - {7853F7AB-87E8-4282-8FDE-6A138B73F9B5}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {7853F7AB-87E8-4282-8FDE-6A138B73F9B5}.Release|AnyCPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D260574D-8D88-442D-A97F-7CF7F02738BC} - EndGlobalSection -EndGlobal diff --git a/src/GitTfs.slnx b/src/GitTfs.slnx new file mode 100644 index 000000000..39fcbbd8b --- /dev/null +++ b/src/GitTfs.slnx @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/GitTfs/Commands/Branch.cs b/src/GitTfs/Commands/Branch.cs index efe3816c1..6cd414554 100644 --- a/src/GitTfs/Commands/Branch.cs +++ b/src/GitTfs/Commands/Branch.cs @@ -3,7 +3,7 @@ using NDesk.Options; using GitTfs.Core; using GitTfs.Core.TfsInterop; -using StructureMap; +using GitTfs.Util; using System.Text; namespace GitTfs.Commands diff --git a/src/GitTfs/Commands/Checkout.cs b/src/GitTfs/Commands/Checkout.cs index 0c988218f..70575dc7e 100644 --- a/src/GitTfs/Commands/Checkout.cs +++ b/src/GitTfs/Commands/Checkout.cs @@ -1,7 +1,7 @@ -using System.ComponentModel; +using System.ComponentModel; using NDesk.Options; using GitTfs.Core; -using StructureMap; +using GitTfs.Util; using System.Diagnostics; namespace GitTfs.Commands diff --git a/src/GitTfs/Commands/CleanupOptions.cs b/src/GitTfs/Commands/CleanupOptions.cs index 52acf5efe..e6632ba19 100644 --- a/src/GitTfs/Commands/CleanupOptions.cs +++ b/src/GitTfs/Commands/CleanupOptions.cs @@ -1,9 +1,7 @@ -using NDesk.Options; -using GitTfs.Util; +using NDesk.Options; namespace GitTfs.Commands { - [StructureMapSingleton] public class CleanupOptions { private readonly Globals _globals; diff --git a/src/GitTfs/Commands/Help.cs b/src/GitTfs/Commands/Help.cs index 2851c54f5..c22ad711f 100644 --- a/src/GitTfs/Commands/Help.cs +++ b/src/GitTfs/Commands/Help.cs @@ -61,7 +61,7 @@ public int Run() Trace.TraceInformation(command); } Trace.TraceInformation(" (use 'git-tfs help [command]' or 'git-tfs [command] --help' for more information)"); - Trace.TraceInformation("\nFind more help in our online help : https://github.com/git-tfs/git-tfs"); + Trace.TraceInformation("\nFind more help in our online help : https://github.com/lucianm/git-tfs"); return GitTfsExitCodes.Help; } @@ -78,7 +78,7 @@ public int Run(GitTfsCommand command) command.GetAllOptions(_container).WriteOptionDescriptions(writer); Trace.TraceInformation(writer.ToString()); - Trace.TraceInformation("\nFind more help in our online help : https://github.com/git-tfs/git-tfs/blob/master/doc/commands/" + GetCommandName(command) + ".md"); + Trace.TraceInformation("\nFind more help in our online help : https://github.com/lucianm/git-tfs/blob/master/doc/commands/" + GetCommandName(command) + ".md"); return GitTfsExitCodes.Help; } diff --git a/src/GitTfs/Commands/Init.cs b/src/GitTfs/Commands/Init.cs index effa1aa3a..9abe0d634 100644 --- a/src/GitTfs/Commands/Init.cs +++ b/src/GitTfs/Commands/Init.cs @@ -187,73 +187,4 @@ private void GitTfsInit(string tfsUrl, string tfsRepositoryPath) => _globals.Rep RemoteOptions = _remoteOptions, }); } - - public static class Ext - { - private static readonly Regex ValidTfsPath = new Regex("^\\$/.+"); - public static bool IsValidTfsPath(this string tfsPath) => ValidTfsPath.IsMatch(tfsPath); - - public static void AssertValidTfsPathOrRoot(this string tfsPath) - { - if (tfsPath == GitTfsConstants.TfsRoot) - return; - AssertValidTfsPath(tfsPath); - } - - public static void AssertValidTfsPath(this string tfsPath) - { - if (!ValidTfsPath.IsMatch(tfsPath)) - throw new GitTfsException("TFS repository can not be root and must start with \"$/\".", SuggestPaths(tfsPath)); - } - - private static IEnumerable SuggestPaths(string tfsPath) - { - if (tfsPath == "$" || tfsPath == "$/") - yield return "Cloning an entire TFS repository is not supported. Try using a subdirectory of the root (e.g. $/MyProject)."; - else if (tfsPath.StartsWith("$")) - yield return "Try using $/" + tfsPath.Substring(1); - else - yield return "Try using $/" + tfsPath; - } - - public static string ToGitRefName(this string expectedRefName) - { - expectedRefName = Regex.Replace(expectedRefName, @"[!~$?[*^: \\]", string.Empty); - expectedRefName = expectedRefName.Replace("@{", string.Empty); - expectedRefName = expectedRefName.Replace("..", string.Empty); - expectedRefName = expectedRefName.Replace("//", string.Empty); - expectedRefName = expectedRefName.Replace("/.", "/"); - expectedRefName = expectedRefName.TrimEnd('.', '/'); - return expectedRefName.Trim('/'); - } - - public static string ToGitBranchNameFromTfsRepositoryPath(this string tfsRepositoryPath, bool includeTeamProjectName = false) - { - if (includeTeamProjectName) - { - return tfsRepositoryPath - .Replace("$/", string.Empty) - .ToGitRefName(); - } - - string gitBranchNameExpected = tfsRepositoryPath.IndexOf("$/") == 0 - ? tfsRepositoryPath.Remove(0, tfsRepositoryPath.IndexOf('/', 2) + 1) - : tfsRepositoryPath; - - return gitBranchNameExpected.ToGitRefName(); - } - - public static string ToTfsTeamProjectRepositoryPath(this string tfsRepositoryPath) - { - if (!tfsRepositoryPath.StartsWith("$/")) - { - return tfsRepositoryPath; - } - - var index = tfsRepositoryPath.IndexOf('/', 2); - return index == -1 ? tfsRepositoryPath : tfsRepositoryPath.Remove(index, tfsRepositoryPath.Length - index); - } - - public static string ToLocalGitRef(this string refName) => "refs/heads/" + refName; - } } diff --git a/src/GitTfs/Commands/InitOptions.cs b/src/GitTfs/Commands/InitOptions.cs index d43648a28..6486c105d 100644 --- a/src/GitTfs/Commands/InitOptions.cs +++ b/src/GitTfs/Commands/InitOptions.cs @@ -1,9 +1,7 @@ using NDesk.Options; -using GitTfs.Util; namespace GitTfs.Commands { - [StructureMapSingleton] public class InitOptions { private const string DefaultAutocrlf = "false"; diff --git a/src/GitTfs/GitTfs.csproj b/src/GitTfs/GitTfs.csproj index c72d80d34..600fc7c9c 100644 --- a/src/GitTfs/GitTfs.csproj +++ b/src/GitTfs/GitTfs.csproj @@ -23,11 +23,14 @@ - - + + + + + + - \ No newline at end of file diff --git a/src/GitTfs/Program.cs b/src/GitTfs/Program.cs index 48c54c2eb..6b3e0180f 100644 --- a/src/GitTfs/Program.cs +++ b/src/GitTfs/Program.cs @@ -130,6 +130,10 @@ private static void Initialize(ConfigurationExpression initializer) var tfsPlugin = TfsPlugin.Find(); initializer.Scan(x => { Initialize(x); tfsPlugin.Initialize(x); }); initializer.For().Add(); + initializer.For().Add(); + initializer.For().Add(); + initializer.For().Add(); + initializer.For().Add(); AddGitChangeTypes(initializer); DoCustomConfiguration(initializer); tfsPlugin.Initialize(initializer); @@ -211,13 +215,16 @@ private static void Initialize(IAssemblyScanner scan) private static void DoCustomConfiguration(ConfigurationExpression initializer) { - foreach (var type in typeof(Program).Assembly.GetTypes()) - { - foreach (ConfiguresStructureMap attribute in type.GetCustomAttributes(typeof(ConfiguresStructureMap), false)) - { - attribute.Initialize(initializer, type); - } - } + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); + initializer.For().Singleton().Use(); } } } diff --git a/src/GitTfs/Util/ConfiguresStructureMap.cs b/src/GitTfs/Util/ConfiguresStructureMap.cs deleted file mode 100644 index 535372224..000000000 --- a/src/GitTfs/Util/ConfiguresStructureMap.cs +++ /dev/null @@ -1,9 +0,0 @@ -using StructureMap; - -namespace GitTfs.Util -{ - public interface ConfiguresStructureMap - { - void Initialize(ConfigurationExpression initializer, Type t); - } -} \ No newline at end of file diff --git a/src/GitTfs/Util/GitTfsCommandFactory.cs b/src/GitTfs/Util/GitTfsCommandFactory.cs index 23a2546af..4cc28c0d4 100644 --- a/src/GitTfs/Util/GitTfsCommandFactory.cs +++ b/src/GitTfs/Util/GitTfsCommandFactory.cs @@ -1,8 +1,7 @@ -using StructureMap; +using StructureMap; namespace GitTfs.Util { - [StructureMapSingleton] public class GitTfsCommandFactory { private readonly IContainer _container; diff --git a/src/GitTfs/Util/StructureMapSingletonAttribute.cs b/src/GitTfs/Util/StructureMapSingletonAttribute.cs deleted file mode 100644 index 3f2ed5409..000000000 --- a/src/GitTfs/Util/StructureMapSingletonAttribute.cs +++ /dev/null @@ -1,10 +0,0 @@ -using StructureMap; - -namespace GitTfs.Util -{ - [AttributeUsage(AttributeTargets.Class)] - public class StructureMapSingletonAttribute : Attribute, ConfiguresStructureMap - { - public void Initialize(ConfigurationExpression initializer, Type t) => initializer.For(t).Singleton().Use(t); - } -} \ No newline at end of file diff --git a/src/GitTfsTest/Commands/ExtTest.cs b/src/GitTfsTest/Commands/ExtTest.cs index 63aadd178..3d4b374d1 100644 --- a/src/GitTfsTest/Commands/ExtTest.cs +++ b/src/GitTfsTest/Commands/ExtTest.cs @@ -1,5 +1,5 @@ -using GitTfs.Commands; using GitTfs.Core; +using GitTfs.Util; using Xunit; namespace GitTfs.Test.Commands diff --git a/src/GitTfsTest/GitTfsTest.csproj b/src/GitTfsTest/GitTfsTest.csproj index 757cd503f..4a89ee314 100644 --- a/src/GitTfsTest/GitTfsTest.csproj +++ b/src/GitTfsTest/GitTfsTest.csproj @@ -12,14 +12,14 @@ true + - + False - ..\packages\xunit.runner.visualstudio\build\_common\xunit.runner.visualstudio.testadapter.dll @@ -50,7 +50,13 @@ - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + \ No newline at end of file diff --git a/src/GitTfsTest/paket.references b/src/GitTfsTest/paket.references deleted file mode 100644 index 6b6671cdc..000000000 --- a/src/GitTfsTest/paket.references +++ /dev/null @@ -1,7 +0,0 @@ -LibGit2Sharp -xunit -xunit.runner.visualstudio -Moq -nlog -structuremap -Moq.AutoMock diff --git a/src/build.cake b/src/build.cake index 32da35a56..b4bbefb61 100644 --- a/src/build.cake +++ b/src/build.cake @@ -9,7 +9,7 @@ ////////////////////////////////////////////////////////////////////// readonly var Target = Argument("target", "Default"); readonly var Configuration = Argument("configuration", "Debug"); -var runInDryRun = Argument("isDryRun", true); +var runInDryRun = Argument("isDryRun", false); readonly var GitHubOwner = Argument("gitHubOwner", "git-tfs"); readonly var GitHubRepository = Argument("gitHubRepository", "git-tfs"); readonly var IdGitHubReleaseToDelete = Argument("idGitHubReleaseToDelete", -1); @@ -25,9 +25,14 @@ const string PathToSln = ApplicationPath + ".sln"; const string TargetFramework = "net48"; //due to new dotnet csproj format readonly var OutDir = "bin/" + Configuration + "/" + TargetFramework + "/"; const string buildAssetPath = @".\.build\"; -const string DownloadUrlTemplate ="https://github.com/git-tfs/git-tfs/releases/download/v{0}/"; +const string _downloadUrlBase = "https://github.com/lucianm/git-tfs"; +const string DownloadUrlTemplate = _downloadUrlBase + "/releases/download/v{0}/"; +// Fork-specific identifiers (empty for upstream) +const string _forkOwner = "lucianm"; // "git-tfs" for upstream +const string _forkPublisher = "LucianM"; // "GitTfs" for upstream +const string _forkPackageSuffix = "Lfs"; // "" for upstream string ReleaseNotesPath = @"..\doc\release-notes\NEXT.md"; -const string ChocolateyBuildDir = buildAssetPath + "choc"; +const string ChocolateyBuildDir = buildAssetPath + "chocolatey"; readonly var OutputDirectory = ApplicationPath + "/" + OutDir; const string TestProjectName = "GitTfsTest"; @@ -42,6 +47,15 @@ string _releaseVersion; string _sha1; string _appVeyorBuildVersion; bool _buildAllVersion = (Target == "AppVeyorRelease"); +Cake.Common.Security.FileHash _sha256; +string _shaFilePath; +string _scoopManifestPath; +string _scoopManifestZip; +string _wingetVersionPath; +string _wingetInstallerPath; +string _wingetLocalePath; +string _wingetManifestZip; +string _chocolateyManifestZip; ////////////////////////////////////////////////////////////////////// // TASKS @@ -75,60 +89,24 @@ Task("DryRun").Description("Set the dry-run flag") runInDryRun = true; }); -Task("TagVersion").Description("Handle release note and tag the new version") +Task("TagVersion").Description("Validate release notes exist for this version") .Does(() => { var version = GitVersion(); - string nextVersion; - string tag; - if(!IsMinorRelease) + var expectedReleaseNotePath = @"..\doc\release-notes\v" + version.MajorMinorPatch + ".md"; + + if(!FileExists(expectedReleaseNotePath)) { - var tagVersion = version.Major + "." + (version.Minor + 1); - tag = "v" + tagVersion; - nextVersion = tagVersion + ".0"; - } - else - { - nextVersion = version.Major + "." + version.Minor + "." + version.CommitsSinceVersionSource; - tag = "v" + nextVersion; - } - Information("Next version will be:" + nextVersion); - - if(!runInDryRun) - { - Information("Creating release tag..."); - var githubAccount = GetGithubUserAccount(); - var githubToken = GetGithubAuthToken(); - if(FileExists(ReleaseNotesPath)) - { - var newReleaseNotePath = @"..\doc\release-notes\v" + nextVersion + ".md"; - MoveFile(ReleaseNotesPath, newReleaseNotePath); - - GitAdd("..", newReleaseNotePath); - GitRemove("..", false, ReleaseNotesPath); - var releaseNoteCommit = GitCommit("..", @"Git-tfs release bot", "no-reply@git-tfs.com", "Prepare release " + tag); - Information("Release note commit created:" + releaseNoteCommit.Sha); - - ReleaseNotesPath = newReleaseNotePath; - GitPush("..", githubAccount, githubToken, "master"); - } - if(!IsMinorRelease) - { - GitTag("..", tag); - GitPushRef("..", githubAccount, githubToken, "origin", "refs/tags/" + tag); - } - } - else - { - if(!IsMinorRelease) - { - Information("[DryRun] Should create the release tag: " + tag); - } - else - { - Information("[DryRun] Minor release => Should not create a release tag"); - } + throw new Exception( + $"Release notes file not found: {expectedReleaseNotePath}\n" + + "Please create the release notes file before tagging:\n" + + " 1. Copy NEXT.md to v" + version.MajorMinorPatch + ".md\n" + + " 2. Commit the new file\n" + + " 3. Create and push the tag: git tag v" + version.MajorMinorPatch + " && git push --follow-tags" + ); } + + Information($"Found release notes: {expectedReleaseNotePath}"); }); Task("Clean").Description("Clean the working directory") @@ -142,19 +120,13 @@ Task("Clean").Description("Clean the working directory") }); }); -Task("Restore-NuGet-Packages").Description("Restore nuget dependencies (with paket)") - .Does(() => -{ - StartProcess(FileExists("paket.exe") ? "paket.exe" : @".paket\paket.exe", "restore"); - StartProcess("dotnet", $"restore {PathToSln}"); -}); - Task("Version").Description("Get the version using GitVersion") .Does(() => { var version = GitVersion(); - _semanticVersionShort = version.Major + "." + version.Minor + "." + version.CommitsSinceVersionSource; - _semanticVersionLong = _semanticVersionShort + "+" + version.Sha + "." + version.BranchName; + // Use GitVersion's SemVer for better tagged commit handling + _semanticVersionShort = version.MajorMinorPatch; + _semanticVersionLong = version.InformationalVersion; Information("Semantic version (short):" + _semanticVersionShort); Information("Semantic version (long ):" + _semanticVersionLong); @@ -162,16 +134,25 @@ Task("Version").Description("Get the version using GitVersion") var normalizedBranchName = NormalizeBrancheName(version.BranchName); _sha1 = version.Sha; var shortSha1 = version.Sha.Substring(0,8); - var postFix = (version.BranchName == "master") ? string.Empty : "-" + shortSha1 + "." + normalizedBranchName; + // For tagged releases (CommitsSinceVersionSource == 0) or master branch, use clean version without postfix + var isTaggedRelease = version.CommitsSinceVersionSource == 0 || version.BranchName == "master" || version.BranchName.StartsWith("tags/"); + var postFix = isTaggedRelease ? string.Empty : "-" + shortSha1 + "." + normalizedBranchName; _zipFilename = string.Format(ZipFileTemplate, _semanticVersionShort + postFix); _zipFilePath = System.IO.Path.Combine(buildAssetPath, _zipFilename); + _shaFilePath = _zipFilePath + ".sha256"; _downloadUrl = string.Format(DownloadUrlTemplate, _semanticVersionShort) + _zipFilename; _releaseVersion = "v" + _semanticVersionShort; + + // Derive release notes path from version (tag-driven releases) + ReleaseNotesPath = @"..\doc\release-notes\" + _releaseVersion + ".md"; + Information("Release notes path: " + ReleaseNotesPath); + // Guard against non-AppVeyor environments + var buildNumber = EnvironmentVariable("APPVEYOR_BUILD_NUMBER") ?? "0"; _appVeyorBuildVersion = _semanticVersionShort + ((version.BranchName == "master") ? string.Empty : "+" + shortSha1 + "." + normalizedBranchName) - + "." + EnvironmentVariable("APPVEYOR_BUILD_NUMBER"); + + "." + buildNumber; }); void UpdateAppVeyorBuildNumber() @@ -200,7 +181,6 @@ Task("UpdateAssemblyInfo").Description("Update AssemblyInfo properties with the }); Task("Build").Description("Build git-tfs") - .IsDependentOn("Restore-NuGet-Packages") .IsDependentOn("UpdateAssemblyInfo") .Does(() => { @@ -325,22 +305,30 @@ Task("Package").Description("Generate the release zip file") CopyDirectory(@"..\doc", OutputDirectory + @"\doc"); CopyFiles(new[] {@"..\README.md", @"..\LICENSE", @"..\NOTICE"}, OutputDirectory); - CopyFiles(new[] {@".\build\CorFlags.exe", @".\build\enable_checkin_policies_support.bat", @".\build\disable_checkin_policies_support.bat"}, OutputDirectory); + CopyFiles(new[] {@".\build\CorFlags.exe", @".\build\enable_checkin_policies_support.bat", @".\build\disable_checkin_policies_support.bat", @".\build\git-tfs.cmd"}, OutputDirectory); DeleteFiles(OutputDirectory + @"\**\*.pdb"); //Create the zip Zip(OutputDirectory, _zipFilePath); + + // calculate sha256 hash, store in variable and file artifact, usable in Choco, Scoop, WinGet... + _sha256 = CalculateFileHash(_zipFilePath); + System.IO.File.WriteAllText(_shaFilePath, $"{_sha256.ToHex()} {_zipFilename}"); + Information($"Hash ({_sha256.Algorithm:G}):" + _sha256.ToHex()); + if(!BuildSystem.IsLocalBuild) { if(BuildSystem.IsRunningOnAppVeyor) { Information("Upload artifacts to AppVeyor..."); BuildSystem.AppVeyor.UploadArtifact(_zipFilePath); + BuildSystem.AppVeyor.UploadArtifact(_shaFilePath); } if(BuildSystem.IsRunningOnAzurePipelinesHosted) { Information("Upload artifacts to VSTS..."); BuildSystem.AzurePipelines.Commands.UploadArtifact("install", _zipFilePath, _zipFilename); + BuildSystem.AzurePipelines.Commands.UploadArtifact("install", _shaFilePath, System.IO.Path.GetFileName(_shaFilePath)); } } }); @@ -435,14 +423,197 @@ string GetGithubAuthToken() return token; } - return ReadToken("GitHub", @"^ghp_[\d\w]{36}$"); + return ReadToken("GitHub", @"^(ghp_|github_pat_).+"); } string ReadReleaseNotes() { if(!FileExists(ReleaseNotesPath)) + { + Warning($"Release notes file not found: {ReleaseNotesPath}"); return string.Empty; - return System.IO.File.ReadAllText(ReleaseNotesPath); + } + var notes = System.IO.File.ReadAllText(ReleaseNotesPath); + Information($"Loaded release notes from: {ReleaseNotesPath}"); + return notes; +} + +void GenerateScoopManifest() +{ + Information("Generating Scoop manifest..."); + + var packageSuffix = string.IsNullOrEmpty(_forkPackageSuffix) ? "" : "-" + _forkPackageSuffix.ToLower(); + var description = string.IsNullOrEmpty(_forkPackageSuffix) + ? "A Git/TFS bridge, similar to git-svn." + : "A Git/TFS bridge with full Git LFS support, similar to git-svn."; + + // Build manifest matching upstream Scoop format + var scoopManifest = new + { + version = _semanticVersionShort, + description = description, + homepage = _downloadUrlBase, + license = "Apache-2.0", + depends = "git", + url = _downloadUrl, + hash = _sha256.ToHex().ToLower(), + bin = "git-tfs.exe", + checkver = new + { + github = _downloadUrlBase + }, + autoupdate = new + { + url = $"{_downloadUrlBase}/releases/download/v$version/GitTfs-$version.zip" + } + }; + + var scoopDir = System.IO.Path.Combine(buildAssetPath, "scoop"); + EnsureDirectoryExists(scoopDir); + CleanDirectory(scoopDir); + + _scoopManifestPath = System.IO.Path.Combine(scoopDir, $"git-tfs{packageSuffix}.json"); + var json = Newtonsoft.Json.JsonConvert.SerializeObject(scoopManifest, Newtonsoft.Json.Formatting.Indented); + System.IO.File.WriteAllText(_scoopManifestPath, json + Environment.NewLine); + Information($"Scoop manifest created: {_scoopManifestPath}"); + + // Zip the Scoop manifest + _scoopManifestZip = System.IO.Path.Combine(buildAssetPath, "manifest.scoop.zip"); + Zip(scoopDir, _scoopManifestZip); + Information($"Scoop manifest zipped: {_scoopManifestZip}"); + + if(BuildSystem.IsRunningOnAppVeyor) + { + Information("Uploading Scoop manifest as AppVeyor artifact..."); + BuildSystem.AppVeyor.UploadArtifact(_scoopManifestZip); + } + if(BuildSystem.IsRunningOnAzurePipelinesHosted) + { + Information("Uploading Scoop manifest as Azure Pipelines artifact..."); + BuildSystem.AzurePipelines.Commands.UploadArtifact("install", _scoopManifestZip, "manifest.scoop.zip"); + } +} + +void GenerateWinGetManifest() +{ + Information("Generating WinGet manifest..."); + + // WinGet uses YAML manifests with three files: version, installer, and locale + // Format: manifests///// + var wingetBaseDir = System.IO.Path.Combine(buildAssetPath, "winget"); + var publisher = string.IsNullOrEmpty(_forkPublisher) ? "GitTfs" : _forkPublisher; + var packageId = $"{publisher}.GitTfs{_forkPackageSuffix}"; + var packageName = string.IsNullOrEmpty(_forkPackageSuffix) ? "git-tfs" : $"git-tfs-{_forkPackageSuffix.ToLower()}"; + + // Create versioned directory structure + var wingetDir = System.IO.Path.Combine(wingetBaseDir, _semanticVersionShort); + EnsureDirectoryExists(wingetDir); + CleanDirectory(wingetDir); + + // Version manifest + var versionManifest = $@"# Created using Cake Build +# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.12.0.schema.json + +PackageIdentifier: {packageId} +PackageVersion: {_semanticVersionShort} +DefaultLocale: en-US +ManifestType: version +ManifestVersion: 1.12.0 +"; + _wingetVersionPath = System.IO.Path.Combine(wingetDir, $"{packageId}.yaml"); + System.IO.File.WriteAllText(_wingetVersionPath, versionManifest); + + // Installer manifest + var installerManifest = $@"# Created using Cake Build +# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.12.0.schema.json + +PackageIdentifier: {packageId} +PackageVersion: {_semanticVersionShort} +InstallerType: zip +Commands: +- git-tfs +Installers: +- Architecture: x64 + NestedInstallerType: portable + NestedInstallerFiles: + - RelativeFilePath: git-tfs.cmd + PortableCommandAlias: git-tfs + InstallerUrl: {_downloadUrl} + InstallerSha256: {_sha256.ToHex()} + Dependencies: + PackageDependencies: + - PackageIdentifier: Git.Git +ManifestType: installer +ManifestVersion: 1.12.0 +"; + _wingetInstallerPath = System.IO.Path.Combine(wingetDir, $"{packageId}.installer.yaml"); + System.IO.File.WriteAllText(_wingetInstallerPath, installerManifest); + + // Locale manifest + var releaseNotes = ReadReleaseNotes(); + if(string.IsNullOrEmpty(releaseNotes)) + { + releaseNotes = $"See {_downloadUrlBase}/releases/tag/v{_semanticVersionShort}"; + } + // WinGet schema 1.12.0 allows up to 10000 characters for ReleaseNotes + if(releaseNotes.Length > 10000) + { + releaseNotes = releaseNotes.Substring(0, 9997) + "..."; + } + // Escape special characters for YAML string formatting + releaseNotes = releaseNotes.Replace("\\", "\\\\").Replace("\"", "\\\""); + + var publisherName = string.IsNullOrEmpty(_forkPublisher) ? "git-tfs contributors" : "Lucian Muresan"; + var description = string.IsNullOrEmpty(_forkPackageSuffix) + ? "git-tfs is a two-way bridge between TFS/Azure DevOps and Git, allowing you to work with a Git repository while interacting with TFS." + : "git-tfs is a two-way bridge between TFS/Azure DevOps and Git, allowing you to work with a Git repository while interacting with TFS. This fork includes full Git LFS awareness via filter-process protocol, supporting LFS right from cloning from TFVC."; + + var localeManifest = $@"# Created using Cake Build +# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.12.0.schema.json + +PackageIdentifier: {packageId} +PackageVersion: {_semanticVersionShort} +PackageLocale: en-US +Publisher: {publisherName} +PublisherUrl: {_downloadUrlBase} +PackageName: {packageName} +PackageUrl: {_downloadUrlBase} +License: Apache-2.0 +LicenseUrl: {_downloadUrlBase}/blob/master/LICENSE +ShortDescription: A Git/TFS bridge with full Git LFS support +Description: {description} +Tags: +- git +- tfs +- version-control +- azure-devops +- lfs +- git-lfs +ReleaseNotes: ""{releaseNotes}"" +ReleaseNotesUrl: {_downloadUrlBase}/releases/tag/v{_semanticVersionShort} +ManifestType: defaultLocale +ManifestVersion: 1.12.0 +"; + _wingetLocalePath = System.IO.Path.Combine(wingetDir, $"{packageId}.locale.en-US.yaml"); + System.IO.File.WriteAllText(_wingetLocalePath, localeManifest); + + Information($"WinGet manifests created in: {wingetDir}"); + + // Zip the WinGet manifests + _wingetManifestZip = System.IO.Path.Combine(buildAssetPath, "manifest.winget.zip"); + Zip(wingetDir, _wingetManifestZip); + Information($"WinGet manifests zipped: {_wingetManifestZip}"); + + if(BuildSystem.IsRunningOnAppVeyor) + { + Information("Uploading WinGet manifest as AppVeyor artifact..."); + BuildSystem.AppVeyor.UploadArtifact(_wingetManifestZip); + } + if(BuildSystem.IsRunningOnAzurePipelinesHosted) + { + Information("Uploading WinGet manifest as Azure Pipelines artifact..."); + BuildSystem.AzurePipelines.Commands.UploadArtifact("install", _wingetManifestZip, "manifest.winget.zip"); + } } Octokit.GitHubClient GetGithubClient() @@ -487,10 +658,8 @@ environmentVariables: { httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", appVeyorToken); httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); - var taskTriggerRelease = httpClient.PostAsync("https://ci.appveyor.com/api/builds", - new System.Net.Http.StringContent(content, System.Text.Encoding.UTF8, "application/json")); - taskTriggerRelease.Wait(); - var httpResponseMessage = taskTriggerRelease.Result; + var httpResponseMessage = httpClient.PostAsync("https://ci.appveyor.com/api/builds", + new System.Net.Http.StringContent(content, System.Text.Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); if(httpResponseMessage.IsSuccessStatusCode) { Information("Release build successfully triggered."); @@ -503,6 +672,7 @@ environmentVariables: { Task("CreateGithubRelease").Description("Create a GitHub release") .IsDependentOn("Package") + .IsDependentOn("GenerateDistributionChannelArtifacts") .WithCriteria(!runInDryRun) .Does(() => { @@ -512,22 +682,66 @@ Task("CreateGithubRelease").Description("Create a GitHub release") var releaseNotes = ReadReleaseNotes(); - releaseNotes += Environment.NewLine + "![Git-Tfs " + _releaseVersion + " download count](https://img.shields.io/github/downloads/git-tfs/git-tfs/" + _releaseVersion + "/total.svg)"; + releaseNotes += Environment.NewLine + "![Git-Tfs " + _releaseVersion + " download count](https://img.shields.io/github/downloads/" + _forkOwner + "/git-tfs/" + _releaseVersion + "/total.svg)"; - var newRelease = new Octokit.NewRelease(_releaseVersion); - newRelease.Name = _releaseVersion; - newRelease.Body = releaseNotes; - newRelease.Draft = false; - newRelease.Prerelease = false; - newRelease.TargetCommitish = _sha1; - - var taskCreateRelease = client.Repository.Release.Create(GitHubOwner, GitHubRepository, newRelease); - taskCreateRelease.Wait(); - var gitHubRelease = taskCreateRelease.Result; - Information("Github Release created. Id:" + gitHubRelease.Id); + // Check if release already exists (for GitHub Actions re-runs) + // Use GetAll and filter by TagName for maximum compatibility + Octokit.Release gitHubRelease = null; + try + { + var allReleases = client.Repository.Release.GetAll(GitHubOwner, GitHubRepository).GetAwaiter().GetResult(); + gitHubRelease = allReleases.FirstOrDefault(r => r.TagName == _releaseVersion); + + if(gitHubRelease != null) + { + Information($"Github Release '{_releaseVersion}' already exists (Id: {gitHubRelease.Id}). Updating..."); + + try + { + // Update existing release + var releaseUpdate = gitHubRelease.ToUpdate(); + releaseUpdate.Body = releaseNotes; + releaseUpdate.Name = _releaseVersion; + releaseUpdate.TargetCommitish = _sha1; + + gitHubRelease = client.Repository.Release.Edit(GitHubOwner, GitHubRepository, gitHubRelease.Id, releaseUpdate).GetAwaiter().GetResult(); + } + catch (Octokit.ApiException ex) + { + throw new Exception($"Failed to update GitHub release '{_releaseVersion}' (Id: {gitHubRelease.Id}): {ex.StatusCode} {ex.Message}", ex); + } + } + else + { + // Release doesn't exist, create it + Information($"Creating new Github Release '{_releaseVersion}'..."); + + try + { + var newRelease = new Octokit.NewRelease(_releaseVersion); + newRelease.Name = _releaseVersion; + newRelease.Body = releaseNotes; + newRelease.Draft = false; + newRelease.Prerelease = false; + newRelease.TargetCommitish = _sha1; + + gitHubRelease = client.Repository.Release.Create(GitHubOwner, GitHubRepository, newRelease).GetAwaiter().GetResult(); + Information("Github Release created. Id:" + gitHubRelease.Id); + } + catch (Octokit.ApiException ex) + { + throw new Exception($"Failed to create GitHub release '{_releaseVersion}': {ex.StatusCode} {ex.Message}", ex); + } + } + } + catch (System.Exception ex) when (!(ex is Octokit.ApiException)) + { + throw new Exception("Failed to create or update GitHub release: " + ex.Message, ex); + } + Information("If needed, delete the Github Release with the command:"); Information(@".\tools\Cake\Cake.exe build.cake -target=DeleteRelease -idGitHubReleaseToDelete="+ gitHubRelease.Id); - UploadReleaseAsset(client, gitHubRelease); + UploadReleaseAssets(client, gitHubRelease); }); Task("DeleteRelease").Description("Delete a (broken) GitHub release") @@ -536,30 +750,72 @@ Task("DeleteRelease").Description("Delete a (broken) GitHub release") { Information("Deleting release '" + IdGitHubReleaseToDelete +"'..."); var client = GetGithubClient(); - var taskDeleteRelease = client.Repository.Release.Delete(GitHubOwner, GitHubRepository, IdGitHubReleaseToDelete); - taskDeleteRelease.Wait(); + client.Repository.Release.Delete(GitHubOwner, GitHubRepository, IdGitHubReleaseToDelete).GetAwaiter().GetResult(); }); -void UploadReleaseAsset(Octokit.GitHubClient client, Octokit.Release release) +void UploadReleaseAssets(Octokit.GitHubClient client, Octokit.Release release) { - Information("Uploading asset..."); - var archiveContents = System.IO.File.OpenRead(_zipFilePath); - var assetUpload = new Octokit.ReleaseAssetUpload() - { - FileName = _zipFilename, - ContentType = "application/zip", - RawData = archiveContents + Information("Uploading release assets..."); + + // Get fresh asset list for idempotent uploads + var existingAssets = client.Repository.Release.GetAllAssets(GitHubOwner, GitHubRepository, release.Id).GetAwaiter().GetResult(); + + // Helper function to upload a single asset + Action uploadAsset = (filePath, contentType) => { + var fileName = System.IO.Path.GetFileName(filePath); + + // Check if asset already exists and delete it + var existingAsset = existingAssets.FirstOrDefault(a => a.Name == fileName); + if(existingAsset != null) + { + Information($"Asset '{fileName}' already exists. Deleting old version..."); + try + { + client.Repository.Release.DeleteAsset(GitHubOwner, GitHubRepository, existingAsset.Id).GetAwaiter().GetResult(); + } + catch (Octokit.ApiException ex) + { + Warning($"Failed to delete existing asset '{fileName}': {ex.StatusCode} {ex.Message}"); + // Continue anyway, upload may still succeed + } + } + + Information($"Uploading asset: {fileName} ({contentType})"); + var fileContents = System.IO.File.OpenRead(filePath); + + try + { + var assetUpload = new Octokit.ReleaseAssetUpload() + { + FileName = fileName, + ContentType = contentType, + RawData = fileContents + }; + + client.Repository.Release.UploadAsset(release, assetUpload).GetAwaiter().GetResult(); + Information($"Successfully uploaded: {fileName}"); + } + catch (Octokit.ApiException ex) + { + throw new Exception($"Failed uploading asset '{fileName}' ({contentType}): {ex.StatusCode} {ex.Message}", ex); + } + finally + { + fileContents.Dispose(); + } }; - - var uploadTask = client.Repository.Release.UploadAsset(release, assetUpload); - uploadTask.Wait(); - if(uploadTask.Exception != null) - { - throw new Exception("Fail to upload asset!!" + uploadTask.Exception.Message); - } + + // Upload all assets + uploadAsset(_zipFilePath, "application/zip"); + uploadAsset(_shaFilePath, "text/plain"); + uploadAsset(_chocolateyManifestZip, "application/zip"); + uploadAsset(_scoopManifestZip, "application/zip"); + uploadAsset(_wingetManifestZip, "application/zip"); + + Information("All release assets uploaded successfully."); } -Task("Chocolatey").Description("Generate the chocolatey package") +Task("GenerateDistributionChannelArtifacts").Description("Generate packaging artifacts for different distribution channels") .IsDependentOn("TagVersion") .IsDependentOn("Package") .Does(() => @@ -570,21 +826,18 @@ Task("Chocolatey").Description("Generate the chocolatey package") CopyFiles(@".\build\ChocolateyTemplates\*.*", ChocolateyBuildDir); var nuspecPathInBuildDir = System.IO.Path.Combine(ChocolateyBuildDir, "gittfs.nuspec"); - var sha256 = CalculateFileHash(_zipFilePath); - Information($"Hash ({sha256.Algorithm:G}):" + sha256.ToHex()); - //Template 'chocolateyInstall.ps1' var installScriptPathInBuildDir = System.IO.Path.Combine(ChocolateyBuildDir, "chocolateyInstall.ps1"); string text = TransformTextFile(installScriptPathInBuildDir, "${", "}") .WithToken("DownloadUrl", _downloadUrl) - .WithToken("Checksum", sha256.ToHex()) + .WithToken("Checksum", _sha256.ToHex()) .ToString(); System.IO.File.WriteAllText(installScriptPathInBuildDir, text); var releaseNotes = ReadReleaseNotes(); if(string.IsNullOrEmpty(releaseNotes)) { - releaseNotes = "See https://github.com/git-tfs/git-tfs/releases/tag/v" + _semanticVersionShort; + releaseNotes = "See " + _downloadUrlBase + "/releases/tag/v" + _semanticVersionShort; } //http://cakebuild.net/dsl/chocolatey Information("Creating Chocolatey package:" + nuspecPathInBuildDir); @@ -629,6 +882,27 @@ Task("Chocolatey").Description("Generate the chocolatey package") { Information($"[DryRun] Would have uploaded chocolatey package '{chocolateyPackagePath}'..."); } + + // Zip Chocolatey artifacts for release + _chocolateyManifestZip = System.IO.Path.Combine(buildAssetPath, "manifest.chocolatey.zip"); + Zip(ChocolateyBuildDir, _chocolateyManifestZip); + Information($"Chocolatey manifest zipped: {_chocolateyManifestZip}"); + + // Upload Chocolatey manifest zip as artifact + if(BuildSystem.IsRunningOnAppVeyor) + { + BuildSystem.AppVeyor.UploadArtifact(_chocolateyManifestZip); + } + if(BuildSystem.IsRunningOnAzurePipelinesHosted) + { + BuildSystem.AzurePipelines.Commands.UploadArtifact("install", _chocolateyManifestZip, "manifest.chocolatey.zip"); + } + + // Generate Scoop manifest + GenerateScoopManifest(); + + // Generate WinGet manifest + GenerateWinGetManifest(); }); ////////////////////////////////////////////////////////////////////// @@ -655,12 +929,10 @@ Task("AppVeyorBuild").Description("Do the continuous integration build with AppV }); Task("AppVeyorRelease").Description("Do the release build with AppVeyor") - .IsDependentOn("TagVersion") .IsDependentOn("Run-Unit-Tests") //.IsDependentOn("Run-Smoke-Tests") //TFS Projects on CodePlex are no more reachable .IsDependentOn("Package") .IsDependentOn("CreateGithubRelease") - .IsDependentOn("Chocolatey") .Finally(() => { if(BuildSystem.IsRunningOnAppVeyor) @@ -673,7 +945,7 @@ Task("AppVeyorRelease").Description("Do the release build with AppVeyor") Task("Release").Description("Build the release and put it on github.com") - .IsDependentOn("Chocolatey"); + .IsDependentOn("CreateGithubRelease"); Task("DryRunRelease").Description("Do a 'dry-run' release to verify easily most of the release tasks") .IsDependentOn("DryRun") diff --git a/src/build/git-tfs.cmd b/src/build/git-tfs.cmd new file mode 100644 index 000000000..bbc5288c5 --- /dev/null +++ b/src/build/git-tfs.cmd @@ -0,0 +1,6 @@ +@echo off +pushd "%~dp0" +git-tfs.exe %* +set EXITCODE=%ERRORLEVEL% +popd +exit /b %EXITCODE% diff --git a/src/paket.dependencies b/src/paket.dependencies deleted file mode 100644 index 13e79214a..000000000 --- a/src/paket.dependencies +++ /dev/null @@ -1,47 +0,0 @@ -# pin paket to a specific version so the build is really reproducable -version 8.0.3 - -framework: net48 -source https://api.nuget.org/v3/index.json - -//If you plan to update this file, you must first absolutly read our documentation on the subject -//because there is some subtleties on how we use it in our project: -//https://github.com/git-tfs/git-tfs/blob/master/doc/paket.md - -nuget nlog -nuget LibGit2Sharp 0.31.0 -nuget Moq -nuget structuremap 4.7.1 -nuget Moq.AutoMock -nuget xunit -nuget xunit.assert -nuget xunit.runner.visualstudio version_in_path: true - -group Build - redirects: off - source https://api.nuget.org/v3/index.json - -nuget Cake ~> 1.3.0 -nuget Cake.Git ~> 1.0.1 -nuget GitVersion.CommandLine -nuget opencover -nuget reportgenerator -nuget xunit.runner.console -nuget Octokit ~> 0.52 - - -group VS2019 - framework: net48 - source https://api.nuget.org/v3/index.json - nuget Microsoft.TeamFoundationServer.Client 16.205.3 - nuget Microsoft.TeamFoundationServer.ExtendedClient 16.205.3 - nuget Microsoft.VisualStudio.Setup.Configuration.Interop - nuget Microsoft.VisualStudio.Settings.15.0 ~> 16.0 - -group VS2022 - framework: net48 - source https://api.nuget.org/v3/index.json - nuget Microsoft.TeamFoundationServer.Client ~> 19.0 - nuget Microsoft.TeamFoundationServer.ExtendedClient ~> 19.0 - nuget Microsoft.VisualStudio.Setup.Configuration.Interop - nuget Microsoft.VisualStudio.Settings.15.0 ~> 17.0 diff --git a/src/paket.exe b/src/paket.exe deleted file mode 100644 index 092b994f5..000000000 Binary files a/src/paket.exe and /dev/null differ diff --git a/src/paket.lock b/src/paket.lock deleted file mode 100644 index e9d4442c3..000000000 --- a/src/paket.lock +++ /dev/null @@ -1,1051 +0,0 @@ -RESTRICTION: == net48 -NUGET - remote: https://api.nuget.org/v3/index.json - Castle.Core (4.4) - LibGit2Sharp (0.31) - LibGit2Sharp.NativeBinaries (2.0.323) - LibGit2Sharp.NativeBinaries (2.0.323) - Moq (4.14.7) - Castle.Core (>= 4.4) - System.Threading.Tasks.Extensions (>= 4.5.1) - Moq.AutoMock (2.1) - Moq (>= 4.13.1) - NLog (4.7.5) - structuremap (4.7.1) - System.Reflection.Emit.Lightweight (>= 4.3) - System.Reflection.Emit.Lightweight (4.7) - System.Runtime.CompilerServices.Unsafe (4.7.1) - System.Threading.Tasks.Extensions (4.5.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - xunit (2.7) - xunit.analyzers (>= 1.11) - xunit.assert (>= 2.7) - xunit.core (2.7) - xunit.abstractions (2.0.3) - xunit.analyzers (1.11) - xunit.assert (2.7) - xunit.core (2.7) - xunit.extensibility.core (2.7) - xunit.extensibility.execution (2.7) - xunit.extensibility.core (2.7) - xunit.abstractions (>= 2.0.3) - xunit.extensibility.execution (2.7) - xunit.extensibility.core (2.7) - xunit.runner.visualstudio (2.4.1) - version_in_path: true - -GROUP Build -REDIRECTS: OFF -NUGET - remote: https://api.nuget.org/v3/index.json - Cake (1.3) - Cake.Git (1.0.1) - GitVersion.CommandLine (5.12) - Octokit (0.52) - OpenCover (4.7.1221) - ReportGenerator (5.5.7) - xunit.runner.console (2.9.3) - -GROUP VS2019 -RESTRICTION: == net48 -NUGET - remote: https://api.nuget.org/v3/index.json - MessagePack (3.1.4) - MessagePack.Annotations (>= 3.1.4) - MessagePackAnalyzer (>= 3.1.4) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.NET.StringTools (>= 17.11.4) - System.Collections.Immutable (>= 8.0) - System.Memory (>= 4.5.5) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - MessagePack.Annotations (3.1.4) - MessagePackAnalyzer (3.1.4) - Microsoft.AspNet.WebApi.Client (6.0) - Newtonsoft.Json (>= 13.0.1) - Newtonsoft.Json.Bson (>= 1.0.2) - System.Memory (>= 4.5.5) - System.Threading.Tasks.Extensions (>= 4.5.4) - Microsoft.AspNet.WebApi.Core (5.3) - Microsoft.AspNet.WebApi.Client (>= 6.0) - Microsoft.AspNet.WebApi.WebHost (5.3) - Microsoft.AspNet.WebApi.Core (>= 5.3) - Microsoft.Bcl.AsyncInterfaces (10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - Microsoft.Bcl.HashCode (6.0) - Microsoft.Bcl.TimeProvider (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.ValueTuple (>= 4.6.2) - Microsoft.Build.Framework (18.4) - System.Collections.Immutable (>= 10.0.1) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Json (>= 10.0.1) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.ValueTuple (>= 4.6.1) - Microsoft.CSharp (4.7) - Microsoft.Extensions.DependencyInjection.Abstractions (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - Microsoft.Extensions.Logging.Abstractions (10.0.7) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.7) - System.Buffers (>= 4.6.1) - System.Diagnostics.DiagnosticSource (>= 10.0.7) - System.Memory (>= 4.6.3) - Microsoft.IdentityModel.Abstractions (8.17) - Microsoft.IdentityModel.Clients.ActiveDirectory (5.3) - System.Net.Http (>= 4.3.4) - System.Private.Uri (>= 4.3.2) - Microsoft.IdentityModel.JsonWebTokens (8.17) - Microsoft.Bcl.TimeProvider (>= 8.0.1) - Microsoft.IdentityModel.Tokens (>= 8.17) - Microsoft.IdentityModel.Logging (8.17) - Microsoft.IdentityModel.Abstractions (>= 8.17) - Microsoft.IdentityModel.Tokens (8.17) - Microsoft.Bcl.TimeProvider (>= 8.0.1) - Microsoft.Extensions.Logging.Abstractions (>= 2.1) - Microsoft.IdentityModel.Logging (>= 8.17) - System.Diagnostics.DiagnosticSource (>= 6.0.2) - System.Memory (>= 4.5.5) - System.Text.Json (>= 8.0.5) - Microsoft.IO.Redist (6.1.3) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - Microsoft.NET.StringTools (18.4) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - Microsoft.NETCore.Platforms (7.0.4) - Microsoft.NETCore.Targets (5.0) - Microsoft.ServiceHub.Analyzers (4.8.55) - Microsoft.ServiceHub.Framework (4.8.55) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.VisualStudio.Composition (>= 17.12.20) - Microsoft.VisualStudio.Threading (>= 17.13.2) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Nerdbank.Streams (>= 2.11.86) - StreamJsonRpc (>= 2.21.10) - System.Collections.Immutable (>= 8.0) - System.Text.Json (>= 8.0.5) - Microsoft.ServiceHub.Resources (4.6.2052) - Microsoft.TeamFoundation.DistributedTask.Common.Contracts (16.205.3) - Microsoft.VisualStudio.Services.Client (16.205.3) - Microsoft.TeamFoundationServer.Client (16.205.3) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.AspNet.WebApi.Core (>= 5.2.7) - Microsoft.AspNet.WebApi.WebHost (>= 5.2.7) - Microsoft.TeamFoundation.DistributedTask.Common.Contracts (16.205.3) - Microsoft.VisualStudio.Services.Client (16.205.3) - Newtonsoft.Json (>= 12.0.3) - Microsoft.TeamFoundationServer.ExtendedClient (16.205.3) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.AspNet.WebApi.Core (>= 5.2.7) - Microsoft.IdentityModel.Clients.ActiveDirectory (>= 5.2.6) - Microsoft.TeamFoundationServer.Client (16.205.3) - Microsoft.VisualStudio.Services.Client (16.205.3) - Microsoft.VisualStudio.Services.InteractiveClient (16.205.3) - Newtonsoft.Json (>= 12.0.3) - System.IdentityModel.Tokens.Jwt (>= 5.6) - Microsoft.VisualStudio.ComponentModelHost (17.14.106) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.VisualStudio.Composition (>= 17.12.20) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.13.39273) - Microsoft.VisualStudio.Interop (>= 17.13.39276) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.Collections.Immutable (>= 8.0) - System.ComponentModel.Composition (>= 8.0) - System.Memory (>= 4.5.5) - System.Reflection.Metadata (>= 8.0) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - Microsoft.VisualStudio.Composition (17.13.41) - MessagePack (>= 2.5.192) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.Collections.Immutable (>= 8.0) - System.ComponentModel.Composition (>= 8.0) - System.Composition (>= 8.0) - System.Composition.AttributedModel (>= 8.0) - System.Reflection.Metadata (>= 8.0) - System.Threading.Tasks.Dataflow (>= 8.0.1) - Microsoft.VisualStudio.Composition.Analyzers (17.13.41) - Microsoft.VisualStudio.GraphModel (17.14.40260) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - System.ComponentModel.Composition (>= 9.0) - Microsoft.VisualStudio.ImageCatalog (17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.Imaging (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (17.14.40254) - Microsoft.VisualStudio.Interop (17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.ProjectAggregator (17.14.40254) - Microsoft.VisualStudio.RegDetour (17.10.34916.79) - Microsoft.VisualStudio.RemoteControl (16.3.52) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.42) - Microsoft.VisualStudio.RpcContracts (17.14.20) - Microsoft.ServiceHub.Framework (>= 4.8.40) - System.Text.Json (>= 8.0.5) - System.Threading.Tasks.Dataflow (>= 8.0.1) - Microsoft.VisualStudio.SDK.Analyzers (17.7.113) - Microsoft.VisualStudio.Services.Client (16.205.3) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.IdentityModel.Tokens (>= 5.6) - Newtonsoft.Json (>= 12.0.3) - System.IdentityModel.Tokens.Jwt (>= 5.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Services.InteractiveClient (16.205.3) - Microsoft.IdentityModel.Clients.ActiveDirectory (>= 5.2.6) - Microsoft.IdentityModel.Logging (>= 5.6) - Microsoft.IdentityModel.Tokens (>= 5.6) - Microsoft.VisualStudio.Services.Client (16.205.3) - Newtonsoft.Json (>= 12.0.3) - System.IdentityModel.Tokens.Jwt (>= 5.6) - Microsoft.VisualStudio.Settings.15.0 (16.10.31321.278) - Microsoft.VisualStudio.RegDetour (>= 16.10.31320.204) - Microsoft.VisualStudio.Shell.15.0 (>= 16.10.31321.278) - Microsoft.VisualStudio.Setup.Configuration.Interop (3.14.2075) - Microsoft.VisualStudio.Shell.15.0 (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.Build.Framework (>= 17.14.7) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.ComponentModelHost (>= 17.14.106) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.GraphModel (>= 17.14.40260) - Microsoft.VisualStudio.ImageCatalog (>= 17.14.40260) - Microsoft.VisualStudio.Imaging (>= 17.14.40264) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.ProjectAggregator (>= 17.14.40254) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.SDK.Analyzers (>= 17.7.79) - Microsoft.VisualStudio.Shell.Framework (>= 17.14.40264) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Shell.Framework (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.Build.Framework (>= 17.14.7) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.GraphModel (>= 17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.SDK.Analyzers (>= 17.7.79) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Telemetry (17.14.18) - Microsoft.CSharp (>= 4.7) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Newtonsoft.Json (>= 13.0.3) - System.Memory (>= 4.5.4) - System.Runtime.CompilerServices.Unsafe (>= 5.0) - Microsoft.VisualStudio.Threading (17.14.15) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - System.Memory (>= 4.6) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Threading.Tasks.Extensions (>= 4.6) - Microsoft.VisualStudio.Threading.Analyzers (17.14.15) - Microsoft.VisualStudio.Threading.Only (17.14.15) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - System.Memory (>= 4.6) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Threading.Tasks.Extensions (>= 4.6) - Microsoft.VisualStudio.Utilities (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Utilities.Internal (16.3.90) - Microsoft.VisualStudio.Validation (17.13.22) - Microsoft.Win32.Registry (5.0) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (>= 5.0) - Nerdbank.MessagePack (1.1.62) - Microsoft.Bcl.HashCode (>= 6.0) - Microsoft.NET.StringTools (>= 18.4) - Microsoft.VisualStudio.Validation (>= 17.13.22) - PolyType (>= 1.3.1) - System.Collections.Immutable (>= 8.0) - System.IO.Pipelines (>= 8.0) - System.Text.Json (>= 8.0.6) - Nerdbank.Streams (2.13.16) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.VisualStudio.Threading.Only (>= 17.13.61) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.IO.Pipelines (>= 8.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - Newtonsoft.Json (13.0.4) - Newtonsoft.Json.Bson (1.0.3) - Newtonsoft.Json (>= 13.0.1) - PolyType (1.3.1) - System.Memory (>= 4.5.5) - System.Reflection.Emit.Lightweight (>= 4.7) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - StreamJsonRpc (2.24.84) - MessagePack (>= 2.5.198) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Validation (>= 17.13.22) - Nerdbank.MessagePack (>= 1.0.2) - Nerdbank.Streams (>= 2.13.16) - Newtonsoft.Json (>= 13.0.3) - System.Collections.Immutable (>= 8.0) - System.Diagnostics.DiagnosticSource (>= 8.0.1) - System.IO.Pipelines (>= 8.0) - System.Text.Json (>= 8.0.6) - System.Threading.Tasks.Dataflow (>= 8.0.1) - System.Buffers (4.6.1) - System.Collections.Immutable (10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.ComponentModel.Composition (10.0.7) - System.Composition (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Convention (>= 10.0.7) - System.Composition.Hosting (>= 10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Composition.TypedParts (>= 10.0.7) - System.Composition.AttributedModel (10.0.7) - System.Composition.Convention (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Hosting (10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Composition.Runtime (10.0.7) - System.Composition.TypedParts (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Hosting (>= 10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Diagnostics.DiagnosticSource (10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.IdentityModel.Tokens.Jwt (8.17) - Microsoft.IdentityModel.JsonWebTokens (>= 8.17) - Microsoft.IdentityModel.Tokens (>= 8.17) - System.IO (4.3) - System.IO.Pipelines (10.0.7) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.Memory (4.6.3) - System.Buffers (>= 4.6.1) - System.Numerics.Vectors (>= 4.6.1) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Net.Http (4.3.4) - System.Security.Cryptography.X509Certificates (>= 4.3) - System.Numerics.Vectors (4.6.1) - System.Private.Uri (4.3.2) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Reflection.Emit.Lightweight (4.7) - System.Reflection.Metadata (10.0.7) - System.Collections.Immutable (>= 10.0.7) - System.Runtime (4.3.1) - System.Runtime.CompilerServices.Unsafe (6.1.2) - System.Security.AccessControl (6.0.1) - System.Security.Principal.Windows (>= 5.0) - System.Security.Cryptography.Algorithms (4.3.1) - System.IO (>= 4.3) - System.Runtime (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Security.Cryptography.Encoding (4.3) - System.Security.Cryptography.Primitives (4.3) - System.Security.Cryptography.X509Certificates (4.3.2) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Principal.Windows (5.0) - System.Text.Encodings.Web (10.0.7) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Json (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.Buffers (>= 4.6.1) - System.IO.Pipelines (>= 10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Encodings.Web (>= 10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.ValueTuple (>= 4.6.2) - System.Threading.AccessControl (10.0.7) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Threading.Tasks.Dataflow (10.0.7) - System.Threading.Tasks.Extensions (4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.ValueTuple (4.6.2) - -GROUP VS2022 -RESTRICTION: == net48 -NUGET - remote: https://api.nuget.org/v3/index.json - MessagePack (3.1.4) - MessagePack.Annotations (>= 3.1.4) - MessagePackAnalyzer (>= 3.1.4) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.NET.StringTools (>= 17.11.4) - System.Collections.Immutable (>= 8.0) - System.Memory (>= 4.5.5) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - MessagePack.Annotations (3.1.4) - MessagePackAnalyzer (3.1.4) - Microsoft.AspNet.WebApi.Client (6.0) - Newtonsoft.Json (>= 13.0.1) - Newtonsoft.Json.Bson (>= 1.0.2) - System.Memory (>= 4.5.5) - System.Threading.Tasks.Extensions (>= 4.5.4) - Microsoft.AspNet.WebApi.Core (5.3) - Microsoft.AspNet.WebApi.Client (>= 6.0) - Microsoft.AspNet.WebApi.WebHost (5.3) - Microsoft.AspNet.WebApi.Core (>= 5.3) - Microsoft.Bcl.AsyncInterfaces (10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - Microsoft.Bcl.HashCode (6.0) - Microsoft.Bcl.TimeProvider (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.ValueTuple (>= 4.6.2) - Microsoft.Build.Framework (18.4) - System.Collections.Immutable (>= 10.0.1) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Json (>= 10.0.1) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.ValueTuple (>= 4.6.1) - Microsoft.CSharp (4.7) - Microsoft.Extensions.DependencyInjection.Abstractions (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - Microsoft.Extensions.Logging.Abstractions (10.0.7) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.7) - System.Buffers (>= 4.6.1) - System.Diagnostics.DiagnosticSource (>= 10.0.7) - System.Memory (>= 4.6.3) - Microsoft.Identity.Client (4.83.3) - Microsoft.IdentityModel.Abstractions (>= 8.14) - System.Diagnostics.DiagnosticSource (>= 6.0.1) - System.Formats.Asn1 (>= 8.0.1) - System.ValueTuple (>= 4.5) - Microsoft.Identity.Client.Extensions.Msal (4.83.3) - Microsoft.Identity.Client (>= 4.83.3) - System.IO.FileSystem.AccessControl (>= 5.0) - System.Security.Cryptography.ProtectedData (>= 4.5) - Microsoft.IdentityModel.Abstractions (8.17) - Microsoft.IdentityModel.JsonWebTokens (8.17) - Microsoft.Bcl.TimeProvider (>= 8.0.1) - Microsoft.IdentityModel.Tokens (>= 8.17) - Microsoft.IdentityModel.Logging (8.17) - Microsoft.IdentityModel.Abstractions (>= 8.17) - Microsoft.IdentityModel.Tokens (8.17) - Microsoft.Bcl.TimeProvider (>= 8.0.1) - Microsoft.Extensions.Logging.Abstractions (>= 2.1) - Microsoft.IdentityModel.Logging (>= 8.17) - System.Diagnostics.DiagnosticSource (>= 6.0.2) - System.Memory (>= 4.5.5) - System.Text.Json (>= 8.0.5) - Microsoft.IO.Redist (6.1.3) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - Microsoft.NET.StringTools (18.4) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - Microsoft.ServiceHub.Analyzers (4.8.55) - Microsoft.ServiceHub.Framework (4.8.55) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.VisualStudio.Composition (>= 17.12.20) - Microsoft.VisualStudio.Threading (>= 17.13.2) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Nerdbank.Streams (>= 2.11.86) - StreamJsonRpc (>= 2.21.10) - System.Collections.Immutable (>= 8.0) - System.Text.Json (>= 8.0.5) - Microsoft.ServiceHub.Resources (4.6.2052) - Microsoft.TeamFoundation.DistributedTask.Common.Contracts (19.225.2) - Microsoft.VisualStudio.Services.Client (19.225.2) - Microsoft.TeamFoundationServer.Client (19.225.2) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.AspNet.WebApi.Core (>= 5.2.7) - Microsoft.AspNet.WebApi.WebHost (>= 5.2.7) - Microsoft.TeamFoundation.DistributedTask.Common.Contracts (19.225.2) - Microsoft.VisualStudio.Services.Client (19.225.2) - Newtonsoft.Json (>= 13.0.2) - Microsoft.TeamFoundationServer.ExtendedClient (19.225.2) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.AspNet.WebApi.Core (>= 5.2.7) - Microsoft.TeamFoundationServer.Client (19.225.2) - Microsoft.VisualStudio.Services.Client (19.225.2) - Microsoft.VisualStudio.Services.InteractiveClient (19.225.2) - Newtonsoft.Json (>= 13.0.2) - System.IdentityModel.Tokens.Jwt (>= 6.30.1) - Microsoft.VisualStudio.ComponentModelHost (17.14.106) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.VisualStudio.Composition (>= 17.12.20) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.13.39273) - Microsoft.VisualStudio.Interop (>= 17.13.39276) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.Collections.Immutable (>= 8.0) - System.ComponentModel.Composition (>= 8.0) - System.Memory (>= 4.5.5) - System.Reflection.Metadata (>= 8.0) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - Microsoft.VisualStudio.Composition (17.13.41) - MessagePack (>= 2.5.192) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.Collections.Immutable (>= 8.0) - System.ComponentModel.Composition (>= 8.0) - System.Composition (>= 8.0) - System.Composition.AttributedModel (>= 8.0) - System.Reflection.Metadata (>= 8.0) - System.Threading.Tasks.Dataflow (>= 8.0.1) - Microsoft.VisualStudio.Composition.Analyzers (17.13.41) - Microsoft.VisualStudio.GraphModel (17.14.40260) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - System.ComponentModel.Composition (>= 9.0) - Microsoft.VisualStudio.ImageCatalog (17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.Imaging (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (17.14.40254) - Microsoft.VisualStudio.Interop (17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.ProjectAggregator (17.14.40254) - Microsoft.VisualStudio.RegDetour (17.10.34916.79) - Microsoft.VisualStudio.RemoteControl (16.3.52) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.42) - Microsoft.VisualStudio.RpcContracts (17.14.20) - Microsoft.ServiceHub.Framework (>= 4.8.40) - System.Text.Json (>= 8.0.5) - System.Threading.Tasks.Dataflow (>= 8.0.1) - Microsoft.VisualStudio.SDK.Analyzers (17.7.113) - Microsoft.VisualStudio.Services.Client (19.225.2) - Microsoft.AspNet.WebApi.Client (>= 5.2.7) - Microsoft.IdentityModel.Tokens (>= 6.30.1) - Newtonsoft.Json (>= 13.0.2) - System.IdentityModel.Tokens.Jwt (>= 6.30.1) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Services.InteractiveClient (19.225.2) - Microsoft.Identity.Client (>= 4.54.1) - Microsoft.Identity.Client.Extensions.Msal (>= 2.23) - Microsoft.IdentityModel.Tokens (>= 6.30.1) - Microsoft.VisualStudio.Services.Client (19.225.2) - Newtonsoft.Json (>= 13.0.2) - System.IdentityModel.Tokens.Jwt (>= 6.30.1) - Microsoft.VisualStudio.Settings.15.0 (17.10.34916.79) - Microsoft.VisualStudio.RegDetour (>= 17.10.34916.79) - Microsoft.VisualStudio.Shell.15.0 (>= 17.10.34916.79) - Microsoft.VisualStudio.Setup.Configuration.Interop (3.14.2075) - Microsoft.VisualStudio.Shell.15.0 (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.Build.Framework (>= 17.14.7) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.ComponentModelHost (>= 17.14.106) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.GraphModel (>= 17.14.40260) - Microsoft.VisualStudio.ImageCatalog (>= 17.14.40260) - Microsoft.VisualStudio.Imaging (>= 17.14.40264) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.ProjectAggregator (>= 17.14.40254) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.SDK.Analyzers (>= 17.7.79) - Microsoft.VisualStudio.Shell.Framework (>= 17.14.40264) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Shell.Framework (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.Build.Framework (>= 17.14.7) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Analyzers (>= 4.8.55) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.GraphModel (>= 17.14.40260) - Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime (>= 17.14.40254) - Microsoft.VisualStudio.Interop (>= 17.14.40260) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.SDK.Analyzers (>= 17.7.79) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities (>= 17.14.40264) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Telemetry (17.14.18) - Microsoft.CSharp (>= 4.7) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Newtonsoft.Json (>= 13.0.3) - System.Memory (>= 4.5.4) - System.Runtime.CompilerServices.Unsafe (>= 5.0) - Microsoft.VisualStudio.Threading (17.14.15) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - System.Memory (>= 4.6) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Threading.Tasks.Extensions (>= 4.6) - Microsoft.VisualStudio.Threading.Analyzers (17.14.15) - Microsoft.VisualStudio.Threading.Only (17.14.15) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - System.Memory (>= 4.6) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Threading.Tasks.Extensions (>= 4.6) - Microsoft.VisualStudio.Utilities (17.14.40264) - MessagePack (>= 2.5.192) - MessagePack.Annotations (>= 2.5.192) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.IO.Redist (>= 6.1) - Microsoft.NET.StringTools (>= 17.14.7) - Microsoft.ServiceHub.Framework (>= 4.8.55) - Microsoft.ServiceHub.Resources (>= 4.6.2052) - Microsoft.VisualStudio.Composition (>= 17.13.41) - Microsoft.VisualStudio.Composition.Analyzers (>= 17.13.41) - Microsoft.VisualStudio.RemoteControl (>= 16.3.52) - Microsoft.VisualStudio.RpcContracts (>= 17.14.20) - Microsoft.VisualStudio.Telemetry (>= 17.14.18) - Microsoft.VisualStudio.Threading (>= 17.14.15) - Microsoft.VisualStudio.Threading.Analyzers (>= 17.14.15) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Utilities.Internal (>= 16.3.90) - Microsoft.VisualStudio.Validation (>= 17.8.8) - Microsoft.Win32.Registry (>= 5.0) - Nerdbank.Streams (>= 2.12.87) - Newtonsoft.Json (>= 13.0.3) - StreamJsonRpc (>= 2.22.11) - System.Buffers (>= 4.6) - System.Collections.Immutable (>= 9.0) - System.ComponentModel.Composition (>= 9.0) - System.Composition (>= 9.0) - System.Composition.AttributedModel (>= 9.0) - System.Composition.Convention (>= 9.0) - System.Composition.Hosting (>= 9.0) - System.Composition.Runtime (>= 9.0) - System.Composition.TypedParts (>= 9.0) - System.Diagnostics.DiagnosticSource (>= 9.0) - System.IO.Pipelines (>= 9.0) - System.Memory (>= 4.6) - System.Numerics.Vectors (>= 4.6) - System.Reflection.Metadata (>= 9.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Text.Encodings.Web (>= 9.0) - System.Text.Json (>= 9.0) - System.Threading.AccessControl (>= 9.0) - System.Threading.Tasks.Dataflow (>= 9.0) - System.Threading.Tasks.Extensions (>= 4.6) - System.ValueTuple (>= 4.5) - Microsoft.VisualStudio.Utilities.Internal (16.3.90) - Microsoft.VisualStudio.Validation (17.13.22) - Microsoft.Win32.Registry (5.0) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (>= 5.0) - Nerdbank.MessagePack (1.1.62) - Microsoft.Bcl.HashCode (>= 6.0) - Microsoft.NET.StringTools (>= 18.4) - Microsoft.VisualStudio.Validation (>= 17.13.22) - PolyType (>= 1.3.1) - System.Collections.Immutable (>= 8.0) - System.IO.Pipelines (>= 8.0) - System.Text.Json (>= 8.0.6) - Nerdbank.Streams (2.13.16) - Microsoft.Bcl.AsyncInterfaces (>= 8.0) - Microsoft.VisualStudio.Threading.Only (>= 17.13.61) - Microsoft.VisualStudio.Validation (>= 17.8.8) - System.IO.Pipelines (>= 8.0) - System.Runtime.CompilerServices.Unsafe (>= 6.1) - Newtonsoft.Json (13.0.4) - Newtonsoft.Json.Bson (1.0.3) - Newtonsoft.Json (>= 13.0.1) - PolyType (1.3.1) - System.Memory (>= 4.5.5) - System.Reflection.Emit.Lightweight (>= 4.7) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Threading.Tasks.Extensions (>= 4.5.4) - StreamJsonRpc (2.24.84) - MessagePack (>= 2.5.198) - Microsoft.Bcl.AsyncInterfaces (>= 9.0) - Microsoft.VisualStudio.Threading.Only (>= 17.14.15) - Microsoft.VisualStudio.Validation (>= 17.13.22) - Nerdbank.MessagePack (>= 1.0.2) - Nerdbank.Streams (>= 2.13.16) - Newtonsoft.Json (>= 13.0.3) - System.Collections.Immutable (>= 8.0) - System.Diagnostics.DiagnosticSource (>= 8.0.1) - System.IO.Pipelines (>= 8.0) - System.Text.Json (>= 8.0.6) - System.Threading.Tasks.Dataflow (>= 8.0.1) - System.Buffers (4.6.1) - System.Collections.Immutable (10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.ComponentModel.Composition (10.0.7) - System.Composition (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Convention (>= 10.0.7) - System.Composition.Hosting (>= 10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Composition.TypedParts (>= 10.0.7) - System.Composition.AttributedModel (10.0.7) - System.Composition.Convention (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Hosting (10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Composition.Runtime (10.0.7) - System.Composition.TypedParts (10.0.7) - System.Composition.AttributedModel (>= 10.0.7) - System.Composition.Hosting (>= 10.0.7) - System.Composition.Runtime (>= 10.0.7) - System.Diagnostics.DiagnosticSource (10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Formats.Asn1 (10.0.7) - System.Memory (>= 4.6.3) - System.ValueTuple (>= 4.6.2) - System.IdentityModel.Tokens.Jwt (8.17) - Microsoft.IdentityModel.JsonWebTokens (>= 8.17) - Microsoft.IdentityModel.Tokens (>= 8.17) - System.IO.FileSystem.AccessControl (5.0) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (>= 5.0) - System.IO.Pipelines (10.0.7) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.Memory (4.6.3) - System.Buffers (>= 4.6.1) - System.Numerics.Vectors (>= 4.6.1) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Numerics.Vectors (4.6.1) - System.Reflection.Emit.Lightweight (4.7) - System.Reflection.Metadata (10.0.7) - System.Collections.Immutable (>= 10.0.7) - System.Runtime.CompilerServices.Unsafe (6.1.2) - System.Security.AccessControl (6.0.1) - System.Security.Principal.Windows (>= 5.0) - System.Security.Cryptography.ProtectedData (10.0.7) - System.Security.Principal.Windows (5.0) - System.Text.Encodings.Web (10.0.7) - System.Buffers (>= 4.6.1) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Json (10.0.7) - Microsoft.Bcl.AsyncInterfaces (>= 10.0.7) - System.Buffers (>= 4.6.1) - System.IO.Pipelines (>= 10.0.7) - System.Memory (>= 4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.Text.Encodings.Web (>= 10.0.7) - System.Threading.Tasks.Extensions (>= 4.6.3) - System.ValueTuple (>= 4.6.2) - System.Threading.AccessControl (10.0.7) - System.Security.AccessControl (>= 6.0) - System.Security.Principal.Windows (>= 5.0) - System.Threading.Tasks.Dataflow (10.0.7) - System.Threading.Tasks.Extensions (4.6.3) - System.Runtime.CompilerServices.Unsafe (>= 6.1.2) - System.ValueTuple (4.6.2)