protected override async Task LoadComponentsAsync(CancellationToken cancellationToken) { var workspace = ComponentModel.GetService <VisualStudioWorkspace>(); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // Ensure the nuget package services are initialized. This initialization pass will only run // once our package is loaded indirectly through a legacy COM service we proffer (like the legacy project systems // loading us) or through something like the IVsEditorFactory or a debugger service. Right now it's fine // we only load this there, because we only use these to provide code fixes. But we only show code fixes in // open files, and so you would have had to open a file, which loads the editor factory, which loads our package, // which will run this. // // This code will have to be moved elsewhere once any of that load path is changed such that the package // no longer loads if a file is opened. _packageInstallerService = workspace.Services.GetService <IPackageInstallerService>() as PackageInstallerService; _symbolSearchService = workspace.Services.GetService <ISymbolSearchService>() as VisualStudioSymbolSearchService; _packageInstallerService?.Connect(this.RoslynLanguageName); _symbolSearchService?.Connect(this.RoslynLanguageName); }
protected override async Task LoadComponentsAsync(CancellationToken cancellationToken) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // Ensure the nuget package services are initialized after we've loaded // the solution. _packageInstallerService = Workspace.Services.GetService <IPackageInstallerService>() as PackageInstallerService; _symbolSearchService = Workspace.Services.GetService <ISymbolSearchService>() as VisualStudioSymbolSearchService; _packageInstallerService?.Connect(this.RoslynLanguageName); _symbolSearchService?.Connect(this.RoslynLanguageName); }
public void IsPackageTest() { //Arrange var TestString = "A,1"; //Act var packageInstallerService = new PackageInstallerService(); var TestResult = packageInstallerService.IsPackage(TestString); //Assert Assert.IsTrue(TestResult); }
protected override void LoadComponentsInUIContext() { ForegroundObject.AssertIsForeground(); // Ensure the nuget package services are initialized after we've loaded // the solution. _packageInstallerService = Workspace.Services.GetService <IPackageInstallerService>() as PackageInstallerService; _symbolSearchService = Workspace.Services.GetService <ISymbolSearchService>() as SymbolSearchService; _packageInstallerService?.Connect(this.RoslynLanguageName); _symbolSearchService?.Connect(this.RoslynLanguageName); }
protected override void LoadComponentsInUIContext() { ForegroundObject.AssertIsForeground(); // Ensure the nuget package services are initialized after we've loaded // the solution. _packageInstallerService = Workspace.Services.GetService <IPackageInstallerService>() as PackageInstallerService; _symbolSearchService = Workspace.Services.GetService <ISymbolSearchService>() as VisualStudioSymbolSearchService; _packageInstallerService?.Connect(this.RoslynLanguageName); _symbolSearchService?.Connect(this.RoslynLanguageName); HACK_AbstractCreateServicesOnUiThread.CreateServicesOnUIThread(ComponentModel, RoslynLanguageName); }
static void Main(string[] args) { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .Build(); var PackageInstallerService = new PackageInstallerService(); var InputFileLocation = config["inputFileLocation"]; var OutputFileLocation = config["outputFileLocation"]; LogFileLocation = config["logFileLocation"]; var InstallLocation = config["installLocation"]; try { //Secure directories for files MakeLocationIfNotExist(InputFileLocation); MakeLocationIfNotExist(OutputFileLocation); MakeLocationIfNotExist(LogFileLocation); MakeLocationIfNotExist(LogFileLocation); Installations = new List <Installation>(); //Enumerate files foreach (var file in GetTextFilesInDirectory(InputFileLocation)) { //Process file var installation = new Installation(); ProcessInputFile(file, installation, PackageInstallerService); Installations.Add(installation); } //Now that we have all the data, we want to organize it a little better. //Step 1 is to grab all packages to be installed. Step 2 is to assign the dormant dependencies from other installations to those packages if they exist. //LINQ is a wonderful tool for this. var PackagesToInstall = Installations.SelectMany(x => x.Packages); var Dependencies = PackagesToInstall.SelectMany(x => x.Dependencies); foreach (var dependency in Dependencies) { //Are there any dormant dependencies not yet mapped to these? If so, map them. var UnmappedDependencies = Installations .SelectMany(x => x.DormantDependencies) .Where(x => x.Name == dependency.Name && x.Version == dependency.Version); //Dreaded nested FOR loop n^2 algorithm...ugh! This is in lieu of ICollection<T> not implementing AddRange(); foreach (var unmappedDependency in UnmappedDependencies) { dependency.Dependencies.Add(unmappedDependency); } } foreach (var packageToInstall in PackagesToInstall) { RecursivelyInstallPackage(packageToInstall, InstallLocation); //Everything as far as dependencies should be mapped to these packages by now. } var OutputNumber = 0; foreach (var installation in Installations) { //Write to output files. var PassFail = installation.Packages.Any(x => !x.IsInstalled) ? "FAIL" : "PASS"; OutputNumber++; WriteTextIntoFile(OutputFileLocation, "output" + OutputNumber.ToString().PadLeft(3, '0') + ".txt", PassFail); } } catch (Exception e) { WriteTextIntoFile(LogFileLocation, "Error_" + Guid.NewGuid() + ".txt", e.ToString()); } }
//The goal of this method is to read the data into an object for organized processing. //It's long and ugly...if I had more time, then I'd brainstorm ways of refactoring it. static void ProcessInputFile(string filePath, Installation installation, PackageInstallerService packageInstallerService) { var FileText = ReadFileIntoText(filePath); var PackageCount = 0; var DependencyCount = 0; foreach (var line in FileText) { try //Attempt to read the line, but don't allow the entire list to be thrown out from one bad line, so try/catch each iteration. { //If the line is a number, then it's either the number of packages to install or the number of dependencies to handle. if (int.TryParse(line, out int LineConvertedToNumber)) { if (PackageCount == 0) { PackageCount = LineConvertedToNumber; //This sort of acts as a boolean switch for the first line in the file, applied to the IF condition. } else { DependencyCount = LineConvertedToNumber; } } else { //This code block is reached when the line is either a package or a dependency list. //The quickest way forward, assuming a consistent format, is to look at the Count variables. //Either way, we are going to need to split the line into a string array. var LineArray = line.Split(","); if (PackageCount > 0) { //Validate that we are working with a package. //This Regex function will check to make sure there are two elements in LineArray, so using LineArray.Count() == 2 is redundant and less valid. if (!packageInstallerService.IsPackage(line)) { throw new Exception( "An invalid package was sent to the input file processor. Package count: " + PackageCount.ToString() + " Line: " + line); } //This line is going to be a package. var version = int.Parse(LineArray.ElementAt(1)); //We already know from the Regex above that this will be \d. var NewPackage = new Package(LineArray.ElementAt(0), version); installation.Packages.Add(NewPackage); //One of our primary packages is added. PackageCount--; //We subtract one package as it has been recorded for processing. continue; //Go to the next iteration since we are done with this line. } if (DependencyCount > 0) { //A package line will be in the format A,1...so that means there will only be one comma, whereas a dependency list will have multiple. if (!IsDependency(line)) { throw new Exception( "An invalid dependency list was sent to the input file processor. Package count: " + PackageCount.ToString() + " Line: " + line); } //LineArray will be a list of packages. //We need to look for the first package and append this dependency to that package. var ParentPackage = installation.Packages.FirstOrDefault(x => x.Name == LineArray.ElementAt(0) && x.Version == int.Parse(LineArray.ElementAt(1))); if (ParentPackage != null) { //Add dependencies to this package. Start at 2 because we skip the first package in the line as it is parent. for (var i = 2; i < LineArray.Count(); i += 2) { var NewDependency = new Package(LineArray.ElementAt(i), int.Parse(LineArray.ElementAt(i + 1))); ParentPackage.Dependencies.Add(NewDependency); } } else { //No parent package, just a dependency to track. var NewDependencyPackage = new Package(LineArray.ElementAt(0), int.Parse(LineArray.ElementAt(1))); for (var i = 2; i < LineArray.Count(); i += 2) { var NewDependency = new Package(LineArray.ElementAt(i), int.Parse(LineArray.ElementAt(i + 1))); NewDependencyPackage.Dependencies.Add(NewDependency); } installation.DormantDependencies.Add(NewDependencyPackage); } DependencyCount--; continue; } } } catch (Exception e) { WriteTextIntoFile(LogFileLocation, "Error_" + Guid.NewGuid() + ".txt", e.ToString()); } } }