├── test ├── libman.IntegrationTest │ ├── TestFiles │ │ ├── EmptyFile.css │ │ ├── EmptyFile.js │ │ ├── EmptyFile.min.css │ │ └── EmptyFile.min.js │ ├── InstallTests.cs │ └── libman.IntegrationTest.csproj ├── LibraryManager.Vsix.IntegrationTest │ ├── TestSolution │ │ ├── LooseFiles │ │ │ └── filesystem.js │ │ ├── TestProjectCore20 │ │ │ ├── wwwroot │ │ │ │ └── js │ │ │ │ │ ├── site.min.js │ │ │ │ │ └── site.js │ │ │ ├── libman.json │ │ │ ├── TestProjectCore20.csproj │ │ │ ├── Program.cs │ │ │ ├── Properties │ │ │ │ └── launchSettings.json │ │ │ └── Startup.cs │ │ └── TestSolution.sln │ ├── Suppressions.cs │ ├── Services │ │ └── InstallDialogVerifier.cs │ ├── Helpers │ │ └── HelperWrapper.cs │ └── Microsoft.Web.LibraryManager.Vsix.IntegrationTest.csproj ├── LibraryManager.Test │ ├── .editorconfig │ ├── InvalidLibraryExceptionTest.cs │ ├── FileHelpersTest.cs │ ├── Microsoft.Web.LibraryManager.Test.csproj │ ├── TestUtilities │ │ ├── StringUtility.cs │ │ └── AssertExtensions.cs │ ├── PathEqualityComparerTest.cs │ ├── TestUtils.cs │ ├── ExtensionsTest.cs │ ├── ErrorTest.cs │ └── Providers │ │ ├── Cdnjs │ │ └── CdnjsProviderFactoryTest.cs │ │ └── FileSystem │ │ └── FileSystemProviderFactoryTest.cs ├── LibraryManager.Build.IntegrationTest │ ├── TestSolution │ │ ├── Libman.Build.TestApp │ │ │ ├── Program.cs │ │ │ ├── appsettings.Development.json │ │ │ ├── appsettings.json │ │ │ ├── Libman.Build.TestApp.csproj │ │ │ └── Properties │ │ │ │ └── launchSettings.json │ │ ├── Directory.Build.props │ │ ├── Directory.Packages.props │ │ ├── Directory.Build.targets │ │ ├── nuget.config │ │ └── Libman.Build.TestApp.sln │ ├── RestoreTests.cs │ └── Microsoft.Web.LibraryManager.Build.IntegrationTest.csproj ├── Directory.Build.props ├── TestGlobalSuppressions.cs ├── LibraryManager.Vsix.Test │ ├── Mocks │ │ └── NullSearchService.cs │ ├── Microsoft.Web.LibraryManager.Vsix.Test.csproj │ ├── UI │ │ └── Converters │ │ │ └── WatermarkVisibilityConverterTests.cs │ └── Search │ │ └── ProviderCatalogSearchServiceTests.cs ├── libman.Test │ ├── TestLogger.cs │ ├── TestInputReader.cs │ ├── libman.Test.csproj │ ├── StringNewLineHelper.cs │ ├── TestEnvironmentHelper.cs │ ├── CommandTestBase.cs │ ├── SampleTestCommand.cs │ └── Mocks │ │ └── HostEnvironment.cs ├── LibraryManager.Contracts.Test │ └── Microsoft.Web.LibraryManager.Contracts.Test.csproj ├── LibraryManager.Build.Test │ ├── Microsoft.Web.LibraryManager.Build.Test.csproj │ └── TaskItem.cs └── LibraryManager.Mocks │ ├── ProviderFactory.cs │ ├── Logger.cs │ ├── Error.cs │ ├── LibraryInstallationState.cs │ ├── Microsoft.Web.LibraryManager.Mocks.csproj │ ├── LibraryGroup.cs │ ├── Library.cs │ └── WebRequestHandler.cs ├── Directory.Build.targets ├── azure-pipelines ├── azure-pipeline.microbuild.before.yml └── Convert-PDB.ps1 ├── src ├── libman │ ├── runtimeconfig.template.json │ ├── DotNetToolSettings.xml │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ExitCode.cs │ ├── Contracts │ │ ├── IHostInteractionInternal.cs │ │ └── IInputReader.cs │ ├── Commands │ │ ├── CacheCommand.cs │ │ ├── RestoreCommand.cs │ │ ├── CleanCommand.cs │ │ └── LibmanApp.cs │ ├── IHostEnvironment.cs │ └── ILibraryInstallationStateExtensions.cs ├── PackageIcon.png ├── LibraryManager.Vsix │ ├── Resources │ │ └── Icon.png │ ├── UI │ │ ├── Models │ │ │ ├── PackageItemType.cs │ │ │ ├── FileSelection.cs │ │ │ ├── FileSelectionType.cs │ │ │ ├── SelectedProviderBinding.cs │ │ │ ├── LibraryNameBinding.cs │ │ │ ├── BindableBase.cs │ │ │ └── TargetLocationViewModel.cs │ │ ├── Theming │ │ │ ├── VsThemedComboBox.xaml │ │ │ ├── VsThemedToolTip.xaml │ │ │ └── VsThemedTreeView.xaml │ │ ├── IInstallDialog.cs │ │ ├── Controls │ │ │ ├── Search │ │ │ │ ├── Wrapper.cs │ │ │ │ ├── LibraryGroupToSearchItemAdapter.cs │ │ │ │ └── LogicalOrConverter.cs │ │ │ ├── AutomationPeers │ │ │ │ └── TextControlTypeAutomationPeer.cs │ │ │ ├── PackageContentsTreeViewAutomationPeer.cs │ │ │ ├── CompletionEntry.cs │ │ │ ├── EditorTooltip.xaml.cs │ │ │ ├── BindingProxy.cs │ │ │ └── EditorTooltip.xaml │ │ ├── Converters │ │ │ ├── NotConverter.cs │ │ │ ├── VisibleIfNonNullConverter.cs │ │ │ ├── BoldingConverter.cs │ │ │ ├── WatermarkVisibilityConverter.cs │ │ │ ├── EnumToBoolConverter.cs │ │ │ ├── HintTextConverter.cs │ │ │ └── CheckBoxAutomationNameConverter.cs │ │ ├── InstallDialogProvider.cs │ │ └── Extensions │ │ │ └── RemoveCharacterExtension.cs │ ├── Contracts │ │ ├── IDependenciesFactory.cs │ │ ├── Dependencies.cs │ │ └── PerProjectLogger.cs │ ├── Search │ │ ├── ISearchService.cs │ │ └── ProviderCatalogSearchService.cs │ ├── Shared │ │ ├── ITaskStatusCenterService.cs │ │ ├── WpfUtil.cs │ │ └── TaskStatusCenterService.cs │ ├── source.extension.cs │ ├── Constants.cs │ ├── Json │ │ └── Completion │ │ │ └── CompletionElementProvider.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ErrorList │ │ └── DisplayError.cs │ └── Commands │ │ └── CommandTable │ │ └── LocalizationFiles │ │ ├── VSCommandTable.en.xlf │ │ ├── VSCommandTable.zh-Hans.xlf │ │ ├── VSCommandTable.zh-Hant.xlf │ │ ├── VSCommandTable.ko.xlf │ │ └── VSCommandTable.ja.xlf ├── LibraryManager.Build │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Microsoft.Web.LibraryManager.Build.props │ └── Contracts │ │ └── Logger.cs ├── LibraryManager.Contracts │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── GlobalSuppressions.cs │ ├── CancellationHelpers.cs │ ├── IError.cs │ ├── IProviderFactory.cs │ ├── IWebRequestHandler.cs │ ├── OperationType.cs │ ├── FileMapping.cs │ ├── ILibrary.cs │ ├── Error.cs │ ├── ILibraryGroup.cs │ ├── ILogger.cs │ ├── IDependencies.cs │ ├── Caching │ │ └── ICacheService.cs │ ├── ILibraryInstallationState.cs │ └── ResourceDownloadException.cs ├── LibraryManager │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Helpers │ │ ├── CancellationHelpers.cs │ │ └── LibraryStateTypeConverter.cs │ ├── Json │ │ ├── FileMapping.cs │ │ ├── ManifestOnDisk.cs │ │ └── LibraryInstallationStateOnDisk.cs │ ├── Providers │ │ ├── Cdnjs │ │ │ ├── CdnjsLibrary.cs │ │ │ ├── CdnjsLibraryGroup.cs │ │ │ └── CdnjsProviderFactory.cs │ │ ├── Unpkg │ │ │ ├── UnpkgLibrary.cs │ │ │ ├── INpmPackageInfoFactory.cs │ │ │ ├── INpmPackageSearch.cs │ │ │ ├── UnpkgProviderFactory.cs │ │ │ └── UnpkgLibraryGroup.cs │ │ ├── jsDelivr │ │ │ ├── JsDelivrLibrary.cs │ │ │ ├── JsDelivrProviderFactory.cs │ │ │ └── JsDelivrLibraryGroup.cs │ │ └── FileSystem │ │ │ ├── FileSystemLibrary.cs │ │ │ ├── FileSystemLibraryGroup.cs │ │ │ └── FileSystemProviderFactory.cs │ ├── FileConflict.cs │ ├── LibraryNaming │ │ ├── SimpleLibraryNamingScheme.cs │ │ └── ILibraryNamingScheme.cs │ ├── Configuration │ │ └── Constants.cs │ ├── Utilities │ │ ├── EncryptionUtility.cs │ │ └── FileGlobbingUtility.cs │ ├── FileIdentifier.cs │ └── Cache │ │ └── CacheFileMetadata.cs └── .editorconfig ├── art ├── light-bulbs.png ├── libmanjsontyping.gif ├── context-menu-config.png └── context-menu-project.png ├── global.json ├── .github ├── pull_request_template.md └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── common └── tools │ └── VsctToXliff │ ├── App.config │ ├── VsctToXliff.sln │ ├── Utilities.cs │ └── Properties │ └── AssemblyInfo.cs ├── nuget.config ├── version.json ├── CODE-OF-CONDUCT.md ├── Install-dotnet.ps1 ├── .context └── TSAConfig.gdntsa ├── azure-pipelines.yml ├── SECURITY.md ├── LICENSE.txt ├── LibraryManager.Settings.targets ├── setup └── Microsoft.Web.LibraryManager.vsmanproj └── Directory.Build.props /test/libman.IntegrationTest/TestFiles/EmptyFile.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/libman.IntegrationTest/TestFiles/EmptyFile.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /test/libman.IntegrationTest/TestFiles/EmptyFile.min.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/libman.IntegrationTest/TestFiles/EmptyFile.min.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /azure-pipelines/azure-pipeline.microbuild.before.yml: -------------------------------------------------------------------------------- 1 | steps: [] -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/LooseFiles/filesystem.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/libman/runtimeconfig.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "rollForwardOnNoCandidateFx": 2 3 | } 4 | -------------------------------------------------------------------------------- /art/light-bulbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/art/light-bulbs.png -------------------------------------------------------------------------------- /src/PackageIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/src/PackageIcon.png -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /art/libmanjsontyping.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/art/libmanjsontyping.gif -------------------------------------------------------------------------------- /art/context-menu-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/art/context-menu-config.png -------------------------------------------------------------------------------- /art/context-menu-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/art/context-menu-project.png -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.415", 4 | "rollForward": "latestMajor" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Summary of the changes 2 | - Detail 1 3 | - Detail 2 4 | 5 | Resolves #bugnumber 6 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. 2 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Resources/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspnet/LibraryManager/HEAD/src/LibraryManager.Vsix/Resources/Icon.png -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "libraries": [ 4 | 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/.editorconfig: -------------------------------------------------------------------------------- 1 | # Dotnet code style settings: 2 | [*.{cs,vb}] 3 | # Naming rules - async methods to be prefixed with Async 4 | dotnet_naming_rule.async_methods_must_end_with_async.severity = none 5 | -------------------------------------------------------------------------------- /common/tools/VsctToXliff/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/libman/DotNetToolSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | var app = builder.Build(); 3 | 4 | app.MapGet("/", () => "Hello World!"); 5 | 6 | app.Run(); 7 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", 3 | "version": "3.0", 4 | "publicRefSpec": [ 5 | "^refs/tags/v\\d+\\.\\d+" // we release tags starting with vN.N 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /src/libman/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Resources; 5 | using System.Runtime.CompilerServices; 6 | 7 | [assembly: NeutralResourcesLanguage("en")] 8 | [assembly: InternalsVisibleTo("libman.Test")] 9 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp/Libman.Build.TestApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Install-dotnet.ps1: -------------------------------------------------------------------------------- 1 | $url="https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1" 2 | $output="$PSScriptRoot\dotnet-install.ps1" 3 | $installDir = Join-Path $PSScriptRoot ".dotnet" 4 | 5 | (New-Object System.Net.WebClient).DownloadFile($url, $output) 6 | Invoke-Expression "& `"$output`" -InstallDir $installDir -Channel 8.0.1xx -Quality ga" 7 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/PackageItemType.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 5 | { 6 | public enum PackageItemType 7 | { 8 | Folder, 9 | File 10 | } 11 | } -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TestGlobalSuppressions.cs 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/Suppressions.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | // Suppress integration tests from running under LUT. 7 | [assembly: TestCategory("SkipWhenLiveUnitTesting")] 8 | -------------------------------------------------------------------------------- /src/LibraryManager.Build/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Resources; 5 | using System.Runtime.CompilerServices; 6 | 7 | [assembly: NeutralResourcesLanguage("en")] 8 | [assembly:InternalsVisibleTo("Microsoft.Web.LibraryManager.Build.Test")] -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/FileSelection.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 5 | { 6 | internal static class FileSelection 7 | { 8 | public static FileSelectionType InstallationType { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/FileSelectionType.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 5 | { 6 | internal enum FileSelectionType 7 | { 8 | InstallAllLibraryFiles, 9 | ChooseSpecificFilesToInstall 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/Services/InstallDialogVerifier.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Test.Apex.VisualStudio; 5 | 6 | namespace Microsoft.Web.LibraryManager.IntegrationTest.Services 7 | { 8 | public class InstallDialogVerifier : VisualStudioInProcessTestExtensionVerifier 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Contracts/IDependenciesFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.Contracts 7 | { 8 | internal interface IDependenciesFactory 9 | { 10 | IDependencies FromConfigFile(string configFilePath); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/TestProjectCore20.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Resources; 5 | using System.Runtime.CompilerServices; 6 | 7 | [assembly: NeutralResourcesLanguage("en")] 8 | [assembly: InternalsVisibleTo("Microsoft.Web.LibraryManager.Test")] 9 | [assembly: InternalsVisibleTo("Microsoft.Web.LibraryManager.Contracts.Test")] 10 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Theming/VsThemedComboBox.xaml: -------------------------------------------------------------------------------- 1 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.Test/Mocks/NullSearchService.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | using Microsoft.Web.LibraryManager.Vsix.Search; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.Test.Mocks 9 | { 10 | internal class NullSearchService : ISearchService 11 | { 12 | public Task PerformSearch(string searchText, int caretPosition) 13 | { 14 | return Task.FromResult(default(CompletionSet)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/IInstallDialog.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading.Tasks; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.UI 7 | { 8 | /// 9 | /// Test contract for add client side libraries dialog. 10 | /// 11 | public interface IInstallDialog 12 | { 13 | string Provider { get; set; } 14 | 15 | string Library { get; set; } 16 | 17 | Task ClickInstallAsync(); 18 | 19 | void CloseDialog(); 20 | 21 | bool IsAnyFileSelected { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/CancellationHelpers.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Web.LibraryManager.Contracts 8 | { 9 | internal static class CancellationHelpers 10 | { 11 | public static Task WithCancellation(this Task task, CancellationToken cancellationToken) 12 | { 13 | var src = new TaskCompletionSource(); 14 | cancellationToken.Register(() => src.SetCanceled()); 15 | return Task.WhenAny(task, src.Task).Unwrap(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/LibraryManager/Helpers/CancellationHelpers.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Web.LibraryManager.Helpers 8 | { 9 | internal static class CancellationHelpers 10 | { 11 | public static Task WithCancellation(this Task task, CancellationToken cancellationToken) 12 | { 13 | var src = new TaskCompletionSource(); 14 | cancellationToken.Register(() => src.SetCanceled()); 15 | return Task.WhenAny(task, src.Task).Unwrap(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/libman/Contracts/IHostInteractionInternal.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Tools.Contracts 7 | { 8 | /// 9 | /// Provides a way to interact with the host environment. 10 | /// 11 | interface IHostInteractionInternal : IHostInteraction 12 | { 13 | /// 14 | /// Allows updating the working directory. 15 | /// 16 | /// 17 | void UpdateWorkingDirectory(string directory); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | branches: 3 | include: ["main", "rel/*"] 4 | paths: 5 | exclude: ["*.md"] 6 | 7 | variables: 8 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true 9 | BuildConfiguration: Release 10 | BuildPlatform: Any CPU 11 | DisableMAT: true 12 | 13 | jobs: 14 | - job: Windows 15 | pool: 16 | vmImage: windows-latest 17 | steps: 18 | - template: azure-pipelines/build.yml 19 | - task: PublishBuildArtifacts@1 20 | inputs: 21 | PathtoPublish: $(Build.ArtifactStagingDirectory)/build_logs 22 | ArtifactName: build_logs 23 | ArtifactType: Container 24 | displayName: Publish build_logs artifacts 25 | condition: succeededOrFailed() 26 | -------------------------------------------------------------------------------- /src/LibraryManager/Json/FileMapping.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | #nullable enable 8 | 9 | namespace Microsoft.Web.LibraryManager.Json 10 | { 11 | internal class FileMapping 12 | { 13 | [JsonProperty(ManifestConstants.Root)] 14 | public string? Root { get; set; } 15 | 16 | [JsonProperty(ManifestConstants.Destination)] 17 | public string? Destination { get; set; } 18 | 19 | [JsonProperty(ManifestConstants.Files)] 20 | public IReadOnlyList? Files { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Cdnjs/CdnjsLibrary.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.Web.LibraryManager.Providers.Cdnjs 8 | { 9 | internal class CdnjsLibrary : ILibrary 10 | { 11 | public string Name { get; set; } 12 | public string ProviderId { get; set; } 13 | public string Version { get; set; } 14 | public IReadOnlyDictionary Files { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return Name; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Unpkg/UnpkgLibrary.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | 7 | namespace Microsoft.Web.LibraryManager.Providers.Unpkg 8 | { 9 | internal class UnpkgLibrary : ILibrary 10 | { 11 | public string Name { get; set; } 12 | public string ProviderId { get; set; } 13 | public string Version { get; set; } 14 | public IReadOnlyDictionary Files { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return Name; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LibraryManager.Build/Microsoft.Web.LibraryManager.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <_ProviderAssembly Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tools\netstandard2.0\Microsoft.Web.LibraryManager.dll 6 | <_ProviderAssembly Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tools\$(NetFxTFM)\Microsoft.Web.LibraryManager.dll 7 | 8 | 9 | $(_ProviderAssembly); 10 | $(LibraryProviderAssemblies) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/jsDelivr/JsDelivrLibrary.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | 7 | namespace Microsoft.Web.LibraryManager.Providers.jsDelivr 8 | { 9 | internal class JsDelivrLibrary : ILibrary 10 | { 11 | public string Name { get; set; } 12 | public string ProviderId { get; set; } 13 | public string Version { get; set; } 14 | public IReadOnlyDictionary Files { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return Name; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/Search/Wrapper.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Windows; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls.Search 7 | { 8 | internal class Wrapper : DependencyObject 9 | { 10 | public static readonly DependencyProperty ParameterProperty = DependencyProperty.Register( 11 | "Parameter", typeof (bool), typeof (Wrapper), new PropertyMetadata(default(bool))); 12 | 13 | public bool Parameter 14 | { 15 | get { return (bool) GetValue(ParameterProperty); } 16 | set { SetValue(ParameterProperty, value); } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/LibraryManager/Providers/FileSystem/FileSystemLibrary.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.Web.LibraryManager.Providers.FileSystem 8 | { 9 | internal class FileSystemLibrary : ILibrary 10 | { 11 | public string Name { get; set; } 12 | public string ProviderId { get; set; } 13 | public string Version => "1.0"; 14 | public IReadOnlyDictionary Files { get; set; } 15 | 16 | public override string ToString() 17 | { 18 | return Name; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/IError.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Contracts 5 | { 6 | /// 7 | /// A object returned from method in case of any errors occured during installation. 8 | /// 9 | public interface IError 10 | { 11 | /// 12 | /// The error code used to uniquely identify the error. 13 | /// 14 | string Code { get; } 15 | 16 | /// 17 | /// The user friendly description of the error. 18 | /// 19 | string Message { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /test/LibraryManager.Test/InvalidLibraryExceptionTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | 7 | namespace Microsoft.Web.LibraryManager.Test 8 | { 9 | [TestClass] 10 | public class InvalidLibraryExceptionTest 11 | { 12 | [TestMethod] 13 | public void Constructor() 14 | { 15 | var ex = new InvalidLibraryException("123", "abc"); 16 | 17 | Assert.AreEqual("123", ex.LibraryId); 18 | Assert.AreEqual("abc", ex.ProviderId); 19 | Assert.IsNotNull(ex.Message); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/SelectedProviderBinding.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 7 | { 8 | internal class SelectedProviderBinding : BindableBase 9 | { 10 | private IProvider _selectedProvider; 11 | 12 | internal IProvider SelectedProvider 13 | { 14 | get { return _selectedProvider; } 15 | set { Set(ref _selectedProvider, value); } 16 | } 17 | 18 | internal SelectedProviderBinding() 19 | { 20 | _selectedProvider = default(IProvider); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace TestProjectCore20 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Shared/ITaskStatusCenterService.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.VisualStudio.TaskStatusCenter; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix.Shared 8 | { 9 | /// 10 | /// Provides an interface for a Task Status Center Service 11 | /// 12 | internal interface ITaskStatusCenterService 13 | { 14 | /// 15 | /// Returns an ITaskHandler with a given task title 16 | /// 17 | /// 18 | /// 19 | Task CreateTaskHandlerAsync(string title); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/NotConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows.Data; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 9 | { 10 | internal class NotConverter : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 13 | { 14 | return !(value is bool && (bool) value); 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | return !(value is bool && (bool)value); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/LibraryNameBinding.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 5 | { 6 | /// 7 | /// It will fire an event whenever a valid library name is typed so as to update the target location. 8 | /// 9 | internal class LibraryNameBinding : BindableBase 10 | { 11 | private string _libraryName; 12 | 13 | internal string LibraryName 14 | { 15 | get { return _libraryName; } 16 | set { Set(ref _libraryName, value); } 17 | } 18 | 19 | internal LibraryNameBinding() 20 | { 21 | _libraryName = string.Empty; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:59019/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "TestProjectCore20": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:59020/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/libman.Test/TestLogger.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Microsoft.Web.LibraryManager.Contracts; 8 | 9 | namespace Microsoft.Web.LibraryManager.Tools.Test 10 | { 11 | internal class TestLogger : ILogger 12 | { 13 | public List> Messages { get; } = new List>(); 14 | 15 | public void Log(string message, LogLevel level) 16 | { 17 | Messages.Add(new KeyValuePair(level, message)); 18 | } 19 | 20 | public void Clear() 21 | { 22 | Messages.Clear(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/IProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Contracts 5 | { 6 | /// 7 | /// Represents a factory needed to register a . 8 | /// 9 | public interface IProviderFactory 10 | { 11 | /// 12 | /// Creates an instance. 13 | /// 14 | /// The provided by the host to handle file system writes etc. 15 | /// A instance. 16 | IProvider CreateProvider(IHostInteraction hostInteraction); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/Helpers/HelperWrapper.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Microsoft.Test.Apex.VisualStudio; 10 | 11 | namespace Microsoft.Web.LibraryManager.IntegrationTest.Helpers 12 | { 13 | public class HelperWrapper 14 | { 15 | public HelperWrapper(VisualStudioHost vsHost) 16 | { 17 | Completion = new CompletionHelper(); 18 | FileIO = new FileIOHelper(); 19 | } 20 | 21 | public CompletionHelper Completion { get; private set; } 22 | 23 | public FileIOHelper FileIO { get; private set; } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/IWebRequestHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.Web.LibraryManager.Contracts 9 | { 10 | /// 11 | /// Implements functionality to retrieve a resource as a stream 12 | /// 13 | public interface IWebRequestHandler 14 | { 15 | /// 16 | /// Returns the requested resource as a Stream 17 | /// 18 | /// 19 | /// 20 | /// 21 | Task GetStreamAsync(string url, CancellationToken cancellationToken); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/source.extension.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by Extensibility Tools v1.10.188 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace Microsoft.Web.LibraryManager.Vsix 7 | { 8 | static class Vsix 9 | { 10 | public const string Id = "69b6bcde-f505-4c03-b071-8981cc1be2b9"; 11 | public const string Name = "Microsoft Library Manager"; 12 | public const string Description = @"Install client-side libraries easily to any web project"; 13 | public const string Language = "en-US"; 14 | public const string Author = "Microsoft"; 15 | public const string Tags = "library, package, client-side, install"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Shared/WpfUtil.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.Imaging.Interop; 5 | using Microsoft.VisualStudio.Shell; 6 | using Microsoft.VisualStudio.Shell.Interop; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.Shared 9 | { 10 | internal static class WpfUtil 11 | { 12 | public static ImageMoniker GetImageMonikerForFile(string file) 13 | { 14 | var imageService = ServiceProvider.GlobalProvider.GetService(typeof(SVsImageService)) as IVsImageService2; 15 | 16 | if (imageService == null) 17 | { 18 | return default; 19 | } 20 | 21 | return imageService.GetImageMonikerForFile(file); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report about something that is not working 4 | --- 5 | 6 | ### Describe the bug 7 | A clear and concise description of what the bug is. 8 | 9 | ### To Reproduce 10 | Steps to reproduce the behavior: 11 | 1. Using this version of Visual Studio '...' 12 | 2. Take this action... 13 | 4. See error 14 | 15 | ### Expected behavior 16 | A clear and concise description of what you expected to happen. 17 | 18 | ### Screenshots 19 | If applicable, add screenshots to help explain your problem. 20 | 21 | ### Additional context 22 | Add any other context about the problem here. 23 | If using the LibMan CLI tool, include the output of `libman --version` 24 | If using Visual Studio, include the version of Visual Studio and of `Microsoft Library Manager` from the Installed Products section of the About dialog. 25 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/VisibleIfNonNullConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows; 7 | using System.Windows.Data; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 10 | { 11 | internal class VisibleIfNonNullConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | return value != null ? Visibility.Visible : Visibility.Collapsed; 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | throw new NotSupportedException(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/AutomationPeers/TextControlTypeAutomationPeer.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Windows.Automation.Peers; 5 | using System.Windows.Controls; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls.AutomationPeers 8 | { 9 | /// 10 | /// Custom AutomationPeer for TargetLocation control 11 | /// 12 | internal class TextControlTypeAutomationPeer : UserControlAutomationPeer 13 | { 14 | public TextControlTypeAutomationPeer(UserControl owner) : base(owner) 15 | { 16 | } 17 | 18 | protected override AutomationControlType GetAutomationControlTypeCore() 19 | { 20 | return AutomationControlType.Text; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/PackageContentsTreeViewAutomationPeer.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Windows.Automation.Peers; 5 | using System.Windows.Controls; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls 8 | { 9 | /// 10 | /// Custom AutomationPeer for PackageContentsTreeView control 11 | /// 12 | internal class PackageContentsTreeViewAutomationPeer : UserControlAutomationPeer 13 | { 14 | public PackageContentsTreeViewAutomationPeer(UserControl owner) : base(owner) 15 | { 16 | } 17 | 18 | protected override AutomationControlType GetAutomationControlTypeCore() 19 | { 20 | return AutomationControlType.Tree; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/InstallDialogProvider.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.UI 7 | { 8 | /// 9 | /// This class gives apex access to opened - add client side libraries dialog. 10 | /// 11 | internal class InstallDialogProvider 12 | { 13 | private static IInstallDialog InstallDialog; 14 | public static event EventHandler WindowChanged; 15 | 16 | public static IInstallDialog Window 17 | { 18 | get { return InstallDialog; } 19 | set 20 | { 21 | InstallDialog = value; 22 | 23 | WindowChanged?.Invoke(null, new EventArgs()); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Unpkg/INpmPackageInfoFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Web.LibraryManager.Providers.Unpkg 8 | { 9 | /// 10 | /// A factory for NPM package info 11 | /// 12 | public interface INpmPackageInfoFactory 13 | { 14 | /// 15 | /// Gets NpmPackageInfo for the given package 16 | /// 17 | /// 18 | /// 19 | /// The NpmPackageInfo for the given packageName 20 | Task GetPackageInfoAsync(string packageName, CancellationToken cancellationToken); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/CompletionEntry.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls 7 | { 8 | public class CompletionEntry 9 | { 10 | public CompletionEntry(CompletionItem completionItem, int start, int length) 11 | { 12 | Start = start; 13 | Length = length; 14 | CompletionItem = completionItem; 15 | } 16 | 17 | public CompletionItem CompletionItem { get; } 18 | 19 | public string Description => CompletionItem.Description; 20 | 21 | public string DisplayText => CompletionItem.DisplayText; 22 | 23 | public int Length { get; } 24 | 25 | public int Start { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LibraryManager/Json/ManifestOnDisk.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Newtonsoft.Json; 8 | 9 | namespace Microsoft.Web.LibraryManager.Json 10 | { 11 | internal class ManifestOnDisk 12 | { 13 | [JsonProperty(ManifestConstants.Version)] 14 | public string Version { get; set; } 15 | 16 | [JsonProperty(ManifestConstants.DefaultProvider)] 17 | public string DefaultProvider { get; set; } 18 | 19 | [JsonProperty(ManifestConstants.DefaultDestination)] 20 | public string DefaultDestination { get; set; } 21 | 22 | [JsonProperty(ManifestConstants.Libraries)] 23 | public IEnumerable Libraries { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/LibraryManager.Contracts.Test/Microsoft.Web.LibraryManager.Contracts.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(NetCoreTFM);$(NetFxTFM) 5 | 6 | enable 7 | enable 8 | 9 | false 10 | true 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/libman.Test/TestInputReader.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Web.LibraryManager.Tools.Test 9 | { 10 | internal class TestInputReader : IInputReader 11 | { 12 | public Dictionary Inputs { get; } = new Dictionary(StringComparer.Ordinal); 13 | 14 | public string GetUserInput(string fieldName) 15 | { 16 | return Inputs[fieldName]; 17 | } 18 | 19 | public string GetUserInputWithDefault(string fieldName, string defaultValue) 20 | { 21 | if (Inputs.TryGetValue(fieldName, out string value)) 22 | { 23 | return value; 24 | } 25 | 26 | return defaultValue; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/libman.Test/libman.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM) 4 | Microsoft.Web.LibraryManager.Tools.Test 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Unpkg/INpmPackageSearch.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.Web.LibraryManager.Providers.Unpkg 9 | { 10 | /// 11 | /// A utility to help retrieve the info for all related packages from a given search term 12 | /// 13 | public interface INpmPackageSearch 14 | { 15 | /// 16 | /// Retrieves info for all related packages given a search term 17 | /// 18 | /// 19 | /// 20 | /// 21 | Task> GetPackageNamesAsync(string searchTerm, CancellationToken cancellationToken); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/OperationType.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Contracts 5 | { 6 | /// 7 | /// The Library Manager types of operation 8 | /// 9 | public enum OperationType 10 | { 11 | /// 12 | /// Restores a library 13 | /// 14 | Restore, 15 | 16 | /// 17 | /// Installs a library 18 | /// 19 | Install, 20 | 21 | /// 22 | /// Uninstalls a library 23 | /// 24 | Uninstall, 25 | 26 | /// 27 | /// Upgrades a library 28 | /// 29 | Upgrade, 30 | 31 | /// 32 | /// Cleans libraries 33 | /// 34 | Clean 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/LibraryManager/Json/LibraryInstallationStateOnDisk.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace Microsoft.Web.LibraryManager.Json 8 | { 9 | internal class LibraryInstallationStateOnDisk 10 | { 11 | [JsonProperty(ManifestConstants.Provider)] 12 | public string ProviderId { get; set; } 13 | 14 | [JsonProperty(ManifestConstants.Library)] 15 | public string LibraryId { get; set; } 16 | 17 | [JsonProperty(ManifestConstants.Destination)] 18 | public string DestinationPath { get; set; } 19 | 20 | [JsonProperty(ManifestConstants.Files)] 21 | public IReadOnlyList Files { get; set; } 22 | 23 | [JsonProperty(ManifestConstants.FileMappings)] 24 | public IReadOnlyList FileMappings { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/libman.Test/StringNewLineHelper.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Web.LibraryManager.Tools.Test 9 | { 10 | internal static class StringHelper 11 | { 12 | public static string NormalizeNewLines(string s) 13 | { 14 | if (string.IsNullOrEmpty(s)) 15 | { 16 | return s; 17 | } 18 | 19 | s = s.Replace("\r\n", "$$$").Replace("\r", "$$$").Replace("\n", "$$$"); 20 | return s.Replace("$$$", Environment.NewLine); 21 | } 22 | 23 | public static bool AreEqualIgnoringNewLineFormats(string s1, string s2) 24 | { 25 | s1 = NormalizeNewLines(s1); 26 | s2 = NormalizeNewLines(s2); 27 | 28 | return s1 == s2; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/BoldingConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows; 7 | using System.Windows.Data; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 10 | { 11 | internal class BoldingConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (value is bool && (bool) value) 16 | { 17 | return FontWeights.Bold; 18 | } 19 | 20 | return FontWeights.Normal; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | return value is FontWeight && (FontWeight) value == FontWeights.Bold; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/libman.Test/TestEnvironmentHelper.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Tools.Test 5 | { 6 | internal class TestEnvironmentHelper 7 | { 8 | public static EnvironmentSettings GetTestSettings(string workingDirectory, string cacheDirectory) 9 | { 10 | return new EnvironmentSettings() 11 | { 12 | Logger = new TestLogger(), 13 | InputReader = new TestInputReader(), 14 | CurrentWorkingDirectory = workingDirectory, 15 | CacheDirectory = cacheDirectory 16 | }; 17 | } 18 | 19 | public static IHostEnvironment GetTestHostEnvironment(string workingDirectory, string cacheDirectory) 20 | { 21 | return new Mocks.HostEnvironment(GetTestSettings(workingDirectory, cacheDirectory)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/FileHelpersTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | 7 | namespace Microsoft.Web.LibraryManager.Test 8 | { 9 | [TestClass] 10 | public class FileHelpersTest 11 | { 12 | [DataTestMethod] 13 | [DataRow("C:\\dir\\file.js", "C:\\dir\\", true)] 14 | [DataRow("C:\\dir\\file1.js", "C:\\dir", true)] 15 | [DataRow("C:\\dir\\", "C:\\dir\\", false)] 16 | [DataRow("/abc/def/ghi", "\\abc\\def", true)] 17 | [DataRow("abc/def", "abc", true)] 18 | [DataRow("abcdef", "abc", false)] 19 | public void UnderRootDirectory(string file, string directory, bool expectedResult) 20 | { 21 | Assert.AreEqual(expectedResult, FileHelpers.IsUnderRootDirectory(file, directory)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/FileMapping.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #nullable enable 5 | 6 | using System.Collections.Generic; 7 | 8 | namespace Microsoft.Web.LibraryManager.Contracts 9 | { 10 | /// 11 | /// 12 | /// 13 | public class FileMapping 14 | { 15 | /// 16 | /// Root path within the library content for this file mapping entry. 17 | /// 18 | public string? Root { get; set; } 19 | 20 | /// 21 | /// Destination folder within the project. 22 | /// 23 | public string? Destination { get; set; } 24 | 25 | /// 26 | /// The file patterns to match for this mapping, relative to . Accepts glob patterns. 27 | /// 28 | public IReadOnlyList? Files { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/Microsoft.Web.LibraryManager.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM);$(NetFxTFM) 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Theming/VsThemedTreeView.xaml: -------------------------------------------------------------------------------- 1 | 4 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/TestUtilities/StringUtility.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Microsoft.Web.LibraryManager.Test.TestUtilities 9 | { 10 | internal static class StringUtility 11 | { 12 | public static string NormalizeNewLines(string s) 13 | { 14 | if (string.IsNullOrEmpty(s)) 15 | { 16 | return s; 17 | } 18 | 19 | s = s.Replace("\r\n", "$$$").Replace("\r", "$$$").Replace("\n", "$$$"); 20 | return s.Replace("$$$", Environment.NewLine); 21 | } 22 | 23 | public static (string, int) ExtractCaret(string input) 24 | { 25 | int cursorPosition = input.IndexOf("|"); 26 | string output = input.Remove(cursorPosition, 1); 27 | 28 | return (output, cursorPosition); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LibraryManager/FileConflict.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager 9 | { 10 | /// 11 | /// Represents a conflicting file in multiple libraries. 12 | /// 13 | internal class FileConflict 14 | { 15 | public FileConflict(string file, List libraries) 16 | { 17 | if (string.IsNullOrEmpty(file)) 18 | { 19 | throw new ArgumentException($"{nameof(file)} cannot be null or empty.", nameof(file)); 20 | } 21 | 22 | File = file; 23 | Libraries = libraries ?? throw new ArgumentNullException(nameof(libraries)); 24 | } 25 | 26 | public string File { get; } 27 | public IList Libraries { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LibraryManager/LibraryNaming/SimpleLibraryNamingScheme.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.LibraryNaming 5 | { 6 | /// 7 | /// A versionless library naming scheme which treats libraryId as the library name. 8 | /// 9 | class SimpleLibraryNamingScheme : ILibraryNamingScheme 10 | { 11 | /// 12 | public string GetLibraryId(string name, string version) 13 | { 14 | return name ?? string.Empty; 15 | } 16 | 17 | /// 18 | public (string Name, string Version) GetLibraryNameAndVersion(string libraryId) 19 | { 20 | return (libraryId ?? string.Empty, string.Empty); 21 | } 22 | 23 | /// 24 | public bool IsValidLibraryId(string libraryId) 25 | { 26 | return !string.IsNullOrEmpty(libraryId); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/WatermarkVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows; 7 | using System.Windows.Data; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 10 | { 11 | public class WatermarkVisibilityConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | bool shouldShow = value is null; 16 | if (value is string s) 17 | { 18 | shouldShow = string.IsNullOrEmpty(s); 19 | } 20 | 21 | return shouldShow ? Visibility.Visible : Visibility.Hidden; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/tools/VsctToXliff/VsctToXliff.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.25909.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VsctToXliff", "VsctToXliff.csproj", "{BBF7FD3F-26BA-4F6C-8485-F221CCA1CF6A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BBF7FD3F-26BA-4F6C-8485-F221CCA1CF6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BBF7FD3F-26BA-4F6C-8485-F221CCA1CF6A}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BBF7FD3F-26BA-4F6C-8485-F221CCA1CF6A}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BBF7FD3F-26BA-4F6C-8485-F221CCA1CF6A}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/Search/LibraryGroupToSearchItemAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | using System.Windows.Media.Imaging; 3 | using LibraryManager.Contracts; 4 | using LibraryManager.Vsix.Models; 5 | 6 | namespace LibraryManager.Vsix.Controls.Search 7 | { 8 | internal class LibraryGroupToSearchItemAdapter : ISearchItem 9 | { 10 | private ILibraryGroup _source; 11 | 12 | public LibraryGroupToSearchItemAdapter(ILibraryGroup source) 13 | { 14 | _source = source; 15 | } 16 | 17 | public string CollapsedItemText => _source.Name; 18 | 19 | public string Alias => _source.Name; 20 | 21 | public ImageSource Icon => null; 22 | 23 | public string Homepage => "N/A"; 24 | 25 | public string Description => _source.Description; 26 | 27 | public ILibraryGroup LibraryGroup => _source; 28 | 29 | public bool IsMatchForSearchTerm(string searchTerm) 30 | { 31 | return PackageSearchUtil.ForTerm(searchTerm).IsMatch(this); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /test/LibraryManager.Test/PathEqualityComparerTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace Microsoft.Web.LibraryManager.Test 7 | { 8 | [TestClass] 9 | public class PathEqualityComparerTest 10 | { 11 | [DataTestMethod] 12 | [DataRow("C:\\dir", "C:\\dir\\", true)] 13 | [DataRow("C:\\dir", "C:\\dir\\..\\dir", true)] 14 | [DataRow("C:\\dir", "", false)] 15 | [DataRow("", "", true)] 16 | [DataRow(null, "", false)] 17 | [DataRow(null, null, true)] 18 | [DataRow("\\abc\\def", "abc\\def\\", true)] 19 | [DataRow("abc\\def", "abc\\def\\\\", true)] 20 | [DataRow("abc/def", "abc\\def\\\\", true)] 21 | public void Compare(string path1, string path2, bool expectedResult) 22 | { 23 | Assert.AreEqual(expectedResult, RelativePathEqualityComparer.Instance.Equals(path1, path2)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | The .NET Core and ASP.NET Core support policy, including supported versions can be found at the [.NET Core Support Policy Page](https://dotnet.microsoft.com/platform/support/policy/dotnet-core). 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Security issues and bugs should be reported privately to the Microsoft Security Response Center (MSRC), either by emailing secure@microsoft.com or via the portal at https://msrc.microsoft.com. 10 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your 11 | original message. Further information, including the MSRC PGP key, can be found in the [MSRC Report an Issue FAQ](https://www.microsoft.com/en-us/msrc/faqs-report-an-issue). 12 | 13 | Reports via MSRC may qualify for the .NET Core Bug Bounty. Details of the .NET Core Bug Bounty including terms and conditions are at [https://aka.ms/corebounty](https://aka.ms/corebounty). 14 | 15 | Please do not open issues for anything you think might have a security implication. 16 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/ILibrary.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.Web.LibraryManager.Contracts 7 | { 8 | /// 9 | /// Represents a library package 10 | /// 11 | public interface ILibrary 12 | { 13 | /// 14 | /// The name of the library. 15 | /// 16 | string Name { get; } 17 | 18 | /// 19 | /// The unique ID of the provider. 20 | /// 21 | string ProviderId { get; } 22 | 23 | /// 24 | /// The version of the library. 25 | /// 26 | string Version { get; } 27 | 28 | /// 29 | /// A list of files and a bool value to determine if the file is suggested as a default file for this library. 30 | /// 31 | IReadOnlyDictionary Files { get; } 32 | } 33 | } -------------------------------------------------------------------------------- /src/libman/Contracts/IInputReader.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Tools 5 | { 6 | /// 7 | /// Provides a way to get input from user. 8 | /// 9 | public interface IInputReader 10 | { 11 | /// 12 | /// Prompts the user for an input for the 13 | /// 14 | /// 15 | /// 16 | string GetUserInput(string fieldName); 17 | 18 | /// 19 | /// Prompts the user for an input for the 20 | /// with a suggested default 21 | /// 22 | /// 23 | /// 24 | /// 25 | string GetUserInputWithDefault(string fieldName, string defaultValue); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/EnumToBoolConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Windows.Data; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 8 | { 9 | internal class EnumToBoolConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 12 | { 13 | if (value != null) 14 | { 15 | return value.ToString().Equals(parameter); 16 | } 17 | 18 | return false; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 22 | { 23 | if (value == null) 24 | { 25 | return Binding.DoNothing; 26 | } 27 | 28 | return value.Equals(true) ? parameter : Binding.DoNothing; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/libman/Commands/CacheCommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Extensions.CommandLineUtils; 5 | 6 | namespace Microsoft.Web.LibraryManager.Tools.Commands 7 | { 8 | /// 9 | /// Defines the cache command for libman. 10 | /// Child commands: clean, list 11 | /// 12 | internal class CacheCommand : BaseCommand 13 | { 14 | public CacheCommand(IHostEnvironment hostEnvironment, bool throwOnUnexpectedArg = true) 15 | : base(throwOnUnexpectedArg, "cache", Resources.Text.CacheCommandDesc, hostEnvironment) 16 | { 17 | } 18 | 19 | public override BaseCommand Configure(CommandLineApplication parent) 20 | { 21 | base.Configure(parent); 22 | 23 | Commands.Add(new CacheCleanCommand(HostEnvironment).Configure(this)); 24 | Commands.Add(new CacheListCommand(HostEnvironment).Configure(this)); 25 | 26 | return this; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Contracts/Dependencies.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using Microsoft.Web.LibraryManager.Contracts; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.Contracts 10 | { 11 | internal class Dependencies : IDependencies 12 | { 13 | private readonly IHostInteraction _hostInteraction; 14 | 15 | internal Dependencies(IHostInteraction hostInteraction, IReadOnlyList providers) 16 | { 17 | _hostInteraction = hostInteraction; 18 | Providers = providers; 19 | } 20 | 21 | public IReadOnlyList Providers { get; } 22 | 23 | public IHostInteraction GetHostInteractions() => _hostInteraction; 24 | 25 | public IProvider GetProvider(string providerId) 26 | { 27 | return Providers?.FirstOrDefault(p => p.Id.Equals(providerId, StringComparison.OrdinalIgnoreCase)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/FileSystem/FileSystemLibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Web.LibraryManager.Contracts; 9 | 10 | namespace Microsoft.Web.LibraryManager.Providers.FileSystem 11 | { 12 | internal class FileSystemLibraryGroup : ILibraryGroup 13 | { 14 | public FileSystemLibraryGroup(string groupName) 15 | { 16 | DisplayName = groupName; 17 | } 18 | 19 | public string DisplayName { get; } 20 | 21 | public string Description => string.Empty; 22 | 23 | public Task> GetLibraryVersions(CancellationToken cancellationToken) 24 | { 25 | return Task.FromResult>(Enumerable.Empty()); 26 | } 27 | 28 | public override string ToString() 29 | { 30 | return DisplayName; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/HintTextConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Windows.Data; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 9 | { 10 | internal class HintTextConverter : IValueConverter 11 | { 12 | object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 13 | { 14 | IProvider provider = value as IProvider; 15 | 16 | if (value == null || provider == null || provider.LibraryIdHintText == null) 17 | { 18 | return string.Empty; 19 | } 20 | 21 | return provider.LibraryIdHintText; 22 | } 23 | 24 | object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.Test/Microsoft.Web.LibraryManager.Build.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM);$(NetFxTFM) 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Libman.Build.TestApp", "Libman.Build.TestApp\Libman.Build.TestApp.csproj", "{DB512B50-3DA7-4082-99E4-99C0ED151545}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(SolutionProperties) = preSolution 14 | HideSolutionNode = FALSE 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {DB512B50-3DA7-4082-99E4-99C0ED151545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {DB512B50-3DA7-4082-99E4-99C0ED151545}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {DB512B50-3DA7-4082-99E4-99C0ED151545}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {DB512B50-3DA7-4082-99E4-99C0ED151545}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Search/ProviderCatalogSearchService.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.Search 9 | { 10 | public class ProviderCatalogSearchService : ISearchService 11 | { 12 | private readonly Func _providerLookup; 13 | 14 | public ProviderCatalogSearchService(Func providerLookup) 15 | { 16 | _providerLookup = providerLookup ?? throw new ArgumentNullException(nameof(providerLookup)); 17 | } 18 | 19 | public Task PerformSearch(string searchText, int caretPosition) 20 | { 21 | IProvider provider = _providerLookup(); 22 | if(provider != null) 23 | { 24 | return provider.GetCatalog().GetLibraryCompletionSetAsync(searchText, caretPosition); 25 | } 26 | 27 | return Task.FromResult(default(CompletionSet)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/TestUtilities/AssertExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Runtime.CompilerServices; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using Microsoft.Web.LibraryManager.Contracts; 12 | 13 | namespace Microsoft.Web.LibraryManager.Test.TestUtilities; 14 | 15 | public static class AssertExtensions 16 | { 17 | public static void ErrorsEqual(this Assert assert, IList expected, IList actual) 18 | { 19 | string BuildString(IList errors) 20 | { 21 | StringBuilder stringBuilder = new StringBuilder(); 22 | foreach (IError error in errors) 23 | { 24 | stringBuilder.AppendLine($"{error.Code}: {error.Message}"); 25 | } 26 | return stringBuilder.ToString(); 27 | } 28 | 29 | Assert.AreEqual(BuildString(expected), BuildString(actual)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/LibraryManager/Configuration/Constants.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Configuration 5 | { 6 | internal class Constants 7 | { 8 | public const string HttpProxy = "http_proxy"; 9 | public const string HttpProxyUser = "http_proxy.user"; 10 | // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification = "Configuration setting name, not a secret.")] 11 | public const string HttpProxyPassword = "http_proxy.password"; 12 | public const string HttpProxyBypass = "http_proxy.bypass"; 13 | 14 | public const string HttpsProxy = "https_proxy"; 15 | public const string HttpsProxyUser = "https_proxy.user"; 16 | // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification = "Configuration setting name, not a secret.")] 17 | public const string HttpsProxyPassword = "https_proxy.password"; 18 | public const string HttpsProxyBypass = "https_proxy.bypass"; 19 | 20 | public const string ForceTls12 = "forcetls12"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/ProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Mocks 7 | { 8 | /// 9 | /// A mock class for use in unit tests. 10 | /// 11 | /// 12 | public class ProviderFactory : IProviderFactory 13 | { 14 | /// 15 | /// Creates an instance and assigns the to it. 16 | /// 17 | /// The provided by the host to handle file system writes etc. 18 | /// A instance. 19 | public virtual IProvider CreateProvider(IHostInteraction hostInteraction) 20 | { 21 | return new Provider(hostInteraction); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/Logger.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace Microsoft.Web.LibraryManager.Mocks 9 | { 10 | /// 11 | /// A mock of the interface. 12 | /// 13 | /// 14 | public class Logger : ILogger 15 | { 16 | /// 17 | /// A list of all the log messages recorded by the method. 18 | /// 19 | public List> Messages = new List>(); 20 | 21 | /// 22 | /// Logs the specified message to the host. 23 | /// 24 | /// The message to log. 25 | /// The level of the message. 26 | public virtual void Log(string message, LogLevel level) 27 | { 28 | Messages.Add(Tuple.Create(message, level)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/EditorTooltip.xaml.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Windows.Controls; 5 | using Microsoft.VisualStudio.PlatformUI; 6 | using Microsoft.Web.LibraryManager.Vsix.Json.Completion; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls 9 | { 10 | /// 11 | /// Interaction logic for EditorTooltip.xaml 12 | /// 13 | public partial class EditorTooltip : UserControl 14 | { 15 | internal EditorTooltip(SimpleCompletionEntry item) 16 | { 17 | InitializeComponent(); 18 | 19 | Loaded += (s, e) => 20 | { 21 | ItemName.Content = item.DisplayText; 22 | ItemName.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.SystemMenuTextBrushKey); 23 | 24 | Description.Text = item.Description; 25 | Description.SetResourceReference(TextBlock.ForegroundProperty, EnvironmentColors.SystemMenuTextBrushKey); 26 | 27 | Glyph.Moniker = item.IconMoniker; 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/Error.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.Contracts 5 | { 6 | /// 7 | /// A basic implementation of . 8 | /// 9 | /// 10 | internal class Error : IError 11 | { 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | /// The error code. 16 | /// A detailed error message. 17 | public Error(string code, string message) 18 | { 19 | Code = code; 20 | Message = message; 21 | } 22 | 23 | /// 24 | /// The error code used to uniquely identify the error. 25 | /// 26 | public string Code { get; set; } 27 | 28 | /// 29 | /// The user friendly description of the error. 30 | /// 31 | public string Message { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/TestSolution/Libman.Build.TestApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:13287", 8 | "sslPort": 44380 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "applicationUrl": "http://localhost:5264", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | } 20 | }, 21 | "https": { 22 | "commandName": "Project", 23 | "dotnetRunMessages": true, 24 | "launchBrowser": true, 25 | "applicationUrl": "https://localhost:7009;http://localhost:5264", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | }, 30 | "IIS Express": { 31 | "commandName": "IISExpress", 32 | "launchBrowser": true, 33 | "environmentVariables": { 34 | "ASPNETCORE_ENVIRONMENT": "Development" 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/ILibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.Web.LibraryManager.Contracts 9 | { 10 | /// 11 | /// Represents the search result for a specific library. 12 | /// 13 | public interface ILibraryGroup 14 | { 15 | /// 16 | /// The user facing display name of the library. 17 | /// 18 | string DisplayName { get; } 19 | 20 | /// 21 | /// The description of the library. 22 | /// 23 | string Description { get; } 24 | 25 | /// 26 | /// Gets a list of versions of the library. 27 | /// 28 | /// A token that allows cancellation of the operation. 29 | /// A list of library IDs used to display library information to the user. 30 | Task> GetLibraryVersions(CancellationToken cancellationToken); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/Error.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | 6 | namespace Microsoft.Web.LibraryManager.Mocks 7 | { 8 | /// 9 | /// A mock object. 10 | /// 11 | /// 12 | public class Error : IError 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The code. 18 | /// The message. 19 | public Error(string code, string message) 20 | { 21 | Code = code; 22 | Message = message; 23 | } 24 | 25 | /// 26 | /// The error code used to uniquely identify the error. 27 | /// 28 | public virtual string Code { get; set; } 29 | 30 | /// 31 | /// The user friendly description of the error. 32 | /// 33 | public virtual string Message { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/Search/LogicalOrConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows.Data; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls.Search 9 | { 10 | internal class LogicalOrConverter : IMultiValueConverter 11 | { 12 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 13 | { 14 | Wrapper wrapper = parameter as Wrapper; 15 | 16 | if (wrapper != null && wrapper.Parameter) 17 | { 18 | return true; 19 | } 20 | 21 | for (int i = 0; i < values.Length; ++i) 22 | { 23 | if (values[i] is bool && (bool)values[i]) 24 | { 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | 32 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/libman.Test/CommandTestBase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | 7 | namespace Microsoft.Web.LibraryManager.Tools.Test 8 | { 9 | public class CommandTestBase 10 | { 11 | protected string WorkingDir { get; set; } 12 | protected string CacheDir { get; set; } 13 | internal IHostEnvironment HostEnvironment { get; set; } 14 | 15 | public virtual void Setup() 16 | { 17 | WorkingDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); 18 | Directory.CreateDirectory(WorkingDir); 19 | CacheDir = Path.Combine(WorkingDir, "cache"); 20 | Directory.CreateDirectory(CacheDir); 21 | 22 | HostEnvironment = TestEnvironmentHelper.GetTestHostEnvironment(WorkingDir, CacheDir); 23 | } 24 | 25 | public virtual void Cleanup() 26 | { 27 | try 28 | { 29 | Directory.Delete(WorkingDir, true); 30 | } 31 | catch 32 | { 33 | // Don't fail the tests if cleanup failed. 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestSolution.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | VisualStudioVersion = 16.0.28106.4001 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestProjectCore20", "TestProjectCore20\TestProjectCore20.csproj", "{ECDD5F9F-5AF0-4A3B-8A6A-62DC3C9C6098}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {ECDD5F9F-5AF0-4A3B-8A6A-62DC3C9C6098}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {ECDD5F9F-5AF0-4A3B-8A6A-62DC3C9C6098}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {ECDD5F9F-5AF0-4A3B-8A6A-62DC3C9C6098}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {ECDD5F9F-5AF0-4A3B-8A6A-62DC3C9C6098}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {00F9ED2D-6E10-45D0-86A1-AF5808F11BCD} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Unpkg/UnpkgProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using Microsoft.Web.LibraryManager.Cache; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Providers.Unpkg 9 | { 10 | internal class UnpkgProviderFactory : IProviderFactory 11 | { 12 | private readonly INpmPackageSearch _packageSearch; 13 | private readonly INpmPackageInfoFactory _packageInfoFactory; 14 | 15 | public UnpkgProviderFactory(INpmPackageSearch packageSearch, INpmPackageInfoFactory packageInfoFactory) 16 | { 17 | _packageSearch = packageSearch; 18 | _packageInfoFactory = packageInfoFactory; 19 | } 20 | 21 | public IProvider CreateProvider(IHostInteraction hostInteraction) 22 | { 23 | if (hostInteraction == null) 24 | { 25 | throw new ArgumentNullException(nameof(hostInteraction)); 26 | } 27 | 28 | return new UnpkgProvider(hostInteraction, new CacheService(WebRequestHandler.Instance), _packageSearch, _packageInfoFactory); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LibraryManager/Helpers/LibraryStateTypeConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | 10 | namespace Microsoft.Web.LibraryManager.Helpers 11 | { 12 | internal class LibraryStateTypeConverter : JsonConverter 13 | { 14 | public override bool CanConvert(Type objectType) => true; 15 | 16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 17 | { 18 | return serializer.Deserialize>(reader).Cast().ToList(); 19 | } 20 | 21 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 22 | { 23 | IEnumerable list = (value as IEnumerable) 24 | .Select(i => LibraryInstallationState.FromInterface(i)); 25 | 26 | serializer.Serialize(writer, list); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.Test/Microsoft.Web.LibraryManager.Vsix.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetFxTFM) 4 | true 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /azure-pipelines/Convert-PDB.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Builds all projects in this repo. 4 | .PARAMETER DllPath 5 | The path to the DLL whose PDB is to be converted. 6 | .PARAMETER PdbPath 7 | The path to the PDB to convert. May be omitted if the DLL was compiled on this machine and the PDB is still at its original path. 8 | .PARAMETER OutputPath 9 | The path of the output PDB to write. 10 | #> 11 | #Function Convert-PortableToWindowsPDB() { 12 | Param( 13 | [Parameter(Mandatory=$true,Position=0)] 14 | [string]$DllPath, 15 | [Parameter()] 16 | [string]$PdbPath, 17 | [Parameter(Mandatory=$true,Position=1)] 18 | [string]$OutputPath 19 | ) 20 | 21 | $version = '1.1.0-beta2-20115-01' 22 | $pdb2pdbpath = "$env:temp\Microsoft.DiaSymReader.Pdb2Pdb.$version\tools\Pdb2Pdb.exe" 23 | if (-not (Test-Path $pdb2pdbpath)) { 24 | nuget install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $env:temp -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json 25 | } 26 | 27 | $args = $DllPath,'/out',$OutputPath,'/nowarn','0021' 28 | if ($PdbPath) { 29 | $args += '/pdb',$PdbPath 30 | } 31 | 32 | & "$pdb2pdbpath" $args 33 | #} 34 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Constants.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix 8 | { 9 | internal static class Constants 10 | { 11 | public const string ConfigFileName = "libman.json"; 12 | public const string TelemetryNamespace = "vs/webtools/librarymanager/"; 13 | public const string MainNuGetPackageId = "Microsoft.Web.LibraryManager.Build"; 14 | public const string ErrorCodeLink = "https://github.com/aspnet/LibraryManager/wiki/Error-codes#{0}"; 15 | public const string WAP = "{349C5851-65DF-11DA-9384-00065B846F21}"; 16 | public const string WebsiteProject = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}"; 17 | /// 18 | /// Project capability for .NET web projects. Used only for UI context rules. 19 | /// 20 | public const string DotNetCoreWebCapability = "DotNetCoreWeb"; 21 | /// 22 | /// Project capability for CPS-based projects. Used to determine how to add/remove items to the project. 23 | /// 24 | public const string CpsCapability = "CPS"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/TestSolution/TestProjectCore20/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace TestProjectCore20 11 | { 12 | public class Startup 13 | { 14 | // This method gets called by the runtime. Use this method to add services to the container. 15 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 16 | public void ConfigureServices(IServiceCollection services) 17 | { 18 | } 19 | 20 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 21 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 22 | { 23 | if (env.IsDevelopment()) 24 | { 25 | app.UseDeveloperExceptionPage(); 26 | } 27 | 28 | app.Run(async (context) => 29 | { 30 | await context.Response.WriteAsync("Hello World!"); 31 | }); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Cdnjs/CdnjsLibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Newtonsoft.Json; 10 | 11 | namespace Microsoft.Web.LibraryManager.Providers.Cdnjs 12 | { 13 | internal class CdnjsLibraryGroup : ILibraryGroup 14 | { 15 | [JsonProperty("name")] 16 | public string DisplayName { get; set; } 17 | 18 | [JsonProperty("description")] 19 | public string Description { get; set; } 20 | 21 | [JsonProperty("version")] 22 | public string Version { get; set; } 23 | 24 | public Task> GetLibraryVersions(CancellationToken cancellationToken) 25 | { 26 | return DisplayInfosTask?.Invoke(cancellationToken) ?? Task.FromResult>(Array.Empty()); 27 | } 28 | 29 | public Func>> DisplayInfosTask { get; set; } 30 | 31 | public override string ToString() 32 | { 33 | return DisplayName; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LibraryManager.Settings.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | chs 5 | 6 | 7 | cht 8 | 9 | 10 | csy 11 | 12 | 13 | esn 14 | 15 | 16 | deu 17 | 18 | 19 | fra 20 | 21 | 22 | ita 23 | 24 | 25 | jpn 26 | 27 | 28 | kor 29 | 30 | 31 | plk 32 | 33 | 34 | ptb 35 | 36 | 37 | ru 38 | 39 | 40 | trk 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Json/Completion/CompletionElementProvider.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.Language.Intellisense; 5 | using Microsoft.VisualStudio.Utilities; 6 | using System.ComponentModel.Composition; 7 | using System.Windows; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.Json.Completion 10 | { 11 | [Export(typeof(IUIElementProvider))] 12 | [Name(nameof(CompletionElementProvider))] 13 | [ContentType("JSON")] 14 | internal class CompletionElementProvider : IUIElementProvider 15 | { 16 | public UIElement GetUIElement(VisualStudio.Language.Intellisense.Completion itemToRender, ICompletionSession context, UIElementType elementType) 17 | { 18 | if (elementType == UIElementType.Tooltip && itemToRender is SimpleCompletionEntry entry) 19 | { 20 | if (!string.IsNullOrEmpty(entry.Description)) 21 | { 22 | return new UI.Controls.EditorTooltip(entry); 23 | } 24 | } 25 | 26 | return null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/jsDelivr/JsDelivrProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using Microsoft.Web.LibraryManager.Cache; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | using Microsoft.Web.LibraryManager.Providers.Unpkg; 8 | 9 | namespace Microsoft.Web.LibraryManager.Providers.jsDelivr 10 | { 11 | internal class JsDelivrProviderFactory : IProviderFactory 12 | { 13 | private readonly INpmPackageSearch _packageSearch; 14 | private readonly INpmPackageInfoFactory _packageInfoFactory; 15 | 16 | public JsDelivrProviderFactory(INpmPackageSearch packageSearch, INpmPackageInfoFactory packageInfoFactory) 17 | { 18 | _packageSearch = packageSearch; 19 | _packageInfoFactory = packageInfoFactory; 20 | } 21 | 22 | public IProvider CreateProvider(IHostInteraction hostInteraction) 23 | { 24 | if (hostInteraction == null) 25 | { 26 | throw new ArgumentNullException(nameof(hostInteraction)); 27 | } 28 | 29 | return new JsDelivrProvider(hostInteraction, new CacheService(WebRequestHandler.Instance), _packageSearch, _packageInfoFactory); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/LibraryManager.Build/Contracts/Logger.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using LogLevel = Microsoft.Web.LibraryManager.Contracts.LogLevel; 6 | 7 | namespace Microsoft.Web.LibraryManager.Build.Contracts 8 | { 9 | internal class Logger : LibraryManager.Contracts.ILogger 10 | { 11 | private Logger() 12 | { 13 | } 14 | 15 | public static Logger Instance { get; } = new Logger(); 16 | public ICollection Messages { get; } = new List(); 17 | public ICollection Errors { get; } = new List(); 18 | 19 | public void Clear() 20 | { 21 | Messages.Clear(); 22 | Errors.Clear(); 23 | } 24 | 25 | public void Log(string message, LogLevel level) 26 | { 27 | switch (level) 28 | { 29 | case LogLevel.Error: 30 | Errors.Add(message); 31 | break; 32 | case LogLevel.Operation: 33 | case LogLevel.Task: 34 | case LogLevel.Status: 35 | Messages.Add(message); 36 | break; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Reflection; 5 | using System.Resources; 6 | using System.Runtime.CompilerServices; 7 | using System.Runtime.InteropServices; 8 | using Microsoft.Web.LibraryManager.Vsix; 9 | 10 | [assembly: AssemblyTitle(Vsix.Name)] 11 | [assembly: AssemblyDescription(Vsix.Description)] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany(Vsix.Author)] 14 | [assembly: AssemblyProduct(Vsix.Name)] 15 | [assembly: AssemblyCopyright(Vsix.Author)] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | [assembly: ComVisible(false)] 20 | 21 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 22 | [assembly: InternalsVisibleTo("Microsoft.Web.LibraryManager.Vsix.IntegrationTest")] 23 | [assembly: InternalsVisibleTo("Microsoft.Web.LibraryManager.Vsix.Test")] 24 | 25 | // TODO: Setting the NeutralResourcesLanguage attribute breaks our menu commands. 26 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1824:Mark assemblies with NeutralResourcesLanguagesAttribute", Justification = "Currently doing this causes our menu items (commands) to not load.")] 27 | //[assembly: NeutralResourcesLanguage("en")] 28 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/FileSystem/FileSystemProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Providers.FileSystem 9 | { 10 | internal class FileSystemProviderFactory : IProviderFactory 11 | { 12 | /// 13 | /// Creates an instance. 14 | /// 15 | /// The provided by the host to handle file system writes etc. 16 | /// 17 | /// A instance. 18 | /// 19 | /// hostInteraction 20 | public IProvider CreateProvider(IHostInteraction hostInteraction) 21 | { 22 | if (hostInteraction == null) 23 | { 24 | throw new ArgumentNullException(nameof(hostInteraction)); 25 | } 26 | 27 | return new FileSystemProvider(hostInteraction); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/libman.Test/SampleTestCommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Microsoft.Web.LibraryManager.Tools.Commands; 10 | 11 | namespace Microsoft.Web.LibraryManager.Tools.Test 12 | { 13 | internal class SampleTestCommand : BaseCommand 14 | { 15 | public bool CreateNewManifest { get; set; } 16 | public string DefaultProvider { get; set; } 17 | public string DefaultDestination { get; set; } 18 | 19 | public SampleTestCommand(IHostEnvironment environment) 20 | : base(false, "Sample", "", environment) 21 | { 22 | } 23 | 24 | public Manifest Manifest { get; private set; } 25 | 26 | protected override async Task ExecuteInternalAsync() 27 | { 28 | if (CreateNewManifest) 29 | { 30 | Manifest = await CreateManifestAsync(DefaultProvider, DefaultDestination, Settings, "", CancellationToken.None); 31 | } 32 | else 33 | { 34 | Manifest = await GetManifestAsync(); 35 | } 36 | 37 | return 0; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/ILogger.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.Web.LibraryManager.Contracts 7 | { 8 | /// 9 | /// Represents a logger used by the to log messages and exceptions. 10 | /// 11 | public interface ILogger 12 | { 13 | /// 14 | /// Logs the specified message to the host. 15 | /// 16 | /// The message to log. 17 | /// The level of the message. 18 | void Log(string message, LogLevel level); 19 | } 20 | 21 | /// 22 | /// The logging level is used to determine where to log the message 23 | /// 24 | public enum LogLevel 25 | { 26 | /// An error may or may not be shown diretly to the user. 27 | Error, 28 | 29 | /// An operation happens by the internal workings of the providers. 30 | Operation, 31 | 32 | /// A task is manually invoked by the user. 33 | Task, 34 | 35 | /// Status is a short message to display to the user. 36 | Status 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/LibraryInstallationState.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.Web.LibraryManager.Mocks 8 | { 9 | /// 10 | /// A mock class. 11 | /// 12 | /// 13 | public class LibraryInstallationState : ILibraryInstallationState 14 | { 15 | /// 16 | public virtual string ProviderId { get; set; } 17 | 18 | /// 19 | public virtual IReadOnlyList Files { get; set; } 20 | 21 | /// 22 | public virtual string DestinationPath { get; set; } 23 | 24 | /// 25 | public string Name { get; set; } 26 | 27 | /// 28 | public string Version { get; set; } 29 | 30 | /// 31 | public bool IsUsingDefaultDestination { get; set; } 32 | 33 | /// 34 | public bool IsUsingDefaultProvider { get; set; } 35 | 36 | /// 37 | public IReadOnlyList FileMappings { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.IntegrationTest/Microsoft.Web.LibraryManager.Vsix.IntegrationTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetFxTFM) 4 | 5 | $(NoWarn);MSB3270 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Contracts/PerProjectLogger.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using Microsoft.Web.LibraryManager.Contracts; 8 | using Microsoft.Web.LibraryManager.Vsix.Shared; 9 | 10 | namespace Microsoft.Web.LibraryManager.Vsix.Contracts 11 | { 12 | internal class PerProjectLogger : ILogger 13 | { 14 | private string _configFileName; 15 | private string _projectName; 16 | 17 | private string ProjectName 18 | { 19 | get 20 | { 21 | if (string.IsNullOrEmpty(_projectName)) 22 | { 23 | string projectName = VsHelpers.GetDTEProjectFromConfig(_configFileName)?.Name; 24 | _projectName = string.IsNullOrEmpty(projectName) ? string.Empty : $" ({projectName})"; 25 | } 26 | 27 | return _projectName; 28 | } 29 | } 30 | 31 | public PerProjectLogger(string configFileName) 32 | { 33 | _configFileName = configFileName; 34 | } 35 | 36 | public void Log(string message, LogLevel level) 37 | { 38 | Logger.LogEvent($"{message}{ProjectName}", level); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Cdnjs/CdnjsProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using Microsoft.Web.LibraryManager.Cache; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Providers.Cdnjs 9 | { 10 | internal class CdnjsProviderFactory : IProviderFactory 11 | { 12 | /// 13 | /// Creates an instance. 14 | /// 15 | /// The provided by the host to handle file system writes etc. 16 | /// 17 | /// A instance. 18 | /// 19 | /// hostInteraction 20 | public IProvider CreateProvider(IHostInteraction hostInteraction) 21 | { 22 | if (hostInteraction == null) 23 | { 24 | throw new ArgumentNullException(nameof(hostInteraction)); 25 | } 26 | 27 | return new CdnjsProvider(hostInteraction, new CacheService(WebRequestHandler.Instance)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/Microsoft.Web.LibraryManager.Mocks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM);$(NetFxTFM) 4 | mocks, unit test, library, client-side, package 5 | True 6 | true 7 | Microsoft 8 | Microsoft Corp. 9 | A collection of mocks for unit testing custom Library Manager extensions 10 | Copyright © Microsoft 11 | 1.0.0-alpha 12 | Microsoft.Web.LibraryManager.Mocks 13 | https://aka.ms/vsextensibilityicon 14 | https://github.com/aspnet/LibraryManager 15 | https://github.com/aspnet/LibraryManager 16 | ..\..\artifacts\$(Configuration) 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/IDependencies.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.Web.LibraryManager.Contracts 7 | { 8 | /// 9 | /// Used to pass in dependencies to the Manifest class. 10 | /// 11 | /// 12 | /// This should be implemented by the host 13 | /// 14 | public interface IDependencies 15 | { 16 | /// 17 | /// Gets the set of providers that are currently registered 18 | /// 19 | IReadOnlyList Providers { get; } 20 | 21 | /// 22 | /// Gets the provider based on the specified providerId. 23 | /// 24 | /// The unique ID of the provider. 25 | /// An or null from the providers resolved by the host. 26 | IProvider GetProvider(string providerId); 27 | 28 | /// 29 | /// Gets the used by to install libraries. 30 | /// 31 | /// The provided by the host. 32 | IHostInteraction GetHostInteractions(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/LibraryManager/Utilities/EncryptionUtility.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | 8 | namespace Microsoft.Web.LibraryManager.Utilities 9 | { 10 | /// 11 | /// Utility class for encrypting/decrypting data for the current user. 12 | /// 13 | internal static class EncryptionUtility 14 | { 15 | private static readonly byte[] EntropyBytes = Encoding.UTF8.GetBytes("LibraryManager"); 16 | 17 | public static string EncryptString(string value) 18 | { 19 | byte[] decryptedByteArray = Encoding.UTF8.GetBytes(value); 20 | byte[] encryptedByteArray = ProtectedData.Protect(decryptedByteArray, EntropyBytes, DataProtectionScope.CurrentUser); 21 | string encryptedString = Convert.ToBase64String(encryptedByteArray); 22 | return encryptedString; 23 | } 24 | 25 | public static string DecryptString(string encryptedString) 26 | { 27 | byte[] encryptedByteArray = Convert.FromBase64String(encryptedString); 28 | byte[] decryptedByteArray = ProtectedData.Unprotect(encryptedByteArray, EntropyBytes, DataProtectionScope.CurrentUser); 29 | return Encoding.UTF8.GetString(decryptedByteArray); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/LibraryManager/LibraryNaming/ILibraryNamingScheme.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | namespace Microsoft.Web.LibraryManager.LibraryNaming 5 | { 6 | /// 7 | /// Allows converting libraryId to name and version and vice versa. 8 | /// 9 | internal interface ILibraryNamingScheme 10 | { 11 | /// 12 | /// Returns whether the given library identifier matches the naming scheme 13 | /// 14 | /// The library ID to validate. 15 | /// Returns true if the library ID matches the naming scheme; false otherwise. 16 | /// This does not indicate that the library ID is valid, but only that it is well-formed. 17 | bool IsValidLibraryId(string libraryId); 18 | 19 | /// 20 | /// Splits libraryId into name and version. 21 | /// 22 | (string Name, string Version) GetLibraryNameAndVersion(string libraryId); 23 | 24 | /// 25 | /// Gets the libraryId from name and version. 26 | /// 27 | /// 28 | /// 29 | /// 30 | string GetLibraryId(string name, string version); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.Test/UI/Converters/WatermarkVisibilityConverterTests.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Windows; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Web.LibraryManager.Vsix.UI.Converters; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.Test.UI.Converters 10 | { 11 | [TestClass] 12 | public class WatermarkVisibilityConverterTests 13 | { 14 | [DataTestMethod] 15 | [DataRow(null, Visibility.Visible)] 16 | [DataRow("", Visibility.Visible)] 17 | [DataRow("non-empty", Visibility.Hidden)] 18 | public void Convert_StringValues(string input, Visibility expected) 19 | { 20 | var testObj = new WatermarkVisibilityConverter(); 21 | 22 | var result = (Visibility)testObj.Convert(input, null, null, null); 23 | 24 | Assert.AreEqual(expected, result); 25 | } 26 | 27 | [TestMethod] 28 | public void Convert_NonStringValue_ShouldReturnHidden() 29 | { 30 | var testObj = new WatermarkVisibilityConverter(); 31 | string[] input = Array.Empty(); // non-string, non-null object 32 | 33 | var result = (Visibility)testObj.Convert(input, null, null, null); 34 | 35 | Assert.AreEqual(Visibility.Hidden, result); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.Test/TaskItem.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using Microsoft.Build.Framework; 11 | 12 | namespace Microsoft.Web.LibraryManager.Build.Test 13 | { 14 | public class TaskItem : ITaskItem 15 | { 16 | public string ItemSpec { get; set; } 17 | 18 | public ICollection MetadataNames => throw new NotImplementedException(); 19 | 20 | public int MetadataCount => throw new NotImplementedException(); 21 | 22 | public IDictionary CloneCustomMetadata() 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | 27 | public void CopyMetadataTo(ITaskItem destinationItem) 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | public string GetMetadata(string metadataName) 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | 37 | public void RemoveMetadata(string metadataName) 38 | { 39 | throw new NotImplementedException(); 40 | } 41 | 42 | public void SetMetadata(string metadataName, string metadataValue) 43 | { 44 | throw new NotImplementedException(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/libman.Test/Mocks/HostEnvironment.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Text; 8 | using Microsoft.Web.LibraryManager.Contracts; 9 | using Microsoft.Web.LibraryManager.Tools.Contracts; 10 | 11 | 12 | namespace Microsoft.Web.LibraryManager.Tools.Test.Mocks 13 | { 14 | internal class HostEnvironment : IHostEnvironment 15 | { 16 | public HostEnvironment(EnvironmentSettings envSettings) 17 | { 18 | EnvironmentSettings = envSettings; 19 | InputReader = new TestInputReader(); 20 | Logger = new TestLogger(); 21 | HostInteraction = new HostInteractionInternal(envSettings.CurrentWorkingDirectory, envSettings.CacheDirectory) 22 | { 23 | Logger = Logger, 24 | }; 25 | } 26 | 27 | public IInputReader InputReader { get; set; } 28 | public ILogger Logger { get; set; } 29 | public IHostInteractionInternal HostInteraction { get; set; } 30 | 31 | public EnvironmentSettings EnvironmentSettings { get; } 32 | 33 | public string ToolInstallationDir => Path.GetDirectoryName(typeof(HostEnvironment).Assembly.Location); 34 | 35 | public void UpdateWorkingDirectory(string directory) 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /common/tools/VsctToXliff/Utilities.cs: -------------------------------------------------------------------------------- 1 | /* **************************************************************************** 2 | * 3 | * Copyright (c) Microsoft Corporation. 4 | * 5 | * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 6 | * copy of the license can be found in the License.html file at the root of this distribution. 7 | * By using this source code in any fashion, you are agreeing to be bound by the terms of 8 | * the Apache License, Version 2.0. 9 | * 10 | * You must not remove this notice, or any other, from this software. 11 | * 12 | * ***************************************************************************/ 13 | 14 | using System; 15 | using System.IO; 16 | 17 | namespace VsctToXliff 18 | { 19 | internal static class Utilities 20 | { 21 | public static string EnsureRootPath(string path) 22 | { 23 | if (Path.IsPathRooted(path)) 24 | { 25 | return path; 26 | } 27 | 28 | return new FileInfo(Path.Combine(Environment.CurrentDirectory, path)).FullName; 29 | } 30 | 31 | /// The filename without extension or locale. 32 | public static string VsctFileNameWithoutExtension(string fileName) 33 | { 34 | // assume filename have the following structure: ..vsct 35 | var file = Path.GetFileName(fileName); 36 | 37 | return file.Substring(0, file.IndexOf('.')); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/BindableBase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Diagnostics; 7 | using System.Runtime.CompilerServices; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 10 | { 11 | internal class BindableBase : INotifyPropertyChanged 12 | { 13 | public event PropertyChangedEventHandler PropertyChanged; 14 | 15 | public bool Set(ref T value, T newValue, IEqualityComparer comparer = null, [CallerMemberName] string propertyName = null) 16 | { 17 | IEqualityComparer comparerToUse = comparer ?? EqualityComparer.Default; 18 | 19 | if (!comparerToUse.Equals(value, newValue)) 20 | { 21 | value = newValue; 22 | OnPropertyChangedCore(propertyName); 23 | return true; 24 | } 25 | 26 | return false; 27 | } 28 | 29 | protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 30 | { 31 | OnPropertyChangedCore(propertyName); 32 | } 33 | 34 | private void OnPropertyChangedCore(string propertyName) 35 | { 36 | Debug.Assert(propertyName != null, "Property name cannot be null"); 37 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/BindingProxy.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.ComponentModel; 5 | using System.Windows; 6 | using System.Windows.Markup; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Controls 9 | { 10 | [ContentProperty(nameof(Input))] 11 | internal class BindingProxy : FrameworkElement 12 | { 13 | public static readonly DependencyProperty InputProperty = DependencyProperty.Register( 14 | nameof(Input), typeof(object), typeof(BindingProxy), new PropertyMetadata(default(object), InputChanged)); 15 | 16 | public static readonly DependencyProperty OutputProperty = DependencyProperty.Register( 17 | nameof(Output), typeof(object), typeof(BindingProxy), new PropertyMetadata(default(object))); 18 | 19 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 20 | public object Input 21 | { 22 | get { return (string)GetValue(InputProperty); } 23 | set { SetValue(InputProperty, value); } 24 | } 25 | 26 | public object Output 27 | { 28 | get { return (string)GetValue(OutputProperty); } 29 | set { SetValue(OutputProperty, value); } 30 | } 31 | 32 | private static void InputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 33 | { 34 | ((BindingProxy)d).Output = e.NewValue; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/LibraryManager/FileIdentifier.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Web.LibraryManager 7 | { 8 | /// 9 | /// Represents a unique identifier for a version of a library file 10 | /// 11 | internal class FileIdentifier 12 | { 13 | public string Path { get; } 14 | public string Version { get; } 15 | 16 | public FileIdentifier(string path, string version) 17 | { 18 | Path = path; 19 | Version = version; 20 | } 21 | 22 | public override bool Equals(object obj) 23 | { 24 | FileIdentifier other = obj as FileIdentifier; 25 | 26 | if (other == null) 27 | { 28 | return false; 29 | } 30 | 31 | return string.Compare(Path.Replace('\\', '/'), other.Path.Replace('\\', '/'), StringComparison.OrdinalIgnoreCase) == 0 && 32 | string.Compare(Version, other.Version, StringComparison.OrdinalIgnoreCase) == 0; 33 | } 34 | 35 | public override int GetHashCode() 36 | { 37 | #if NET8_0_OR_GREATER 38 | return HashCode.Combine(Path, Version); 39 | #else 40 | int hashPath = Path == null ? 0 : Path.GetHashCode(); 41 | int hashVersion = Version == null ? 0 : Version.GetHashCode(); 42 | 43 | return hashPath ^ hashVersion; 44 | #endif 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Shared/TaskStatusCenterService.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.ComponentModel.Composition; 5 | using System.Threading.Tasks; 6 | using Microsoft.VisualStudio.Shell; 7 | using Microsoft.VisualStudio.TaskStatusCenter; 8 | 9 | /// 10 | /// Implementation of the TaskStatusCenterService allowing backaground tasks to be registered to IVsTaskStatusCenterService. 11 | /// 12 | namespace Microsoft.Web.LibraryManager.Vsix.Shared 13 | { 14 | using Package = Microsoft.VisualStudio.Shell.Package; 15 | 16 | [Export(typeof(ITaskStatusCenterService))] 17 | internal class TaskStatusCenterService : ITaskStatusCenterService 18 | { 19 | public async Task CreateTaskHandlerAsync(string title) 20 | { 21 | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); 22 | 23 | IVsTaskStatusCenterService taskStatusCenter = (IVsTaskStatusCenterService)Package.GetGlobalService(typeof(SVsTaskStatusCenterService)); 24 | TaskHandlerOptions options = default(TaskHandlerOptions); 25 | options.Title = title; 26 | options.ActionsAfterCompletion = CompletionActions.None; 27 | 28 | TaskProgressData data = default(TaskProgressData); 29 | data.CanBeCanceled = true; 30 | 31 | ITaskHandler handler = taskStatusCenter.PreRegister(options, data); 32 | return handler; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Extensions/RemoveCharacterExtension.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Windows.Markup; 6 | 7 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Extensions 8 | { 9 | [MarkupExtensionReturnType(typeof(string))] 10 | internal class RemoveCharacterExtension : MarkupExtension 11 | { 12 | private object _text; 13 | private string _remove; 14 | 15 | public RemoveCharacterExtension(object text, string remove) 16 | { 17 | _text = text; 18 | _remove = remove; 19 | } 20 | 21 | public override object ProvideValue(IServiceProvider serviceProvider) 22 | { 23 | if (_text == null) 24 | { 25 | return null; 26 | } 27 | 28 | string s = null; 29 | 30 | MarkupExtension m = _text as MarkupExtension; 31 | if (m != null) 32 | { 33 | s = m.ProvideValue(serviceProvider) as string; 34 | } 35 | 36 | if (s == null) 37 | { 38 | s = _text as string; 39 | } 40 | 41 | for (int i = 0; i < _remove.Length; i++) 42 | { 43 | if (s != null) 44 | { 45 | s = s.Replace(_remove[i].ToString(), string.Empty); 46 | } 47 | } 48 | 49 | return s; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /setup/Microsoft.Web.LibraryManager.vsmanproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | v4.7.2 8 | 9 | build-manifest 10 | true 11 | true 12 | LibraryManagerPackagesManifest 13 | vs 14 | 2016 15 | true 16 | $(BaseOutputPath)\setup 17 | 18 | $(ManifestOutputPath)\_manifest\spdx_2.2 19 | $(RepoRoot)\bin\sbom 20 | 21 | 22 | 23 | 26 | / 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Controls/EditorTooltip.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 28 | 29 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/Unpkg/UnpkgLibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Web.LibraryManager.Contracts; 9 | 10 | namespace Microsoft.Web.LibraryManager.Providers.Unpkg 11 | { 12 | internal class UnpkgLibraryGroup : ILibraryGroup 13 | { 14 | private readonly INpmPackageInfoFactory _infoFactory; 15 | 16 | public UnpkgLibraryGroup(INpmPackageInfoFactory infoFactory, string displayName, string description = null) 17 | { 18 | _infoFactory = infoFactory; 19 | DisplayName = displayName; 20 | Description = description; 21 | } 22 | 23 | public string DisplayName { get; } 24 | 25 | public string Description { get; } 26 | 27 | public async Task> GetLibraryVersions(CancellationToken cancellationToken) 28 | { 29 | NpmPackageInfo npmPackageInfo = await _infoFactory.GetPackageInfoAsync(DisplayName, CancellationToken.None); 30 | 31 | if (npmPackageInfo != null) 32 | { 33 | return npmPackageInfo.Versions 34 | .OrderByDescending(v => v) 35 | .Select(semanticVersion => semanticVersion.ToString()) 36 | .ToList(); 37 | } 38 | 39 | return Enumerable.Empty(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/ErrorList/DisplayError.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.Imaging; 5 | using Microsoft.VisualStudio.Imaging.Interop; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.ErrorList 9 | { 10 | internal class DisplayError 11 | { 12 | public DisplayError(IError error) 13 | { 14 | ErrorCode = error.Code; 15 | Description = error.Message; 16 | } 17 | 18 | /// The error code is displayed in the Error List. 19 | public string ErrorCode { get; } 20 | 21 | /// A short description of the error. 22 | public string Description { get; } 23 | 24 | #pragma warning disable CA1308 // Normalize strings to uppercase 25 | // Reason: we prefer the URLs to be lowercase. 26 | /// A URL pointing to documentation about the error. 27 | public string HelpLink => string.Format(Constants.ErrorCodeLink, ErrorCode.ToLowerInvariant()); 28 | #pragma warning restore CA1308 // Normalize strings to uppercase 29 | 30 | /// The line number containing the error. 31 | public int Line { get; set; } 32 | 33 | /// The column number containing the error. 34 | public int Column { get; set; } 35 | 36 | public ImageMoniker Moniker => KnownMonikers.StatusWarning; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/LibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Microsoft.Web.LibraryManager.Mocks 10 | { 11 | /// 12 | /// A mock of the interface. 13 | /// 14 | /// 15 | public class LibraryGroup : ILibraryGroup 16 | { 17 | /// 18 | /// The user facing display name of the library. 19 | /// 20 | public virtual string DisplayName { get; set; } 21 | 22 | /// 23 | /// The description of the library. 24 | /// 25 | public virtual string Description { get; set; } 26 | 27 | /// 28 | /// Gets a list of IDs for the different versions of the library. 29 | /// 30 | /// A token that allows cancellation of the operation. 31 | /// 32 | /// A list of library IDs used to display library information to the user. 33 | /// 34 | public virtual Task> GetLibraryVersions(CancellationToken cancellationToken) 35 | { 36 | string[] ids = { "test" }; 37 | return Task.FromResult>(ids); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/libman/IHostEnvironment.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using Microsoft.Web.LibraryManager.Tools.Contracts; 6 | 7 | namespace Microsoft.Web.LibraryManager.Tools 8 | { 9 | /// 10 | /// Libman host environment 11 | /// 12 | internal interface IHostEnvironment 13 | { 14 | /// 15 | /// Provides a input reader to get user input. 16 | /// 17 | IInputReader InputReader { get; set; } 18 | 19 | /// 20 | /// Provides a logger to display messages to user. 21 | /// 22 | ILogger Logger { get; set; } 23 | 24 | /// 25 | /// Provides the host interactions to expose host specific operations. 26 | /// 27 | IHostInteractionInternal HostInteraction { get; set; } 28 | 29 | /// 30 | /// Provides Environment Settings for libman operations. 31 | /// 32 | EnvironmentSettings EnvironmentSettings { get; } 33 | 34 | /// 35 | /// Directory where 'libman' global tool is installed. 36 | /// 37 | string ToolInstallationDir { get; } 38 | 39 | /// 40 | /// Allows updating the working directory for library. 41 | /// 42 | /// 43 | void UpdateWorkingDirectory(string directory); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/TestUtils.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | 7 | namespace Microsoft.Web.LibraryManager.Test 8 | { 9 | internal static class TestUtils 10 | { 11 | public static void DeleteDirectoryWithRetries(string projectFolder) 12 | { 13 | int retries = 3; 14 | 15 | while (retries > 0) 16 | { 17 | try 18 | { 19 | DeleteDirectory(projectFolder); 20 | } 21 | catch 22 | { 23 | } 24 | 25 | Thread.Sleep(10); 26 | retries--; 27 | } 28 | } 29 | 30 | public static void DeleteDirectory(string projectFolder) 31 | { 32 | if (!Directory.Exists(projectFolder)) 33 | { 34 | return; 35 | } 36 | 37 | string[] files = Directory.GetFiles(projectFolder); 38 | string[] dirs = Directory.GetDirectories(projectFolder); 39 | 40 | foreach (string file in files) 41 | { 42 | File.SetAttributes(file, FileAttributes.Normal); 43 | File.Delete(file); 44 | } 45 | 46 | foreach (string dir in dirs) 47 | { 48 | DeleteDirectory(dir); 49 | } 50 | 51 | Directory.Delete(projectFolder, true); 52 | 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /common/tools/VsctToXliff/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("VsctToXliff")] 8 | [assembly: AssemblyDescription("Tool to generate Xliff files from vsct files, and generate localized vsct files.")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Microsoft")] 11 | [assembly: AssemblyProduct("VsctToXliff")] 12 | [assembly: AssemblyCopyright("Copyright © Microsoft 2016")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("bbf7fd3f-26ba-4f6c-8485-f221cca1cf6a")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/RestoreTests.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Microsoft.Web.LibraryManager.Build.IntegrationTest; 11 | 12 | [TestClass] 13 | public class RestoreTests : BuildTestBase 14 | { 15 | [TestMethod] 16 | public async Task Restore_LibraryWithFileMapping_NamedFiles() 17 | { 18 | string manifest = """ 19 | { 20 | "version": "3.0", 21 | "defaultProvider": "jsdelivr", 22 | "libraries": [ 23 | { 24 | "library": "jquery@3.6.0", 25 | "destination": "wwwroot/lib/jquery", 26 | "fileMappings": [ 27 | { 28 | "files": [ 29 | "dist/jquery.min.js", 30 | "dist/jquery.min.map" 31 | ] 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | """; 38 | await CreateManifestFileAsync(manifest); 39 | 40 | await RunDotnetCommandLineAsync("build", TestProjectDirectory); 41 | 42 | AssertFileExists("wwwroot/lib/jquery/dist/jquery.min.js"); 43 | AssertFileExists("wwwroot/lib/jquery/dist/jquery.min.map"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Commands/CommandTable/LocalizationFiles/VSCommandTable.en.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Client-Side &Library... 8 | 9 | 10 | Restore Client-Side &Libraries 11 | 12 | 13 | &Clean Client-Side Libraries 14 | 15 | 16 | Enable Restore Client-Side Libraries on Build... 17 | 18 | 19 | &Manage Client-Side Libraries... 20 | 21 | 22 | &Restore Client-Side Libraries 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/Library.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.Web.LibraryManager.Contracts; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.Web.LibraryManager.Mocks 8 | { 9 | /// 10 | /// A mock class. 11 | /// 12 | /// 13 | public class Library : ILibrary 14 | { 15 | /// 16 | /// The string that lets the uniquely identify the specific library. 17 | /// 18 | public virtual string Name { get; set; } 19 | 20 | /// 21 | /// The unique ID of the provider. 22 | /// 23 | public virtual string ProviderId { get; set; } 24 | 25 | /// 26 | /// The version of the library. 27 | /// 28 | public virtual string Version { get; set; } 29 | 30 | /// 31 | /// A list of files and a bool value to determine if the file is suggested as a default file for this library. 32 | /// 33 | public virtual IReadOnlyDictionary Files { get; set; } 34 | 35 | /// 36 | /// Returns a that represents this instance. 37 | /// 38 | /// 39 | /// A that represents this instance. 40 | /// 41 | public override string ToString() 42 | { 43 | return Name; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/Caching/ICacheService.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Web.LibraryManager.Contracts.Caching 8 | { 9 | /// 10 | /// Contract for defining the operations for a caching layer 11 | /// 12 | public interface ICacheService 13 | { 14 | /// 15 | /// Gets the contents from the specified URL, or if the request fails then from a locally cached copy 16 | /// 17 | /// The URL to request 18 | /// The locally cached file 19 | /// Cancellation token 20 | /// 21 | Task GetContentsFromUriWithCacheFallbackAsync(string url, string cacheFile, CancellationToken cancellationToken); 22 | 23 | /// 24 | /// Gets the contents of a local cache file, or if the file does not exist then requests it from the specified URL 25 | /// 26 | /// The locally cached file 27 | /// The URL to request 28 | /// Cancellation token 29 | /// 30 | /// Thrown when the file doesn't exist and the resource download fails 31 | Task GetContentsFromCachedFileWithWebRequestFallbackAsync(string cacheFile, string url, CancellationToken cancellationToken); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/LibraryManager.Build.IntegrationTest/Microsoft.Web.LibraryManager.Build.IntegrationTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM) 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | PreserveNewest 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/LibraryManager/Providers/jsDelivr/JsDelivrLibraryGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Web.LibraryManager.Contracts; 9 | using Microsoft.Web.LibraryManager.Providers.Unpkg; 10 | 11 | namespace Microsoft.Web.LibraryManager.Providers.jsDelivr 12 | { 13 | internal class JsDelivrLibraryGroup : ILibraryGroup 14 | { 15 | private readonly INpmPackageInfoFactory _infoCache; 16 | 17 | public JsDelivrLibraryGroup(INpmPackageInfoFactory infoCache, string displayName, string description = null) 18 | { 19 | _infoCache = infoCache; 20 | DisplayName = displayName; 21 | Description = description; 22 | } 23 | 24 | public string DisplayName { get; } 25 | 26 | public string Description { get; } 27 | 28 | public async Task> GetLibraryVersions(CancellationToken cancellationToken) 29 | { 30 | 31 | if (!JsDelivrCatalog.IsGitHub(DisplayName)) 32 | { 33 | NpmPackageInfo npmPackageInfo = await _infoCache.GetPackageInfoAsync(DisplayName, CancellationToken.None); 34 | 35 | if (npmPackageInfo != null) 36 | { 37 | return npmPackageInfo.Versions 38 | .OrderByDescending(v => v) 39 | .Select(v => v.ToString()) 40 | .ToList(); 41 | } 42 | } 43 | 44 | return Enumerable.Empty(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/libman.IntegrationTest/libman.IntegrationTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(NetCoreTFM) 4 | Microsoft.Web.LibraryManager.Cli.IntegrationTest 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/ExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | using Microsoft.Web.LibraryManager.Helpers; 8 | using Microsoft.Web.LibraryManager.Mocks; 9 | 10 | namespace Microsoft.Web.LibraryManager.Test 11 | { 12 | [TestClass] 13 | public class ExtensionsTest 14 | { 15 | [TestMethod] 16 | public void TestGetInvalidFiles() 17 | { 18 | var files = new Dictionary 19 | { 20 | ["abc.js"] = true, 21 | ["xyz.js"] = false 22 | }; 23 | 24 | ILibrary library = new Library() 25 | { 26 | Files = files, 27 | Name = "DummyLibrary", 28 | ProviderId = "DummyProvider" 29 | }; 30 | 31 | IReadOnlyList invalidFiles = Extensions.GetInvalidFiles(library, null); 32 | 33 | Assert.AreEqual(0, invalidFiles.Count); 34 | 35 | var filesToCheck = new List() 36 | { 37 | "abc.js", 38 | "xyz.js" 39 | }; 40 | 41 | invalidFiles = Extensions.GetInvalidFiles(library, filesToCheck); 42 | 43 | Assert.AreEqual(0, invalidFiles.Count); 44 | 45 | filesToCheck.Add("def"); 46 | invalidFiles = Extensions.GetInvalidFiles(library, filesToCheck); 47 | 48 | Assert.AreEqual(1, invalidFiles.Count); 49 | 50 | Assert.AreEqual("def", invalidFiles[0]); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/ILibraryInstallationState.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.Web.LibraryManager.Contracts 7 | { 8 | /// 9 | /// An interface that describes the library to install. 10 | /// 11 | public interface ILibraryInstallationState 12 | { 13 | /// 14 | /// The name of the library. 15 | /// 16 | string Name { get; } 17 | 18 | /// 19 | /// Version of the library. 20 | /// 21 | string Version { get; } 22 | 23 | /// 24 | /// The unique identifier of the provider. 25 | /// 26 | string ProviderId { get; } 27 | 28 | /// 29 | /// The list of file names to install 30 | /// 31 | IReadOnlyList Files { get; } 32 | 33 | /// 34 | /// List of mappings of a portion of library assets to a unique destination. 35 | /// 36 | IReadOnlyList FileMappings { get; } 37 | 38 | /// 39 | /// The path relative to the working directory to copy the files to. 40 | /// 41 | string DestinationPath { get; } 42 | 43 | /// 44 | /// Indicates whether the library is using the default destination 45 | /// 46 | bool IsUsingDefaultDestination { get; } 47 | 48 | /// 49 | /// Indicates whether the library is using the default provider 50 | /// 51 | bool IsUsingDefaultProvider { get; } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/ErrorTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.Web.LibraryManager.Contracts; 6 | using Microsoft.Web.LibraryManager.Mocks; 7 | 8 | namespace Microsoft.Web.LibraryManager.Test 9 | { 10 | [TestClass] 11 | public class ErrorTest 12 | { 13 | [TestMethod] 14 | public void Constructor() 15 | { 16 | var error = new Mocks.Error("123", "abc"); 17 | 18 | Assert.AreEqual("123", error.Code); 19 | Assert.AreEqual("abc", error.Message); 20 | } 21 | 22 | [TestMethod] 23 | public void Predefined() 24 | { 25 | TestError(PredefinedErrors.UnknownException(), "LIB000"); 26 | TestError(PredefinedErrors.ProviderUnknown("_prov_"), "LIB001", "_prov_"); 27 | TestError(PredefinedErrors.UnableToResolveSource("_libid_", "_prov_"), "LIB002", "_libid_", "_prov_"); 28 | TestError(PredefinedErrors.CouldNotWriteFile("file.js"), "LIB003", "file.js"); 29 | TestError(PredefinedErrors.ManifestMalformed(), "LIB004"); 30 | TestError(PredefinedErrors.PathIsUndefined(), "LIB005"); 31 | TestError(PredefinedErrors.LibraryIdIsUndefined(), "LIB006"); 32 | TestError(PredefinedErrors.ProviderIsUndefined(), "LIB007"); 33 | } 34 | 35 | private void TestError(IError error, string code, params string[] pieces) 36 | { 37 | Assert.AreEqual(code, error.Code); 38 | 39 | foreach (string piece in pieces) 40 | { 41 | Assert.IsTrue(error.Message.Contains(piece)); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/Providers/Cdnjs/CdnjsProviderFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Web.LibraryManager.Contracts; 8 | using Microsoft.Web.LibraryManager.Mocks; 9 | using Microsoft.Web.LibraryManager.Providers.Cdnjs; 10 | 11 | namespace Microsoft.Web.LibraryManager.Test.Providers.Cdnjs 12 | { 13 | [TestClass] 14 | public class CdnjsProviderFactoryTest 15 | { 16 | private IHostInteraction _hostInteraction; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | string cacheFolder = Environment.ExpandEnvironmentVariables(@"%localappdata%\Microsoft\Library\"); 22 | string projectFolder = Path.Combine(Path.GetTempPath(), "LibraryManager"); 23 | _hostInteraction = new HostInteraction(projectFolder, cacheFolder); 24 | } 25 | 26 | [TestMethod] 27 | public void CreateProvider_Success() 28 | { 29 | var factory = new CdnjsProviderFactory(); 30 | IProvider provider = factory.CreateProvider(_hostInteraction); 31 | 32 | Assert.AreSame(_hostInteraction.WorkingDirectory, provider.HostInteraction.WorkingDirectory); 33 | Assert.AreSame(_hostInteraction.CacheDirectory, provider.HostInteraction.CacheDirectory); 34 | Assert.IsFalse(string.IsNullOrEmpty(provider.Id)); 35 | } 36 | 37 | [TestMethod, ExpectedException(typeof(ArgumentNullException))] 38 | public void CreateProvider_NullParameter() 39 | { 40 | var factory = new CdnjsProviderFactory(); 41 | IProvider provider = factory.CreateProvider(null); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/LibraryManager.Test/Providers/FileSystem/FileSystemProviderFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.IO; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Microsoft.Web.LibraryManager.Contracts; 8 | using Microsoft.Web.LibraryManager.Mocks; 9 | using Microsoft.Web.LibraryManager.Providers.FileSystem; 10 | 11 | namespace Microsoft.Web.LibraryManager.Test.Providers.Cdnjs 12 | { 13 | [TestClass] 14 | public class FileSystemProviderFactoryTest 15 | { 16 | private IHostInteraction _hostInteraction; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | string cacheFolder = Environment.ExpandEnvironmentVariables(@"%localappdata%\Microsoft\Library\"); 22 | string projectFolder = Path.Combine(Path.GetTempPath(), "LibraryManager"); 23 | _hostInteraction = new HostInteraction(projectFolder, cacheFolder); 24 | } 25 | 26 | [TestMethod] 27 | public void CreateProvider_Success() 28 | { 29 | var factory = new FileSystemProviderFactory(); 30 | IProvider provider = factory.CreateProvider(_hostInteraction); 31 | 32 | Assert.AreSame(_hostInteraction.WorkingDirectory, provider.HostInteraction.WorkingDirectory); 33 | Assert.AreSame(_hostInteraction.CacheDirectory, provider.HostInteraction.CacheDirectory); 34 | Assert.IsFalse(string.IsNullOrEmpty(provider.Id)); 35 | } 36 | 37 | [TestMethod, ExpectedException(typeof(ArgumentNullException))] 38 | public void CreateProvider_NullParameter() 39 | { 40 | var factory = new FileSystemProviderFactory(); 41 | IProvider provider = factory.CreateProvider(null); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(MSBuildThisFileDirectory) 4 | true 5 | $(RepoRoot)\bin\$(MSBuildProjectName) 6 | $(RepoRoot)\obj\$(MSBuildProjectName) 7 | $(RepoRoot)\bin\Microsoft.Web.LibraryManager.Vsix\$(Configuration) 8 | 9 | Microsoft 10 | Microsoft Corp. 11 | Create custom providers for the Visual Studio Library Manager 12 | © Microsoft Corporation. All rights reserved. 13 | 14 | Microsoft.Web.LibraryManager 15 | https://github.com/aspnet/LibraryManager 16 | PackageIcon.png 17 | License.txt 18 | https://github.com/aspnet/LibraryManager 19 | $(RepoRoot)\artifacts\$(Configuration) 20 | true 21 | true 22 | net481 23 | net8.0 24 | Latest 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/libman/Commands/RestoreCommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Microsoft.Web.LibraryManager.Contracts; 10 | 11 | namespace Microsoft.Web.LibraryManager.Tools.Commands 12 | { 13 | /// 14 | /// Defines the libman restore command. 15 | /// 16 | internal class RestoreCommand : BaseCommand 17 | { 18 | public RestoreCommand(IHostEnvironment hostEnvironment, bool throwOnUnexpectedArg = true) 19 | : base(throwOnUnexpectedArg, "restore", Resources.Text.RestoreCommandDesc, hostEnvironment) 20 | { 21 | } 22 | 23 | public override string Remarks => Resources.Text.RestoreCommandRemarks; 24 | 25 | protected override async Task ExecuteInternalAsync() 26 | { 27 | var sw = new Stopwatch(); 28 | sw.Start(); 29 | 30 | Manifest manifest = await GetManifestAsync(); 31 | IEnumerable> validationResults = await manifest.GetValidationResultsAsync(CancellationToken.None); 32 | 33 | if (!validationResults.All(r => r.Success)) 34 | { 35 | sw.Stop(); 36 | LogErrors(validationResults.SelectMany(r => r.Errors)); 37 | 38 | return (int)ExitCode.Failure; 39 | } 40 | 41 | IList> results = await ManifestRestorer.RestoreManifestAsync(manifest, Logger, CancellationToken.None); 42 | sw.Stop(); 43 | LogResultsSummary(results, OperationType.Restore, sw.Elapsed); 44 | 45 | return results.Any(r => r.Errors.Any()) ? (int)ExitCode.Failure : (int)ExitCode.Success; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/LibraryManager/Cache/CacheFileMetadata.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Web.LibraryManager.Cache 7 | { 8 | /// 9 | /// Holds information for pair: source, destination for a resource to be cached 10 | /// 11 | public class CacheFileMetadata : IEquatable 12 | { 13 | /// 14 | /// Create a new CacheFileMetadata 15 | /// 16 | /// The URI from where the file originated 17 | /// The path where the file is to be cached 18 | public CacheFileMetadata(string source, string cacheFile) 19 | { 20 | DestinationPath = cacheFile; 21 | Source = source; 22 | } 23 | 24 | /// 25 | /// Path for cache file to be written 26 | /// 27 | public string DestinationPath { get; private set; } 28 | 29 | /// 30 | /// Source for the cache's contents 31 | /// 32 | public string Source { get; private set; } 33 | 34 | /// 35 | public bool Equals(CacheFileMetadata other) 36 | { 37 | return DestinationPath == other?.DestinationPath && Source == other?.Source; 38 | } 39 | 40 | /// 41 | public override bool Equals(object obj) 42 | { 43 | return Equals(obj as CacheFileMetadata); 44 | } 45 | 46 | /// 47 | public override int GetHashCode() 48 | { 49 | #if NET8_0_OR_GREATER 50 | return DestinationPath.GetHashCode(StringComparison.Ordinal); // this should be a unique identifier 51 | #else 52 | return DestinationPath.GetHashCode(); // this should be a unique identifier 53 | #endif 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/LibraryManager.Contracts/ResourceDownloadException.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using Microsoft.Web.LibraryManager.Contracts.Resources; 6 | 7 | namespace Microsoft.Web.LibraryManager.Contracts 8 | { 9 | /// 10 | /// An exception to be thrown when a fails to be downloaded 11 | /// 12 | /// 13 | /// 14 | [Serializable] 15 | public class ResourceDownloadException : Exception 16 | { 17 | /// 18 | /// Creates a new instance of the . 19 | /// 20 | /// The url for the resource. 21 | public ResourceDownloadException(string url) 22 | : this(string.Format(Text.ErrorUnableToDownloadResource, url), null) 23 | { 24 | } 25 | 26 | /// 27 | /// Creates a new instance of the . 28 | /// 29 | /// The url for the resource. 30 | /// Inner exception 31 | public ResourceDownloadException(string url, Exception innerException) 32 | : base(string.Format(Text.ErrorUnableToDownloadResource, url), innerException) 33 | { 34 | Url = url; 35 | } 36 | 37 | /// 38 | /// The Url for the of the invalid library 39 | /// 40 | public string Url { get; } 41 | 42 | /// 43 | /// Serialization constructor for this exception type. 44 | /// 45 | protected ResourceDownloadException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) 46 | : this(serializationInfo?.GetString(nameof(Url))) 47 | { 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/libman/ILibraryInstallationStateExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Text; 6 | using Microsoft.Web.LibraryManager.Contracts; 7 | using Microsoft.Web.LibraryManager.LibraryNaming; 8 | 9 | namespace Microsoft.Web.LibraryManager.Tools 10 | { 11 | /// 12 | /// Extension Methods for 13 | /// 14 | internal static class ILibraryInstallationStateExtensions 15 | { 16 | /// 17 | /// Returns a string that can be used to display the library information on the console. 18 | /// 19 | /// 20 | /// 21 | public static string ToConsoleDisplayString(this ILibraryInstallationState libraryInstallationState) 22 | { 23 | if (libraryInstallationState == null) 24 | { 25 | throw new ArgumentNullException(nameof(libraryInstallationState)); 26 | } 27 | 28 | string libraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId( 29 | libraryInstallationState.Name, 30 | libraryInstallationState.Version, 31 | libraryInstallationState.ProviderId); 32 | 33 | var sb = new StringBuilder("{"+libraryId); 34 | 35 | if (!string.IsNullOrEmpty(libraryInstallationState.ProviderId)) 36 | { 37 | sb.Append(", " + libraryInstallationState.ProviderId); 38 | } 39 | 40 | if (!string.IsNullOrEmpty(libraryInstallationState.DestinationPath)) 41 | { 42 | sb.Append(", " + libraryInstallationState.DestinationPath); 43 | } 44 | 45 | sb.Append('}'); 46 | 47 | return sb.ToString(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Converters/CheckBoxAutomationNameConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Globalization; 6 | using System.Windows.Data; 7 | using Microsoft.Web.LibraryManager.Vsix.Resources; 8 | 9 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Converters 10 | { 11 | internal class CheckBoxAutomationNameConverter : IMultiValueConverter 12 | { 13 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | ValidateInputs(values); 16 | 17 | if (values[2] == null) 18 | { 19 | return string.Format(Text.Indeterminate, (string)values[0], (string)values[1]); 20 | } 21 | 22 | bool isChecked = (bool)values[2]; 23 | 24 | if (isChecked) 25 | { 26 | return string.Format(Text.Checked, (string)values[0], (string)values[1]); 27 | } 28 | else 29 | { 30 | return string.Format(Text.UnChecked, (string)values[0], (string)values[1]); 31 | } 32 | } 33 | 34 | private void ValidateInputs(object[] values) 35 | { 36 | if (values == null) 37 | { 38 | throw new ArgumentNullException(nameof(values)); 39 | } 40 | 41 | if (values.Length != 3) 42 | { 43 | throw new ArgumentOutOfRangeException(nameof(values), $"{nameof(values)} length must be 3"); 44 | } 45 | 46 | if (!(values[0] is string)) 47 | { 48 | throw new ArgumentException(string.Format("{0} is not a string", values[0])); 49 | } 50 | } 51 | 52 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 53 | { 54 | throw new NotSupportedException(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/LibraryManager.Mocks/WebRequestHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using Microsoft.Web.LibraryManager.Contracts; 11 | 12 | namespace Microsoft.Web.LibraryManager.Mocks 13 | { 14 | /// 15 | /// Public Mock class for unit testing 16 | /// 17 | public class WebRequestHandler : IWebRequestHandler 18 | { 19 | private Dictionary _arrangedResponses = new Dictionary(StringComparer.OrdinalIgnoreCase); 20 | 21 | /// 22 | /// Returns a Stream for testing purposes 23 | /// 24 | /// 25 | /// 26 | /// 27 | public Task GetStreamAsync(string url, CancellationToken cancellationToken) 28 | { 29 | UnicodeEncoding uniEncoding = new UnicodeEncoding(); 30 | string responseText = "Stream content for test"; 31 | if (_arrangedResponses.ContainsKey(url)) 32 | { 33 | responseText = _arrangedResponses[url]; 34 | } 35 | 36 | byte[] content = Encoding.Default.GetBytes(responseText); 37 | 38 | return Task.FromResult( new MemoryStream(content)); 39 | } 40 | 41 | /// 42 | /// Register a prerecorded response for a specified URL 43 | /// 44 | /// 45 | /// 46 | /// 47 | public WebRequestHandler ArrangeResponse(string url, string responseContent) 48 | { 49 | _arrangedResponses.Add(url, responseContent); 50 | 51 | return this; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/libman/Commands/CleanCommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using Microsoft.Web.LibraryManager.Contracts; 11 | 12 | namespace Microsoft.Web.LibraryManager.Tools.Commands 13 | { 14 | /// 15 | /// Defines the clean command to allow user to clean the files installed via libman. 16 | /// 17 | internal class CleanCommand : BaseCommand 18 | { 19 | public CleanCommand(IHostEnvironment hostEnvironment, bool throwOnUnexpectedArg = true) 20 | : base(throwOnUnexpectedArg, "clean", Resources.Text.CleanCommandDesc, hostEnvironment) 21 | { 22 | } 23 | 24 | public override string Remarks => Resources.Text.CleanCommandRemarks; 25 | 26 | protected override async Task ExecuteInternalAsync() 27 | { 28 | var sw = new Stopwatch(); 29 | sw.Start(); 30 | 31 | Manifest manifest = await GetManifestAsync(); 32 | Task deleteFileAction(IEnumerable s) => HostInteractions.DeleteFilesAsync(s, CancellationToken.None); 33 | IEnumerable> validationResults = await manifest.GetValidationResultsAsync(CancellationToken.None); 34 | 35 | if (!validationResults.All(r => r.Success)) 36 | { 37 | sw.Stop(); 38 | LogErrors(validationResults.SelectMany(r => r.Errors)); 39 | 40 | return 0; 41 | } 42 | 43 | IEnumerable> results = await manifest.CleanAsync(deleteFileAction, CancellationToken.None); 44 | sw.Stop(); 45 | LogResultsSummary(results, OperationType.Clean, sw.Elapsed); 46 | 47 | return 0; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Commands/CommandTable/LocalizationFiles/VSCommandTable.zh-Hans.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Client-Side &Library... 8 | 客户端库(&L)... 9 | 10 | 11 | Restore Client-Side &Libraries 12 | 还原客户端库(&L) 13 | 14 | 15 | &Clean Client-Side Libraries 16 | 清理客户端库(&C) 17 | 18 | 19 | Enable Restore Client-Side Libraries on Build... 20 | 在生成时启用“还原客户端库”... 21 | 22 | 23 | &Manage Client-Side Libraries... 24 | 管理客户端库(&M)... 25 | 26 | 27 | &Restore Client-Side Libraries 28 | 还原客户端库(&R) 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/libman/Commands/LibmanApp.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System.Diagnostics; 5 | using Microsoft.Extensions.CommandLineUtils; 6 | 7 | namespace Microsoft.Web.LibraryManager.Tools.Commands 8 | { 9 | /// 10 | /// Defines the libman command. 11 | /// Child commands: init, install, uninstall, restore, clean, cache, update 12 | /// 13 | internal class LibmanApp : BaseCommand 14 | { 15 | public LibmanApp(IHostEnvironment hostEnvironment, bool throwOnUnexpectedArg = true) 16 | : base(throwOnUnexpectedArg, "libman", Resources.Text.LibmanCommandDesc, hostEnvironment) 17 | { 18 | 19 | } 20 | 21 | public override BaseCommand Configure(CommandLineApplication parent = null) 22 | { 23 | base.Configure(parent); 24 | 25 | VersionOption("--version", GetVersion, null); 26 | 27 | Commands.Add(new InitCommand(HostEnvironment).Configure(this)); 28 | Commands.Add(new InstallCommand(HostEnvironment).Configure(this)); 29 | Commands.Add(new UninstallCommand(HostEnvironment).Configure(this)); 30 | Commands.Add(new RestoreCommand(HostEnvironment).Configure(this)); 31 | Commands.Add(new CleanCommand(HostEnvironment).Configure(this)); 32 | Commands.Add(new CacheCommand(HostEnvironment).Configure(this)); 33 | Commands.Add(new UpdateCommand(HostEnvironment).Configure(this)); 34 | Commands.Add(new ConfigCommand(HostEnvironment).Configure(this)); 35 | 36 | // These are shown by child commands. 37 | RootDir.ShowInHelpText = false; 38 | Verbosity.ShowInHelpText = false; 39 | 40 | return this; 41 | } 42 | 43 | private string GetVersion() 44 | { 45 | var info = FileVersionInfo.GetVersionInfo(GetType().Assembly.Location); 46 | return info.ProductVersion; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Commands/CommandTable/LocalizationFiles/VSCommandTable.zh-Hant.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Client-Side &Library... 8 | 用戶端程式庫(&L)... 9 | 10 | 11 | Restore Client-Side &Libraries 12 | 還原用戶端程式庫(&L) 13 | 14 | 15 | &Clean Client-Side Libraries 16 | 清理用戶端程式庫(&C) 17 | 18 | 19 | Enable Restore Client-Side Libraries on Build... 20 | 允許在建置時還原用戶端程式庫... 21 | 22 | 23 | &Manage Client-Side Libraries... 24 | 管理用戶端程式庫(&M)... 25 | 26 | 27 | &Restore Client-Side Libraries 28 | 還原用戶端程式庫(&R) 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Commands/CommandTable/LocalizationFiles/VSCommandTable.ko.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Client-Side &Library... 8 | 클라이언트 쪽 라이브러리(&L)... 9 | 10 | 11 | Restore Client-Side &Libraries 12 | 클라이언트 쪽 라이브러리 복원(&L) 13 | 14 | 15 | &Clean Client-Side Libraries 16 | 클라이언트 쪽 라이브러리 정리(&C) 17 | 18 | 19 | Enable Restore Client-Side Libraries on Build... 20 | 빌드 시 클라이언트 쪽 라이브러리 복원 사용... 21 | 22 | 23 | &Manage Client-Side Libraries... 24 | 클라이언트 쪽 라이브러리 관리(&M)... 25 | 26 | 27 | &Restore Client-Side Libraries 28 | 클라이언트 쪽 라이브러리 복원(&R) 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/UI/Models/TargetLocationViewModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using Microsoft.Web.LibraryManager.Vsix.Search; 7 | 8 | namespace Microsoft.Web.LibraryManager.Vsix.UI.Models 9 | { 10 | internal class TargetLocationViewModel : SearchTextBoxViewModel 11 | { 12 | private readonly string _baseFolder; 13 | private readonly LibraryNameBinding _libraryNameBinding; 14 | private string _lastSuggestedTargetLocation; 15 | 16 | public TargetLocationViewModel(string baseFolder, 17 | LibraryNameBinding libraryNameBinding, 18 | ISearchService searchService) 19 | : base(searchService, baseFolder, null, automationName: Resources.Text.TargetLocation) 20 | { 21 | _baseFolder = baseFolder ?? string.Empty; 22 | _lastSuggestedTargetLocation = baseFolder ?? string.Empty; 23 | SearchText = baseFolder; 24 | 25 | _libraryNameBinding = libraryNameBinding ?? throw new ArgumentNullException(nameof(libraryNameBinding)); 26 | _libraryNameBinding.PropertyChanged += LibraryNameChanged; 27 | } 28 | 29 | private void LibraryNameChanged(object sender, PropertyChangedEventArgs e) 30 | { 31 | string targetLibrary = _libraryNameBinding.LibraryName; 32 | 33 | if (!string.IsNullOrEmpty(targetLibrary)) 34 | { 35 | if (SearchText.Equals(_lastSuggestedTargetLocation, StringComparison.OrdinalIgnoreCase)) 36 | { 37 | // remove any trailing forward slashes, because we probably put them there 38 | targetLibrary = targetLibrary.TrimEnd('/'); 39 | 40 | SearchText = _lastSuggestedTargetLocation = _baseFolder + targetLibrary + '/'; 41 | OnExternalTextChange(); 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/LibraryManager.Vsix/Commands/CommandTable/LocalizationFiles/VSCommandTable.ja.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Client-Side &Library... 8 | クライアント側のライブラリ(&L)... 9 | 10 | 11 | Restore Client-Side &Libraries 12 | クライアント側のライブラリを復元する(&L) 13 | 14 | 15 | &Clean Client-Side Libraries 16 | クライアント側のライブラリをクリーンアップする(&C) 17 | 18 | 19 | Enable Restore Client-Side Libraries on Build... 20 | ビルド時にクライアント側のライブラリの復元を有効にする... 21 | 22 | 23 | &Manage Client-Side Libraries... 24 | クライアント側のライブラリを管理する(&M)... 25 | 26 | 27 | &Restore Client-Side Libraries 28 | クライアント側のライブラリを復元する(&R) 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /test/LibraryManager.Vsix.Test/Search/ProviderCatalogSearchServiceTests.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | using Microsoft.Web.LibraryManager.Contracts; 9 | using Microsoft.Web.LibraryManager.Vsix.Search; 10 | 11 | namespace Microsoft.Web.LibraryManager.Vsix.Test.Search 12 | { 13 | using Mocks = LibraryManager.Mocks; 14 | 15 | [TestClass] 16 | public class ProviderCatalogSearchServiceTests 17 | { 18 | private readonly IProvider _testProvider = new Mocks.Provider(new Mocks.HostInteraction()) 19 | { 20 | Catalog = new Mocks.LibraryCatalog() 21 | .AddLibrary(new Mocks.Library { Name = "aardvark", Version = "2.0" }) 22 | .AddLibrary(new Mocks.Library { Name = "anteater", Version = "1.0" }) 23 | .AddLibrary(new Mocks.Library { Name = "platypus", Version = "1.2" }), 24 | }; 25 | 26 | [TestMethod] 27 | [ExpectedException(typeof(ArgumentNullException))] 28 | public void Ctor_NullLookup_Throws() 29 | { 30 | new ProviderCatalogSearchService(null); 31 | } 32 | 33 | [TestMethod] 34 | public async Task PerformSearch_LookupYieldsNullProvider_ReturnsEmptyCompletionSet() 35 | { 36 | var testObj = new ProviderCatalogSearchService(() => null); 37 | 38 | CompletionSet result = await testObj.PerformSearch("", 0); 39 | 40 | Assert.AreEqual(default(CompletionSet), result); 41 | } 42 | 43 | [TestMethod] 44 | public async Task PerformSearch_ProviderIsNotNull_ReturnsProviderResults() 45 | { 46 | var testObj = new ProviderCatalogSearchService(() => _testProvider); 47 | 48 | CompletionSet result = await testObj.PerformSearch("", 0); 49 | 50 | Assert.IsNotNull(result); 51 | Assert.AreEqual(3, result.Completions.Count()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/LibraryManager/Utilities/FileGlobbingUtility.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using Minimatch; 8 | 9 | namespace Microsoft.Web.LibraryManager.Utilities 10 | { 11 | internal class FileGlobbingUtility 12 | { 13 | private static readonly char[] GlobIndicatorCharacters = "*?[".ToCharArray(); 14 | 15 | public static IEnumerable ExpandFileGlobs(IEnumerable potentialGlobs, IEnumerable libraryFiles) 16 | { 17 | var finalSetOfFiles = new HashSet(); 18 | var negatedOptions = new Minimatch.Options { FlipNegate = true }; 19 | 20 | foreach (string potentialGlob in potentialGlobs) 21 | { 22 | // only process globs where we find them, otherwise it can get expensive 23 | if (potentialGlob.StartsWith("!", StringComparison.Ordinal)) 24 | { 25 | // Remove matches from the files list 26 | var filesToRemove = finalSetOfFiles.Where(f => Minimatcher.Check(f, potentialGlob, negatedOptions)).ToList(); 27 | foreach (string file in filesToRemove) 28 | { 29 | finalSetOfFiles.Remove(file); 30 | } 31 | } 32 | else if (potentialGlob.IndexOfAny(GlobIndicatorCharacters) >= 0) 33 | { 34 | IEnumerable filterResult = libraryFiles.Where(f => Minimatcher.Check(f, potentialGlob)); 35 | if (filterResult.Any()) 36 | { 37 | finalSetOfFiles.UnionWith(filterResult); 38 | } 39 | } 40 | else 41 | { 42 | // not a glob pattern, so just include the file literally 43 | finalSetOfFiles.Add(potentialGlob); 44 | } 45 | } 46 | 47 | return finalSetOfFiles; 48 | } 49 | } 50 | } 51 | --------------------------------------------------------------------------------