예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
 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);
        }