public void ThrowsException_CannotFindMSBuildProjectFile() { var workspacePath = "for_workspace_finder/no_project_or_solution/"; var exceptionMessageStart = string.Format( Resources.Could_not_find_a_MSBuild_project_or_solution_file_in_0_Specify_which_to_use_with_the_workspace_argument, Path.Combine(ProjectsPath, workspacePath)).Replace('/', Path.DirectorySeparatorChar); var exception = Assert.Throws <FileNotFoundException>(() => MSBuildWorkspaceFinder.FindWorkspace(ProjectsPath, workspacePath)); Assert.StartsWith(exceptionMessageStart, exception.Message); }
public void ThrowsException_SolutionAndProjectAmbiguity() { var workspacePath = "for_workspace_finder/project_and_solution/"; var exceptionMessageStart = string.Format( Resources.Both_a_MSBuild_project_file_and_solution_file_found_in_0_Specify_which_to_use_with_the_workspace_argument, Path.Combine(ProjectsPath, workspacePath)).Replace('/', Path.DirectorySeparatorChar); var exception = Assert.Throws <FileNotFoundException>(() => MSBuildWorkspaceFinder.FindWorkspace(ProjectsPath, workspacePath)); Assert.Equal(exceptionMessageStart, exception.Message); }
public void ThrowsException_MultipleMSBuildSolutionFiles() { var workspacePath = "tests/projects/for_workspace_finder/multiple_solutions/"; var exceptionMessageStart = string.Format( Resources.Multiple_MSBuild_solution_files_found_in_0_Specify_which_to_use_with_the_workspace_option, Path.Combine(SolutionPath, workspacePath)).Replace('/', Path.DirectorySeparatorChar); var exception = Assert.Throws <FileNotFoundException>(() => MSBuildWorkspaceFinder.FindWorkspace(SolutionPath, workspacePath)); Assert.Equal(exceptionMessageStart, exception.Message); }
public void FindsProjectByFolder() { const string Path = "for_workspace_finder/single_project/"; var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(ProjectsPath, Path); var solutionFileName = System.IO.Path.GetFileName(workspacePath); Assert.Equal("single_project.csproj", solutionFileName); Assert.False(isSolution); }
public void FindsSolutionByFilePath() { const string Path = "for_workspace_finder/multiple_solutions/solution_b.sln"; var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(ProjectsPath, Path); var solutionFileName = System.IO.Path.GetFileName(workspacePath); Assert.Equal("solution_b.sln", solutionFileName); Assert.True(isSolution); }
public void FindsSolutionByFolder() { const string Path = "tests/projects/for_workspace_finder/single_solution/"; var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(SolutionPath, Path); var solutionFileName = System.IO.Path.GetFileName(workspacePath); Assert.Equal("single_solution.sln", solutionFileName); Assert.True(isSolution); }
public void FindsProjectByFilePath() { const string Path = "tests/projects/for_workspace_finder/multiple_projects/project_b.csproj"; var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(SolutionPath, Path); var solutionFileName = System.IO.Path.GetFileName(workspacePath); Assert.Equal("project_b.csproj", solutionFileName); Assert.False(isSolution); }
public static async Task <int> Run(string workspace, string verbosity, bool dryRun, IConsole console = null) { var serviceCollection = new ServiceCollection(); var logLevel = GetLogLevel(verbosity); ConfigureServices(serviceCollection, console, logLevel); var serviceProvider = serviceCollection.BuildServiceProvider(); var logger = serviceProvider.GetService <ILogger <Program> >(); var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; try { var workingDirectory = Directory.GetCurrentDirectory(); var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(workingDirectory, workspace); // To ensure we get the version of MSBuild packaged with the dotnet SDK used by the // workspace, use its directory as our working directory which will take into account // a global.json if present. var workspaceDirectory = Path.GetDirectoryName(workspacePath); MSBuildEnvironment.ApplyEnvironmentVariables(workspaceDirectory); MSBuildCoreLoader.LoadDotnetInstance(workspaceDirectory); return(await CodeFormatter.FormatWorkspaceAsync( logger, workspacePath, isSolution, logAllWorkspaceWarnings : logLevel == LogLevel.Trace, saveFormattedFiles : !dryRun, cancellationTokenSource.Token).ConfigureAwait(false)); } catch (FileNotFoundException fex) { logger.LogError(fex.Message); return(1); } catch (OperationCanceledException) { return(1); } }
public static async Task <int> Run( string?workspace, bool noRestore, bool folder, bool fixWhitespace, string?fixStyle, string?fixAnalyzers, string[] diagnostics, string?verbosity, bool check, string[] include, string[] exclude, string?report, bool includeGenerated, string?binarylog, IConsole console = null !) { if (s_parseResult == null) { return(1); } // Setup logging. var logLevel = GetLogLevel(verbosity); var logger = SetupLogging(console, minimalLogLevel: logLevel, minimalErrorLevel: LogLevel.Warning); // Hook so we can cancel and exit when ctrl+c is pressed. var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; var currentDirectory = string.Empty; try { currentDirectory = Environment.CurrentDirectory; var formatVersion = GetVersion(); logger.LogDebug(Resources.The_dotnet_format_version_is_0, formatVersion); string? workspaceDirectory; string workspacePath; WorkspaceType workspaceType; // The folder option means we should treat the project path as a folder path. if (folder) { // If folder isn't populated, then use the current directory workspacePath = Path.GetFullPath(workspace ?? ".", Environment.CurrentDirectory); workspaceDirectory = workspacePath; workspaceType = WorkspaceType.Folder; } else { var(isSolution, workspaceFilePath) = MSBuildWorkspaceFinder.FindWorkspace(currentDirectory, workspace); workspacePath = workspaceFilePath; workspaceType = isSolution ? WorkspaceType.Solution : WorkspaceType.Project; // To ensure we get the version of MSBuild packaged with the dotnet SDK used by the // workspace, use its directory as our working directory which will take into account // a global.json if present. workspaceDirectory = Path.GetDirectoryName(workspacePath); if (workspaceDirectory is null) { throw new Exception($"Unable to find folder at '{workspacePath}'"); } } if (workspaceType != WorkspaceType.Folder) { var runtimeVersion = GetRuntimeVersion(); logger.LogDebug(Resources.The_dotnet_runtime_version_is_0, runtimeVersion); // Load MSBuild Environment.CurrentDirectory = workspaceDirectory; if (!TryGetDotNetCliVersion(out var dotnetVersion)) { logger.LogError(Resources.Unable_to_locate_dotnet_CLI_Ensure_that_it_is_on_the_PATH); return(UnableToLocateDotNetCliExitCode); } logger.LogTrace(Resources.The_dotnet_CLI_version_is_0, dotnetVersion); if (!TryLoadMSBuild(out var msBuildPath)) { logger.LogError(Resources.Unable_to_locate_MSBuild_Ensure_the_NET_SDK_was_installed_with_the_official_installer); return(UnableToLocateMSBuildExitCode); } logger.LogTrace(Resources.Using_msbuildexe_located_in_0, msBuildPath); } var fixType = FixCategory.None; if (s_parseResult.WasOptionUsed("--fix-style", "-s")) { fixType |= FixCategory.CodeStyle; } if (s_parseResult.WasOptionUsed("--fix-analyzers", "-a")) { fixType |= FixCategory.Analyzers; } if (fixType == FixCategory.None && diagnostics.Length > 0) { logger.LogWarning(Resources.The_diagnostics_option_only_applies_when_fixing_style_or_running_analyzers); } if (fixType == FixCategory.None || fixWhitespace) { fixType |= FixCategory.Whitespace; } HandleStandardInput(logger, ref include, ref exclude); var fileMatcher = SourceFileMatcher.CreateMatcher(include, exclude); var formatOptions = new FormatOptions( workspacePath, workspaceType, noRestore, logLevel, fixType, codeStyleSeverity: GetSeverity(fixStyle ?? FixSeverity.Error), analyzerSeverity: GetSeverity(fixAnalyzers ?? FixSeverity.Error), diagnostics: diagnostics.ToImmutableHashSet(), saveFormattedFiles: !check, changesAreErrors: check, fileMatcher, reportPath: report, includeGenerated); var formatResult = await CodeFormatter.FormatWorkspaceAsync( formatOptions, logger, cancellationTokenSource.Token, binaryLogPath : GetBinaryLogPath(s_parseResult, binarylog)).ConfigureAwait(false); return(GetExitCode(formatResult, check));
public static int Run(string?project, string?workspace, string?msbuildPath, string?tfm, bool allowPreviews, bool diffOnly, bool noBackup) { if (!string.IsNullOrWhiteSpace(project) && !string.IsNullOrWhiteSpace(workspace)) { Console.WriteLine("Cannot specify both a project and a workspace."); return(-1); } try { msbuildPath = MSBuildHelpers.HookAssemblyResolveForMSBuild(msbuildPath); if (string.IsNullOrWhiteSpace(msbuildPath)) { Console.WriteLine("Could not find an MSBuild."); return(-1); } if (tfm is null) { tfm = TargetFrameworkHelper.FindHighestInstalledTargetFramework(allowPreviews); } else { tfm = tfm.Trim(); if (!TargetFrameworkHelper.IsValidTargetFramework(tfm)) { Console.WriteLine($"Invalid framework specified for --target-framework: '{tfm}'"); return(-1); } } var workspacePath = string.Empty; MSBuildWorkspaceType workspaceType; if (!string.IsNullOrWhiteSpace(project)) { workspacePath = Path.GetFullPath(project, Environment.CurrentDirectory); workspaceType = MSBuildWorkspaceType.Project; } else { var(isSolution, workspaceFilePath) = MSBuildWorkspaceFinder.FindWorkspace(Environment.CurrentDirectory, workspace); workspaceType = isSolution ? MSBuildWorkspaceType.Solution : MSBuildWorkspaceType.Project; workspacePath = workspaceFilePath; } var workspaceLoader = new MSBuildWorkspaceLoader(workspacePath, workspaceType); // do not create backup if --diff-only specified noBackup = noBackup || diffOnly; var msbuildWorkspace = workspaceLoader.LoadWorkspace(workspacePath, noBackup); foreach (var item in msbuildWorkspace.WorkspaceItems) { if (diffOnly) { var differ = new Differ(item.UnconfiguredProject.FirstConfiguredProject, item.SdkBaselineProject.Project.FirstConfiguredProject); differ.GenerateReport(Directory.GetParent(workspacePath).FullName); } else { var converter = new Converter(item.UnconfiguredProject, item.SdkBaselineProject, item.ProjectRootElement); converter.Convert(tfm, item.ProjectRootElement.FullPath); } } } catch (Exception e) { Console.WriteLine(e.ToString()); return(-1); } Console.WriteLine("Conversion complete!"); return(0); }
public static async Task <int> Run(string folder, string workspace, string verbosity, bool check, string[] include, string[] exclude, string report, IConsole console = null) { // Setup logging. var serviceCollection = new ServiceCollection(); var logLevel = GetLogLevel(verbosity); ConfigureServices(serviceCollection, console, logLevel); var serviceProvider = serviceCollection.BuildServiceProvider(); var logger = serviceProvider.GetService <ILogger <Program> >(); // Hook so we can cancel and exit when ctrl+c is pressed. var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; var currentDirectory = string.Empty; try { currentDirectory = Environment.CurrentDirectory; string workspaceDirectory; string workspacePath; WorkspaceType workspaceType; if (!string.IsNullOrEmpty(folder) && !string.IsNullOrEmpty(workspace)) { logger.LogWarning(Resources.Cannot_specify_both_folder_and_workspace_options); return(1); } if (!string.IsNullOrEmpty(folder)) { folder = Path.GetFullPath(folder, Environment.CurrentDirectory); workspacePath = folder; workspaceDirectory = workspacePath; workspaceType = WorkspaceType.Folder; } else { var(isSolution, workspaceFilePath) = MSBuildWorkspaceFinder.FindWorkspace(currentDirectory, workspace); workspacePath = workspaceFilePath; workspaceType = isSolution ? WorkspaceType.Solution : WorkspaceType.Project; // To ensure we get the version of MSBuild packaged with the dotnet SDK used by the // workspace, use its directory as our working directory which will take into account // a global.json if present. workspaceDirectory = Path.GetDirectoryName(workspacePath); } Environment.CurrentDirectory = workspaceDirectory; // Since we are running as a dotnet tool we should be able to find an instance of // MSBuild in a .NET Core SDK. var msBuildInstance = Build.Locator.MSBuildLocator.QueryVisualStudioInstances().First(); // Since we do not inherit msbuild.deps.json when referencing the SDK copy // of MSBuild and because the SDK no longer ships with version matched assemblies, we // register an assembly loader that will load assemblies from the msbuild path with // equal or higher version numbers than requested. LooseVersionAssemblyLoader.Register(msBuildInstance.MSBuildPath); Build.Locator.MSBuildLocator.RegisterInstance(msBuildInstance); var fileMatcher = SourceFileMatcher.CreateMatcher(include, exclude); var formatOptions = new FormatOptions( workspacePath, workspaceType, logLevel, saveFormattedFiles: !check, changesAreErrors: check, fileMatcher, reportPath: report); var formatResult = await CodeFormatter.FormatWorkspaceAsync( formatOptions, logger, cancellationTokenSource.Token).ConfigureAwait(false); return(GetExitCode(formatResult, check)); } catch (FileNotFoundException fex) { logger.LogError(fex.Message); return(UnhandledExceptionExitCode); } catch (OperationCanceledException) { return(UnhandledExceptionExitCode); } finally { if (!string.IsNullOrEmpty(currentDirectory)) { Environment.CurrentDirectory = currentDirectory; } } }
public static async Task <int> Run(string workspace, string verbosity, bool dryRun, bool check, string files, IConsole console = null) { var serviceCollection = new ServiceCollection(); var logLevel = GetLogLevel(verbosity); ConfigureServices(serviceCollection, console, logLevel); var serviceProvider = serviceCollection.BuildServiceProvider(); var logger = serviceProvider.GetService <ILogger <Program> >(); var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; string currentDirectory = string.Empty; try { currentDirectory = Environment.CurrentDirectory; var workingDirectory = Directory.GetCurrentDirectory(); var(isSolution, workspacePath) = MSBuildWorkspaceFinder.FindWorkspace(workingDirectory, workspace); // To ensure we get the version of MSBuild packaged with the dotnet SDK used by the // workspace, use its directory as our working directory which will take into account // a global.json if present. var workspaceDirectory = Path.GetDirectoryName(workspacePath); Environment.CurrentDirectory = workingDirectory; var fileList = GetFileList(files); // Since we are running as a dotnet tool we should be able to find an instance of // MSBuild in a .NET Core SDK. var msBuildInstance = Build.Locator.MSBuildLocator.QueryVisualStudioInstances().First(); // Since we do not inherit msbuild.deps.json when referencing the SDK copy // of MSBuild and because the SDK no longer ships with version matched assemblies, we // register an assembly loader that will load assemblies from the msbuild path with // equal or higher version numbers than requested. LooseVersionAssemblyLoader.Register(msBuildInstance.MSBuildPath); Build.Locator.MSBuildLocator.RegisterInstance(msBuildInstance); var formatResult = await CodeFormatter.FormatWorkspaceAsync( logger, workspacePath, isSolution, logAllWorkspaceWarnings : logLevel == LogLevel.Trace, saveFormattedFiles : !dryRun, filesToFormat : fileList, cancellationTokenSource.Token).ConfigureAwait(false); return(GetExitCode(formatResult, check)); } catch (FileNotFoundException fex) { logger.LogError(fex.Message); return(1); } catch (OperationCanceledException) { return(1); } finally { if (!string.IsNullOrEmpty(currentDirectory)) { Environment.CurrentDirectory = currentDirectory; } } }
public static int Run(string project, string workspace, string msbuildPath, bool diffOnly, bool noBackup) { if (!string.IsNullOrWhiteSpace(project) && !string.IsNullOrWhiteSpace(workspace)) { Console.WriteLine("Cannot specify both a project and a workspace."); return(-1); } try { msbuildPath = MSBuildHelpers.HookAssemblyResolveForMSBuild(msbuildPath); if (string.IsNullOrWhiteSpace(msbuildPath)) { Console.WriteLine("Could not find an MSBuild."); return(-1); } var currentDirectory = Environment.CurrentDirectory; var workspacePath = string.Empty; MSBuildWorkspaceType workspaceType; if (!string.IsNullOrWhiteSpace(project)) { workspacePath = Path.GetFullPath(project, Environment.CurrentDirectory); workspaceType = MSBuildWorkspaceType.Project; } else if (!string.IsNullOrWhiteSpace(workspace)) { var(isSolution, workspaceFilePath) = MSBuildWorkspaceFinder.FindWorkspace(currentDirectory, workspace); workspaceType = isSolution ? MSBuildWorkspaceType.Solution : MSBuildWorkspaceType.Project; workspacePath = workspaceFilePath; } else { throw new ArgumentException("No valid arguments to fulfill a workspace are given."); } var workspaceLoader = new MSBuildWorkspaceLoader(workspacePath, workspaceType); var msbuildWorkspace = workspaceLoader.LoadWorkspace(workspacePath, noBackup); foreach (var item in msbuildWorkspace.WorkspaceItems) { if (diffOnly) { var differ = new Differ(item.UnconfiguredProject.FirstConfiguredProject, item.SdkBaselineProject.Project.FirstConfiguredProject); differ.GenerateReport(Directory.GetParent(workspacePath).FullName); } else { var converter = new Converter(item.UnconfiguredProject, item.SdkBaselineProject, item.ProjectRootElement); converter.Convert(item.ProjectRootElement.FullPath); } } } catch (Exception e) { Console.WriteLine(e.ToString()); return(-1); } Console.WriteLine("Conversion complete!"); return(0); }
public static async Task <int> Run( string?workspace, bool folder, string?fixStyle, string?fixAnalyzers, string?verbosity, bool check, string[] include, string[] exclude, string?report, bool includeGenerated, IConsole console = null !) { if (s_parseResult == null) { return(1); } // Setup logging. var logLevel = GetLogLevel(verbosity); var logger = SetupLogging(console, logLevel); // Hook so we can cancel and exit when ctrl+c is pressed. var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; var currentDirectory = string.Empty; try { currentDirectory = Environment.CurrentDirectory; string workspaceDirectory; string workspacePath; WorkspaceType workspaceType; // The folder option means we should treat the project path as a folder path. if (folder) { // If folder isn't populated, then use the current directory workspacePath = Path.GetFullPath(workspace ?? ".", Environment.CurrentDirectory); workspaceDirectory = workspacePath; workspaceType = WorkspaceType.Folder; } else { var(isSolution, workspaceFilePath) = MSBuildWorkspaceFinder.FindWorkspace(currentDirectory, workspace); workspacePath = workspaceFilePath; workspaceType = isSolution ? WorkspaceType.Solution : WorkspaceType.Project; // To ensure we get the version of MSBuild packaged with the dotnet SDK used by the // workspace, use its directory as our working directory which will take into account // a global.json if present. workspaceDirectory = Path.GetDirectoryName(workspacePath); if (workspaceDirectory is null) { throw new Exception($"Unable to find folder at '{workspacePath}'"); } } // Load MSBuild Environment.CurrentDirectory = workspaceDirectory; if (!TryGetDotNetCliVersion(out var dotnetVersion)) { logger.LogError(Resources.Unable_to_locate_dotnet_CLI_Ensure_that_it_is_on_the_PATH); return(UnableToLocateDotNetCliExitCode); } logger.LogTrace(Resources.The_dotnet_CLI_version_is_0, dotnetVersion); if (!TryLoadMSBuild(out var msBuildPath)) { logger.LogError(Resources.Unable_to_locate_MSBuild_Ensure_the_NET_SDK_was_installed_with_the_official_installer); return(UnableToLocateMSBuildExitCode); } logger.LogTrace(Resources.Using_msbuildexe_located_in_0, msBuildPath); var fileMatcher = SourceFileMatcher.CreateMatcher(include, exclude); var formatOptions = new FormatOptions( workspacePath, workspaceType, logLevel, fixCodeStyle: s_parseResult.WasOptionUsed("--fix-style", "-fs"), codeStyleSeverity: GetSeverity(fixStyle ?? FixSeverity.Error), fixAnalyzers: s_parseResult.WasOptionUsed("--fix-analyzers", "-fa"), analyerSeverity: GetSeverity(fixAnalyzers ?? FixSeverity.Error), saveFormattedFiles: !check, changesAreErrors: check, fileMatcher, reportPath: report, includeGenerated); var formatResult = await CodeFormatter.FormatWorkspaceAsync( formatOptions, logger, cancellationTokenSource.Token, createBinaryLog : logLevel == LogLevel.Trace).ConfigureAwait(false); return(GetExitCode(formatResult, check)); } catch (FileNotFoundException fex) { logger.LogError(fex.Message); return(UnhandledExceptionExitCode); } catch (OperationCanceledException) { return(UnhandledExceptionExitCode); } finally { if (!string.IsNullOrEmpty(currentDirectory)) { Environment.CurrentDirectory = currentDirectory; } } }