protected ITaskItem ConvertPackageElement(ITaskItem project, PackageReference packageReference) { var id = packageReference.Id; var version = packageReference.Version; var targetFramework = packageReference.TargetFramework; var isDevelopmentDependency = packageReference.IsDevelopmentDependency; var requireReinstallation = packageReference.RequireReinstallation; var versionConstraint = packageReference.VersionConstraint; var item = new TaskItem(id); project.CopyMetadataTo(item); var packageDirectoryPath = GetPackageDirectoryPath(project.GetMetadata("FullPath"), id, version); item.SetMetadata("PackageDirectoryPath", packageDirectoryPath); item.SetMetadata("ProjectPath", project.GetMetadata("FullPath")); item.SetMetadata("IsDevelopmentDependency", isDevelopmentDependency.ToString()); item.SetMetadata("RequireReinstallation", requireReinstallation.ToString()); if (version != null) item.SetMetadata(Metadata.Version, version.ToString()); if (targetFramework != null) item.SetMetadata(Metadata.TargetFramework, targetFramework.GetShortFrameworkName()); if (versionConstraint != null) item.SetMetadata("VersionConstraint", versionConstraint.ToString()); return item; }
private ITaskItem GetOutputEntryPoint(ITaskItem entryPoint, PublishInfo[] manifestEntryPointList) { if (entryPoint == null) { return(null); } TaskItem outputEntryPoint = new TaskItem(entryPoint.ItemSpec); entryPoint.CopyMetadataTo(outputEntryPoint); string targetPath = entryPoint.GetMetadata("TargetPath"); if (!string.IsNullOrEmpty(targetPath)) { for (int i = 0; i < manifestEntryPointList.Length; i++) { if (String.Equals(targetPath, manifestEntryPointList[i].key, StringComparison.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(manifestEntryPointList[i].includeHash)) { if (manifestEntryPointList[i].state != PublishState.Exclude && string.Equals(manifestEntryPointList[i].includeHash, "false", StringComparison.OrdinalIgnoreCase) && SigningManifests == true) { _canPublish = false; } outputEntryPoint.SetMetadata("IncludeHash", manifestEntryPointList[i].includeHash); } return(outputEntryPoint); } } } return(outputEntryPoint); }
IEnumerable <ITaskItem> GetCompilationDirectoryOutput(ITaskItem expected) { var name = Path.GetFileNameWithoutExtension(expected.ItemSpec); var extension = Path.GetExtension(expected.ItemSpec); var dir = Path.GetDirectoryName(expected.ItemSpec); var nibDir = expected.GetMetadata("LogicalName"); foreach (var target in GetTargetDevices(plist)) { var fileName = name + "~" + target + extension; var path = Path.Combine(dir, fileName); if (!Directory.Exists(path) && !File.Exists(path)) { continue; } var logicalName = !string.IsNullOrEmpty(nibDir) ? Path.Combine(nibDir, fileName) : fileName; var item = new TaskItem(path); expected.CopyMetadataTo(item); item.SetMetadata("LogicalName", logicalName); yield return(item); } if (Directory.Exists(expected.ItemSpec) || File.Exists(expected.ItemSpec)) { yield return(expected); } yield break; }
private ITaskItem GetOutputEntryPoint(ITaskItem entryPoint, PublishInfo[] manifestEntryPointList) { if (entryPoint == null) { return(null); } TaskItem destinationItem = new TaskItem(entryPoint.ItemSpec); entryPoint.CopyMetadataTo(destinationItem); string metadata = entryPoint.GetMetadata("TargetPath"); if (!string.IsNullOrEmpty(metadata)) { for (int i = 0; i < manifestEntryPointList.Length; i++) { if (string.Equals(metadata, manifestEntryPointList[i].key, StringComparison.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(manifestEntryPointList[i].includeHash)) { if (((manifestEntryPointList[i].state != PublishState.Exclude) && string.Equals(manifestEntryPointList[i].includeHash, "false", StringComparison.OrdinalIgnoreCase)) && this.SigningManifests) { this.canPublish = false; } destinationItem.SetMetadata("IncludeHash", manifestEntryPointList[i].includeHash); } return(destinationItem); } } } return(destinationItem); }
private static ITaskItem TaskItemWithNewExtension(ITaskItem item, string extension) { var newItem = new TaskItem(Path.ChangeExtension(item.ItemSpec, extension)); item.CopyMetadataTo(newItem); return(newItem); }
// Creates an output item for a prerequisite. private static ITaskItem CreatePrerequisiteItem(ITaskItem item) { ITaskItem outputItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(outputItem); outputItem.SetMetadata("DependencyType", "Prerequisite"); return(outputItem); }
internal bool ResolveProject(ITaskItem projectRef, out ITaskItem resolvedPath) { string projectItem = base.GetProjectItem(projectRef); if (projectItem != null) { resolvedPath = new TaskItem(projectItem); projectRef.CopyMetadataTo(resolvedPath); return true; } resolvedPath = null; return false; }
public override bool Execute() { List <string> selectorNames = (Selectors ?? string.Empty) .Split(';') .Select(item => item.Trim()) .DefaultIfEmpty("*") .ToList(); bool removeAll = false; if (selectorNames.Any(item => item == "*")) { removeAll = true; } List <SelectorInfo> selectors = selectorNames.Select(item => new SelectorInfo(Log, item)).ToList(); WarnIfUneven(Tuple.Create("Inputs", Inputs), Tuple.Create("Outputs", Outputs)); foreach (var tuple in Zip(Inputs, Outputs)) { ITaskItem input = tuple.Item1; ITaskItem output = tuple.Item2; Log.LogMessage(MessageImportance.High, input.ItemSpec); bool updatedItem = false; HtmlDocument document = new HtmlDocument(); document.Load(input.ItemSpec); if (removeAll) { Log.LogMessage(MessageImportance.Normal, "Removing all <style/> tags"); updatedItem = RemoveAll(document); } else { Log.LogMessage(MessageImportance.Normal, "Removing {0}", Selectors); updatedItem = RemoveSelectors(Log, document, selectors); } output.RequireParentDirectory(Log); if (updatedItem) { document.Save(output.ItemSpec); } else { File.Copy(input.ItemSpec, output.ItemSpec, true); } input.CopyMetadataTo(output); } return(true); }
internal bool ResolveProject(ITaskItem projectRef, out ITaskItem resolvedPath) { string projectItem = base.GetProjectItem(projectRef); if (projectItem != null) { resolvedPath = new TaskItem(projectItem); projectRef.CopyMetadataTo(resolvedPath); return(true); } resolvedPath = null; return(false); }
ResolvedReference ResolveWithAlternateName(ITaskItem item, string[] extensions) { foreach (string extn in extensions) { if (item.ItemSpec.EndsWith(extn)) { ITaskItem altitem = new TaskItem(item.ItemSpec.Substring(0, item.ItemSpec.Length - extn.Length)); item.CopyMetadataTo(altitem); return(ResolveReference(altitem, searchPaths, true)); } } return(null); }
public TaskItem(ITaskItem sourceItem) { ErrorUtilities.VerifyThrowArgumentNull(sourceItem, "sourceItem"); ITaskItem2 item = sourceItem as ITaskItem2; if (item == null) { this.itemSpec = sourceItem.ItemSpec; } else { this.itemSpec = item.EvaluatedIncludeEscaped; } sourceItem.CopyMetadataTo(this); }
public TaskItem(ITaskItem sourceItem) { ErrorUtilities.VerifyThrowArgumentNull(sourceItem, "sourceItem"); ITaskItem2 item = sourceItem as ITaskItem2; if (item == null) { this.itemSpec = sourceItem.ItemSpec; } else { this.itemSpec = item.EvaluatedIncludeEscaped; } sourceItem.CopyMetadataTo(this); }
private TaskItem BuildContent(ITaskItem folder, Document document, PathMapping folderMapping) { PathMapping documentPath = new PathMapping(folderMapping, new TaskItem().FillMetadata(document)); string targetFile = documentPath.MappedPath; TaskItem content = new TaskItem(targetFile); folder.CopyMetadataTo(content, FolderMetadataPrefix ?? "Folder"); content.FillMetadata(documentPath); content.FillMetadata(document); content.RequireParentDirectory(Log); if (content.Exists()) { DateTime updated = File.GetLastWriteTime(targetFile); Log.LogMessage(MessageImportance.Normal, "Exists at \"{0}\"", targetFile); if (updated != document.Updated) { Log.LogMessage(MessageImportance.Low, "Updated - Local: {0} Remote: {1}", updated, document.Updated); } else { Log.LogMessage(MessageImportance.Low, "Updated - {0}", document.Updated); } } else { Log.LogMessage(MessageImportance.Normal, "Detected new document"); } if (document.DocumentEntry != null && document.DocumentEntry.Content != null && document.DocumentEntry.Content.Src != null) { content.SetMetadata("ExportUri", document.DocumentEntry.Content.Src.ToString()); } content.Save(Log, document.Updated); return(content); }
private static ITaskItem CreateFileItem(ITaskItem item, string group, string targetPath, string includeHash, bool isDataFile) { ITaskItem destinationItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(destinationItem); if (string.IsNullOrEmpty(targetPath)) { targetPath = GetItemTargetPath(destinationItem); } destinationItem.SetMetadata("TargetPath", targetPath); if (!string.IsNullOrEmpty(group) && !isDataFile) { destinationItem.SetMetadata("Group", group); } if (!string.IsNullOrEmpty(includeHash)) { destinationItem.SetMetadata("IncludeHash", includeHash); } destinationItem.SetMetadata("IsDataFile", isDataFile.ToString().ToLowerInvariant()); return destinationItem; }
private static ITaskItem CreateAssemblyItem(ITaskItem item, string group, string targetPath, string includeHash) { ITaskItem destinationItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(destinationItem); destinationItem.SetMetadata("DependencyType", "Install"); if (string.IsNullOrEmpty(targetPath)) { targetPath = GetItemTargetPath(destinationItem); } destinationItem.SetMetadata("TargetPath", targetPath); if (!string.IsNullOrEmpty(group)) { destinationItem.SetMetadata("Group", group); } if (!string.IsNullOrEmpty(includeHash)) { destinationItem.SetMetadata("IncludeHash", includeHash); } return destinationItem; }
private static ITaskItem CreateAssemblyItem(ITaskItem item, string group, string targetPath, string includeHash) { ITaskItem destinationItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(destinationItem); destinationItem.SetMetadata("DependencyType", "Install"); if (string.IsNullOrEmpty(targetPath)) { targetPath = GetItemTargetPath(destinationItem); } destinationItem.SetMetadata("TargetPath", targetPath); if (!string.IsNullOrEmpty(group)) { destinationItem.SetMetadata("Group", group); } if (!string.IsNullOrEmpty(includeHash)) { destinationItem.SetMetadata("IncludeHash", includeHash); } return(destinationItem); }
private static ITaskItem CreateFileItem(ITaskItem item, string group, string targetPath, string includeHash, bool isDataFile) { ITaskItem destinationItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(destinationItem); if (string.IsNullOrEmpty(targetPath)) { targetPath = GetItemTargetPath(destinationItem); } destinationItem.SetMetadata("TargetPath", targetPath); if (!string.IsNullOrEmpty(group) && !isDataFile) { destinationItem.SetMetadata("Group", group); } if (!string.IsNullOrEmpty(includeHash)) { destinationItem.SetMetadata("IncludeHash", includeHash); } destinationItem.SetMetadata("IsDataFile", isDataFile.ToString().ToLowerInvariant()); return(destinationItem); }
public ProjectItem(MSBuildProject project, string itemName, ITaskItem taskItem) { if (project == null) { throw new ArgumentNullException("project"); } else if (string.IsNullOrEmpty(itemName)) { throw new ArgumentNullException("itemName"); } else if (taskItem == null) { throw new ArgumentNullException("taskItem"); } _project = project; _name = itemName; _metaData = new Dictionary <string, string>(); taskItem.CopyMetadataTo(this); _include = taskItem.ItemSpec.Replace("%20", ""); }
// Creates an output item for a an assembly, with optional Group attribute. private static ITaskItem CreateAssemblyItem(ITaskItem item, string group, string targetPath, string includeHash) { ITaskItem outputItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(outputItem); outputItem.SetMetadata("DependencyType", "Install"); if (String.IsNullOrEmpty(targetPath)) { targetPath = GetItemTargetPath(outputItem); } outputItem.SetMetadata(ItemMetadataNames.targetPath, targetPath); if (!String.IsNullOrEmpty(group)) { outputItem.SetMetadata("Group", group); } if (!String.IsNullOrEmpty(includeHash)) { outputItem.SetMetadata("IncludeHash", includeHash); } return(outputItem); }
IEnumerable <ITaskItem> GetCompilationOutput(ITaskItem expected) { if (IsWatchApp) { var logicalName = expected.GetMetadata("LogicalName"); foreach (var extension in WatchAppExtensions) { var path = GetPathWithoutExtension(expected.ItemSpec) + extension; if (File.Exists(path)) { var item = new TaskItem(path); expected.CopyMetadataTo(item); item.SetMetadata("LogicalName", GetPathWithoutExtension(logicalName) + extension); yield return(item); } } } yield return(expected); }
private ITaskItem ProcessFile(ITaskItem file, XamlPreprocessor preprocessor) { var sourcePath = file.GetMetadata("FullPath"); // properly resolve linked xaml var targetRelativePath = file.GetMetadata("Link"); if (string.IsNullOrEmpty(targetRelativePath)) { targetRelativePath = file.ItemSpec; } // if targetRelativePath is still absolute, use file name if (Path.IsPathRooted(targetRelativePath)) { targetRelativePath = Path.GetFileName(targetRelativePath); } var targetPath = Path.Combine(this.OutputPath, targetRelativePath); TaskItem result = null; // process XAML Log.LogMessage(MessageImportance.High, "XCC > Preprocessing {0}", targetRelativePath); var start = DateTime.Now; if (preprocessor.ProcessXamlFile(sourcePath, targetPath)) { // targetPath has been written, create linked item result = new TaskItem(targetPath); file.CopyMetadataTo(result); result.SetMetadata("Link", targetRelativePath); // this is the trick that makes it all work (replace page with a page link pointing to \obj\debug\preprocessedxaml\*) } var duration = (DateTime.Now - start).TotalMilliseconds; Log.LogMessage(MessageImportance.Normal, "XCC > Preprocess completed in {0}ms, {1} has {2}changed", duration, targetRelativePath, result == null ? "not " : ""); return(result); }
protected ITaskItem ConvertPackageElement(ITaskItem project, PackageReference packageReference) { var id = packageReference.PackageIdentity.Id; var version = packageReference.PackageIdentity.Version; var targetFramework = packageReference.TargetFramework; var isDevelopmentDependency = packageReference.IsDevelopmentDependency; var requireReinstallation = packageReference.RequireReinstallation; var versionConstraint = packageReference.AllowedVersions; var item = new TaskItem(id); project.CopyMetadataTo(item); var packageDirectoryPath = GetPackageDirectoryPath(project.GetMetadata("FullPath"), id, version); item.SetMetadata("PackageDirectoryPath", packageDirectoryPath); item.SetMetadata("ProjectPath", project.GetMetadata("FullPath")); item.SetMetadata("IsDevelopmentDependency", isDevelopmentDependency.ToString()); item.SetMetadata("RequireReinstallation", requireReinstallation.ToString()); if (version != null) { item.SetMetadata(Metadata.Version, version.ToString()); } if (targetFramework != null) { item.SetMetadata(Metadata.TargetFramework, targetFramework.GetShortFolderName()); } if (versionConstraint != null) { item.SetMetadata("VersionConstraint", versionConstraint.ToString()); } return(item); }
/// <summary> /// This constructor creates a new TaskItem, using the given ITaskItem. /// </summary> /// <param name="sourceItem">The item to copy.</param> public TaskItem ( ITaskItem sourceItem ) { ErrorUtilities.VerifyThrowArgumentNull(sourceItem, "sourceItem"); ITaskItem2 sourceItemAsITaskItem2 = sourceItem as ITaskItem2; // Attempt to preserve escaped state if (sourceItemAsITaskItem2 == null) { _itemSpec = EscapingUtilities.Escape(sourceItem.ItemSpec); _definingProject = EscapingUtilities.EscapeWithCaching(sourceItem.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath)); } else { _itemSpec = sourceItemAsITaskItem2.EvaluatedIncludeEscaped; _definingProject = sourceItemAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath); } sourceItem.CopyMetadataTo(this); }
private void DoDownload(Request documentsRequest, ITaskItem document, ITaskItem download) { string sourceFile = document.ItemSpec; string targetFile = download.ItemSpec; string targetDirectory = Path.GetDirectoryName(targetFile); Log.LogMessage(MessageImportance.High, "Downloading \"{0}\"", document.RequireTitle()); Log.LogMessage(MessageImportance.Normal, "To \"{0}\"", targetDirectory); download.RequireParentDirectory(Log); if (!File.Exists(sourceFile)) { throw new FileNotFoundException("Cannot find", sourceFile); } ResourceType resourceType = document.RequireResourceType(); switch (resourceType) { case ResourceType.file: DoFileDownload(documentsRequest, document, targetFile); break; case ResourceType.document: DoDocumentDownload(documentsRequest, document, targetFile); break; default: throw new NotImplementedException(string.Format("Resource Type '{0}' is unsupported", resourceType)); } DateTime updated = document.GetTimestamp(); File.SetLastWriteTime(download.ItemSpec, updated); document.CopyMetadataTo(download); }
IEnumerable <ITaskItem> GetBundleResources(ITaskItem compiledItem) { var baseLogicalName = compiledItem.GetMetadata("LogicalName"); var baseDir = compiledItem.ItemSpec; // Note: Watch App storyboards will be compiled to something like Interface.storyboardc/Interface.plist, but // Interface.plist needs to be moved up 1 level (e.g. drop the "Interface.storyboardc"). // See https://bugzilla.xamarin.com/show_bug.cgi?id=33853 for details if (IsWatchApp && baseLogicalName.EndsWith(".storyboardc", StringComparison.Ordinal)) { baseLogicalName = Path.GetDirectoryName(baseLogicalName); } foreach (var path in Directory.EnumerateFiles(baseDir, "*.*", SearchOption.AllDirectories)) { var rpath = PathUtils.AbsoluteToRelative(baseDir, Path.GetFullPath(path)); var bundleResource = new TaskItem(path); string logicalName; if (!string.IsNullOrEmpty(baseLogicalName)) { logicalName = Path.Combine(baseLogicalName, rpath); } else { logicalName = rpath; } compiledItem.CopyMetadataTo(bundleResource); bundleResource.SetMetadata("LogicalName", logicalName); yield return(bundleResource); } yield break; }
public override bool Execute() { if (sourceFiles.Length == 0) { // nothing to copy! return(true); } try { List <ITaskItem> temporaryCopiedFiles = new List <ITaskItem> (); if (sourceFiles != null && destinationFiles != null && sourceFiles.Length != destinationFiles.Length) { Log.LogError("Number of source files is different than number of destination files."); return(false); } if (destinationFiles != null && destinationFolder != null) { Log.LogError("You must specify only one attribute from DestinationFiles and DestinationFolder"); return(false); } if (destinationFiles != null && destinationFiles.Length > 0) { for (int i = 0; i < sourceFiles.Length; i++) { ITaskItem sourceItem = sourceFiles [i]; ITaskItem destinationItem = destinationFiles [i]; string sourceFile = sourceItem.GetMetadata("FullPath"); string destinationFile = destinationItem.GetMetadata("FullPath"); if (!File.Exists(sourceFile)) { Log.LogError("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); continue; } if (!skipUnchangedFiles || HasFileChanged(sourceFile, destinationFile)) { CopyFile(sourceFile, destinationFile, true); } sourceItem.CopyMetadataTo(destinationItem); temporaryCopiedFiles.Add(destinationItem); } } else if (destinationFolder != null) { List <ITaskItem> temporaryDestinationFiles = new List <ITaskItem> (); string destinationDirectory = destinationFolder.GetMetadata("FullPath"); bool directoryCreated = CreateDirectoryIfRequired(destinationDirectory); foreach (ITaskItem sourceItem in sourceFiles) { string sourceFile = sourceItem.GetMetadata("FullPath"); string filename = sourceItem.GetMetadata("Filename") + sourceItem.GetMetadata("Extension"); string destinationFile = Path.Combine(destinationDirectory, filename); if (!File.Exists(sourceFile)) { Log.LogError("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); continue; } if (!skipUnchangedFiles || directoryCreated || HasFileChanged(sourceFile, destinationFile)) { CopyFile(sourceFile, destinationFile, false); } temporaryCopiedFiles.Add(new TaskItem( Path.Combine(destinationFolder.GetMetadata("Identity"), filename), sourceItem.CloneCustomMetadata())); temporaryDestinationFiles.Add(new TaskItem( Path.Combine(destinationFolder.GetMetadata("Identity"), filename), sourceItem.CloneCustomMetadata())); } destinationFiles = temporaryDestinationFiles.ToArray(); } else { Log.LogError("You must specify DestinationFolder or DestinationFiles attribute."); return(false); } copiedFiles = temporaryCopiedFiles.ToArray(); return(true); } catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } }
private bool ProcessProject(ITaskItem project, out ITaskItem result) { result = new TaskItem(project); project.CopyMetadataTo(project); Dictionary<string, string> properties; if (!ParseProperties(project.GetMetadata("Properties"), out properties)) return false; string parentCustomBeforeTargets, parentCustomAfterTargets; if (properties.TryGetValue("CustomBeforeMicrosoftCommonTargets", out parentCustomBeforeTargets)) { properties["HookProject-Parent-CustomBeforeMicrosoftCommonTargets"] = Escape(parentCustomBeforeTargets); } if (properties.TryGetValue("HookProject-Parent-CustomAfterMicrosoftCommonTargets", out parentCustomAfterTargets)) { properties["HookProject-Parent-CustomAfterMicrosoftCommonTargets"] = Escape(parentCustomAfterTargets); } properties["CustomBeforeMicrosoftCommonTargets"] = Escape(ProjectBeforeFile); properties["CustomAfterMicrosoftCommonTargets"] = Escape(ProjectAfterFile); properties["HookProject-DefineConstants"] = Escape(string.Join(";", DefineConstants)); properties["HookProject-SourceFiles"] = Escape(string.Join(";", SourceFiles)); result.SetMetadata("Properties", PropertiesToString(properties)); return true; }
// Creates an output item for a file, with optional Group and IsData attributes. private static ITaskItem CreateFileItem(ITaskItem item, string group, string targetPath, string includeHash, bool isDataFile) { ITaskItem outputItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(outputItem); if (String.IsNullOrEmpty(targetPath)) targetPath = GetItemTargetPath(outputItem); outputItem.SetMetadata(ItemMetadataNames.targetPath, targetPath); if (!String.IsNullOrEmpty(group) && !isDataFile) outputItem.SetMetadata("Group", group); if (!String.IsNullOrEmpty(includeHash)) outputItem.SetMetadata("IncludeHash", includeHash); outputItem.SetMetadata("IsDataFile", isDataFile.ToString().ToLowerInvariant()); return outputItem; }
private ITaskItem GetOutputEntryPoint(ITaskItem entryPoint, PublishInfo[] manifestEntryPointList) { if (entryPoint == null) { return null; } TaskItem outputEntryPoint = new TaskItem(entryPoint.ItemSpec); entryPoint.CopyMetadataTo(outputEntryPoint); string targetPath = entryPoint.GetMetadata("TargetPath"); if (!string.IsNullOrEmpty(targetPath)) { for (int i = 0; i < manifestEntryPointList.Length; i++) { if (String.Equals(targetPath, manifestEntryPointList[i].key, StringComparison.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(manifestEntryPointList[i].includeHash)) { if (manifestEntryPointList[i].state != PublishState.Exclude && string.Equals(manifestEntryPointList[i].includeHash, "false", StringComparison.OrdinalIgnoreCase) && SigningManifests == true) _canPublish = false; outputEntryPoint.SetMetadata("IncludeHash", manifestEntryPointList[i].includeHash); } return outputEntryPoint; } } } return outputEntryPoint; }
public override bool Execute() { if (src_files == null || src_files.Length == 0) { return(true); } bool success = true; List <ITaskItem> outputs = new List <ITaskItem>(); String dependency_log_file = dependency_log.ItemSpec != null ? dependency_log.ItemSpec : null; String command_log_file = command_log.ItemSpec != null ? command_log.ItemSpec : null; Dependencies depends = new Dependencies(dependency_log_file, command_log_file); cancelled = false; for (int i = 0; i < src_files.Length && !cancelled; ++i) { ITaskItem item = src_files[i]; String source_file = item.ItemSpec; String target_file = item.GetMetadata("TargetFile"); if (String.IsNullOrWhiteSpace(target_file)) { target_file = source_file + ".cpp"; Log.LogWarning("no target file specified, defaulting to '" + target_file + '\''); } ITaskItem item_out = new TaskItem(target_file); item.CopyMetadataTo(item_out); CommandLine cmdline = new CommandLine(item, source_file, target_file); String target_title = source_file; if (depends.NeedsToBuild(force_rebuild, source_file, target_file, cmdline.CmdLineString)) { Log.LogMessageFromText(source_file, MessageImportance.High); depends.ResetDependencies(source_file); LogListener log_listener = new LogListener(Log, cmdline, depends); if (Compile(cmdline.CmdLineString, log_listener) != 0) { success = false; continue; } } else { Log.LogMessageFromText(target_title + " up to date", MessageImportance.Normal); } outputs.Add(item_out); depends.SetCommandline(target_file, cmdline.CmdLineString); } output_files = outputs.ToArray(); //depends.Write(dependency_log_file, command_log_file); return(success); }
public override bool Execute() { GDataCredentials credentials = GetDataCredentials(); RequestSettings settings = new RequestSettings("code.google.com/p/exult/", credentials); settings.AutoPaging = true; settings.PageSize = 100; List <ITaskItem> folderContent = new List <ITaskItem>(); WarnIfUneven(Tuple.Create("Folders", Folders), Tuple.Create("FolderListings", FolderListings)); foreach (var tuple in Zip(Folders, FolderListings)) { if (_Cancelled) { return(false); } ITaskItem folder = tuple.Item1; ITaskItem folderListing = tuple.Item2; folder.LoadCustomMetadata(); folder.RequireDocumentType(Document.DocumentType.Folder); //yada/hrm.folder -> yada/hrm/ string folderPath = Path.Combine(Path.GetDirectoryName(folder.ItemSpec), Path.GetFileNameWithoutExtension(folder.ItemSpec)); RequireDirectory(folderPath); PathMapping folderMapping = new PathMapping(folderPath); Request request = new Request(settings); string resourceId = folder.RequireResourceId(); Log.LogMessage(MessageImportance.High, "Getting Folder Content \"{0}\"", folder.RequireTitlePath()); Feed <Document> feed = request.GetFolderContent(resourceId); // this takes care of paging the results in List <Document> documents = feed.Entries.Where(item => item.Type != Document.DocumentType.Folder).ToList(); Log.LogMessage(MessageImportance.Normal, "Found {0} Item(s)", documents.Count); DateTime folderTimestamp = folder.GetTimestamp(); DateTime latestTimestamp = folderTimestamp; foreach (Document document in documents) { if (_Cancelled) { return(false); } if (document.Updated > latestTimestamp) { latestTimestamp = document.Updated; } if (Pattern == null || PatternExpression.IsMatch(document.Title)) { Log.LogMessage(MessageImportance.Normal, "Matched \"{0}\"", document.Title); folderContent.Add(BuildContent(folder, document, folderMapping)); } else { Log.LogMessage(MessageImportance.Low, "Skipped \"{0}\"", document.Title); } } folder.CopyMetadataTo(folderListing); folderListing.Save(Log, latestTimestamp); } FolderContent = folderContent.ToArray(); return(true); }
ResolvedReference ResolveWithAlternateName (ITaskItem item, string[] extensions) { foreach (string extn in extensions) { if (item.ItemSpec.EndsWith (extn)) { ITaskItem altitem = new TaskItem (item.ItemSpec.Substring (0, item.ItemSpec.Length - extn.Length)); item.CopyMetadataTo (altitem); return ResolveReference (altitem, searchPaths, true); } } return null; }
private ITaskItem ProcessFile(ITaskItem file, XamlPreprocessor preprocessor) { var sourcePath = file.GetMetadata("FullPath"); // properly resolve linked xaml var targetRelativePath = file.GetMetadata("Link"); if (string.IsNullOrEmpty(targetRelativePath)) { targetRelativePath = file.ItemSpec; } // if targetRelativePath is still absolute, use file name if (Path.IsPathRooted(targetRelativePath)) { targetRelativePath = Path.GetFileName(targetRelativePath); } var targetPath = Path.Combine(this.OutputPath, targetRelativePath); TaskItem result = null; // process XAML Log.LogMessage(MessageImportance.High, "XCC > Preprocessing {0}", targetRelativePath); var start = DateTime.Now; if (preprocessor.ProcessXamlFile(sourcePath, targetPath)) { // targetPath has been written, create linked item result = new TaskItem(targetPath); file.CopyMetadataTo(result); result.SetMetadata("Link", targetRelativePath); // this is the trick that makes it all work (replace page with a page link pointing to \obj\debug\preprocessedxaml\*) } var duration = (DateTime.Now - start).TotalMilliseconds; Log.LogMessage(MessageImportance.Normal, "XCC > Preprocess completed in {0}ms, {1} has {2}changed", duration, targetRelativePath, result == null ? "not " : ""); return result; }
/// <summary> /// Helper manifest resolution method. Cracks the manifest and extracts the different elements from it. /// </summary> internal bool ExtractFromManifest(ITaskItem taskItem, string path, Hashtable containingReferenceFilesTable, Hashtable containedPrerequisiteAssembliesTable, Hashtable containedComComponentsTable, Hashtable containedTypeLibrariesTable, Hashtable containedLooseTlbFilesTable, Hashtable containedLooseEtcFilesTable) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveNativeReference.Comment", path); Manifest manifest = null; try { manifest = ManifestReader.ReadManifest(path, false); } catch (System.Xml.XmlException ex) { Log.LogErrorWithCodeFromResources("GenerateManifest.ReadInputManifestFailed", path, ex.Message); return false; } if (manifest != null) { manifest.TreatUnfoundNativeAssembliesAsPrerequisites = true; manifest.ReadOnly = true; // only reading a manifest, set flag so we get GenerateManifest.ResolveFailedInReadOnlyMode instead of GenerateManifest.ResolveFailedInReadWriteMode messages manifest.ResolveFiles(); if (!manifest.OutputMessages.LogTaskMessages(this)) return false; ApplicationManifest applicationManifest = manifest as ApplicationManifest; bool isClickOnceApp = applicationManifest != null && applicationManifest.IsClickOnceManifest; // ClickOnce application manifest should not be added as native reference, but we should open and process it. if (containingReferenceFilesTable.ContainsKey(path) == false && !isClickOnceApp) { ITaskItem itemNativeReferenceFile = new TaskItem(); itemNativeReferenceFile.ItemSpec = path; if (manifest.AssemblyIdentity.Name != null) itemNativeReferenceFile.SetMetadata(ItemMetadataNames.fusionName, manifest.AssemblyIdentity.Name); if (taskItem != null) taskItem.CopyMetadataTo(itemNativeReferenceFile); containingReferenceFilesTable.Add(path, itemNativeReferenceFile); } if (manifest.AssemblyReferences != null) { foreach (AssemblyReference assemblyref in manifest.AssemblyReferences) { if (assemblyref.IsVirtual) { //It is a CLR virtual reference, not a real reference. continue; } if (!assemblyref.IsPrerequisite) { // recurse and call ExtractFromManifest for this assembly--if it has a manifest it will be cracked. ExtractFromManifest(null, assemblyref.ResolvedPath, containingReferenceFilesTable, containedPrerequisiteAssembliesTable, containedComComponentsTable, containedTypeLibrariesTable, containedLooseTlbFilesTable, containedLooseEtcFilesTable); } else { string id = assemblyref.AssemblyIdentity.GetFullName(AssemblyIdentity.FullNameFlags.All); // add the assembly to the prerequisites list, if it's not already there if (containedPrerequisiteAssembliesTable.ContainsKey(id) == false) { ITaskItem item = new TaskItem(); item.ItemSpec = id; item.SetMetadata("DependencyType", "Prerequisite"); containedPrerequisiteAssembliesTable.Add(id, item); } } } } if (manifest.FileReferences != null) { foreach (FileReference fileref in manifest.FileReferences) { if (fileref.ResolvedPath == null) continue; // add the loose file to the outputs list, if it's not already there if (containedLooseEtcFilesTable.ContainsKey(fileref.ResolvedPath) == false) { ITaskItem itemLooseEtcFile = new TaskItem(); itemLooseEtcFile.ItemSpec = fileref.ResolvedPath; // The ParentFile attribute (visible thru Project Outputs) relates the loose // file to the parent assembly of which it is a part. This is important so we can // group those files together with their parent assembly in the deployment tool // (i.e. ClickOnce application files dialog). itemLooseEtcFile.SetMetadata(ItemMetadataNames.parentFile, Path.GetFileName(path)); containedLooseEtcFilesTable.Add(fileref.ResolvedPath, itemLooseEtcFile); } if (fileref.ComClasses != null) { foreach (ComClass comclass in fileref.ComClasses) { // add the comclass to the outputs list, if it's not already there if (containedComComponentsTable.ContainsKey(comclass.ClsId) == false) { ITaskItem itemComClass = new TaskItem(); itemComClass.ItemSpec = comclass.ClsId; containedComComponentsTable.Add(comclass.ClsId, itemComClass); } } } if (fileref.TypeLibs != null) { foreach (TypeLib typelib in fileref.TypeLibs) { // add the typelib to the outputs list, if it's not already there if (containedTypeLibrariesTable.ContainsKey(typelib.TlbId) == false) { ITaskItem itemTypeLib = new TaskItem(); itemTypeLib.ItemSpec = typelib.TlbId; itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.wrapperTool, ComReferenceTypes.tlbimp); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.guid, typelib.TlbId); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.lcid, "0"); string delimStr = "."; char[] delimiter = delimStr.ToCharArray(); string[] verMajorAndMinor = null; verMajorAndMinor = typelib.Version.Split(delimiter); // UNDONE: are major and minor version numbers in base 10 or 16? itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.versionMajor, verMajorAndMinor[0]); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.versionMinor, verMajorAndMinor[1]); containedTypeLibrariesTable.Add(typelib.TlbId, itemTypeLib); } } // add the loose TLB file to the outputs list, if it's not already there if (containedLooseTlbFilesTable.Contains(fileref.ResolvedPath) == false) { ITaskItem itemLooseTlbFile = new TaskItem(); itemLooseTlbFile.ItemSpec = fileref.ResolvedPath; containedLooseTlbFilesTable.Add(fileref.ResolvedPath, itemLooseTlbFile); } } } } } return true; }
private void DoDownload(Request documentsRequest, ITaskItem document, ITaskItem download) { string sourceFile = document.ItemSpec; string targetFile = download.ItemSpec; string targetDirectory = Path.GetDirectoryName(targetFile); Log.LogMessage(MessageImportance.High,"Downloading \"{0}\"", document.RequireTitle()); Log.LogMessage(MessageImportance.Normal, "To \"{0}\"", targetDirectory); download.RequireParentDirectory(Log); if (!File.Exists(sourceFile)) { throw new FileNotFoundException("Cannot find", sourceFile); } ResourceType resourceType = document.RequireResourceType(); switch (resourceType) { case ResourceType.file: DoFileDownload(documentsRequest, document, targetFile); break; case ResourceType.document: DoDocumentDownload(documentsRequest, document, targetFile); break; default: throw new NotImplementedException(string.Format("Resource Type '{0}' is unsupported", resourceType)); } DateTime updated = document.GetTimestamp(); File.SetLastWriteTime(download.ItemSpec, updated); document.CopyMetadataTo(download); }
/// <summary> /// Prepares HelixWorkItem given xUnit project information. /// </summary> /// <returns>An ITaskItem instance representing the prepared HelixWorkItem.</returns> private async Task <ITaskItem> PrepareWorkItem(ITaskItem xunitProject) { // Forces this task to run asynchronously await Task.Yield(); if (!xunitProject.GetRequiredMetadata(Log, "PublishDirectory", out string publishDirectory)) { return(null); } if (!xunitProject.GetRequiredMetadata(Log, "TargetPath", out string targetPath)) { return(null); } if (!xunitProject.GetRequiredMetadata(Log, "RuntimeTargetFramework", out string runtimeTargetFramework)) { return(null); } xunitProject.TryGetMetadata("Arguments", out string arguments); string assemblyName = Path.GetFileName(targetPath); string driver = runtimeTargetFramework.Contains("core") ? $"{PathToDotnet} exec " : ""; string runnerName = runtimeTargetFramework.Contains("core") ? "xunit.console.dll" : "xunit.console.exe"; string correlationPayload = IsPosixShell ? "$HELIX_CORRELATION_PAYLOAD" : "%HELIX_CORRELATION_PAYLOAD%"; string xUnitRunner = $"{correlationPayload}/xunit-runner/tools/{runtimeTargetFramework}/{runnerName}"; if (runtimeTargetFramework.Contains("core")) { // If we don't know what version we are, or it isn't 1.x or 2.x, add --roll-forward if (string.IsNullOrEmpty(DotNetCliVersion) || !(DotNetCliVersion.StartsWith("1.") || DotNetCliVersion.StartsWith("2."))) { Log.LogMessage("Adding dotnet cli roll-forward policy."); driver += "--roll-forward Major "; } var assemblyBaseName = assemblyName; if (assemblyBaseName.EndsWith(".dll")) { assemblyBaseName = assemblyBaseName.Substring(0, assemblyBaseName.Length - 4); } Log.LogMessage($"Adding runtimeconfig and depsfile parameters for assembly {assemblyBaseName}."); driver += $"--runtimeconfig {assemblyBaseName}.runtimeconfig.json --depsfile {assemblyBaseName}.deps.json "; } string command = $"{driver}{xUnitRunner} {assemblyName}{(XUnitArguments != null ? " " + XUnitArguments : "")} -xml testResults.xml {arguments}"; Log.LogMessage($"Creating work item with properties Identity: {assemblyName}, PayloadDirectory: {publishDirectory}, Command: {command}"); TimeSpan timeout = TimeSpan.FromMinutes(5); if (!string.IsNullOrEmpty(XUnitWorkItemTimeout)) { if (!TimeSpan.TryParse(XUnitWorkItemTimeout, out timeout)) { Log.LogWarning($"Invalid value \"{XUnitWorkItemTimeout}\" provided for XUnitWorkItemTimeout; falling back to default value of \"00:05:00\" (5 minutes)"); } } var result = new Microsoft.Build.Utilities.TaskItem(assemblyName, new Dictionary <string, string>() { { "Identity", assemblyName }, { "PayloadDirectory", publishDirectory }, { "Command", command }, { "Timeout", timeout.ToString() }, }); xunitProject.CopyMetadataTo(result); return(result); }
public override bool Execute() { var outputDir = MergeOutputDir; Directory.CreateDirectory(outputDir); var restoreMap = BuildRestoreMap(RestoreAssemblyResources); if (restoreMap == null) { return(false); } var changedReferencePaths = new List <ITaskItem> (); var removedReferencePaths = new List <ITaskItem> (); IAssemblyResolver resolver = null; foreach (var asm in restoreMap) { var asmName = new AssemblyName(asm.Key); ITaskItem item = FindMatchingAssembly(InputReferencePaths, asmName); if (item == null) { if (ThrowOnMissingAssembly) { return(false); } else { continue; } } var originalAsmPath = item.GetMetadata("FullPath"); //TODO: collision avoidance. AssemblyName MD5? NuGet package ID? var mergedAsmPath = Path.Combine(outputDir, asmName.Name + ".dll"); var mergedFileInfo = new FileInfo(mergedAsmPath); if (!mergedFileInfo.Exists || mergedFileInfo.LastWriteTime < File.GetLastWriteTime(originalAsmPath)) { if (resolver == null) { resolver = CreateAssemblyResolver(); } if (!MergeResources(resolver, originalAsmPath, mergedAsmPath, asm.Key, asm.Value)) { return(false); } } removedReferencePaths.Add(item); var newItem = new TaskItem(mergedAsmPath); item.CopyMetadataTo(newItem); changedReferencePaths.Add(newItem); } ChangedReferencePaths = changedReferencePaths.ToArray(); RemovedReferencePaths = removedReferencePaths.ToArray(); return(true); }
private static ITaskItem TaskItemWithNewExtension(ITaskItem item, string extension) { var newItem = new TaskItem(Path.ChangeExtension(item.ItemSpec, extension)); item.CopyMetadataTo(newItem); return newItem; }
/// <summary> /// This constructor creates a new TaskItem, using the given ITaskItem. /// </summary> /// <param name="sourceItem">The item to copy.</param> public TaskItem ( ITaskItem sourceItem ) { ErrorUtilities.VerifyThrowArgumentNull(sourceItem, "sourceItem"); ITaskItem2 sourceItemAsITaskItem2 = sourceItem as ITaskItem2; // Attempt to preserve escaped state if (sourceItemAsITaskItem2 == null) { _itemSpec = EscapingUtilities.Escape(sourceItem.ItemSpec); _definingProject = EscapingUtilities.EscapeWithCaching(sourceItem.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath)); } else { _itemSpec = sourceItemAsITaskItem2.EvaluatedIncludeEscaped; _definingProject = sourceItemAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath); } sourceItem.CopyMetadataTo(this); }
// Creates an output item for a an assembly, with optional Group attribute. private static ITaskItem CreateAssemblyItem(ITaskItem item, string group, string targetPath, string includeHash) { ITaskItem outputItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(outputItem); outputItem.SetMetadata("DependencyType", "Install"); if (String.IsNullOrEmpty(targetPath)) targetPath = GetItemTargetPath(outputItem); outputItem.SetMetadata(ItemMetadataNames.targetPath, targetPath); if (!String.IsNullOrEmpty(group)) outputItem.SetMetadata("Group", group); if (!String.IsNullOrEmpty(includeHash)) outputItem.SetMetadata("IncludeHash", includeHash); return outputItem; }
/// <summary> The internal implementation of the execute task </summary> /// <returns> ErrorCodes.Success if succeeds, one of the other ErrorCodes otherwise </returns> internal int InternalExecute() { bool isTargetRuntimeManaged = TargetRuntime.Equals("Managed", StringComparison.OrdinalIgnoreCase); List <ITaskItem> currentAppxPackagePayload = AppxPackagePayload.ToList(); string transformedAppxManifest = Path.Combine(OutputPath, "AppxManifest.xml"); // Perform setup: // - Create output directory if it does not already exist // - Delete existing AppxManifest.xml if it exists try { Directory.CreateDirectory(OutputPath); File.Delete(transformedAppxManifest); } catch (PathTooLongException) { Log.LogError(Resources.Error_PathTooLongExceptionOutputFolder); return((int)ErrorCodes.PathTooLongException); } catch (IOException ioException) { Log.LogError(Resources.Error_IOExceptionOutputFolder, ioException.Message); return((int)ErrorCodes.InputFileReadError); } catch (Exception e) { Log.LogError(Resources.Error_InternalWireUpCoreRuntimeError, e.Message); return((int)ErrorCodes.InternalWireUpCoreRuntimeError); } // Apply transformations required to hook up the Core Runtime // 1. For Managed apps, move <app.exe> to [AppEntryPointDir]\<app.exe> and copy UWPShim.exe to package root as <app.exe> // 2. Replace all ClrHost.dll with either UWPShim.exe (for hybrid apps) or <app.exe> (for managed apps) // 3. If #2 above is performed, inject UWPShim.exe into the output directory for unmanaged apps // which contain managed winmd and for managed background tasks (which do not contain entrypoint exe) // 4. If #1 or #2 above is performed, add a package dependency to CoreRuntime framework package. using (StreamReader sr = new StreamReader(AppxManifest)) { XDocument doc = XDocument.Load(sr, LoadOptions.None); XNamespace ns = @"http://schemas.microsoft.com/appx/manifest/foundation/windows10"; string inprocServer = UWPShimEXE; var uwpShimLocation = Path.Combine(new [] { CoreRuntimeSDKLocation, "AppLocal", UWPShimEXE }); IEnumerable <XAttribute> entryPointExecutables = Enumerable.Empty <XAttribute>(); if (isTargetRuntimeManaged) { // 1. For Managed apps, move <app.exe> to [AppEntryPointDir]\<app.exe> and copy UWPShim.exe to package root as <app.exe> entryPointExecutables = doc.Descendants(ns + "Applications").Descendants(ns + "Application").Where(x => x.Attribute("Executable") != null).Select(x => x.Attribute("Executable")); if (entryPointExecutables.Any()) { // Set the inprocServer to the <app.exe>. From this point on that's our UWPShim.exe // and since we will be copying uwpShim possibly several times with different names, yet they are all // uwpshim.exe, it's OK to grab the first one and use it as inprocserver entry inprocServer = entryPointExecutables.First().Value; if (entryPointExecutables.Any(x => x.Value.Contains(Path.DirectorySeparatorChar))) { Log.LogError(Resources.Error_CustomEntryPointNotSupported); return((int)ErrorCodes.NotSupported); } foreach (var entryPointExecutable in entryPointExecutables) { // Do not copy <app.exe> from original location, just modify TargetPath to [AppEntryPointDir]\<app.exe> ITaskItem currentManagedEntryPointExecutableTaskItem = AppxPackagePayload.Where(x => x.GetMetadata("TargetPath") == entryPointExecutable.Value).Single(); currentManagedEntryPointExecutableTaskItem.SetMetadata("TargetPath", AppEntryPointDir + "\\" + entryPointExecutable.Value); // Copy UWPShim var entryPointExecutableShim = Path.Combine(OutputPath, entryPointExecutable.Value); File.Copy(uwpShimLocation, entryPointExecutableShim, true); var copyResourcesReturncode = CopyWin32Resources(currentManagedEntryPointExecutableTaskItem.ItemSpec, entryPointExecutableShim); if (copyResourcesReturncode != 0) { Log.LogError(Resources.Error_CopyWin32ResourcesFailed, copyResourcesReturncode); return((int)ErrorCodes.CoreRuntimeLinkageError); } // Add UWPShim to appx package payload ITaskItem entryPointExecutableShimTaskItem = new TaskItem(entryPointExecutableShim); entryPointExecutableShimTaskItem.SetMetadata("TargetPath", entryPointExecutable.Value); currentManagedEntryPointExecutableTaskItem.CopyMetadataTo(entryPointExecutableShimTaskItem); currentAppxPackagePayload.Add(entryPointExecutableShimTaskItem); } } } // // 2. Replace all ClrHost.dll with either UWPShim.exe (for hybrid apps) or <app.exe> (for managed apps) var inprocServerNodes = doc.DescendantNodes().OfType <XText>() .Where(x => x.Value.Equals("ClrHost.dll", StringComparison.OrdinalIgnoreCase)) .Select(x => x); bool bHasManagedWinMD = false; foreach (var node in inprocServerNodes) { node.Value = inprocServer; bHasManagedWinMD = true; } // // 3. If #2 above is performed, inject UWPShim.exe into the output directory for unmanaged apps // which contain managed winmd and for managed background tasks (which do not contain entrypoint exe) if (bHasManagedWinMD && inprocServer.Equals(UWPShimEXE)) { try { // Copy UWPShim string uwpDestination = Path.Combine(OutputPath, inprocServer); File.Copy(uwpShimLocation, uwpDestination, true); // Add UWPShim to appx package payload TaskItem uwpShimTaskItem = new TaskItem(uwpDestination); uwpShimTaskItem.SetMetadata("TargetPath", inprocServer); currentAppxPackagePayload.Add(uwpShimTaskItem); } catch (Exception exception) { Log.LogError(Resources.Error_UnspecifiedCreatingUWPShimForHybrid, exception.Message); return((int)ErrorCodes.CoreRuntimeLinkageError); } } // // 4. If #1 or #2 above is performed, add a package dependency to CoreRuntime framework package. if (isTargetRuntimeManaged || bHasManagedWinMD) { foreach (var FrameworkPackage in FrameworkPackages) { string FrameworkPackageName = FrameworkPackage.GetMetadata("Name"); string FrameworkPackageMinVersion = FrameworkPackage.GetMetadata("Version"); string FrameworkPackagePublisher = FrameworkPackage.GetMetadata("Publisher"); if (!doc.Descendants(ns + "PackageDependency").Any(x => x.Attributes("Name").SingleOrDefault().Value == FrameworkPackageName)) { // There aren't any such PackageDependency. Add it now. XElement packageDependency = new XElement( ns + "PackageDependency", new XAttribute("Name", FrameworkPackageName), new XAttribute("MinVersion", FrameworkPackageMinVersion), new XAttribute("Publisher", FrameworkPackagePublisher) ); doc.Descendants(ns + "Dependencies").SingleOrDefault().Add(packageDependency); FrameworkPackagesNeedsToBeDeployed = true; } } } doc.Save(transformedAppxManifest); } TransformedAppxPackagePayload = currentAppxPackagePayload.ToArray(); return((int)ErrorCodes.Success); }
internal bool ExtractFromManifest(ITaskItem taskItem, string path, Hashtable containingReferenceFilesTable, Hashtable containedPrerequisiteAssembliesTable, Hashtable containedComComponentsTable, Hashtable containedTypeLibrariesTable, Hashtable containedLooseTlbFilesTable, Hashtable containedLooseEtcFilesTable) { base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveNativeReference.Comment", new object[] { path }); Manifest manifest = null; try { manifest = ManifestReader.ReadManifest(path, false); } catch (XmlException exception) { base.Log.LogErrorWithCodeFromResources("GenerateManifest.ReadInputManifestFailed", new object[] { path, exception.Message }); return false; } if (manifest != null) { manifest.TreatUnfoundNativeAssembliesAsPrerequisites = true; manifest.ReadOnly = true; manifest.ResolveFiles(); if (!manifest.OutputMessages.LogTaskMessages(this)) { return false; } ApplicationManifest manifest2 = manifest as ApplicationManifest; bool flag = (manifest2 != null) && manifest2.IsClickOnceManifest; if (!containingReferenceFilesTable.ContainsKey(path) && !flag) { ITaskItem destinationItem = new TaskItem { ItemSpec = path }; if (manifest.AssemblyIdentity.Name != null) { destinationItem.SetMetadata("FusionName", manifest.AssemblyIdentity.Name); } if (taskItem != null) { taskItem.CopyMetadataTo(destinationItem); } containingReferenceFilesTable.Add(path, destinationItem); } if (manifest.AssemblyReferences != null) { foreach (AssemblyReference reference in manifest.AssemblyReferences) { if (!reference.IsVirtual) { if (!reference.IsPrerequisite) { this.ExtractFromManifest(null, reference.ResolvedPath, containingReferenceFilesTable, containedPrerequisiteAssembliesTable, containedComComponentsTable, containedTypeLibrariesTable, containedLooseTlbFilesTable, containedLooseEtcFilesTable); } else { string fullName = reference.AssemblyIdentity.GetFullName(AssemblyIdentity.FullNameFlags.All); if (!containedPrerequisiteAssembliesTable.ContainsKey(fullName)) { ITaskItem item2 = new TaskItem { ItemSpec = fullName }; item2.SetMetadata("DependencyType", "Prerequisite"); containedPrerequisiteAssembliesTable.Add(fullName, item2); } } } } } if (manifest.FileReferences != null) { foreach (FileReference reference2 in manifest.FileReferences) { if (reference2.ResolvedPath != null) { if (!containedLooseEtcFilesTable.ContainsKey(reference2.ResolvedPath)) { ITaskItem item3 = new TaskItem { ItemSpec = reference2.ResolvedPath }; item3.SetMetadata("ParentFile", Path.GetFileName(path)); containedLooseEtcFilesTable.Add(reference2.ResolvedPath, item3); } if (reference2.ComClasses != null) { foreach (ComClass class2 in reference2.ComClasses) { if (!containedComComponentsTable.ContainsKey(class2.ClsId)) { ITaskItem item4 = new TaskItem { ItemSpec = class2.ClsId }; containedComComponentsTable.Add(class2.ClsId, item4); } } } if (reference2.TypeLibs != null) { foreach (TypeLib lib in reference2.TypeLibs) { if (!containedTypeLibrariesTable.ContainsKey(lib.TlbId)) { ITaskItem item5 = new TaskItem { ItemSpec = lib.TlbId }; item5.SetMetadata("WrapperTool", "tlbimp"); item5.SetMetadata("Guid", lib.TlbId); item5.SetMetadata("Lcid", "0"); char[] separator = ".".ToCharArray(); string[] strArray = null; strArray = lib.Version.Split(separator); item5.SetMetadata("VersionMajor", strArray[0]); item5.SetMetadata("VersionMinor", strArray[1]); containedTypeLibrariesTable.Add(lib.TlbId, item5); } } if (!containedLooseTlbFilesTable.Contains(reference2.ResolvedPath)) { ITaskItem item6 = new TaskItem { ItemSpec = reference2.ResolvedPath }; containedLooseTlbFilesTable.Add(reference2.ResolvedPath, item6); } } } } } } return true; }
private ITaskItem GetOutputEntryPoint(ITaskItem entryPoint, PublishInfo[] manifestEntryPointList) { if (entryPoint == null) { return null; } TaskItem destinationItem = new TaskItem(entryPoint.ItemSpec); entryPoint.CopyMetadataTo(destinationItem); string metadata = entryPoint.GetMetadata("TargetPath"); if (!string.IsNullOrEmpty(metadata)) { for (int i = 0; i < manifestEntryPointList.Length; i++) { if (string.Equals(metadata, manifestEntryPointList[i].key, StringComparison.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(manifestEntryPointList[i].includeHash)) { if (((manifestEntryPointList[i].state != PublishState.Exclude) && string.Equals(manifestEntryPointList[i].includeHash, "false", StringComparison.OrdinalIgnoreCase)) && this.SigningManifests) { this.canPublish = false; } destinationItem.SetMetadata("IncludeHash", manifestEntryPointList[i].includeHash); } return destinationItem; } } } return destinationItem; }
public override bool Execute() { var additionalFileWrites = new List <ITaskItem> (); var outputDir = MergeOutputDir; Directory.CreateDirectory(outputDir); var restoreMap = BuildRestoreMap(RestoreAssemblyResources); if (restoreMap == null) { return(false); } var changedReferencePaths = new List <ITaskItem> (); var removedReferencePaths = new List <ITaskItem> (); IAssemblyResolver resolver = null; foreach (var asm in restoreMap) { var asmName = new AssemblyName(asm.Key); ITaskItem item = FindMatchingAssembly(InputReferencePaths, asmName); if (item == null) { if (ThrowOnMissingAssembly) { return(false); } else { continue; } } //TODO: collision avoidance. AssemblyName MD5? NuGet package ID? var originalAsmPath = item.GetMetadata("FullPath"); var intermediateAsmPath = Path.Combine(outputDir, asmName.Name + ".dll"); var outputAsmPath = OverwriteSourceAssembly ? originalAsmPath : intermediateAsmPath; var stampAsmPath = intermediateAsmPath + ".stamp"; if (File.Exists(stampAsmPath)) { additionalFileWrites.Add(new TaskItem(stampAsmPath)); Log.LogMessage("Reference has already had resources merged, skipping due to: {0}", stampAsmPath); } else if (OverwriteSourceAssembly || !File.Exists(intermediateAsmPath) || File.GetLastWriteTime(intermediateAsmPath) < File.GetLastWriteTime(originalAsmPath)) { if (resolver == null) { resolver = CreateAssemblyResolver(); } if (!MergeResources(resolver, originalAsmPath, outputAsmPath, asm.Key, asm.Value)) { return(false); } File.WriteAllText(stampAsmPath, string.Empty); additionalFileWrites.Add(new TaskItem(stampAsmPath)); } removedReferencePaths.Add(item); var newItem = new TaskItem(intermediateAsmPath); item.CopyMetadataTo(newItem); changedReferencePaths.Add(newItem); } if (OverwriteSourceAssembly) { ChangedReferencePaths = new ITaskItem [0]; RemovedReferencePaths = new ITaskItem [0]; } else { ChangedReferencePaths = changedReferencePaths.ToArray(); RemovedReferencePaths = removedReferencePaths.ToArray(); } AdditionalFileWrites = additionalFileWrites.ToArray(); return(true); }
public void HarvestFilesFromPackage() { string pathToPackage = _packageFolders[PackageId]; var livePackageItems = Files.NullAsEmpty() .Where(f => IsIncludedExtension(f.GetMetadata("Extension"))) .Select(f => new PackageItem(f)); var livePackageFiles = new Dictionary <string, PackageItem>(StringComparer.OrdinalIgnoreCase); foreach (var livePackageItem in livePackageItems) { PackageItem existingitem; if (livePackageFiles.TryGetValue(livePackageItem.TargetPath, out existingitem)) { Log.LogError($"Package contains two files with same targetpath: {livePackageItem.TargetPath}, items:{livePackageItem.SourcePath}, {existingitem.SourcePath}."); } else { livePackageFiles.Add(livePackageItem.TargetPath, livePackageItem); } } var harvestedFiles = new List <ITaskItem>(); var removeFiles = new List <ITaskItem>(); // make sure we preserve refs that match desktop assemblies var liveDesktopDlls = livePackageFiles.Values.Where(pi => pi.IsDll && pi.TargetFramework?.Framework == FrameworkConstants.FrameworkIdentifiers.Net); var desktopRefVersions = liveDesktopDlls.Where(d => d.IsRef && d.Version != null).Select(d => d.Version); var desktopLibVersions = liveDesktopDlls.Where(d => !d.IsRef && d.Version != null).Select(d => d.Version); // find desktop assemblies with no matching lib. var preserveRefVersion = new HashSet <Version>(desktopLibVersions); preserveRefVersion.ExceptWith(desktopRefVersions); foreach (var extension in s_includedExtensions) { foreach (var packageFile in Directory.EnumerateFiles(pathToPackage, $"*{extension}", SearchOption.AllDirectories)) { string harvestPackagePath = packageFile.Substring(pathToPackage.Length + 1).Replace('\\', '/'); // determine if we should include this file from the harvested package // exclude if its specifically set for exclusion if (ShouldExclude(harvestPackagePath)) { Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is specifically excluded."); continue; } ITaskItem includeItem = null; if (!IncludeAllPaths && !ShouldInclude(harvestPackagePath, out includeItem)) { Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is not included in {nameof(PathsToInclude)}."); continue; } // allow for the harvested item to be moved var remappedTargetPath = includeItem?.GetMetadata("TargetPath"); if (!String.IsNullOrEmpty(remappedTargetPath)) { harvestPackagePath = remappedTargetPath + '/' + Path.GetFileName(packageFile); } List <string> targetPaths = new List <string>() { harvestPackagePath }; var additionalTargetPaths = includeItem?.GetMetadata("AdditionalTargetPath"); if (!String.IsNullOrEmpty(additionalTargetPaths)) { foreach (var additionalTargetPath in additionalTargetPaths.Split(';')) { if (!String.IsNullOrEmpty(additionalTargetPath)) { targetPaths.Add(additionalTargetPath + '/' + Path.GetFileName(packageFile)); } } } var assemblyVersion = extension == s_dll?VersionUtility.GetAssemblyVersion(packageFile) : null; PackageItem liveFile = null; foreach (var livePackagePath in targetPaths) { // determine if the harvested file clashes with a live built file // we'll prefer the harvested reference assembly so long as it's the same API // version and not required to match implementation 1:1 as is the case for desktop if (livePackageFiles.TryGetValue(livePackagePath, out liveFile)) { // Not a dll, or not a versioned assembly: prefer live built file. if (extension != s_dll || assemblyVersion == null || liveFile.Version == null) { // we don't consider this an error even for explicitly included files Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {livePackagePath} over the asset from last stable package because the file is not versioned."); continue; } // not a ref if (!liveFile.IsRef) { LogSkipIncludedFile(livePackagePath, " because it is a newer implementation."); continue; } // preserve desktop references to ensure bindingRedirects will work. if (liveFile.TargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.Net) { LogSkipIncludedFile(livePackagePath, " because it is desktop reference."); continue; } // as above but handle the case where a netstandard ref may be used for a desktop impl. if (preserveRefVersion.Contains(liveFile.Version)) { LogSkipIncludedFile(livePackagePath, " because it will be applicable for desktop projects."); continue; } // preserve references with a different major.minor version if (assemblyVersion.Major != liveFile.Version.Major || assemblyVersion.Minor != liveFile.Version.Minor) { LogSkipIncludedFile(livePackagePath, $" because it is a different API version ( {liveFile.Version.Major}.{liveFile.Version.Minor} vs {assemblyVersion.Major}.{assemblyVersion.Minor}."); continue; } // preserve references that specifically set the preserve metadata. bool preserve = false; bool.TryParse(liveFile.OriginalItem.GetMetadata("Preserve"), out preserve); if (preserve) { LogSkipIncludedFile(livePackagePath, " because it set metadata Preserve=true."); continue; } // replace the live file with the harvested one, removing both the live file and PDB from the // file list. Log.LogMessage($"Using reference {livePackagePath} from last stable package {PackageId}/{PackageVersion} rather than the built reference {liveFile.SourcePath} since it is the same API version. Set <Preserve>true</Preserve> on {liveFile.SourceProject} if you'd like to avoid this.."); removeFiles.Add(liveFile.OriginalItem); PackageItem livePdbFile; if (livePackageFiles.TryGetValue(Path.ChangeExtension(livePackagePath, ".pdb"), out livePdbFile)) { removeFiles.Add(livePdbFile.OriginalItem); } } else { Log.LogMessage(LogImportance.Low, $"Including {livePackagePath} from last stable package {PackageId}/{PackageVersion}."); } var item = new TaskItem(packageFile); if (liveFile?.OriginalItem != null) { // preserve all the meta-data from the live file that was replaced. liveFile.OriginalItem.CopyMetadataTo(item); } else { if (includeItem != null) { includeItem.CopyMetadataTo(item); } var targetPath = Path.GetDirectoryName(livePackagePath).Replace('\\', '/'); item.SetMetadata("TargetPath", targetPath); string targetFramework = GetTargetFrameworkFromPackagePath(targetPath); item.SetMetadata("TargetFramework", targetFramework); // only harvest for non-portable frameworks, matches logic in packaging.targets. bool harvestDependencies = !targetFramework.StartsWith("portable-"); item.SetMetadata("HarvestDependencies", harvestDependencies.ToString()); item.SetMetadata("IsReferenceAsset", IsReferencePackagePath(targetPath).ToString()); } if (assemblyVersion != null) { // overwrite whatever metadata may have been copied from the live file. item.SetMetadata("AssemblyVersion", assemblyVersion.ToString()); } item.SetMetadata("HarvestedFrom", $"{PackageId}/{PackageVersion}/{harvestPackagePath}"); harvestedFiles.Add(item); } } } HarvestedFiles = harvestedFiles.ToArray(); if (_pathsNotIncluded != null) { foreach (var pathNotIncluded in _pathsNotIncluded) { Log.LogError($"Path '{pathNotIncluded}' was specified in {nameof(PathsToInclude)} but was not found in the package {PackageId}/{PackageVersion}."); } } if (Files != null) { UpdatedFiles = Files.Except(removeFiles).ToArray(); } }
/// <summary> /// Helper manifest resolution method. Cracks the manifest and extracts the different elements from it. /// </summary> internal bool ExtractFromManifest(ITaskItem taskItem, string path, Hashtable containingReferenceFilesTable, Hashtable containedPrerequisiteAssembliesTable, Hashtable containedComComponentsTable, Hashtable containedTypeLibrariesTable, Hashtable containedLooseTlbFilesTable, Hashtable containedLooseEtcFilesTable) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveNativeReference.Comment", path); Manifest manifest = null; try { manifest = ManifestReader.ReadManifest(path, false); } catch (System.Xml.XmlException ex) { Log.LogErrorWithCodeFromResources("GenerateManifest.ReadInputManifestFailed", path, ex.Message); return(false); } if (manifest != null) { manifest.TreatUnfoundNativeAssembliesAsPrerequisites = true; manifest.ReadOnly = true; // only reading a manifest, set flag so we get GenerateManifest.ResolveFailedInReadOnlyMode instead of GenerateManifest.ResolveFailedInReadWriteMode messages manifest.ResolveFiles(); if (!manifest.OutputMessages.LogTaskMessages(this)) { return(false); } ApplicationManifest applicationManifest = manifest as ApplicationManifest; bool isClickOnceApp = applicationManifest != null && applicationManifest.IsClickOnceManifest; // ClickOnce application manifest should not be added as native reference, but we should open and process it. if (containingReferenceFilesTable.ContainsKey(path) == false && !isClickOnceApp) { ITaskItem itemNativeReferenceFile = new TaskItem(); itemNativeReferenceFile.ItemSpec = path; if (manifest.AssemblyIdentity.Name != null) { itemNativeReferenceFile.SetMetadata(ItemMetadataNames.fusionName, manifest.AssemblyIdentity.Name); } if (taskItem != null) { taskItem.CopyMetadataTo(itemNativeReferenceFile); } containingReferenceFilesTable.Add(path, itemNativeReferenceFile); } if (manifest.AssemblyReferences != null) { foreach (AssemblyReference assemblyref in manifest.AssemblyReferences) { if (assemblyref.IsVirtual) { //It is a CLR virtual reference, not a real reference. continue; } if (!assemblyref.IsPrerequisite) { // recurse and call ExtractFromManifest for this assembly--if it has a manifest it will be cracked. ExtractFromManifest(null, assemblyref.ResolvedPath, containingReferenceFilesTable, containedPrerequisiteAssembliesTable, containedComComponentsTable, containedTypeLibrariesTable, containedLooseTlbFilesTable, containedLooseEtcFilesTable); } else { string id = assemblyref.AssemblyIdentity.GetFullName(AssemblyIdentity.FullNameFlags.All); // add the assembly to the prerequisites list, if it's not already there if (containedPrerequisiteAssembliesTable.ContainsKey(id) == false) { ITaskItem item = new TaskItem(); item.ItemSpec = id; item.SetMetadata("DependencyType", "Prerequisite"); containedPrerequisiteAssembliesTable.Add(id, item); } } } } if (manifest.FileReferences != null) { foreach (FileReference fileref in manifest.FileReferences) { if (fileref.ResolvedPath == null) { continue; } // add the loose file to the outputs list, if it's not already there if (containedLooseEtcFilesTable.ContainsKey(fileref.ResolvedPath) == false) { ITaskItem itemLooseEtcFile = new TaskItem(); itemLooseEtcFile.ItemSpec = fileref.ResolvedPath; // The ParentFile attribute (visible thru Project Outputs) relates the loose // file to the parent assembly of which it is a part. This is important so we can // group those files together with their parent assembly in the deployment tool // (i.e. ClickOnce application files dialog). itemLooseEtcFile.SetMetadata(ItemMetadataNames.parentFile, Path.GetFileName(path)); containedLooseEtcFilesTable.Add(fileref.ResolvedPath, itemLooseEtcFile); } if (fileref.ComClasses != null) { foreach (ComClass comclass in fileref.ComClasses) { // add the comclass to the outputs list, if it's not already there if (containedComComponentsTable.ContainsKey(comclass.ClsId) == false) { ITaskItem itemComClass = new TaskItem(); itemComClass.ItemSpec = comclass.ClsId; containedComComponentsTable.Add(comclass.ClsId, itemComClass); } } } if (fileref.TypeLibs != null) { foreach (TypeLib typelib in fileref.TypeLibs) { // add the typelib to the outputs list, if it's not already there if (containedTypeLibrariesTable.ContainsKey(typelib.TlbId) == false) { ITaskItem itemTypeLib = new TaskItem(); itemTypeLib.ItemSpec = typelib.TlbId; itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.wrapperTool, ComReferenceTypes.tlbimp); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.guid, typelib.TlbId); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.lcid, "0"); string delimStr = "."; char[] delimiter = delimStr.ToCharArray(); string[] verMajorAndMinor = null; verMajorAndMinor = typelib.Version.Split(delimiter); // UNDONE: are major and minor version numbers in base 10 or 16? itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.versionMajor, verMajorAndMinor[0]); itemTypeLib.SetMetadata(ComReferenceItemMetadataNames.versionMinor, verMajorAndMinor[1]); containedTypeLibrariesTable.Add(typelib.TlbId, itemTypeLib); } } // add the loose TLB file to the outputs list, if it's not already there if (containedLooseTlbFilesTable.Contains(fileref.ResolvedPath) == false) { ITaskItem itemLooseTlbFile = new TaskItem(); itemLooseTlbFile.ItemSpec = fileref.ResolvedPath; containedLooseTlbFilesTable.Add(fileref.ResolvedPath, itemLooseTlbFile); } } } } } return(true); }
private TaskItem BuildContent(ITaskItem folder, Document document, PathMapping folderMapping) { PathMapping documentPath = new PathMapping(folderMapping, new TaskItem().FillMetadata(document)); string targetFile = documentPath.MappedPath; TaskItem content = new TaskItem(targetFile); folder.CopyMetadataTo(content, FolderMetadataPrefix ?? "Folder"); content.FillMetadata(documentPath); content.FillMetadata(document); content.RequireParentDirectory(Log); if (content.Exists()) { DateTime updated = File.GetLastWriteTime(targetFile); Log.LogMessage(MessageImportance.Normal, "Exists at \"{0}\"", targetFile); if (updated != document.Updated) { Log.LogMessage(MessageImportance.Low, "Updated - Local: {0} Remote: {1}", updated, document.Updated); } else { Log.LogMessage(MessageImportance.Low, "Updated - {0}", document.Updated); } } else { Log.LogMessage(MessageImportance.Normal, "Detected new document"); } if (document.DocumentEntry != null && document.DocumentEntry.Content != null && document.DocumentEntry.Content.Src != null) { content.SetMetadata("ExportUri", document.DocumentEntry.Content.Src.ToString()); } content.Save(Log, document.Updated); return content; }
/// <summary> /// Parallelize I/O with the same semantics as the single-threaded copy method above. /// ResolveAssemblyReferences tends to generate longer and longer lists of files to send /// to CopyTask as we get further and further down the dependency graph. /// The OS can handle a lot of parallel I/O so let's minimize wall clock time to get /// it all done. /// </summary> private bool CopyParallel( CopyFileWithState copyFile, int parallelism, out List <ITaskItem> destinationFilesSuccessfullyCopied) { bool success = true; // We must supply the same semantics as the single-threaded version above: // // - For copy operations in the list that have the same destination, we must // provide for in-order copy attempts that allow re-copying different files // and avoiding copies for later files that match SkipUnchangedFiles semantics. // We must also add a destination file copy item for each attempt. // - The order of entries in destinationFilesSuccessfullyCopied must match // the order of entries passed in, along with copied metadata. // - Metadata must not be copied to destination item if the copy operation failed. // // We split the work into different Tasks: // // - Entries with unique destination file paths each get their own parallel operation. // - Each subset of copies into the same destination get their own Task to run // the single-threaded logic in order. // // At the end we reassemble the result list in the same order as was passed in. // Map: Destination path -> indexes in SourceFiles/DestinationItems array indices (ordered low->high). var partitionsByDestination = new Dictionary <string, List <int> >( DestinationFiles.Length, // Set length to common case of 1:1 source->dest. StringComparer.OrdinalIgnoreCase); for (int i = 0; i < SourceFiles.Length && !_cancellationTokenSource.IsCancellationRequested; ++i) { ITaskItem destItem = DestinationFiles[i]; string destPath = destItem.ItemSpec; if (!partitionsByDestination.TryGetValue(destPath, out List <int> sourceIndices)) { // Use 1 for list length - common case is for no destination overlap. sourceIndices = new List <int>(1); partitionsByDestination[destPath] = sourceIndices; } sourceIndices.Add(i); } // Lockless flags updated from each thread - each needs to be a processor word for atomicity. var successFlags = new IntPtr[DestinationFiles.Length]; var actionBlockOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = parallelism, CancellationToken = _cancellationTokenSource.Token }; var partitionCopyActionBlock = new ActionBlock <List <int> >( async(List <int> partition) => { // Break from synchronous thread context of caller to get onto thread pool thread. await System.Threading.Tasks.Task.Yield(); for (int partitionIndex = 0; partitionIndex < partition.Count && !_cancellationTokenSource.IsCancellationRequested; partitionIndex++) { int fileIndex = partition[partitionIndex]; ITaskItem sourceItem = SourceFiles[fileIndex]; ITaskItem destItem = DestinationFiles[fileIndex]; string sourcePath = sourceItem.ItemSpec; // Check if we just copied from this location to the destination, don't copy again. bool copyComplete = partitionIndex > 0 && String.Equals( sourcePath, SourceFiles[partition[partitionIndex - 1]].ItemSpec, StringComparison.OrdinalIgnoreCase); if (!copyComplete) { if (DoCopyIfNecessary( new FileState(sourceItem.ItemSpec), new FileState(destItem.ItemSpec), copyFile)) { copyComplete = true; } else { // Thread race to set outer variable but they race to set the same (false) value. success = false; } } if (copyComplete) { sourceItem.CopyMetadataTo(destItem); successFlags[fileIndex] = (IntPtr)1; } } }, actionBlockOptions); foreach (List <int> partition in partitionsByDestination.Values) { bool partitionAccepted = partitionCopyActionBlock.Post(partition); if (!partitionAccepted) { // Retail assert... ErrorUtilities.VerifyThrow(false, "Failed posting a file copy to an ActionBlock. Should not happen with block at max int capacity."); } } partitionCopyActionBlock.Complete(); partitionCopyActionBlock.Completion.GetAwaiter().GetResult(); // Assemble an in-order list of destination items that succeeded. destinationFilesSuccessfullyCopied = new List <ITaskItem>(DestinationFiles.Length); for (int i = 0; i < successFlags.Length; i++) { if (successFlags[i] != (IntPtr)0) { destinationFilesSuccessfullyCopied.Add(DestinationFiles[i]); } } return(success); }
private static ITaskItem CreatePrerequisiteItem(ITaskItem item) { ITaskItem destinationItem = new TaskItem(item.ItemSpec); item.CopyMetadataTo(destinationItem); destinationItem.SetMetadata("DependencyType", "Prerequisite"); return destinationItem; }