public static async Task <MSBuildProj> DotNetNewAsync(string fullPath, ILogger logger, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); MSBuildProj project = null; bool ownsDir = false; if (fullPath == null) { throw new ArgumentNullException(nameof(fullPath)); } fullPath = Path.GetFullPath(fullPath); string projectName = Path.GetFileNameWithoutExtension(fullPath); string projectExtension = Path.GetExtension(fullPath); string projectDir = Path.GetDirectoryName(fullPath); if (string.IsNullOrEmpty(projectName) || string.CompareOrdinal(projectExtension.ToLowerInvariant(), ".csproj") != 0) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Shared.Resources.ErrorFullPathNotAProjectFilePathFormat, fullPath)); } if (File.Exists(fullPath)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Shared.Resources.ErrorProjectFileAlreadyExistsFormat, fullPath)); } // ensure we have a working directory for the ProcessRunner (ProjectPropertyResolver). if (!Directory.Exists(projectDir)) { Directory.CreateDirectory(projectDir); ownsDir = true; } var sdkVersion = await ProjectPropertyResolver.GetSdkVersionAsync(projectDir, logger, cancellationToken).ConfigureAwait(false); var dotnetNewParams = $"new console {GetNoRestoreParam(sdkVersion)} --force --type project --language C# --output . --name {projectName}"; await ProcessRunner.RunAsync("dotnet", dotnetNewParams, projectDir, logger, cancellationToken).ConfigureAwait(false); project = await ParseAsync(File.ReadAllText(fullPath), fullPath, logger, cancellationToken).ConfigureAwait(false); project._ownsDirectory = ownsDir; project.SdkVersion = sdkVersion ?? string.Empty; project._isSaved = true; return(project); }
public static async Task <MSBuildProj> ParseAsync(string projectText, string projectFullPath, ILogger logger, CancellationToken cancellationToken) { using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, $"Parsing project {Path.GetFileName(projectFullPath)}").ConfigureAwait(false)) { projectFullPath = Path.GetFullPath(projectFullPath); MSBuildProj msbuildProj = new MSBuildProj { FileName = Path.GetFileName(projectFullPath), DirectoryPath = Path.GetDirectoryName(projectFullPath) }; XDocument projDefinition = XDocument.Parse(projectText); var msbuildNS = XNamespace.None; if (projDefinition.Root != null && projDefinition.Root.Name != null) { msbuildNS = projDefinition.Root.Name.Namespace; } msbuildProj._msbuildNS = msbuildNS; msbuildProj.ProjectNode = projDefinition.Element(msbuildNS + "Project"); if (msbuildProj.ProjectNode == null) { throw new Exception(Shared.Resources.ErrorInvalidProjectFormat); } // The user project can declare TargetFramework and/or TargetFrameworks property. If both are provided, TargetFramework wins. // When TargetFrameworks is provided, the project is built for every entry specified in the TargetFramework property. IEnumerable <XElement> targetFrameworkElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "PropertyGroup", "TargetFramework"); if (targetFrameworkElements.Count() > 0) { // If property is specified more than once, MSBuild will resolve it by overwriting it with the last value. var targetFramework = targetFrameworkElements.Last().Value.Trim(); if (!string.IsNullOrWhiteSpace(targetFramework)) { if (targetFramework.StartsWith("net5.0-")) { targetFramework = "net5.0"; } msbuildProj._targetFrameworks.Add(targetFramework); } } if (msbuildProj._targetFrameworks.Count == 0) { // TargetFramework was not provided, check TargetFrameworks property. IEnumerable <XElement> targetFrameworksElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "PropertyGroup", "TargetFrameworks"); if (targetFrameworksElements.Count() > 0) { var targetFrameworks = targetFrameworksElements.Last().Value; foreach (var targetFx in targetFrameworks.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim())) { if (!string.IsNullOrWhiteSpace(targetFx)) { msbuildProj._targetFrameworks.Add(targetFx); } } } } msbuildProj._targetFramework = TargetFrameworkHelper.GetBestFitTargetFramework(msbuildProj._targetFrameworks); // Ensure target framework is valid. FrameworkInfo frameworkInfo = TargetFrameworkHelper.GetValidFrameworkInfo(msbuildProj.TargetFramework); IEnumerable <XElement> runtimeIdentifierElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "PropertyGroup", "RuntimeIdentifier"); if (runtimeIdentifierElements.Count() > 0) { msbuildProj.RuntimeIdentifier = runtimeIdentifierElements.Last().Value.Trim(); } IEnumerable <XElement> packageReferenceElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "ItemGroup", "PackageReference"); foreach (XElement reference in packageReferenceElements) { if (!TryGetItemIdentity(reference, out var packageName)) { continue; } string version = GetItemValue(reference, "Version"); ProjectDependency packageDep = ProjectDependency.FromPackage(packageName, version); msbuildProj._dependencies.Add(packageDep); } IEnumerable <XElement> toolReferenceElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "ItemGroup", "DotNetCliToolReference"); foreach (XElement reference in toolReferenceElements) { if (!TryGetItemIdentity(reference, out var packageName)) { continue; } string version = GetItemValue(reference, "Version"); ProjectDependency packageDep = ProjectDependency.FromCliTool(packageName, version); msbuildProj._dependencies.Add(packageDep); } IEnumerable <XElement> projectReferenceElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "ItemGroup", "ProjectReference"); foreach (XElement reference in projectReferenceElements) { string projectPath = GetItemValue(reference, "Include", throwIfMissing: true); ProjectDependency projectDep = ProjectDependency.FromProject(projectPath); msbuildProj._dependencies.Add(projectDep); } IEnumerable <XElement> binReferenceElements = GetSubGroupValues(msbuildProj.ProjectNode, msbuildNS, "ItemGroup", "Reference"); foreach (XElement reference in binReferenceElements) { //Find hint path or path string binReference = GetItemIdentity(reference); if (!Path.IsPathRooted(binReference)) { string fullPath = null; bool fullPathFound = true; XElement hintPath = reference.Element("HintPath"); XElement path = reference.Element("Path"); if (path != null) { fullPath = path.Value; } else if (hintPath != null) { fullPath = hintPath.Value; } else { try { fullPath = new FileInfo(Path.Combine(msbuildProj.DirectoryPath, binReference)).FullName; } catch { } if (fullPath == null || !File.Exists(fullPath)) { fullPathFound = false; // If we're only targeting .NET Core or .NET Standard projects we throw if we can't find the full path to the assembly. if (!TargetFrameworkHelper.ContainsFullFrameworkTarget(msbuildProj._targetFrameworks)) { throw new Exception(string.Format(CultureInfo.CurrentCulture, Shared.Resources.ErrorProjectReferenceMissingFilePathFormat, binReference)); } } } if (fullPathFound) { if (System.IO.Directory.Exists(fullPath)) // IsDir? { fullPath = Path.Combine(fullPath, binReference); } else if (Directory.Exists(Path.Combine(msbuildProj.DirectoryPath, fullPath))) { fullPath = Path.Combine(msbuildProj.DirectoryPath, fullPath, binReference); } binReference = fullPath; } } ProjectDependency projectDep = ProjectDependency.FromAssembly(binReference); msbuildProj._dependencies.Add(projectDep); } // ensure we have a working directory for the ProcessRunner (ProjectPropertyResolver).. if (!Directory.Exists(msbuildProj.DirectoryPath)) { Directory.CreateDirectory(msbuildProj.DirectoryPath); msbuildProj._ownsDirectory = true; } var sdkVersion = await ProjectPropertyResolver.GetSdkVersionAsync(msbuildProj.DirectoryPath, logger, cancellationToken).ConfigureAwait(false); msbuildProj.SdkVersion = sdkVersion ?? string.Empty; return(msbuildProj); } }
private MSBuildProj() { _propertyResolver = new ProjectPropertyResolver(); }
public static async Task <AppInsightsTelemetryClient> GetInstanceAsync(CancellationToken cancellationToken) { if (s_instance == null) { try { if (!bool.TryParse(Environment.GetEnvironmentVariable(testModeVariable), out bool testMode)) { testMode = false; } lock (s_lockObj) { if (s_instance == null) { if (!IsUserOptedIn) { // If the user hasn't opted in return now with a null telemetry client to ensure we don't create any telemetry context. return(new AppInsightsTelemetryClient(null)); } TelemetryConfiguration config; try { config = TelemetryConfiguration.Active; } catch (InvalidOperationException) { config = new TelemetryConfiguration(); } config.TelemetryChannel.DeveloperMode = testMode; s_instance = new AppInsightsTelemetryClient(new TelemetryClient(config)); } } var telemetryClient = s_instance._telemetryClient; telemetryClient.InstrumentationKey = instrumentationKey; // Populate context with properties that are common and should be logged for all events. var context = telemetryClient.Context; context.Device.OperatingSystem = GetOperatingSystemString(); #if !NETCORE10 // Set the user id to a stable hash of the user's current username. Users with the same username // or those with hash collisions will show up as the same id. So the user id won't be perfectly unique. // However, it will give us some idea of how many different users are using the tool. context.User.Id = GetStableHashCode(Environment.UserName).ToString(); #endif // DebugLogger tracks telemetry when adding exceptions. We pass null for the logger to avoid the possibility of an endless cyclic call if something goes wrong in GetSdkVersionAsync. var sdkVersion = await ProjectPropertyResolver.GetSdkVersionAsync(System.IO.Directory.GetCurrentDirectory(), null /* logger */, cancellationToken).ConfigureAwait(false); context.Properties["SvcUtil.Version"] = Tool.PackageVersion; context.Properties["Dotnet.Version"] = string.IsNullOrEmpty(sdkVersion) ? "unknown" : sdkVersion; context.Properties["TestMode"] = testMode.ToString(); } catch (Exception ex) { #if DEBUG ToolConsole.WriteWarning(ex.Message); #endif s_isUserOptedIn = false; } } return(s_instance); }