Ejemplo n.º 1
0
        public void LoadXml(string inputXmlFile, string baseDirectory = null)
        {
            base_directory = baseDirectory ?? Path.GetDirectoryName(inputXmlFile);
            var doc         = XDocument.Load(inputXmlFile, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo | LoadOptions.SetBaseUri);
            var rootElement = doc.Element("solution");

            var projectsElement = rootElement.Element("projects");

            this.projects = new List <ProjectInSolution> ();
            foreach (var projectElement in projectsElement.Elements("project"))
            {
                var projectFile = projectElement.Attribute("file")?.Value;
                if (projectFile == null)
                {
                    Console.Error.WriteLine($"WARNING: <project> element '{projectElement.Attribute ("name")}' has no 'file' attribute. Ignoring.");
                    continue;
                }
                var projectFileFullPath = Path.Combine(base_directory, projectFile.Replace('\\', Path.DirectorySeparatorChar));
                if (!File.Exists(projectFileFullPath))
                {
                    Console.Error.WriteLine($"WARNING: <project> file '{projectFileFullPath}' does not exist. Ignoring.");
                    continue;
                }
                var project = ProjectRootElement.Open(projectFileFullPath);
                Func <string, string> chop        = s => s?.Substring(1, s.Length - 2);
                Func <string, string> getGuidProp = name => chop(project.PropertyGroups.SelectMany(g => g.Properties).FirstOrDefault(p => p.Name.Equals(name))?.Value);
                projects.Add(new ProjectInSolution {
                    Path             = projectFile,
                    Name             = projectElement.Attribute("name")?.Value ?? Path.GetFileNameWithoutExtension(projectFileFullPath),
                    ProjectGuid      = getGuidProp("ProjectGuid") ?? Guid.NewGuid().ToString(),
                    ProjectTypeGuids = getGuidProp("ProjectTypeGuids"),
                });
            }

            var solutionConfigsElement = rootElement.Element("config-names-for-solution");

            this.solution_configuration_platforms = new List <string> ();
            foreach (var configElement in solutionConfigsElement.Elements("config"))
            {
                solution_configuration_platforms.Add(configElement.Attribute("name").Value);
            }

            var folders = rootElement.Element("solution-folders");

            this.nested_projects = new List <Nest> ();
            foreach (var folder in folders.Elements("folder"))
            {
                string folderName = folder.Attribute("name").Value;
                // if the solution folder is not part of project list, then add it.
                if (!projects.Any(p => p.Name.Equals(folderName, StringComparison.OrdinalIgnoreCase)))
                {
                    projects.Add(new ProjectInSolution {
                        Name             = folderName,
                        Path             = folderName,
                        ProjectTypeGuids = ProjectTypeGuids.SolutionFolder,
                        ProjectGuid      = Guid.NewGuid().ToString()
                    });
                }

                foreach (var item in folder.Elements("project"))
                {
                    var itemName = item.Attribute("name").Value;
                    nested_projects.Add(new Nest {
                        Item = ProjectNameToGuid(itemName), Parent = ProjectNameToGuid(folderName)
                    });
                }
            }

            string [] default_properties    = { "ActiveCfg", "Build.0" };
            var       projectConfigsElement = rootElement.Element("project-config-properties");

            this.project_configuration_platforms = new List <ProjectConfigurationPlatform> ();
            foreach (var projectElement in projectConfigsElement.Elements("project"))
            {
                var projectName = projectElement.Attribute("name").Value;
                var projectGuid = ProjectNameToGuid(projectName);
                var pattern     = projectElement.Attribute("pattern")?.Value;
                switch (pattern)
                {
                case "all":
                    foreach (var config in solution_configuration_platforms)
                    {
                        foreach (var prop in default_properties)
                        {
                            int sepidx = config.IndexOf('|');
                            var cfg    = sepidx < 0 ? null : config.Substring(0, sepidx);
                            cfg = cfg != null && cfg.EndsWith("Release") ? "Release" : cfg.EndsWith("Debug") ? "Debug" : cfg;
                            var arch = sepidx < 0 ? null : config.Substring(sepidx + 1);
                            project_configuration_platforms.Add(new ProjectConfigurationPlatform {
                                ProjectGuid = projectGuid,
                                SolutionConfigurationName = config,
                                Property           = prop,
                                ConfigurationValue = (cfg != null ? cfg + '|' + arch : config).Replace("AnyCPU", "Any CPU"),
                            });
                        }
                    }
                    break;

                case null:
                    foreach (var configPlatformElement in projectElement.Elements("config-platform"))
                    {
                        var config = configPlatformElement.Attribute("config").Value;
                        var prop   = configPlatformElement.Attribute("property").Value;
                        var value  = configPlatformElement.Attribute("value").Value;
                        project_configuration_platforms.Add(new ProjectConfigurationPlatform {
                            ProjectGuid = projectGuid,
                            SolutionConfigurationName = config,
                            Property           = prop,
                            ConfigurationValue = value
                        });
                    }
                    break;

                default:
                    throw new ArgumentException("Unexpected pattern value: " + pattern);
                }
            }

            var otherElement = rootElement.Element("other-global-sections");

            this.other_global_sections = new List <GlobalSection> ();
            foreach (var sectionElement in otherElement.Elements("section"))
            {
                other_global_sections.Add(new GlobalSection {
                    Name  = sectionElement.Attribute("name")?.Value,
                    Type  = sectionElement.Attribute("type")?.Value,
                    Value = sectionElement.Value,
                });
            }
        }
Ejemplo n.º 2
0
        public static MSBuildProject Open(string path)
        {
            var root = ProjectRootElement.Open(path);

            return(root != null ? new MSBuildProject(root) : null);
        }
Ejemplo n.º 3
0
        ///  Simple function to make sure the Api assembly references are configured correctly
        public static void FixApiHintPath(string projectPath)
        {
            var root = ProjectRootElement.Open(projectPath);

            Debug.Assert(root != null);

            bool dirty = false;

            void AddPropertyIfNotPresent(string name, string condition, string value)
            {
                if (root.PropertyGroups
                    .Any(g => g.Condition == string.Empty || g.Condition == condition &&
                         g.Properties
                         .Any(p => p.Name == name &&
                              p.Value == value &&
                              (p.Condition == condition || g.Condition == condition))))
                {
                    return;
                }

                root.AddProperty(name, value).Condition = condition;
                dirty = true;
            }

            AddPropertyIfNotPresent(name: "ApiConfiguration",
                                    condition: " '$(Configuration)' != 'Release' ",
                                    value: "Debug");
            AddPropertyIfNotPresent(name: "ApiConfiguration",
                                    condition: " '$(Configuration)' == 'Release' ",
                                    value: "Release");

            void SetReferenceHintPath(string referenceName, string condition, string hintPath)
            {
                foreach (var itemGroup in root.ItemGroups.Where(g =>
                                                                g.Condition == string.Empty || g.Condition == condition))
                {
                    var references = itemGroup.Items.Where(item =>
                                                           item.ItemType == "Reference" &&
                                                           item.Include == referenceName &&
                                                           (item.Condition == condition || itemGroup.Condition == condition));

                    var referencesWithHintPath = references.Where(reference =>
                                                                  reference.Metadata.Any(m => m.Name == "HintPath"));

                    if (referencesWithHintPath.Any(reference => reference.Metadata
                                                   .Any(m => m.Name == "HintPath" && m.Value == hintPath)))
                    {
                        // Found a Reference item with the right HintPath
                        return;
                    }

                    var referenceWithHintPath = referencesWithHintPath.FirstOrDefault();
                    if (referenceWithHintPath != null)
                    {
                        // Found a Reference item with a wrong HintPath
                        foreach (var metadata in referenceWithHintPath.Metadata.ToList()
                                 .Where(m => m.Name == "HintPath"))
                        {
                            // Safe to remove as we duplicate with ToList() to loop
                            referenceWithHintPath.RemoveChild(metadata);
                        }

                        referenceWithHintPath.AddMetadata("HintPath", hintPath);
                        dirty = true;
                        return;
                    }

                    var referenceWithoutHintPath = references.FirstOrDefault();
                    if (referenceWithoutHintPath != null)
                    {
                        // Found a Reference item without a HintPath
                        referenceWithoutHintPath.AddMetadata("HintPath", hintPath);
                        dirty = true;
                        return;
                    }
                }

                // Found no Reference item at all. Add it.
                root.AddItem("Reference", referenceName).Condition = condition;
                dirty = true;
            }

            const string coreProjectName   = "GodotSharp";
            const string editorProjectName = "GodotSharpEditor";

            const string coreCondition   = "";
            const string editorCondition = " '$(Configuration)' == 'Tools' ";

            var coreHintPath   = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll";
            var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll";

            SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath);
            SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath);

            if (dirty)
            {
                root.Save();
            }
        }
Ejemplo n.º 4
0
        int IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pUpgradeRequired       = 0;
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName))
            {
                pUpgradeProjectCapabilityFlags = 0;
                return(VSConstants.E_INVALIDARG);
            }

            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try
            {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                if (upgradeRequired != ProjectUpgradeState.NotNeeded)
                {
                    pUpgradeRequired = 1;
                }
            }
            catch (Exception ex) when(!ExceptionExtensions.IsCriticalException(ex))
            {
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try
                {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                }
                catch (InvalidOperationException)
                {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = 0;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID)
            {
                pguidNewProjectFactory = Guid.Empty;
            }

            return(VSConstants.S_OK);
        }
        private bool ConvertProject(string projectPath, string packagesConfigPath)
        {
            try
            {
                Log.Info($"  Converting project \"{projectPath}\"");

                PackagesConfigReader packagesConfigReader = new PackagesConfigReader(XDocument.Load(packagesConfigPath));

                List <PackageReference> packages = packagesConfigReader.GetPackages(allowDuplicatePackageIds: true).Select(i => new PackageReference(i.PackageIdentity, i.TargetFramework, i.IsUserInstalled, i.IsDevelopmentDependency, i.RequireReinstallation, i.AllowedVersions, PackagePathResolver, VersionFolderPathResolver)).ToList();

                DetectMissingTransitiveDependencies(packages, projectPath);

                ProjectRootElement project = ProjectRootElement.Open(projectPath, _projectCollection, preserveFormatting: true);

                ProjectItemGroupElement packageReferenceItemGroupElement = null;

                foreach (ProjectElement element in project.AllChildren)
                {
                    ProcessElement(element, packages);

                    if (packageReferenceItemGroupElement == null && element is ProjectItemElement itemElement && itemElement.ItemType.Equals("Reference"))
                    {
                        // Find the first Reference item and use it to add PackageReference items to, otherwise a new ItemGroup is added
                        packageReferenceItemGroupElement = element.Parent as ProjectItemGroupElement;
                    }
                }

                if (packageReferenceItemGroupElement == null)
                {
                    packageReferenceItemGroupElement = project.AddItemGroup();
                }

                Log.Info("    Current package references:");

                foreach (PackageReference package in packages.Where(i => !i.IsMissingTransitiveDependency))
                {
                    Log.Info($"      {package.PackageIdentity}");
                }

                foreach (ProjectElement element in packages.Where(i => !i.IsMissingTransitiveDependency).SelectMany(i => i.AllElements))
                {
                    Log.Debug($"    {element.Location}: Removing element {element.ToXmlString()}");
                    element.Remove();
                }

                if (this._converterSettings.TrimPackages)
                {
                    List <NuGetFramework> targetFrameworks = new List <NuGetFramework>
                    {
                        FrameworkConstants.CommonFrameworks.Net45
                    };
                    using (SourceCacheContext sourceCacheContext = new SourceCacheContext
                    {
                        IgnoreFailedSources = true,
                    })
                    {
                        var packageRestoreGraph = GetRestoreTargetGraph(packages, projectPath, targetFrameworks, sourceCacheContext);
                        TrimPackages(packages, projectPath, packageRestoreGraph.Flattened);
                    }
                }

                Log.Info("    Converted package references:");

                foreach (PackageReference package in packages)
                {
                    ProjectItemElement packageReferenceItemElement = AddPackageReference(packageReferenceItemGroupElement, package);

                    Log.Info($"      {packageReferenceItemElement.ToXmlString()}");
                }


                if (project.HasUnsavedChanges)
                {
                    Log.Debug($"    Saving project \"{project.FullPath}\"");
                    project.Save();
                }

                Log.Debug($"    Deleting file \"{packagesConfigPath}\"");

                File.Delete(packagesConfigPath);

                Log.Info($"  Successfully converted \"{project.FullPath}\"");
            }
            catch (Exception e)
            {
                Log.Error($"Failed to convert '{projectPath}' : {e}");

                return(false);
            }

            return(true);
        }
Ejemplo n.º 6
0
        private async Task <Project> OpenProject(UFile projectPath)
        {
            if (msbuildWorkspace == null)
            {
                // Only load workspace for C# assemblies (default includes VB but not added as a NuGet package)
                //var csharpWorkspaceAssemblies = new[] { Assembly.Load("Microsoft.CodeAnalysis.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.CSharp.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.Workspaces.Desktop") };
                var host = await RoslynHost;
                msbuildWorkspace = MSBuildWorkspace.Create(ImmutableDictionary <string, string> .Empty, host.HostServices);
            }

            msbuildWorkspace.CloseSolution();

            // Try up to 10 times (1 second)
            const int retryCount = 10;

            for (var i = retryCount - 1; i >= 0; --i)
            {
                try
                {
                    var project = await msbuildWorkspace.OpenProjectAsync(projectPath.ToWindowsPath());

                    // Change the default CSharp language version to match the supported version for a specific visual studio version or MSBuild version
                    //  this is because roslyn  will always resolve Default to Latest which might not match the
                    //  latest version supported by the build tools installed on the machine
                    var csharpParseOptions = project.ParseOptions as CSharpParseOptions;
                    if (csharpParseOptions != null)
                    {
                        if (csharpParseOptions.SpecifiedLanguageVersion == LanguageVersion.Default || csharpParseOptions.SpecifiedLanguageVersion == LanguageVersion.Latest)
                        {
                            LanguageVersion targetLanguageVersion = csharpParseOptions.SpecifiedLanguageVersion;

                            // Check the visual studio version inside the solution first, which is what visual studio uses to decide which version to open
                            //  this should not be confused with the toolsVersion below, since this is the MSBuild version (they might be different)
                            Version visualStudioVersion = session.CurrentProject?.Package.Session.VisualStudioVersion;
                            if (visualStudioVersion != null)
                            {
                                if (visualStudioVersion.Major <= 14)
                                {
                                    targetLanguageVersion = LanguageVersion.CSharp6;
                                }
                            }
                            else
                            {
                                // Fallback to checking the tools version on the csproj
                                //  this happens when you open an sdpkg instead of a sln file as a project
                                ProjectRootElement xml = ProjectRootElement.Open(projectPath);
                                Version            toolsVersion;
                                if (Version.TryParse(xml.ToolsVersion, out toolsVersion))
                                {
                                    if (toolsVersion.Major <= 14)
                                    {
                                        targetLanguageVersion = LanguageVersion.CSharp6;
                                    }
                                }
                            }
                            project = project.WithParseOptions(csharpParseOptions.WithLanguageVersion(targetLanguageVersion));
                        }
                    }
                    return(project);
                }
                catch (IOException)
                {
                    // FIle might still be locked, let's wait little bit more
                    await Task.Delay(100);

                    if (i == 0)
                    {
                        throw;
                    }
                }
            }

            // Unreachable
            throw new InvalidOperationException();
        }
Ejemplo n.º 7
0
 public ProjectRootElement CsProj()
 {
     // Passing new collection to prevent using cached version
     return(ProjectRootElement.Open(CsProjPath, new ProjectCollection()));
 }
        private Project OpenProject(string filePath)
        {
            ProjectRootElement root = ProjectRootElement.Open(filePath, _projectCollection, true);

            return(new Project(root));
        }
Ejemplo n.º 9
0
        public static MsBuildProject OpenProjectForEditing(string projectFilePath, ProjectCollection projectCollection)
        {
            var projectRootElement = ProjectRootElement.Open(projectFilePath, projectCollection, preserveFormatting: true);

            return(new MsBuildProject(projectRootElement));
        }
Ejemplo n.º 10
0
 public static IEnumerable <ReferenceInfo> GetDXReferencePaths(string absolutePath, bool includeRoot)
 {
     return(GetDXReferencePaths(ProjectRootElement.Open(absolutePath), includeRoot));
 }
Ejemplo n.º 11
0
 public static string GetAssemblyNameFromProject(string proj)
 {
     return(GetAssemblyNameFromProject(ProjectRootElement.Open(proj)));
 }
        /// <summary>
        /// Function called after a project file change has been detected which pushes the changes to CPS. The return value indicates the status of the
        /// reload.
        /// </summary>
        public async Task <ProjectReloadResult> ReloadProjectAsync()
        {
            // We need a write lock to modify the project file contents. Note that all awaits while holding the lock need
            // to capture the context as the project lock service has a special execution context which ensures only a single
            // thread has access.
            using (var writeAccess = await _projectVsServices.ProjectLockService.WriteLockAsync())
            {
                await writeAccess.CheckoutAsync(_projectVsServices.Project.FullPath).ConfigureAwait(true);

                var msbuildProject = await writeAccess.GetProjectXmlAsync(_projectVsServices.Project.FullPath, CancellationToken.None).ConfigureAwait(true);

                if (msbuildProject.HasUnsavedChanges)
                {
                    // For now force a solution reload.
                    return(ProjectReloadResult.ReloadFailedProjectDirty);
                }
                else
                {
                    // What we need to do is load the one on disk. This accomplishes two things: 1) verifies that at least the msbuild is OK. If it isn't
                    // we want to let the normal solution reload occur so that the user sees the failure, and 2) it allows us to clear the current project
                    // and do a deep copy from the newly loaded one to the original - replacing its contents. Note that the Open call is cached so that if
                    // the project is already in a collection, it will just return the cached one. For this reason, and the fact we don't want the project to
                    // appear in the global project collection, the file is opened in a new collection which we will discard when done.
                    try
                    {
                        ProjectCollection thisCollection = new ProjectCollection();
                        var newProject = ProjectRootElement.Open(_projectVsServices.Project.FullPath, thisCollection);

                        // First copy to a temp project, so that any failures will not corrupt the users project.
                        ProjectRootElement.Create().DeepCopyFrom(newProject);

                        msbuildProject.RemoveAllChildren();
                        msbuildProject.DeepCopyFrom(newProject);

                        // There isn't a way to clear the dirty flag on the project xml, so to work around that the project is saved
                        // to a StringWriter.
                        var tw = new StringWriter();
                        msbuildProject.Save(tw);

                        thisCollection.UnloadAllProjects();
                    }
                    catch (Microsoft.Build.Exceptions.InvalidProjectFileException)
                    {
                        // Indicate we weren't able to complete the action. We want to do a normal reload
                        return(ProjectReloadResult.ReloadFailed);
                    }
                    catch (Exception ex)
                    {
                        // Any other exception likely mean the msbuildProject is not in a good state. Example, DeepCopyFrom failed.
                        // The only safe thing to do at this point is to reload the project in the solution
                        // TODO: should we have an additional return value here to indicate that the existing project could be in a bad
                        // state and the reload needs to happen without the user being able to block it?
                        System.Diagnostics.Debug.Assert(false, "Replace xml failed with: " + ex.Message);
                        return(ProjectReloadResult.ReloadFailed);
                    }
                }
            }

            // It is important to wait for the new tree to be published to ensure all updates have occurred before the reload manager
            // releases its hold on the UI thread. This prevents unnecessary race conditions and prevent the user
            // from interacting with the project until the evaluation has completed.
            await _projectVsServices.ProjectTree.TreeService.PublishLatestTreeAsync(blockDuringLoadingTree : true).ConfigureAwait(false);

            return(ProjectReloadResult.ReloadCompleted);
        }
        private void VerifyPackageReferences(string filePath, IReadOnlyDictionary <string, PackageVersionVariable> versionVariables)
        {
            ProjectRootElement doc;

            try
            {
                doc = ProjectRootElement.Open(filePath);
            }
            catch (InvalidProjectFileException ex)
            {
                Log.LogError(null, null, null, filePath, 0, 0, 0, 0, message: "Invalid project file: " + ex.Message);
                return;
            }

            var packageReferences = doc.Items.Where(i => i.ItemType == "PackageReference");

            foreach (var pkgRef in packageReferences)
            {
                var id = pkgRef.Include;

                if (string.IsNullOrEmpty(id))
                {
                    // this node is an Update or Remove node
                    continue;
                }

                var versionMetadata = pkgRef.Metadata.LastOrDefault(m => m.Name == "Version");
                var versionRaw      = versionMetadata?.Value;
                if (versionMetadata == null || string.IsNullOrEmpty(versionRaw))
                {
                    Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageReferenceDoesNotHaveVersion, $"PackageReference to {id} does not define a Version");
                    continue;
                }

                var versionIsVariable =
                    versionRaw != null &&
                    versionRaw.Length > 3 &&
                    versionRaw[0] == '$' &&
                    versionRaw[1] == '(' &&
                    versionRaw[versionRaw.Length - 1] == ')' &&
                    versionRaw.IndexOf(')') == versionRaw.Length - 1;

                if (!versionIsVariable)
                {
                    Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageRefHasLiteralVersion, "PackageReference must use an MSBuild variable to set the version.");
                    continue;
                }

                var versionVarName = versionRaw.Substring(2, versionRaw.Length - 3);

                if (!versionVariables.TryGetValue(versionVarName, out var variable))
                {
                    Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.VariableNotFoundInDependenciesPropsFile, $"The variable {versionRaw} could not be found in {DependenciesFile}");
                    continue;
                }

                var versionValue = variable.Version;
                if (!VersionRange.TryParse(versionValue, out var nugetVersion))
                {
                    Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.InvalidPackageVersion, $"PackageReference to {id} has an invalid version identifier: '{versionValue}'");
                    continue;
                }

                if (nugetVersion.IsFloating)
                {
                    Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageRefHasFloatingVersion, $"PackageReference to {id} uses a floating version: '{versionValue}'");
                }
            }
        }
Ejemplo n.º 14
0
        public void ConcurrentProjectOpenAndCloseThroughProjectRootElement()
        {
            int iterations = 500;

            string[] paths = ObjectModelHelpers.GetTempFiles(iterations);

            try
            {
                var projects = new ProjectRootElement[iterations];

                var collection = new ProjectCollection();
                int counter    = 0;
                int remaining  = iterations;
                var done       = new ManualResetEvent(false);

                for (int i = 0; i < iterations; i++)
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        var current = Interlocked.Increment(ref counter) - 1;

                        CreatePREWithSubstantialContent().Save(paths[current]);
                        projects[current] = ProjectRootElement.Open(paths[current], collection);

                        if (Interlocked.Decrement(ref remaining) == 0)
                        {
                            done.Set();
                        }
                    });
                }

                done.WaitOne();

                counter   = 0;
                remaining = iterations;
                done.Reset();

                for (int i = 0; i < iterations; i++)
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        var current = Interlocked.Increment(ref counter) - 1;

                        collection.UnloadProject(projects[current]);

                        if (Interlocked.Decrement(ref remaining) == 0)
                        {
                            done.Set();
                        }
                    });
                }

                done.WaitOne();
            }
            finally
            {
                for (int i = 0; i < iterations; i++)
                {
                    File.Delete(paths[i]);
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Clear out the project's construction model and add a simple SDK-based project to get a baseline.
        /// We need to use the same name as the original csproj and same path so that all the default that derive
        /// from name\path get the right values (there are a lot of them).
        /// </summary>
        private bool TryCreateSdkBaselineProject(string projectFilePath, IProject project, IProjectRootElement root, ImmutableDictionary <string, ImmutableDictionary <string, string> > configurations, string tfm, bool keepCurrentTFMs, [NotNullWhen(true)] out BaselineProject?baselineProject)
        {
            var projectStyle = GetProjectStyle(root);
            var outputType   = GetProjectOutputType(root);
            var rootElement  = ProjectRootElement.Open(projectFilePath);

            rootElement.RemoveAllChildren();
            switch (projectStyle)
            {
            case ProjectStyle.Default:
            case ProjectStyle.DefaultSubset:
            case ProjectStyle.MSTest:
                rootElement.Sdk = MSBuildFacts.DefaultSDKAttribute;
                break;

            case ProjectStyle.WindowsDesktop:
                rootElement.Sdk =
                    tfm.ContainsIgnoreCase(MSBuildFacts.Net5)
                            ? MSBuildFacts.DefaultSDKAttribute
                            : DesktopFacts.WinSDKAttribute; // pre-.NET 5 apps need a special SDK attribute.
                break;

            case ProjectStyle.Web:
                rootElement.Sdk = WebFacts.WebSDKAttribute;
                break;

            default:
                baselineProject = null;
                return(false);
            }

            var propGroup = rootElement.AddPropertyGroup();

            propGroup.AddProperty(MSBuildFacts.TargetFrameworkNodeName, project.GetTargetFramework());

            var outputTypeValue = outputType switch
            {
                ProjectOutputType.Exe => MSBuildFacts.ExeOutputType,
                ProjectOutputType.Library => MSBuildFacts.LibraryOutputType,
                ProjectOutputType.WinExe => MSBuildFacts.WinExeOutputType,
                _ => project.GetPropertyValue(MSBuildFacts.OutputTypeNodeName)
            };

            propGroup.AddProperty(MSBuildFacts.OutputTypeNodeName, outputTypeValue ?? throw new InvalidOperationException($"OutputType is not set! '{projectFilePath}'"));

            if (projectStyle == ProjectStyle.WindowsDesktop)
            {
                if (MSBuildHelpers.IsWinForms(root))
                {
                    MSBuildHelpers.AddUseWinForms(propGroup);
                }

                if (MSBuildHelpers.IsWPF(root))
                {
                    MSBuildHelpers.AddUseWPF(propGroup);
                }

                // User is referencing WindowsBase only
                if (MSBuildHelpers.IsDesktop(root) && !MSBuildHelpers.HasWPFOrWinForms(propGroup))
                {
                    MSBuildHelpers.AddUseWinForms(propGroup);
                }
            }

            // Create a new collection because a project with this name has already been loaded into the global collection.
            using var pc = new ProjectCollection();
            var newProject = new UnconfiguredProject(configurations);

            newProject.LoadProjects(pc, rootElement);

            // If the original project had the TargetFramework property don't touch it during conversion.
            var propertiesInTheBaseline = ImmutableArray.Create(MSBuildFacts.OutputTypeNodeName);

            if (project.GetProperty(MSBuildFacts.TargetFrameworkNodeName) is { })
Ejemplo n.º 16
0
        public void GeneratesFile()
        {
            var engine = new MockEngine(_output);
            var task   = new GeneratePackageVersionPropsFile
            {
                BuildEngine = engine,
                Packages    = new[]
                {
                    // Order is important. These are intentionally reverse sorted to ensure the generated file sorts properties by prop name
                    new TaskItem("Newtonsoft.Json", new Hashtable {
                        ["Version"] = "10.0.3", ["VariableName"] = "JsonNetVersion"
                    }),
                    new TaskItem("Microsoft.Azure", new Hashtable {
                        ["Version"] = "1.2.0"
                    }),
                    new TaskItem("Another.Package", new Hashtable {
                        ["Version"] = "0.0.1", ["TargetFramework"] = "netstandard1.0"
                    }),
                },
                OutputPath = _tempFile,
            };

            Assert.True(task.Execute(), "Task is expected to pass");

            var project = ProjectRootElement.Open(_tempFile);

            _output.WriteLine(File.ReadAllText(_tempFile));

            Assert.Empty(project.Imports);
            Assert.Empty(project.ImportGroups);

            var defaultPropGroup = Assert.Single(project.PropertyGroups, pg => string.IsNullOrEmpty(pg.Label));
            var allProjectsProp  = Assert.Single(defaultPropGroup.Properties);

            Assert.Equal("MSBuildAllProjects", allProjectsProp.Name);
            Assert.Empty(allProjectsProp.Condition);
            Assert.Equal("$(MSBuildAllProjects);$(MSBuildThisFileFullPath)", allProjectsProp.Value);

            var versions = Assert.Single(project.PropertyGroups, pg => pg.Label == "Package Versions");

            // Order is important. These should be sorted.
            Assert.Collection(versions.Properties,
                              p =>
            {
                Assert.Equal("AnotherPackagePackageVersion", p.Name);
                Assert.Equal("Another.Package", p.Label);
                Assert.Equal("0.0.1", p.Value);
                Assert.Empty(p.Condition);
            },
                              p =>
            {
                Assert.Equal("JsonNetVersion", p.Name);
                Assert.Equal("Newtonsoft.Json", p.Label);
                Assert.Equal("10.0.3", p.Value);
                Assert.Empty(p.Condition);
            },
                              p =>
            {
                Assert.Equal("MicrosoftAzurePackageVersion", p.Name);
                Assert.Equal("Microsoft.Azure", p.Label);
                Assert.Equal("1.2.0", p.Value);
                Assert.Empty(p.Condition);
            });
        }
Ejemplo n.º 17
0
        private static ExitCodes OnInstallCommand(string versionJsonRoot, string version, IReadOnlyList <string> sources)
        {
            if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver))
            {
                Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec.");
                return(ExitCodes.InvalidVersionSpec);
            }

            var options = new VersionOptions
            {
                Version = semver,
                PublicReleaseRefSpec = new string[]
                {
                    @"^refs/heads/master$",
                    @"^refs/heads/v\d+(?:\.\d+)?$",
                },
                CloudBuild = new VersionOptions.CloudBuildOptions
                {
                    BuildNumber = new VersionOptions.CloudBuildNumberOptions
                    {
                        Enabled = true,
                    },
                },
            };
            string searchPath = GetSpecifiedOrCurrentDirectoryPath(versionJsonRoot);

            if (!Directory.Exists(searchPath))
            {
                Console.Error.WriteLine("\"{0}\" is not an existing directory.", searchPath);
                return(ExitCodes.NoGitRepo);
            }

            using var context = GitContext.Create(searchPath, writable: true);
            if (!context.IsRepository)
            {
                Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath);
                return(ExitCodes.NoGitRepo);
            }

            if (string.IsNullOrEmpty(versionJsonRoot))
            {
                versionJsonRoot = context.WorkingTreePath;
            }

            var existingOptions = context.VersionFile.GetVersion();

            if (existingOptions != null)
            {
                if (!string.IsNullOrEmpty(version))
                {
                    var setVersionExitCode = OnSetVersionCommand(versionJsonRoot, version);
                    if (setVersionExitCode != ExitCodes.OK)
                    {
                        return(setVersionExitCode);
                    }
                }
            }
            else
            {
                string versionJsonPath = context.VersionFile.SetVersion(versionJsonRoot, options);
                context.Stage(versionJsonPath);
            }

            // Create/update the Directory.Build.props file in the directory of the version.json file to add the NB.GV package.
            string             directoryBuildPropsPath = Path.Combine(versionJsonRoot, "Directory.Build.props");
            ProjectRootElement propsFile = File.Exists(directoryBuildPropsPath)
                ? ProjectRootElement.Open(directoryBuildPropsPath)
                : ProjectRootElement.Create(directoryBuildPropsPath);

            const string PackageReferenceItemType = "PackageReference";

            if (!propsFile.Items.Any(i => i.ItemType == PackageReferenceItemType && i.Include == PackageId))
            {
                // Validate given sources
                foreach (var source in sources)
                {
                    if (!Uri.TryCreate(source, UriKind.Absolute, out var _))
                    {
                        Console.Error.WriteLine($"\"{source}\" is not a valid NuGet package source.");
                        return(ExitCodes.InvalidNuGetPackageSource);
                    }
                }

                string packageVersion = GetLatestPackageVersionAsync(PackageId, versionJsonRoot, sources).GetAwaiter().GetResult();
                if (string.IsNullOrEmpty(packageVersion))
                {
                    string verifyPhrase = sources.Any()
                        ? "Please verify the given 'source' option(s)."
                        : "Please verify the package sources in the NuGet.Config files.";
                    Console.Error.WriteLine($"Latest stable version of the {PackageId} package could not be determined. " + verifyPhrase);
                    return(ExitCodes.PackageIdNotFound);
                }

                var item = propsFile.AddItem(
                    PackageReferenceItemType,
                    PackageId,
                    new Dictionary <string, string>
                {
                    { "Version", packageVersion },
                    { "PrivateAssets", "all" },
                });
                item.Condition = "!Exists('packages.config')";

                propsFile.Save(directoryBuildPropsPath);
            }

            context.Stage(directoryBuildPropsPath);

            return(ExitCodes.OK);
        }
Ejemplo n.º 18
0
        int IVsProjectUpgradeViaFactory.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pUpgradeRequired       = 0;
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName))
            {
                pUpgradeProjectCapabilityFlags = 0;
                return(VSConstants.E_INVALIDARG);
            }


            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                if (upgradeRequired != ProjectUpgradeState.NotNeeded)
                {
                    pUpgradeRequired = 1;
                }
            } catch (Exception ex) {
                if (ex.IsCriticalException())
                {
                    throw;
                }
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                CommonUtils.ActivityLogError(GetType().FullName, ex.ToString());
                pUpgradeRequired = 0;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID)
            {
                pguidNewProjectFactory = Guid.Empty;
            }

            return(VSConstants.S_OK);
        }
Ejemplo n.º 19
0
        public static string[] GetIncludeFiles(string projectPath, string itemType)
        {
            var result        = new List <string>();
            var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");

            var root = ProjectRootElement.Open(projectPath);

            Debug.Assert(root != null);

            if (root.AreDefaultCompileItemsEnabled())
            {
                var excluded = new List <string>();
                result.AddRange(existingFiles);

                foreach (var item in root.Items)
                {
                    if (string.IsNullOrEmpty(item.Condition))
                    {
                        continue;
                    }

                    if (item.ItemType != itemType)
                    {
                        continue;
                    }


                    string normalizedRemove = item.Remove.NormalizePath();

                    var glob = MSBuildGlob.Parse(normalizedRemove);

                    excluded.AddRange(result.Where(includedFile => glob.IsMatch(includedFile)));
                }

                result.RemoveAll(f => excluded.Contains(f));
            }

            foreach (var itemGroup in root.ItemGroups)
            {
                if (itemGroup.Condition.Length != 0)
                {
                    continue;
                }

                foreach (var item in itemGroup.Items)
                {
                    if (item.ItemType != itemType)
                    {
                        continue;
                    }

                    string normalizedInclude = item.Include.NormalizePath();

                    var glob = MSBuildGlob.Parse(normalizedInclude);

                    foreach (var existingFile in existingFiles)
                    {
                        if (glob.IsMatch(existingFile))
                        {
                            result.Add(existingFile);
                        }
                    }
                }
            }

            return(result.ToArray());
        }
        public override bool Execute()
        {
            var vstemplate      = XDocument.Load(VsTemplateShell);
            var workingTemplate = XDocument.Load(VsTemplateShell);

            // var workingTemplate = XDocument.Parse(@"<VSTemplate Version=""3.0.0"" xmlns=""http://schemas.microsoft.com/developer/vstemplate/2005"" Type=""Project"" />");

            if (vstemplate.Root == null || workingTemplate.Root == null)
            {
                return(false);
            }

            // var templateData = new XElement(XName.Get("TemplateData", VsTemplateSchema));
            // workingTemplate.Root.Add(templateData);
            // MergeTemplateData(templateData, vstemplate.Root.Element(XName.Get("TemplateData", VsTemplateSchema)));

            var project         = ProjectRootElement.Open(GetProjectFile(vstemplate));
            var realProjectFile = Path.GetFileName(project.FullPath);

            if (realProjectFile == null)
            {
                return(false);
            }

            var projectExtension = Path.GetExtension(project.FullPath);

            if (projectExtension == null)
            {
                return(false);
            }

            var      templateContentElement = vstemplate.Root.Element(XName.Get("TemplateContent", VsTemplateSchema));
            XElement projectElement         = null;

            if (templateContentElement != null)
            {
                var element = templateContentElement.Element(XName.Get("Project", VsTemplateSchema));

                if (element != null)
                {
                    projectElement = XElement.Parse(element.ToString());
                }

                templateContentElement.Remove();
            }

            var tcToRemove = workingTemplate.Root.Element(XName.Get("TemplateContent", VsTemplateSchema));

            if (tcToRemove != null)
            {
                tcToRemove.Remove();
            }

            templateContentElement = new XElement(XName.Get("TemplateContent", VsTemplateSchema));
            templateContentElement.Add(projectElement);

            if (projectElement == null)
            {
                projectElement = new XElement(XName.Get("Project", VsTemplateSchema));
                templateContentElement.Add(projectElement);
            }
            //else {
            //    projectElement.RemoveAttributes();
            //}
            // instead of calling RemoveAttribute and then Add we can just call SetAttributeValue below so that we don't
            // remove any attributes we are not aware of


            if (UpdateProjectElement)
            {
                projectElement.SetAttributeValue(XName.Get("TargetFileName"), "$safeprojectname$" + projectExtension);
                projectElement.SetAttributeValue(XName.Get("File"), realProjectFile);
                projectElement.SetAttributeValue(XName.Get("ReplaceParameters"), true);
            }

            // projectElement.Add(new XAttribute(XName.Get("TargetFileName"), "$safeprojectname$" + projectExtension));
            // projectElement.Add(new XAttribute(XName.Get("File"), realProjectFile));
            // projectElement.Add(new XAttribute(XName.Get("ReplaceParameters"), true));

            workingTemplate.Root.Add(templateContentElement);
            var sourceFileNames = new HashSet <string>();
            var targetFileNames = new HashSet <string>();

            List <string> filesToExclude = GetFilesToExlucudeAsList();

            RecurseItems(projectElement, sourceFileNames, targetFileNames);
            _filesToCopy = new List <string>();
            var itemsToMerge = new List <string>();

            foreach (var item in project.Items)
            {
                if (!IsPotentialSourceFile(item))
                {
                    continue;
                }

                var name      = item.Include;
                var lowerName = name.ToLower();

                if (targetFileNames.Contains(lowerName))
                {
                    continue;
                }

                if (filesToExclude.Contains(lowerName))
                {
                    continue;
                }

                if (item.ItemType != "Folder")
                {
                    _filesToCopy.Add(name);
                }

                if (!sourceFileNames.Contains(lowerName))
                {
                    itemsToMerge.Add(name);
                }
            }

            //Copy all non-mutated sections
            var mutatedTemplateSections = new[] { "TemplateContent", "TemplateData" };

            // In commit f668a11df0f403520ae1457d3fd5a872ace2107d the entire file is copied first,
            // so this should no longer be needed.
            // var elementsToCopyDirectly = vstemplate.Root.Elements().Where(x => !mutatedTemplateSections.Contains(x.Name.LocalName));
            //foreach (var element in elementsToCopyDirectly) {
            //    var clonedElement = XElement.Parse(element.ToString());
            //    workingTemplate.Root.Add(clonedElement);
            //}

            Merge(projectElement, itemsToMerge);
            workingTemplate.Save(DestinationTemplateLocation);

            FilesToCopy = new ITaskItem[_filesToCopy.Count];
            for (int i = 0; i < FilesToCopy.Length; i++)
            {
                FilesToCopy[i] = new TaskItem(_filesToCopy[i]);
            }

            return(true);
        }
Ejemplo n.º 21
0
        int IVsProjectUpgradeViaFactory.UpgradeProject(
            string bstrFileName,
            uint fUpgradeFlag,
            string bstrCopyLocation,
            out string pbstrUpgradedFullyQualifiedFileName,
            IVsUpgradeLogger pLogger,
            out int pUpgradeRequired,
            out Guid pguidNewProjectFactory
            )
        {
            pbstrUpgradedFullyQualifiedFileName = null;

            // We first run (or re-run) the upgrade check and bail out early if
            // there is actually no need to upgrade.
            var hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                bstrFileName,
                pLogger,
                out pUpgradeRequired,
                out pguidNewProjectFactory,
                out var dummy
                );

            if (!ErrorHandler.Succeeded(hr))
            {
                return(hr);
            }

            var logger = new UpgradeLogger(bstrFileName, pLogger);

            var  backup = (__VSPPROJECTUPGRADEVIAFACTORYFLAGS)fUpgradeFlag;
            bool anyBackup, sxsBackup, copyBackup;

            anyBackup = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED);
            if (anyBackup)
            {
                sxsBackup  = backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP);
                copyBackup = !sxsBackup && backup.HasFlag(__VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP);
            }
            else
            {
                sxsBackup = copyBackup = false;
            }

            if (copyBackup)
            {
                throw new NotSupportedException("PUVFF_COPYBACKUP is not supported");
            }

            pbstrUpgradedFullyQualifiedFileName = bstrFileName;

            if (pUpgradeRequired == 0 && !copyBackup)
            {
                // No upgrade required, and no backup required.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                return(VSConstants.S_OK);
            }

            try
            {
                UpgradeLogger logger2      = null;
                var           userFileName = bstrFileName + ".user";
                if (File.Exists(userFileName))
                {
                    logger2 = new UpgradeLogger(userFileName, pLogger);
                }
                else
                {
                    userFileName = null;
                }

                if (sxsBackup)
                {
                    // For SxS backups we want to put the old project file alongside
                    // the current one.
                    bstrCopyLocation = Path.GetDirectoryName(bstrFileName);
                }

                if (anyBackup)
                {
                    var namePart          = Path.GetFileNameWithoutExtension(bstrFileName);
                    var extPart           = Path.GetExtension(bstrFileName) + (sxsBackup ? ".old" : "");
                    var projectFileBackup = Path.Combine(bstrCopyLocation, namePart + extPart);
                    for (var i = 1; File.Exists(projectFileBackup); ++i)
                    {
                        projectFileBackup = Path.Combine(
                            bstrCopyLocation,
                            string.Format("{0}{1}{2}", namePart, i, extPart)
                            );
                    }

                    File.Copy(bstrFileName, projectFileBackup);

                    // Back up the .user file if there is one
                    if (userFileName != null)
                    {
                        if (sxsBackup)
                        {
                            File.Copy(
                                userFileName,
                                Path.ChangeExtension(projectFileBackup, ".user.old")
                                );
                        }
                        else
                        {
                            File.Copy(userFileName, projectFileBackup + ".old");
                        }
                    }

                    // TODO: Implement support for backing up all files
                    //if (copyBackup) {
                    //  - Open the project
                    //  - Inspect all Items
                    //  - Copy those items that are referenced relative to the
                    //    project file into bstrCopyLocation
                    //}
                }

                if (this.site.GetService(typeof(SVsQueryEditQuerySave)) is IVsQueryEditQuerySave2 queryEdit)
                {
                    var tagVSQueryEditFlags_QEF_AllowUnopenedProjects = (tagVSQueryEditFlags)0x80;

                    ErrorHandler.ThrowOnFailure(queryEdit.QueryEditFiles(
                                                    (uint)(tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting |
                                                           tagVSQueryEditFlags.QEF_DisallowInMemoryEdits |
                                                           tagVSQueryEditFlags_QEF_AllowUnopenedProjects),
                                                    1,
                                                    new[] { bstrFileName },
                                                    null,
                                                    null,
                                                    out var editVerdict,
                                                    out var queryEditMoreInfo
                                                    ));

                    if (editVerdict != (uint)tagVSQueryEditResult.QER_EditOK)
                    {
                        logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UpgradeCannotCheckOutProject));
                        return(VSConstants.E_FAIL);
                    }

                    // File may have been updated during checkout, so check
                    // again whether we need to upgrade.
                    if ((queryEditMoreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0)
                    {
                        hr = ((IVsProjectUpgradeViaFactory)this).UpgradeProject_CheckOnly(
                            bstrFileName,
                            pLogger,
                            out pUpgradeRequired,
                            out pguidNewProjectFactory,
                            out dummy
                            );

                        if (!ErrorHandler.Succeeded(hr))
                        {
                            return(hr);
                        }
                        if (pUpgradeRequired == 0)
                        {
                            logger.Log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradeNotRequired));
                            return(VSConstants.S_OK);
                        }
                    }
                }

                // Load the project file and user file into MSBuild as plain
                // XML to make it easier for subclasses.
                var projectXml = ProjectRootElement.Open(bstrFileName);
                if (projectXml == null)
                {
                    throw new Exception(SR.GetString(SR.UpgradeCannotLoadProject));
                }

                var userXml = userFileName != null?ProjectRootElement.Open(userFileName) : null;

                // Invoke our virtual UpgradeProject function. If it fails, it
                // will throw and we will log the exception.
                UpgradeProject(ref projectXml, ref userXml, logger.Log);

                // Get the SCC info from the project file.
                if (projectXml != null)
                {
                    this._cachedSccProject     = bstrFileName;
                    this._cachedSccProjectName = string.Empty;
                    this._cachedSccAuxPath     = string.Empty;
                    this._cachedSccLocalPath   = string.Empty;
                    this._cachedSccProvider    = string.Empty;
                    foreach (var property in projectXml.Properties)
                    {
                        switch (property.Name)
                        {
                        case ProjectFileConstants.SccProjectName:
                            this._cachedSccProjectName = property.Value;
                            break;

                        case ProjectFileConstants.SccAuxPath:
                            this._cachedSccAuxPath = property.Value;
                            break;

                        case ProjectFileConstants.SccLocalPath:
                            this._cachedSccLocalPath = property.Value;
                            break;

                        case ProjectFileConstants.SccProvider:
                            this._cachedSccProvider = property.Value;
                            break;

                        default:
                            break;
                        }
                    }
                }

                // Save the updated files.
                if (projectXml != null)
                {
                    projectXml.Save();
                }
                if (userXml != null)
                {
                    userXml.Save();
                }

                // Need to add "Converted" (unlocalized) to the report because
                // the XSLT refers to it.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_STATUSMSG, "Converted");
                return(VSConstants.S_OK);
            }
            catch (Exception ex) when(!ExceptionExtensions.IsCriticalException(ex))
            {
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try
                {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                }
                catch (InvalidOperationException)
                {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                return(VSConstants.E_FAIL);
            }
        }
Ejemplo n.º 22
0
        public static void MigrateFromOldConfigNames(string projectPath)
        {
            var root = ProjectRootElement.Open(projectPath);

            Debug.Assert(root != null);

            bool dirty = false;

            bool hasGodotProjectGeneratorVersion = false;
            bool foundOldConfiguration           = false;

            foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition == string.Empty))
            {
                if (!hasGodotProjectGeneratorVersion && propertyGroup.Properties.Any(p => p.Name == "GodotProjectGeneratorVersion"))
                {
                    hasGodotProjectGeneratorVersion = true;
                }

                foreach (var configItem in propertyGroup.Properties
                         .Where(p => p.Condition.Trim() == "'$(Configuration)' == ''" && p.Value == "Tools"))
                {
                    configItem.Value      = "Debug";
                    foundOldConfiguration = true;
                    dirty = true;
                }
            }

            if (!hasGodotProjectGeneratorVersion)
            {
                root.PropertyGroups.First(g => g.Condition == string.Empty)?
                .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
                dirty = true;
            }

            if (!foundOldConfiguration)
            {
                var toolsConditions = new[]
                {
                    "'$(Configuration)|$(Platform)' == 'Tools|AnyCPU'",
                    "'$(Configuration)|$(Platform)' != 'Tools|AnyCPU'",
                    "'$(Configuration)' == 'Tools'",
                    "'$(Configuration)' != 'Tools'"
                };

                foundOldConfiguration = root.PropertyGroups
                                        .Any(g => toolsConditions.Any(c => c == g.Condition.Trim()));
            }

            if (foundOldConfiguration)
            {
                void MigrateConfigurationConditions(string oldConfiguration, string newConfiguration)
                {
                    void MigrateConditions(string oldCondition, string newCondition)
                    {
                        foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition))
                        {
                            propertyGroup.Condition = " " + newCondition + " ";
                            dirty = true;
                        }

                        foreach (var propertyGroup in root.PropertyGroups)
                        {
                            foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition))
                            {
                                prop.Condition = " " + newCondition + " ";
                                dirty          = true;
                            }
                        }

                        foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition))
                        {
                            itemGroup.Condition = " " + newCondition + " ";
                            dirty = true;
                        }

                        foreach (var itemGroup in root.ItemGroups)
                        {
                            foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition))
                            {
                                item.Condition = " " + newCondition + " ";
                                dirty          = true;
                            }
                        }
                    }

                    foreach (var op in new[] { "==", "!=" })
                    {
                        MigrateConditions($"'$(Configuration)|$(Platform)' {op} '{oldConfiguration}|AnyCPU'", $"'$(Configuration)|$(Platform)' {op} '{newConfiguration}|AnyCPU'");
                        MigrateConditions($"'$(Configuration)' {op} '{oldConfiguration}'", $"'$(Configuration)' {op} '{newConfiguration}'");
                    }
                }

                MigrateConfigurationConditions("Debug", "ExportDebug");
                MigrateConfigurationConditions("Release", "ExportRelease");
                MigrateConfigurationConditions("Tools", "Debug"); // Must be last
            }


            if (dirty)
            {
                root.Save();
            }
        }
Ejemplo n.º 23
0
        void IVsProjectUpgradeViaFactory4.UpgradeProject_CheckOnly(
            string bstrFileName,
            IVsUpgradeLogger pLogger,
            out uint pUpgradeRequired,
            out Guid pguidNewProjectFactory,
            out uint pUpgradeProjectCapabilityFlags
            )
        {
            pguidNewProjectFactory = Guid.Empty;

            if (!File.Exists(bstrFileName))
            {
                pUpgradeRequired = 0;
                pUpgradeProjectCapabilityFlags = 0;
                return;
            }

            var backupSupport = __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_BACKUPSUPPORTED |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_COPYBACKUP |
                                __VSPPROJECTUPGRADEVIAFACTORYFLAGS.PUVFF_SXSBACKUP;
            var logger = new UpgradeLogger(bstrFileName, pLogger);

            try
            {
                var projectXml      = ProjectRootElement.Open(bstrFileName);
                var userProjectName = bstrFileName + ".user";
                var userProjectXml  = File.Exists(userProjectName) ? ProjectRootElement.Open(userProjectName) : null;

                var upgradeRequired = UpgradeProjectCheck(
                    projectXml,
                    userProjectXml,
                    logger.Log,
                    ref pguidNewProjectFactory,
                    ref backupSupport
                    );

                switch (upgradeRequired)
                {
                case ProjectUpgradeState.SafeRepair:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_SAFEREPAIR;
                    break;

                case ProjectUpgradeState.UnsafeRepair:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_UNSAFEREPAIR;
                    break;

                case ProjectUpgradeState.OneWayUpgrade:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_ONEWAYUPGRADE;
                    break;

                case ProjectUpgradeState.Incompatible:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_INCOMPATIBLE;
                    break;

                case ProjectUpgradeState.Deprecated:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_DEPRECATED;
                    break;

                default:
                case ProjectUpgradeState.NotNeeded:
                    pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
                    break;
                }
            }
            catch (Exception ex) when(!ExceptionExtensions.IsCriticalException(ex))
            {
                // Log the error and don't attempt to upgrade the project.
                logger.Log(__VSUL_ERRORLEVEL.VSUL_ERROR, SR.GetString(SR.UnexpectedUpgradeError, ex.Message));
                try
                {
                    ActivityLog.LogError(GetType().FullName, ex.ToString());
                }
                catch (InvalidOperationException)
                {
                    // Cannot log to ActivityLog. This may occur if we are
                    // outside of VS right now (for example, unit tests).
                    System.Diagnostics.Trace.TraceError(ex.ToString());
                }
                pUpgradeRequired = (uint)__VSPPROJECTUPGRADEVIAFACTORYREPAIRFLAGS.VSPUVF_PROJECT_NOREPAIR;
            }
            pUpgradeProjectCapabilityFlags = (uint)backupSupport;

            // If the upgrade checker set the factory GUID to ourselves, we need
            // to clear it
            if (pguidNewProjectFactory == GetType().GUID)
            {
                pguidNewProjectFactory = Guid.Empty;
            }
        }
        public static DependencyVersionsFile Load(string sourceFile)
        {
            var project = ProjectRootElement.Open(sourceFile, ProjectCollection.GlobalProjectCollection, preserveFormatting: true);

            return(Load(project));
        }
Ejemplo n.º 25
0
        public override bool Execute()
        {
            var collection = new ProjectCollection();
            var xml        = new ConcurrentDictionary <string, XDocument>(StringComparer.OrdinalIgnoreCase);
            var root       = ProjectRootElement.Open(HelpProject, collection);
            var eval       = new Project(root, null, null, collection);

            var logical = eval.GetLogicalProject().ToArray();

            var allProps = logical
                           .OfType <ProjectPropertyElement>()
                           // Add the local props first
                           .Where(x => x.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase))
                           .Concat(logical
                                   .OfType <ProjectPropertyElement>()
                                   .Where(x => !x.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase)))
                           .ToArray();

            var allTargets = logical
                             .OfType <ProjectTargetElement>()
                             // Add the local props first
                             .Where(x => x.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase))
                             .Concat(logical
                                     .OfType <ProjectTargetElement>()
                                     .Where(x => !x.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase)))
                             .ToArray();

            var includeExpr = new Regex(HelpInclude, RegexOptions.IgnoreCase);
            var excludeExpr = new Regex(HelpExclude, RegexOptions.IgnoreCase);
            var searchExpr  = new Regex(HelpSearch, RegexOptions.IgnoreCase);

            // Should exclude it if it doesn't match the include or matches the exclude
            bool ShouldExclude(string value)
            => (!includeExpr.IsMatch(value) || excludeExpr.IsMatch(value));

            bool SatisfiesSearch(string value)
            => string.IsNullOrWhiteSpace(HelpSearch) || searchExpr.IsMatch(value);

            var helpProperties = bool.Parse(HelpProperties);
            var helpTargets    = bool.Parse(HelpTargets);
            var helpImports    = bool.Parse(HelpImports);

            var metaHelp = new StringBuilder();

            metaHelp.Append("Help: properties to customize what 'Help' reports");

            var help     = new StringBuilder();
            var standard =
                allTargets.Any(t => t.Name == "Configure") &&
                allTargets.Any(t => t.Name == "Build") &&
                allTargets.Any(t => t.Name == "Test");

            if (standard)
            {
                help.AppendLine(UseColors ?
                                "Standard: {YES:LawnGreen} √ (Configure, Build and Test targets supported)" :
                                "Standard: YES √ (Configure, Build and Test targets supported)").AppendLine();
            }
            else
            {
                help.AppendLine(UseColors ?
                                "Standard: {NO:Tomato} x (Missing Configure, Build, Test or Run targets. Lean more at http://corebuild.io" :
                                "Standard: NO x (Missing Configure, Build, Test or Run targets. Lean more at http://corebuild.io").AppendLine();
                Log.LogWarning(null, "CB01", null, null, 0, 0, 0, 0, "This project is NOT CoreBuild Standard compatible. Please provide Configure, Build and Test targets. Lean more at http://corebuild.io");
            }

            var hasProps = false;

            if (helpProperties)
            {
                var propsHelp = new StringBuilder();
                propsHelp.Append("Properties:");
                var processed     = new HashSet <string>();
                var alwaysInclude = new HashSet <string>(HelpProperty.Select(x => x.ItemSpec));

                foreach (var prop in allProps
                         .Where(x => x != null && !x.Name.StartsWith("_"))
                         .OrderBy(x => x.Name))
                {
                    // First property to make it to the list wins.
                    // Target project source is loaded first, followed by imported properties.
                    if (processed.Contains(prop.Name))
                    {
                        continue;
                    }

                    var isMeta  = Path.GetFileName(prop.Location.File) == "CoreBuild.Help.targets";
                    var builder = isMeta ? metaHelp : propsHelp;

                    if (!alwaysInclude.Contains(prop.Name))
                    {
                        // Skip non-meta props that should be excluded
                        if (!isMeta && ShouldExclude(prop.Name))
                        {
                            processed.Add(prop.Name);
                            continue;
                        }

                        var isLocal = prop.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase);
                        // Skip non-meta props that are from imports as needed
                        if (!isMeta && !helpImports && !isLocal)
                        {
                            processed.Add(prop.Name);
                            continue;
                        }
                    }

                    var candidate = new CandidateElement(prop.Name, allProps.Where(x => x.Name == prop.Name), xml);
                    if (candidate.IsHidden)
                    {
                        processed.Add(prop.Name);
                        continue;
                    }

                    if (isMeta || alwaysInclude.Contains(prop.Name) || SatisfiesSearch(prop.Name) || SatisfiesSearch(candidate.Comment))
                    {
                        // We got a prop. Flag if non-meta
                        if (!isMeta)
                        {
                            hasProps = true;
                        }

                        if (isMeta)
                        {
                            builder.AppendLine().Append($"\t- {prop.Name}");
                        }
                        else
                        {
                            builder.AppendLine().Append(UseColors ?
                                                        $"\t- {{{prop.Name}:Aqua}}" :
                                                        $"\t- {prop.Name}");
                        }

                        if (!string.IsNullOrWhiteSpace(candidate.Comment))
                        {
                            AppendComment(builder, prop.Name, candidate.Comment);
                        }

                        processed.Add(prop.Name);
                    }
                }

                if (hasProps)
                {
                    help.Append(propsHelp.ToString());
                }
            }

            if (helpTargets)
            {
                var hasTargets  = false;
                var targetsHelp = new StringBuilder();
                if (hasProps)
                {
                    targetsHelp.AppendLine().AppendLine();
                }

                targetsHelp.Append("Targets:");
                var processed     = new HashSet <string>();
                var alwaysInclude = new HashSet <string>(HelpTarget.Select(x => x.ItemSpec));

                foreach (var target in allTargets
                         .Where(x => x.Name != "Help" && !x.Name.StartsWith("_"))
                         .OrderBy(x => x.Name))
                {
                    // First target to make it to the list wins.
                    // Target project source is loaded first, followed by imported targets.
                    if (processed.Contains(target.Name))
                    {
                        continue;
                    }

                    if (!alwaysInclude.Contains(target.Name))
                    {
                        var isLocal = target.Location.File.Equals(HelpProject, StringComparison.OrdinalIgnoreCase);
                        // Skip targets that should be excluded
                        if (ShouldExclude(target.Name) ||
                            // Skip targets that are from imports as needed
                            (!helpImports && !isLocal))
                        {
                            processed.Add(target.Name);
                            continue;
                        }
                    }

                    var candidate = new CandidateElement(target.Name, allTargets.Where(x => x.Name == target.Name), xml);
                    if (candidate.IsHidden)
                    {
                        processed.Add(target.Name);
                        continue;
                    }

                    if (alwaysInclude.Contains(target.Name) || SatisfiesSearch(target.Name) || SatisfiesSearch(candidate.Comment))
                    {
                        hasTargets = true;
                        targetsHelp.AppendLine().Append(UseColors ?
                                                        $"\t- {{{target.Name}:Yellow}}" :
                                                        $"\t- {target.Name}");
                        if (!string.IsNullOrWhiteSpace(candidate.Comment))
                        {
                            AppendComment(targetsHelp, target.Name, candidate.Comment);
                        }
                    }
                }

                if (hasTargets)
                {
                    help.Append(targetsHelp.ToString());
                }
            }

            help.AppendLine();
            metaHelp.AppendLine();
            Log.LogMessage(MessageImportance.High, help.ToString());
            Log.LogMessage(MessageImportance.Normal, metaHelp.ToString());

            return(true);
        }
Ejemplo n.º 26
0
        static void Main(string[] args)
        {
            var sdkRootPath = args[0];

            var beforeCommonSdkTargetsFilePath = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.BeforeCommon.targets");
            var commonSdkTargetsFilePath       = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.Common.targets");
            var sdkTargetsFilePath             = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.targets");
            var sdkPropsFilePath      = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.props");
            var csharpTargetsFilePath = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.CSharp.targets");
            var csharpPropsFilePath   = Path.Combine(sdkRootPath, "src", "Tasks", "Microsoft.NET.Build.Tasks", "build", "Microsoft.NET.Sdk.CSharp.props");

            var beforeCommonSdkTargetsFile = ProjectRootElement.Open(beforeCommonSdkTargetsFilePath);
            var commonSdkTargetsFile       = ProjectRootElement.Open(commonSdkTargetsFilePath);
            var sdkTargetsFile             = ProjectRootElement.Open(sdkTargetsFilePath);
            var sdkPropsFile      = ProjectRootElement.Open(sdkPropsFilePath);
            var csharpPropsFile   = ProjectRootElement.Open(csharpPropsFilePath);
            var csharpTargetsFile = ProjectRootElement.Open(csharpTargetsFilePath);

            var allProperties = new List <DefaultProjectPropertyInfo>();
            var allItems      = new List <DefaultProjectItemInfo>();

            AddPropertyDefault(allProperties, sdkPropsFile, "OutputType");
            AddPropertyDefault(allProperties, sdkPropsFile, "Configuration", ignoreConditions: true);
            AddPropertyDefault(allProperties, sdkPropsFile, "Platform");
            AddPropertyDefault(allProperties, sdkPropsFile, "FileAlignment");
            AddPropertyDefault(allProperties, sdkPropsFile, "PlatformTarget");
            AddPropertyDefault(allProperties, sdkPropsFile, "ErrorReport");
            AddPropertyDefault(allProperties, sdkPropsFile, "AssemblyName");
            AddPropertyDefault(allProperties, sdkPropsFile, "RootNamespace");
            AddPropertyDefault(allProperties, sdkPropsFile, "Deterministic");

            AddPropertyDefault(allProperties, csharpPropsFile, "WarningLevel");
            AddPropertyDefault(allProperties, csharpPropsFile, "NoWarn");

            AddHardcodedPropertyDefault(allProperties, "PackageRequireLicenseAcceptance", "false");

            AddConfigurationPropertyDefaults(allProperties, sdkPropsFile, "Debug");
            AddConfigurationPropertyDefaults(allProperties, sdkPropsFile, "Release");

            AddConfigurationPropertyDefaults(allProperties, csharpPropsFile, "Debug");
            AddConfigurationPropertyDefaults(allProperties, csharpPropsFile, "Release");

            AddPropertyDefault(allProperties, commonSdkTargetsFile, "VersionPrefix", ignoreConditions: true);
            AddPropertyDefault(allProperties, commonSdkTargetsFile, "AssemblyTitle", ignoreConditions: true);
            AddPropertyDefault(allProperties, commonSdkTargetsFile, "Product", ignoreConditions: true);
            AddPropertyDefault(allProperties, commonSdkTargetsFile, "NeutralLanguage", ignoreConditions: true);

            AddPropertyDefault(allProperties, beforeCommonSdkTargetsFile, "AutoUnifyAssemblyReferences", ignoreConditions: true);
            AddPropertyDefault(allProperties, beforeCommonSdkTargetsFile, "DesignTimeAutoUnify", ignoreConditions: true);
            AddPropertyDefault(allProperties, beforeCommonSdkTargetsFile, "TargetExt", ignoreConditions: true);

            AddCompileAndEmbeddedResourceDefaults(allItems, sdkTargetsFile);

            var wrapper = new SerializableMigrationDefaultsInfo()
            {
                Items      = allItems,
                Properties = allProperties
            };

            var    output = Path.Combine(Directory.GetCurrentDirectory(), "sdkdefaults.json");
            string json   = JsonConvert.SerializeObject(wrapper, Formatting.Indented);

            File.WriteAllText(output, json);
        }
Ejemplo n.º 27
0
        List <CustomBuildEval> EvaluateCustomBuild()
        {
            var eval           = new List <CustomBuildEval>();
            var evaluateTarget = new XElement(ns + "Target",
                                              new XAttribute("Name", "EvaluateCustomBuild"),
                                              new XElement(ns + "PropertyGroup",
                                                           new XElement(ns + "CustomBuildEval", "@(CustomBuild->'" +
                                                                        "{%(Identity)}" +
                                                                        "{%(AdditionalInputs)}" +
                                                                        "{%(Outputs)}" +
                                                                        "{%(Message)}" +
                                                                        "{%(Command)}')")));

            this[Files.Project].xml.Root.Add(evaluateTarget);

            var tempProjFile = Path.Combine(
                Path.GetDirectoryName(this[Files.Project].filePath),
                Path.GetRandomFileName());

            if (File.Exists(tempProjFile))
            {
                File.Delete(tempProjFile);
            }
            this[Files.Project].xml.Save(tempProjFile);
            var projRoot = ProjectRootElement.Open(tempProjFile);

            var pattern = new Regex(@"{([^}]+)}{([^}]+)}{([^}]+)}{([^}]+)}{([^}]+)}");

            var projConfigs = this[Files.Project].xml
                              .Elements(ns + "Project")
                              .Elements(ns + "ItemGroup")
                              .Elements(ns + "ProjectConfiguration");

            foreach (var projConfig in projConfigs)
            {
                string configName = (string)projConfig.Attribute("Include");
                var    properties = new Dictionary <string, string>();
                foreach (var configProp in projConfig.Elements())
                {
                    properties.Add(configProp.Name.LocalName, (string)configProp);
                }
                var projInst = new ProjectInstance(projRoot, properties,
                                                   null, new ProjectCollection());
                var buildRequest = new BuildRequestData(
                    projInst, new string[] { "EvaluateCustomBuild" },
                    null, BuildRequestDataFlags.ProvideProjectStateAfterBuild);
                var buildResult = BuildManager.DefaultBuildManager.Build(
                    new BuildParameters(), buildRequest);
                string customBuildEval = buildResult.ProjectStateAfterBuild
                                         .GetPropertyValue("CustomBuildEval");
                foreach (Match cbEval in pattern.Matches(customBuildEval))
                {
                    eval.Add(new CustomBuildEval {
                        ProjectConfig    = configName,
                        Identity         = cbEval.Groups[1].Value,
                        AdditionalInputs = cbEval.Groups[2].Value,
                        Outputs          = cbEval.Groups[3].Value,
                        Message          = cbEval.Groups[4].Value,
                        Command          = cbEval.Groups[5].Value,
                    });
                }
            }

            evaluateTarget.Remove();
            File.Delete(tempProjFile);
            return(eval);
        }
Ejemplo n.º 28
0
 public ProjectRootPathNode(string filePath)
 {
     _filePath = filePath;
     _element  = ProjectRootElement.Open(_filePath);
 }
Ejemplo n.º 29
0
        public static void AddProject(this SlnFile slnFile, string fullProjectPath, IList <string> solutionFolders)
        {
            if (string.IsNullOrEmpty(fullProjectPath))
            {
                throw new ArgumentException();
            }

            var relativeProjectPath = Path.GetRelativePath(
                PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
                fullProjectPath);

            if (slnFile.Projects.Any((p) =>
                                     string.Equals(p.FilePath, relativeProjectPath, StringComparison.OrdinalIgnoreCase)))
            {
                Reporter.Output.WriteLine(string.Format(
                                              CommonLocalizableStrings.SolutionAlreadyContainsProject,
                                              slnFile.FullPath,
                                              relativeProjectPath));
            }
            else
            {
                ProjectRootElement rootElement     = null;
                ProjectInstance    projectInstance = null;
                try
                {
                    rootElement     = ProjectRootElement.Open(fullProjectPath);
                    projectInstance = new ProjectInstance(rootElement);
                }
                catch (InvalidProjectFileException e)
                {
                    Reporter.Error.WriteLine(string.Format(
                                                 CommonLocalizableStrings.InvalidProjectWithExceptionMessage,
                                                 fullProjectPath,
                                                 e.Message));
                    return;
                }

                var slnProject = new SlnProject
                {
                    Id       = projectInstance.GetProjectId(),
                    TypeGuid = rootElement.GetProjectTypeGuid() ?? projectInstance.GetDefaultProjectTypeGuid(),
                    Name     = Path.GetFileNameWithoutExtension(relativeProjectPath),
                    FilePath = relativeProjectPath
                };

                if (string.IsNullOrEmpty(slnProject.TypeGuid))
                {
                    Reporter.Error.WriteLine(
                        string.Format(
                            CommonLocalizableStrings.UnsupportedProjectType,
                            projectInstance.FullPath));
                    return;
                }

                // NOTE: The order you create the sections determines the order they are written to the sln
                // file. In the case of an empty sln file, in order to make sure the solution configurations
                // section comes first we need to add it first. This doesn't affect correctness but does
                // stop VS from re-ordering things later on. Since we are keeping the SlnFile class low-level
                // it shouldn't care about the VS implementation details. That's why we handle this here.
                slnFile.AddDefaultBuildConfigurations();

                slnFile.MapSolutionConfigurationsToProject(
                    projectInstance,
                    slnFile.ProjectConfigurationsSection.GetOrCreatePropertySet(slnProject.Id));

                if (solutionFolders != null)
                {
                    slnFile.AddSolutionFolders(slnProject, solutionFolders);
                }

                slnFile.Projects.Add(slnProject);

                Reporter.Output.WriteLine(
                    string.Format(CommonLocalizableStrings.ProjectAddedToTheSolution, relativeProjectPath));
            }
        }
        public override bool Execute()
        {
            var unifiedPackageList = new Dictionary <string, PackageReferenceInfo>(StringComparer.OrdinalIgnoreCase);

            var projects    = new ProjectInfoFactory(Log).CreateMany(Projects, Properties, false, _cts.Token);
            var packageRefs = projects.SelectMany(p => p.Frameworks).SelectMany(f => f.Dependencies);

            foreach (var packageRef in packageRefs)
            {
                if (packageRef.Value.IsImplicitlyDefined)
                {
                    // skip PackageReferences added by the SDK
                    continue;
                }

                if (packageRef.Value.NoWarn.Contains(KoreBuildErrors.Prefix + KoreBuildErrors.ConflictingPackageReferenceVersions))
                {
                    // Make it possible to suppress version conflicts while generating this file.
                    continue;
                }

                if (unifiedPackageList.TryGetValue(packageRef.Value.Id, out var other))
                {
                    if (other.Version != packageRef.Value.Version)
                    {
                        Log.LogKoreBuildError(KoreBuildErrors.ConflictingPackageReferenceVersions, $"Conflicting dependency versions for {packageRef.Value.Id}: {other.Project.FileName} references '{other.Version}' but {packageRef.Value.Project.FileName} references '{packageRef.Value.Version}'");
                    }
                }
                else
                {
                    unifiedPackageList.Add(packageRef.Value.Id, packageRef.Value);
                    Log.LogMessage(MessageImportance.Low, $"Found {packageRef.Value.Id} = {packageRef.Value.Version}");
                }
            }

            if (Log.HasLoggedErrors)
            {
                return(false);
            }

            var items = unifiedPackageList.Values.Select(p => new TaskItem(p.Id, new Hashtable {
                ["Version"] = p.Version
            })).ToArray();

            var task = new GeneratePackageVersionPropsFile
            {
                AddOverrideImport      = true,
                SuppressVariableLabels = true,
                Packages    = items,
                BuildEngine = BuildEngine,
                HostObject  = HostObject,
                OutputPath  = DependenciesFile,
            };

            if (!task.Execute())
            {
                return(false);
            }

            var otherImports = OtherImports != null
                ? OtherImports.Select(p => p.ItemSpec)
                : Array.Empty <string>();

            foreach (var proj in projects.Select(p => p.FullPath).Concat(otherImports))
            {
                var project = ProjectRootElement.Open(proj, ProjectCollection.GlobalProjectCollection, preserveFormatting: true);
                var changed = false;
                foreach (var item in project.Items.Where(i => i.ItemType == "PackageReference"))
                {
                    var noWarn = item.Metadata.FirstOrDefault(m => m.Name == "NoWarn");
                    if (noWarn != null && noWarn.Value.Contains(KoreBuildErrors.Prefix + KoreBuildErrors.ConflictingPackageReferenceVersions))
                    {
                        continue;
                    }

                    var versionMetadata = item.Metadata.LastOrDefault(p => p.Name == "Version");
                    if (versionMetadata != null && versionMetadata.Value.StartsWith("$("))
                    {
                        continue;
                    }
                    changed = true;

                    var varName = $"$({DependencyVersionsFile.GetVariableName(item.Include)})";
                    if (versionMetadata == null)
                    {
                        item.AddMetadata("Version", varName, expressAsAttribute: true);
                    }
                    else
                    {
                        versionMetadata.Value = varName;
                    }
                }

                if (changed)
                {
                    Log.LogMessage(MessageImportance.High, $"Updated {proj}");
                    project.Save(proj);
                }
                else
                {
                    Log.LogMessage(MessageImportance.Normal, $"Skipping {proj}. Already up to date.");
                }
            }

            return(!Log.HasLoggedErrors);
        }