/// <summary> /// Recursively detect all dependencies /// </summary> /// <param name="allProjPackages"></param> /// <returns></returns> public List <string> ResolveRecursiveDependencies(HashSet <PackagesConfig> allPackages) { if (impliedDependencies_ != null) { return(impliedDependencies_); } impliedDependencies_ = new List <string>(Dependencies); foreach (string dep in Dependencies) { // Dependency is not a local project or has no dependencies of its own? PackagesConfig pcDep = allPackages.FirstOrDefault((pc) => dep.Equals(pc.Id)); if (pcDep == null) { continue; } List <string> depDep = pcDep.ResolveRecursiveDependencies(allPackages); if (depDep.Contains(Id)) { throw new Exception($"Cyclic dependency discovered {Id} <--> {dep}"); } impliedDependencies_.AddRange(depDep); } return(impliedDependencies_); }
public ProjectMigrator(TaskLoggingHelper logger, ITaskItem proj, ITaskItem[] allProjects, string packageVersion) { logger_ = logger; projectItem_ = proj; packageVersion_ = packageVersion; string prjFile = proj.GetMetadata("FullPath"); if (string.IsNullOrWhiteSpace(prjFile) || !File.Exists(prjFile)) { throw new FileNotFoundException(proj.ItemSpec); } allProjects_ = new HashSet <ITaskItem>(allProjects); globalProps_ = new Dictionary <string, string>(); if (!globalProps_.ContainsKey("SolutionDir")) { string solutionDir = Path.GetDirectoryName(prjFile); globalProps_["SolutionDir"] = solutionDir; } string moreProps = $"{proj.GetMetadata("Properties")};{proj.GetMetadata("AdditionalProperties")}"; string[] morePropsList = moreProps.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string kv in morePropsList) { int i = kv.IndexOf('='); if (i > 0) { string k = kv.Substring(0, i); string v = kv.Substring(1 + i); globalProps_[k] = v; } } packagesConfig_ = PackagesConfig.Create(projectItem_, PackageIdPrefix); if (packagesConfig_ == null) { logger_.LogWarning($"Can't resolve package.config file for '{projectItem_.ItemSpec}"); } string projectFile = projectItem_.GetMetadata("FullPath"); project_ = new Project(projectFile, globalProps_, null); }
private HashSet <PackagesConfig> GetAllPackages() { HashSet <PackagesConfig> allPackages = new HashSet <PackagesConfig>(); // Accumulate package dependencies for all projects. foreach (ITaskItem p in AllProjects) { string projPath = p.GetMetadata("FullPath"); Log.LogMessage(MessageImportance.Low, $"Inspecting '{projPath}'."); if (string.IsNullOrWhiteSpace(projPath) || !File.Exists(projPath)) { Log.LogWarning($"FullPath not found for project {p.ItemSpec}"); continue; } // Project already handled? string projId = PackageIdPrefix + PackagesConfig.GetProjectId(p); if (allPackages.Any((i) => projId.Equals(i.Id))) { continue; } // package.config file exists? PackagesConfig pc = PackagesConfig.Create(p, PackageIdPrefix); if (pc == null) { Log.LogMessage(MessageImportance.Low, $"Can't find packages.config file for '{p.ItemSpec}'."); continue; } Log.LogMessage(MessageImportance.Low, $"Parsing dependencies of '{p.ItemSpec}'."); allPackages.Add(pc); if (cancel_) { Log.LogMessage(MessageImportance.Low, "Exit on cancel signal"); return(null); } } return(allPackages); }
private void ConvertLibToPkg(string libName) { logger_.LogMessage(MessageImportance.Low, $"Inspecting '{libName}'"); foreach (ITaskItem i in allProjects_) { string pp = i.GetMetadata("FullPath"); if (string.IsNullOrEmpty(pp) || !File.Exists(pp)) { continue; } string alias = PackagesConfig.GetProjectId(i); if (!string.IsNullOrEmpty(alias) && alias.Equals(libName, StringComparison.OrdinalIgnoreCase)) { logger_.LogMessage($"Project {projectItem_.ItemSpec}- Converting library reference '{i.ItemSpec}' to Nuget package '{PackageIdPrefix + alias}' version {packageVersion_}"); packagesConfig_.Add(PackageIdPrefix + alias, packageVersion_); break; } } }
public void MigrateProjectReferences() { List <ProjectItem> allProjReferences = new List <ProjectItem>(); foreach (ProjectItem i in project_.GetItemsIgnoringCondition("ProjectReference")) { allProjReferences.Add(i); string refProj = i.GetMetadataValue("FullPath"); if (string.IsNullOrWhiteSpace(refProj) || !File.Exists(refProj)) { logger_.LogWarning($"File not found for project reference {i.UnevaluatedInclude}"); continue; } // Resolve project to package alias string alias = Path.GetFileNameWithoutExtension(refProj); ITaskItem refProjItem = allProjects_.FirstOrDefault((ii) => refProj.Equals(ii.GetMetadata("FullPath"))); if (refProjItem != null) { alias = PackagesConfig.GetProjectId(refProjItem); } logger_.LogMessage($"Project {projectItem_.ItemSpec}- Converting library reference '{refProj}' to Nuget package '{PackageIdPrefix + alias}' version {packageVersion_}"); packagesConfig_.Add(PackageIdPrefix + alias, packageVersion_); } foreach (ProjectItem i in project_.GetItemsIgnoringCondition("Link")) { string libDependencies = i.GetMetadataValue("AdditionalDependencies"); string[] libs = libDependencies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string l in libs) { string li = Path.GetFileNameWithoutExtension(l); ConvertLibToPkg(li); } } foreach (ProjectMetadata i in project_.AllEvaluatedItemDefinitionMetadata) { if (i.ItemType.Equals("Link") && i.Name.Equals("AdditionalDependencies")) { string libDependencies = i.EvaluatedValue; string[] libs = libDependencies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string l in libs) { string li = Path.GetFileNameWithoutExtension(l); ConvertLibToPkg(li); } } } ProjectItemDefinition pid = project_.ItemDefinitions["Link"]; if (pid != null) { string libDependencies = pid.GetMetadataValue("AdditionalDependencies"); string[] libs = libDependencies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string l in libs) { string li = Path.GetFileNameWithoutExtension(l); ConvertLibToPkg(li); } } project_.RemoveItems(allProjReferences); packagesConfig_.Save(); project_.Save(); }
private HashSet <PackagesConfig> ResolveProjectsToBuild(HashSet <PackagesConfig> allPackages) { // Detect projects that depend on a target project. bool buildAll = ((DependecyProjects == null) || (DependecyProjects.Count() == 0)); if (buildAll) { Log.LogMessage(MessageImportance.Low, "Building all projects since DependecyProjects list is empty"); return(new HashSet <PackagesConfig>(allPackages)); } HashSet <PackagesConfig> buildSet = new HashSet <PackagesConfig>(); foreach (ITaskItem depProj in DependecyProjects) { if (cancel_) { Log.LogMessage(MessageImportance.Low, "Exit on cancel signal"); return(null); } string targetProject = depProj.GetMetadata("FullPath"); if (string.IsNullOrWhiteSpace(targetProject) || !File.Exists(targetProject)) { Log.LogError($"FullPath not found for target project {depProj.ItemSpec}"); return(null); } Log.LogMessage(MessageImportance.Low, $"Inspecting target project '{depProj.ItemSpec}'."); PackagesConfig tgtPc = allPackages.FirstOrDefault((pc) => pc.ProjectTaskItem.GetMetadata("FullPath")?.Equals(targetProject) ?? false); if (tgtPc == null) { Log.LogWarning($"Did not find target project '{depProj.ItemSpec}' in AllProjects list. Have you defined item metadata DependecyProjects?"); tgtPc = PackagesConfig.Create(depProj, PackageIdPrefix); allPackages.Add(tgtPc); } buildSet.Add(tgtPc); foreach (PackagesConfig pc in allPackages) { if (pc.Id == tgtPc.Id) { continue; } List <string> pcDep = pc.ResolveRecursiveDependencies(allPackages); if (pcDep.Contains(tgtPc.Id) && !buildSet.Contains(pc)) { Log.LogMessage(MessageImportance.Low, $"Build requires '{pc.Id}'."); buildSet.Add(pc); } if (cancel_) { Log.LogMessage(MessageImportance.Low, "Exit on cancel signal"); return(null); } } } return(buildSet); }