Beispiel #1
0
        /// <summary>
        /// Calls Path.GetFullPath for each of the inputs.  Preserves metadata.
        /// </summary>
        /// <returns>true on success, false on failure</returns>
        public override bool Execute()
        {
            List<ITaskItem> absolutePathsList = new List<ITaskItem>();

            foreach (ITaskItem path in this.Paths)
            {
                try
                {
                    // Only call Path.GetFullPath if the path is not rooted to avoid 
                    // going to disk when it is not necessary
                    if (!Path.IsPathRooted(path.ItemSpec))
                    {
                        if (path is ITaskItem2)
                        {
                            ((ITaskItem2)path).EvaluatedIncludeEscaped = ((ITaskItem2)path).GetMetadataValueEscaped("FullPath");
                        }
                        else
                        {
                            path.ItemSpec = EscapingUtilities.Escape(path.GetMetadata("FullPath"));
                        }
                    }
                    absolutePathsList.Add(path);
                }
                catch (ArgumentException e)
                {
                    Log.LogErrorWithCodeFromResources("General.InvalidArgument", e.Message);
                }
            }

            this.AbsolutePaths = absolutePathsList.ToArray();
            return !Log.HasLoggedErrors;
        }
 public void Escape()
 {
     Assert.Equal("%2a", EscapingUtilities.Escape("*"));
     Assert.Equal("%3f", EscapingUtilities.Escape("?"));
     Assert.Equal("#%2a%3f%2a#%2a", EscapingUtilities.Escape("#*?*#*"));
     Assert.Equal("%25%2a%3f%2a%25%2a", EscapingUtilities.Escape("%*?*%*"));
 }
Beispiel #3
0
        /// <summary>
        /// Set up our list of destination files.
        /// </summary>
        /// <returns>False if an error occurred, implying aborting the overall copy operation.</returns>
        private bool InitializeDestinationFiles()
        {
            if (DestinationFiles == null)
            {
                // If the caller passed in DestinationFolder, convert it to DestinationFiles
                DestinationFiles = new ITaskItem[SourceFiles.Length];

                for (int i = 0; i < SourceFiles.Length; ++i)
                {
                    // Build the correct path.
                    string destinationFile;
                    try
                    {
                        destinationFile = Path.Combine(DestinationFolder.ItemSpec, Path.GetFileName(SourceFiles[i].ItemSpec));
                    }
                    catch (ArgumentException e)
                    {
                        Log.LogErrorWithCodeFromResources("Copy.Error", SourceFiles[i].ItemSpec, DestinationFolder.ItemSpec, e.Message);
                        // Clear the outputs.
                        DestinationFiles = Array.Empty <ITaskItem>();
                        return(false);
                    }

                    // Initialize the destinationFolder item.
                    // ItemSpec is unescaped, and the TaskItem constructor expects an escaped input, so we need to
                    // make sure to re-escape it here.
                    DestinationFiles[i] = new TaskItem(EscapingUtilities.Escape(destinationFile));

                    // Copy meta-data from source to destinationFolder.
                    SourceFiles[i].CopyMetadataTo(DestinationFiles[i]);
                }
            }

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Sets the value of the specified custom metadata.
        /// </summary>
        /// <owner>SumedhK</owner>
        /// <param name="metadataName"></param>
        /// <param name="metadataValue"></param>
        public void SetMetadata(string metadataName, string metadataValue)
        {
            ErrorUtilities.VerifyThrowArgumentLength(metadataName, "metadataName");
            ErrorUtilities.VerifyThrowArgumentNull(metadataValue, "metadataValue");

            item.SetMetadata(metadataName, EscapingUtilities.Escape(metadataValue));
        }
Beispiel #5
0
        /// <summary>
        /// Calls a method on the TaskLoggingHelper to parse a single line of text to
        /// see if there are any errors or warnings in canonical format.
        /// </summary>
        /// <remarks>
        /// Overridden to handle any custom regular expressions supplied.
        /// </remarks>
        protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
        {
            if (OutputMatchesRegex(singleLine, ref _customErrorRegex))
            {
                Log.LogError(singleLine);
            }
            else if (OutputMatchesRegex(singleLine, ref _customWarningRegex))
            {
                Log.LogWarning(singleLine);
            }
            else if (_ignoreStandardErrorWarningFormat)
            {
                // Not detecting regular format errors and warnings, and it didn't
                // match any regexes either -- log as a regular message
                Log.LogMessage(messageImportance, singleLine, null);
            }
            else
            {
                // This is the normal code path: match standard format errors and warnings
                Log.LogMessageFromText(singleLine, messageImportance);
            }

            if (ConsoleToMSBuild)
            {
                string trimmedTextLine = singleLine.Trim();
                if (trimmedTextLine.Length > 0)
                {
                    // The lines read may be unescaped, so we need to escape them
                    // before passing them to the TaskItem.
                    _nonEmptyOutput.Add(new TaskItem(EscapingUtilities.Escape(trimmedTextLine)));
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Execute the task.
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            ArrayList inPathList    = new ArrayList();
            ArrayList outOfPathList = new ArrayList();

            string conePath;

            try
            {
                conePath = OpportunisticIntern.InternStringIfPossible(System.IO.Path.GetFullPath(_path.ItemSpec));
                conePath = FileUtilities.EnsureTrailingSlash(conePath);
            }
            catch (Exception e) when(ExceptionHandling.IsIoRelatedException(e))
            {
                Log.LogErrorWithCodeFromResources(null, "", 0, 0, 0, 0,
                                                  "FindUnderPath.InvalidParameter", "Path", _path.ItemSpec, e.Message);
                return(false);
            }

            int conePathLength = conePath.Length;

            Log.LogMessageFromResources(MessageImportance.Low, "FindUnderPath.ComparisonPath", Path.ItemSpec);

            foreach (ITaskItem item in Files)
            {
                string fullPath;
                try
                {
                    fullPath = OpportunisticIntern.InternStringIfPossible(System.IO.Path.GetFullPath(item.ItemSpec));
                }
                catch (Exception e) when(ExceptionHandling.IsIoRelatedException(e))
                {
                    Log.LogErrorWithCodeFromResources(null, "", 0, 0, 0, 0,
                                                      "FindUnderPath.InvalidParameter", "Files", item.ItemSpec, e.Message);
                    return(false);
                }

                // Compare the left side of both strings to see if they're equal.
                if (String.Compare(conePath, 0, fullPath, 0, conePathLength, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // If we should use the absolute path, update the item contents
                    // Since ItemSpec, which fullPath comes from, is unescaped, re-escape when setting
                    // item.ItemSpec, since the setter for ItemSpec expects an escaped value.
                    if (_updateToAbsolutePaths)
                    {
                        item.ItemSpec = EscapingUtilities.Escape(fullPath);
                    }

                    inPathList.Add(item);
                }
                else
                {
                    outOfPathList.Add(item);
                }
            }

            InPath    = (ITaskItem[])inPathList.ToArray(typeof(ITaskItem));
            OutOfPath = (ITaskItem[])outOfPathList.ToArray(typeof(ITaskItem));
            return(true);
        }
Beispiel #7
0
 private BuildResult MapBuildResult(string project, Microsoft.Build.Execution.BuildResult buildResult)
 {
     var escapedProject = EscapingUtilities.Escape(project);
     return new BuildResult
     {
         Project = project,
         Exception = buildResult.Exception,
         CircularDependency = buildResult.CircularDependency,
         ConfigurationId = buildResult.ConfigurationId,
         GlobalRequestId = buildResult.GlobalRequestId,
         NodeRequestId = buildResult.NodeRequestId,
         OverallResult = buildResult.OverallResult,
         ParentGlobalRequestId = buildResult.ParentGlobalRequestId,
         ResultsByTarget = new ResultsByTarget(buildResult.ResultsByTarget.ToDictionary(x => x.Key, x => new TargetResult
         {
             Name = x.Key,
             Exception = x.Value.Exception,
             ResultCode = x.Value.ResultCode,
             Items = x.Value.Items.Cast<ITaskItem2>().Select(
                 y => new TaskItem(
                     y.EvaluatedIncludeEscaped,
                     escapedProject,
                     ToGeneric(y.CloneCustomMetadataEscaped())))
                 .ToArray()
         }))
     };
 }
            /// <summary>
            /// Allows custom metadata on the item to be copied to another item.
            /// </summary>
            /// <remarks>
            /// RECOMMENDED GUIDELINES FOR METHOD IMPLEMENTATIONS:
            /// 1) this method should NOT copy over the item-spec
            /// 2) if a particular piece of metadata already exists on the destination item, it should NOT be overwritten
            /// 3) if there are pieces of metadata on the item that make no semantic sense on the destination item, they should NOT be copied
            /// </remarks>
            /// <param name="destinationItem">The item to copy metadata to.</param>
            public void CopyMetadataTo(ITaskItem destinationItem)
            {
                ErrorUtilities.VerifyThrowArgumentNull(destinationItem, nameof(destinationItem));

                // also copy the original item-spec under a "magic" metadata -- this is useful for tasks that forward metadata
                // between items, and need to know the source item where the metadata came from
                string originalItemSpec = destinationItem.GetMetadata("OriginalItemSpec");

                if (_customEscapedMetadata != null)
                {
                    foreach (KeyValuePair <string, string> entry in _customEscapedMetadata)
                    {
                        string value = destinationItem.GetMetadata(entry.Key);

                        if (String.IsNullOrEmpty(value))
                        {
                            destinationItem.SetMetadata(entry.Key, entry.Value);
                        }
                    }
                }

                if (String.IsNullOrEmpty(originalItemSpec))
                {
                    destinationItem.SetMetadata("OriginalItemSpec", EscapingUtilities.Escape(ItemSpec));
                }
            }
Beispiel #9
0
        /// <summary>
        /// Used for the purposes of evaluating an item specification. Given a filespec that may include wildcard characters * and
        /// ?, we translate it into an actual list of files. If the input filespec doesn't contain any wildcard characters, and it
        /// doesn't appear to point to an actual file on disk, then we just give back the input string as an array of length one,
        /// assuming that it wasn't really intended to be a filename (as items are not required to necessarily represent files).
        /// Any wildcards passed in that are unescaped will be treated as real wildcards.
        /// The "include" of items passed back from the filesystem will be returned canonically escaped.
        /// The ordering of the list returned is deterministic (it is sorted).
        /// Will never throw IO exceptions: if there is no match, returns the input verbatim.
        /// </summary>
        /// <param name="directoryEscaped">The directory to evaluate, escaped.</param>
        /// <param name="filespecEscaped">The filespec to evaluate, escaped.</param>
        /// <param name="returnEscaped"><code>true</code> to return escaped specs.</param>
        /// <param name="excludeSpecsEscaped">The exclude specification, escaped.</param>
        /// <returns>Array of file paths.</returns>
        private static string[] GetFileList
        (
            string directoryEscaped,
            string filespecEscaped,
            bool returnEscaped,
            IEnumerable <string> excludeSpecsEscaped = null
        )
        {
            ErrorUtilities.VerifyThrowInternalLength(filespecEscaped, "filespecEscaped");

            if (excludeSpecsEscaped == null)
            {
                excludeSpecsEscaped = Enumerable.Empty <string>();
            }

            string[] fileList;

            if (FilespecHasWildcards(filespecEscaped))
            {
                // Unescape before handing it to the filesystem.
                var directoryUnescaped    = EscapingUtilities.UnescapeAll(directoryEscaped);
                var filespecUnescaped     = EscapingUtilities.UnescapeAll(filespecEscaped);
                var excludeSpecsUnescaped = excludeSpecsEscaped.Where(IsValidExclude).Select(EscapingUtilities.UnescapeAll).ToList();

                // Get the list of actual files which match the filespec.  Put
                // the list into a string array.  If the filespec started out
                // as a relative path, we will get back a bunch of relative paths.
                // If the filespec started out as an absolute path, we will get
                // back a bunch of absolute paths.
                fileList = FileMatcher.GetFiles(directoryUnescaped, filespecUnescaped, excludeSpecsUnescaped);

                ErrorUtilities.VerifyThrow(fileList != null, "We must have a list of files here, even if it's empty.");

                // Before actually returning the file list, we sort them alphabetically.  This
                // provides a certain amount of extra determinism and reproducability.  That is,
                // we're sure that the build will behave in exactly the same way every time,
                // and on every machine.
                Array.Sort(fileList, StringComparer.OrdinalIgnoreCase);

                if (returnEscaped)
                {
                    // We must now go back and make sure all special characters are escaped because we always
                    // store data in the engine in escaped form so it doesn't interfere with our parsing.
                    // Note that this means that characters that were not escaped in the original filespec
                    // may now be escaped, but that's not easy to avoid.
                    for (int i = 0; i < fileList.Length; i++)
                    {
                        fileList[i] = EscapingUtilities.Escape(fileList[i]);
                    }
                }
            }
            else
            {
                // Just return the original string.
                fileList = new string[] { returnEscaped?filespecEscaped : EscapingUtilities.UnescapeAll(filespecEscaped) };
            }

            return(fileList);
        }
Beispiel #10
0
 /// <summary>
 /// This sets an arbitrary attribute on the task element.  These
 /// are attributes that the project author has placed on the task element
 /// that get passed in to the task.
 ///
 /// This optionally escapes the parameter value so it will be treated as a literal.
 /// </summary>
 /// <param name="parameterName"></param>
 /// <param name="parameterValue"></param>
 /// <param name="treatParameterValueAsLiteral"></param>
 /// <owner>RGoel</owner>
 public void SetParameterValue
 (
     string parameterName,
     string parameterValue,
     bool treatParameterValueAsLiteral
 )
 {
     this.SetParameterValue(parameterName, treatParameterValueAsLiteral ? EscapingUtilities.Escape(parameterValue) : parameterValue);
 }
        public void EscapeUnescape()
        {
            string text = "%2a";

            Assert.Equal(text, EscapingUtilities.Escape(EscapingUtilities.UnescapeAll(text)));

            text = "%3f";
            Assert.Equal(text, EscapingUtilities.Escape(EscapingUtilities.UnescapeAll(text)));

            text = "#%2a%3f%2a#%2a";
            Assert.Equal(text, EscapingUtilities.Escape(EscapingUtilities.UnescapeAll(text)));
        }
Beispiel #12
0
        /// <summary>
        /// Creates a new ITaskItem with the contents of the old one.
        /// </summary>
        private ITaskItem CreateNewTaskItemFrom(ITaskItem copyFrom)
        {
            ITaskItem2 copyFromAsITaskItem2 = copyFrom as ITaskItem2;

            string escapedItemSpec        = null;
            string escapedDefiningProject = null;
            Dictionary <string, string> escapedMetadata = null;

            if (copyFromAsITaskItem2 != null)
            {
                escapedItemSpec        = copyFromAsITaskItem2.EvaluatedIncludeEscaped;
                escapedDefiningProject = copyFromAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath);
                IDictionary nonGenericEscapedMetadata = copyFromAsITaskItem2.CloneCustomMetadataEscaped();

                if (nonGenericEscapedMetadata is Dictionary <string, string> )
                {
                    escapedMetadata = (Dictionary <string, string>)nonGenericEscapedMetadata;
                }
                else
                {
                    escapedMetadata = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                    foreach (object key in nonGenericEscapedMetadata.Keys)
                    {
                        escapedMetadata[(string)key] = (string)nonGenericEscapedMetadata[key] ?? String.Empty;
                    }
                }
            }
            else
            {
                // If we don't have ITaskItem2 to fall back on, we have to make do with the fact that
                // CloneCustomMetadata, GetMetadata, & ItemSpec returns unescaped values, and
                // TaskParameterTaskItem's constructor expects escaped values, so escaping them all
                // is the closest approximation to correct we can get.
                escapedItemSpec = EscapingUtilities.Escape(copyFrom.ItemSpec);

                escapedDefiningProject = EscapingUtilities.EscapeWithCaching(copyFrom.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath));

                IDictionary customMetadata = copyFrom.CloneCustomMetadata();
                escapedMetadata = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                if (customMetadata != null && customMetadata.Count > 0)
                {
                    foreach (string key in customMetadata.Keys)
                    {
                        escapedMetadata.Add(key, EscapingUtilities.Escape((string)customMetadata[key] ?? String.Empty));
                    }
                }
            }

            TaskParameterTaskItem taskItem = new TaskParameterTaskItem(escapedItemSpec, escapedDefiningProject, escapedMetadata);

            return(taskItem);
        }
        public void UnescapeEscape()
        {
            string text = "*";

            Assert.Equal(text, EscapingUtilities.UnescapeAll(EscapingUtilities.Escape(text)));

            text = "?";
            Assert.Equal(text, EscapingUtilities.UnescapeAll(EscapingUtilities.Escape(text)));

            text = "#*?*#*";
            Assert.Equal(text, EscapingUtilities.UnescapeAll(EscapingUtilities.Escape(text)));
        }
Beispiel #14
0
        /// <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, nameof(sourceItem));

            // Attempt to preserve escaped state
            if (!(sourceItem is ITaskItem2 sourceItemAsITaskItem2))
            {
                _itemSpec        = EscapingUtilities.Escape(sourceItem.ItemSpec);
                _definingProject = EscapingUtilities.EscapeWithCaching(sourceItem.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath));
            }
Beispiel #15
0
        public override bool Execute()
        {
            if (PropertiesAndValues != null)
            {
                XElement root = UseAttributeForTargetFrameworkInfoPropertyNames ?
                                new("TargetFramework", new XAttribute("Name", EscapingUtilities.Escape(RootElementName))) :
                                new(RootElementName);

                foreach (ITaskItem item in PropertiesAndValues)
                {
                    root.Add(new XElement(item.ItemSpec, item.GetMetadata("Value")));
                }

                Result = root.ToString();
            }
            return(!Log.HasLoggedErrors);
        }
Beispiel #16
0
        /// <summary>
        /// Execute the task.
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            bool success = true;

            if (File != null)
            {
                if (System.IO.File.Exists(File.ItemSpec))
                {
                    string[] textLines = null;
                    try
                    {
                        textLines = System.IO.File.ReadAllLines(File.ItemSpec);

                        ArrayList nonEmptyLines = new ArrayList();
                        char[]    charsToTrim   = new char[] { '\0', ' ', '\t' };

                        foreach (string textLine in textLines)
                        {
                            // A customer has given us a project with a FileList.txt file containing
                            // a line full of '\0' characters.  We don't know how these characters
                            // got in there, but when we try to read the file back in, we fail
                            // miserably.  Here, we Trim to protect us from this situation.
                            string trimmedTextLine = textLine.Trim(charsToTrim);
                            if (trimmedTextLine.Length > 0)
                            {
                                // The lines were written to the file in unescaped form, so we need to escape them
                                // before passing them to the TaskItem.
                                nonEmptyLines.Add(new TaskItem(EscapingUtilities.Escape(trimmedTextLine)));
                            }
                        }

                        Lines = (ITaskItem[])nonEmptyLines.ToArray(typeof(ITaskItem));
                    }
                    catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception.
                    {
                        if (ExceptionHandling.NotExpectedException(e))
                        {
                            throw;
                        }
                        LogError(_file, e, ref success);
                    }
                }
            }

            return(success);
        }
Beispiel #17
0
        public void CopyMetadataTo(ITaskItem destinationItem)
        {
            ErrorUtilities.VerifyThrowArgumentNull(destinationItem, "destinationItem");
            string     metadata = destinationItem.GetMetadata("OriginalItemSpec");
            ITaskItem2 item     = destinationItem as ITaskItem2;

            if (this.metadata != null)
            {
                TaskItem item2 = destinationItem as TaskItem;
                if ((item2 != null) && (item2.metadata == null))
                {
                    item2.metadata = this.metadata.Clone();
                }
                else
                {
                    foreach (KeyValuePair <string, string> pair in this.metadata)
                    {
                        if (item != null)
                        {
                            if (string.IsNullOrEmpty(item.GetMetadataValueEscaped(pair.Key)))
                            {
                                item.SetMetadata(pair.Key, pair.Value);
                            }
                        }
                        else if (string.IsNullOrEmpty(destinationItem.GetMetadata(pair.Key)))
                        {
                            destinationItem.SetMetadata(pair.Key, EscapingUtilities.Escape(pair.Value));
                        }
                    }
                }
            }
            if (string.IsNullOrEmpty(metadata))
            {
                if (item != null)
                {
                    item.SetMetadata("OriginalItemSpec", ((ITaskItem2)this).EvaluatedIncludeEscaped);
                }
                else
                {
                    destinationItem.SetMetadata("OriginalItemSpec", EscapingUtilities.Escape(this.ItemSpec));
                }
            }
        }
Beispiel #18
0
        public override bool Execute()
        {
            bool success = true;

            if (File != null)
            {
                if (FileSystems.Default.FileExists(File.ItemSpec))
                {
                    try
                    {
                        string[] textLines = System.IO.File.ReadAllLines(File.ItemSpec);

                        var    nonEmptyLines = new List <ITaskItem>();
                        char[] charsToTrim   = { '\0', ' ', '\t' };

                        foreach (string textLine in textLines)
                        {
                            // A customer has given us a project with a FileList.txt file containing
                            // a line full of '\0' characters.  We don't know how these characters
                            // got in there, but when we try to read the file back in, we fail
                            // miserably.  Here, we Trim to protect us from this situation.
                            string trimmedTextLine = textLine.Trim(charsToTrim);
                            if (trimmedTextLine.Length > 0)
                            {
                                // The lines were written to the file in unescaped form, so we need to escape them
                                // before passing them to the TaskItem.
                                nonEmptyLines.Add(new TaskItem(EscapingUtilities.Escape(trimmedTextLine)));
                            }
                        }

                        Lines = nonEmptyLines.ToArray();
                    }
                    catch (Exception e) when(ExceptionHandling.IsIoRelatedException(e))
                    {
                        Log.LogErrorWithCodeFromResources("ReadLinesFromFile.ErrorOrWarning", File.ItemSpec, e.Message);
                        success = false;
                    }
                }
            }

            return(success);
        }
        public static Dictionary <string, string> ParseEnvironmentVariables(TaskLoggingHelper logger, string inputFileName, bool escape)
        {
            var vars = new Dictionary <string, string> ();

            foreach (var line in File.ReadAllLines(inputFileName))
            {
                var match = Regex.Match(line);
                if (!match.Success)
                {
                    logger.LogError($"Failed to parse environment export: '{line}'.");
                    return(null);
                }

                var name  = match.Groups[1].Value;
                var value = escape ? EscapingUtilities.Escape(match.Groups[2].Value) : match.Groups[2].Value;
                vars.Add(name, value);
            }

            return(vars);
        }
Beispiel #20
0
        /// <summary>
        /// Extract the value for "RecursiveDir", if any, from the Include.
        /// If there is none, returns an empty string.
        /// </summary>
        /// <remarks>
        /// Inputs to and outputs of this function are all escaped.
        /// </remarks>
        private static string GetRecursiveDirValue(string evaluatedIncludeBeforeWildcardExpansionEscaped, string evaluatedIncludeEscaped)
        {
            // If there were no wildcards, the two strings will be the same, and there is no recursivedir part.
            if (String.Equals(evaluatedIncludeBeforeWildcardExpansionEscaped, evaluatedIncludeEscaped, StringComparison.OrdinalIgnoreCase))
            {
                return(String.Empty);
            }

            // we're going to the file system, so unescape the include value here:
            string evaluatedIncludeBeforeWildcardExpansion = EscapingUtilities.UnescapeAll(evaluatedIncludeBeforeWildcardExpansionEscaped);
            string evaluatedInclude = EscapingUtilities.UnescapeAll(evaluatedIncludeEscaped);

            FileMatcher.Result match = FileMatcher.Default.FileMatch(evaluatedIncludeBeforeWildcardExpansion, evaluatedInclude);

            if (match.isLegalFileSpec && match.isMatch)
            {
                return(EscapingUtilities.Escape(match.wildcardDirectoryPart));
            }

            return(String.Empty);
        }
        // Create a temporary file and run the task on it
        private static void RunTask(FindUnderPath t, out FileInfo testFile, out bool success)
        {
            string fileName = ObjectModelHelpers.CreateFileInTempProjectDirectory("file%3b.temp", "foo");

            testFile = new FileInfo(fileName);

            t.Path  = new TaskItem(ObjectModelHelpers.TempProjectDir);
            t.Files = new ITaskItem[] { new TaskItem(EscapingUtilities.Escape(testFile.Name)), new TaskItem(@"C:\SomeoneElsesProject\File2.txt") };

            success = false;
            string currentDirectory = Directory.GetCurrentDirectory();

            try
            {
                Directory.SetCurrentDirectory(ObjectModelHelpers.TempProjectDir);
                success = t.Execute();
            }
            finally
            {
                Directory.SetCurrentDirectory(currentDirectory);
            }
        }
Beispiel #22
0
        /// <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);
        }
Beispiel #23
0
            /// <summary>
            /// If OutputFiles is null, we need to generate default output names
            /// to pass to resgen.exe (which would generate the names on its own, but
            /// then we wouldn't have access to them)
            /// </summary>
            private void GenerateOutputFileNames()
            {
                ErrorUtilities.VerifyThrow(!ResGen.IsNullOrEmpty(InputFiles), "If InputFiles is empty, the task should have returned before reaching this point");

                ITaskItem[] inputFiles  = InputFiles;
                ITaskItem[] outputFiles = new ITaskItem[inputFiles.Length];

                // Set the default OutputFiles values
                for (int i = 0; i < inputFiles.Length; i++)
                {
                    ITaskItem2 inputFileAsITaskItem2 = inputFiles[i] as ITaskItem2;

                    if (inputFileAsITaskItem2 != null)
                    {
                        outputFiles[i] = new TaskItem(Path.ChangeExtension(inputFileAsITaskItem2.EvaluatedIncludeEscaped, ".resources"));
                    }
                    else
                    {
                        outputFiles[i] = new TaskItem(Path.ChangeExtension(EscapingUtilities.Escape(inputFiles[i].ItemSpec), ".resources"));
                    }
                }

                Bag["OutputFiles"] = outputFiles;
            }
 /// <summary>
 /// Sets the exact metadata value given to the metadata name requested.
 /// </summary>
 void ITaskItem2.SetMetadataValueLiteral(string metadataName, string metadataValue)
 {
     SetMetadata(metadataName, EscapingUtilities.Escape(metadataValue));
 }
        /// <summary>
        /// Write the given ITaskItem, using the given write translator
        /// </summary>
        private void WriteITaskItem(ITranslator translator, ITaskItem wrappedItem)
        {
            ErrorUtilities.VerifyThrow(translator.Mode == TranslationDirection.WriteToStream, "Cannot call this method when reading!");

            if (!TranslateNullable(translator, wrappedItem))
            {
                return;
            }

            string      escapedItemSpec;
            string      escapedDefiningProject;
            IDictionary wrappedMetadata;
            bool        wrappedMetadataIsEscaped;

            ITaskItem2 wrappedItemAsITaskItem2 = wrappedItem as ITaskItem2;

            if (wrappedItemAsITaskItem2 != null)
            {
                escapedItemSpec          = wrappedItemAsITaskItem2.EvaluatedIncludeEscaped;
                escapedDefiningProject   = wrappedItemAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath);
                wrappedMetadata          = wrappedItemAsITaskItem2.CloneCustomMetadataEscaped();
                wrappedMetadataIsEscaped = true;
            }
            else
            {
                // We know that the ITaskItem constructor expects an escaped string, and that ITaskItem.ItemSpec
                // is expected to be unescaped, so make sure we give the constructor what it wants.
                escapedItemSpec          = EscapingUtilities.Escape(wrappedItem.ItemSpec);
                escapedDefiningProject   = EscapingUtilities.EscapeWithCaching(wrappedItem.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath));
                wrappedMetadata          = wrappedItem.CloneCustomMetadata();
                wrappedMetadataIsEscaped = false;
            }

            Dictionary <string, string> escapedGenericWrappedMetadata = wrappedMetadata as Dictionary <string, string>;

            if (escapedGenericWrappedMetadata == null)
            {
                escapedGenericWrappedMetadata = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                foreach (object key in wrappedMetadata.Keys)
                {
                    string value = (string)wrappedMetadata[key];

                    if (!wrappedMetadataIsEscaped)
                    {
                        value = (value == null) ? value : EscapingUtilities.Escape(value);
                    }

                    escapedGenericWrappedMetadata.Add((string)key, value);
                }
            }
            else if (!wrappedMetadataIsEscaped)
            {
                foreach (KeyValuePair <string, string> entry in escapedGenericWrappedMetadata)
                {
                    escapedGenericWrappedMetadata[entry.Key] = entry.Value == null ? entry.Value : EscapingUtilities.Escape(entry.Value);
                }
            }

            translator.Translate(ref escapedItemSpec);
            translator.Translate(ref escapedDefiningProject);
            translator.TranslateDictionary(ref escapedGenericWrappedMetadata, StringComparer.OrdinalIgnoreCase);
        }
Beispiel #26
0
        /// <summary>
        /// Used to load information about default MSBuild tasks i.e. tasks that do not need to be explicitly declared in projects
        /// with the &lt;UsingTask&gt; element. Default task information is read from special files, which are located in the same
        /// directory as the MSBuild binaries.
        /// </summary>
        /// <remarks>
        /// 1) a default tasks file needs the &lt;Project&gt; root tag in order to be well-formed
        /// 2) the XML declaration tag &lt;?xml ...&gt; is ignored
        /// 3) comment tags are always ignored regardless of their placement
        /// 4) the rest of the tags are expected to be &lt;UsingTask&gt; tags
        /// </remarks>
        private void RegisterDefaultTasks(BuildEventContext buildEventContext)
        {
            if (!defaultTasksRegistrationAttempted)
            {
                try
                {
                    this.defaultTaskRegistry = new TaskRegistry();

                    string[] defaultTasksFiles = { };

                    try
                    {
                        defaultTasksFiles = getFiles(toolset.ToolsPath, defaultTasksFilePattern);

                        if (defaultTasksFiles.Length == 0)
                        {
                            loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                       "DefaultTasksFileLoadFailureWarning",
                                                       defaultTasksFilePattern, toolset.ToolsPath, String.Empty);
                        }
                    }
                    // handle security problems when finding the default tasks files
                    catch (UnauthorizedAccessException e)
                    {
                        loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                   "DefaultTasksFileLoadFailureWarning",
                                                   defaultTasksFilePattern, toolset.ToolsPath, e.Message);
                    }
                    // handle problems when reading the default tasks files
                    catch (Exception e) // Catching Exception, but rethrowing unless it's an IO related exception.
                    {
                        if (ExceptionHandling.NotExpectedException(e))
                        {
                            throw;
                        }

                        loggingServices.LogWarning(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                                                   "DefaultTasksFileLoadFailureWarning",
                                                   defaultTasksFilePattern, toolset.ToolsPath, e.Message);
                    }

                    BuildPropertyGroup propertyBag = null;

                    foreach (string defaultTasksFile in defaultTasksFiles)
                    {
                        try
                        {
                            XmlDocument defaultTasks = loadXmlFromPath(defaultTasksFile);

                            // look for the first root tag that is not a comment or an XML declaration -- this should be the <Project> tag
                            // NOTE: the XML parser will guarantee there is only one real root element in the file
                            // but we need to find it amongst the other types of XmlNode at the root.
                            foreach (XmlNode topLevelNode in defaultTasks.ChildNodes)
                            {
                                if (XmlUtilities.IsXmlRootElement(topLevelNode))
                                {
                                    ProjectErrorUtilities.VerifyThrowInvalidProject(topLevelNode.LocalName == XMakeElements.project,
                                                                                    topLevelNode, "UnrecognizedElement", topLevelNode.Name);

                                    ProjectErrorUtilities.VerifyThrowInvalidProject((topLevelNode.Prefix.Length == 0) && (String.Equals(topLevelNode.NamespaceURI, XMakeAttributes.defaultXmlNamespace, StringComparison.OrdinalIgnoreCase)),
                                                                                    topLevelNode, "ProjectMustBeInMSBuildXmlNamespace", XMakeAttributes.defaultXmlNamespace);

                                    // the <Project> tag can only the XML namespace -- no other attributes
                                    foreach (XmlAttribute projectAttribute in topLevelNode.Attributes)
                                    {
                                        ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(projectAttribute.Name == XMakeAttributes.xmlns, projectAttribute);
                                    }

                                    // look at all the child tags of the <Project> root tag we found
                                    foreach (XmlNode usingTaskNode in topLevelNode.ChildNodes)
                                    {
                                        if (usingTaskNode.NodeType != XmlNodeType.Comment)
                                        {
                                            ProjectErrorUtilities.VerifyThrowInvalidProject(usingTaskNode.Name == XMakeElements.usingTask,
                                                                                            usingTaskNode, "UnrecognizedElement", usingTaskNode.Name);

                                            // Initialize the property bag if it hasn't been already.
                                            if (propertyBag == null)
                                            {
                                                // Set the value of the MSBuildBinPath/ToolsPath properties.
                                                BuildPropertyGroup reservedPropertyBag = new BuildPropertyGroup();

                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.binPath, EscapingUtilities.Escape(toolset.ToolsPath),
                                                                      PropertyType.ReservedProperty));

                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.toolsPath, EscapingUtilities.Escape(toolset.ToolsPath),
                                                                      PropertyType.ReservedProperty));

                                                // Also set MSBuildAssemblyVersion so that the tasks file can tell between v4 and v12 MSBuild
                                                reservedPropertyBag.SetProperty(
                                                    new BuildProperty(ReservedPropertyNames.assemblyVersion, Constants.AssemblyVersion,
                                                                      PropertyType.ReservedProperty));

                                                propertyBag = new BuildPropertyGroup();
                                                propertyBag.ImportInitialProperties(parentEngine.EnvironmentProperties, reservedPropertyBag, BuildProperties, parentEngine.GlobalProperties);
                                            }

                                            defaultTaskRegistry.RegisterTask(new UsingTask((XmlElement)usingTaskNode, true), new Expander(propertyBag), loggingServices, buildEventContext);
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                        // handle security problems when loading the default tasks file
                        catch (UnauthorizedAccessException e)
                        {
                            loggingServices.LogError(buildEventContext, new BuildEventFileInfo(defaultTasksFile), "DefaultTasksFileFailure", e.Message);
                            break;
                        }
                        // handle problems when loading the default tasks file
                        catch (IOException e)
                        {
                            loggingServices.LogError(buildEventContext, new BuildEventFileInfo(defaultTasksFile), "DefaultTasksFileFailure", e.Message);
                            break;
                        }
                        // handle XML errors in the default tasks file
                        catch (XmlException e)
                        {
                            ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, new BuildEventFileInfo(e),
                                                                                    "DefaultTasksFileFailure", e.Message);
                        }
                    }
                }
                finally
                {
                    defaultTasksRegistrationAttempted = true;
                }
            }
        }
Beispiel #27
0
 internal static string Escape(this string unescapedString)
 {
     return(EscapingUtilities.Escape(unescapedString));
 }
Beispiel #28
0
        /// <summary>
        /// Execute the task.
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            AssignedFiles = new ITaskItem[Files.Length];

            if (Files.Length > 0)
            {
                // Compose a file in the root folder.
                // NOTE: at this point fullRootPath may or may not have a trailing
                // slash because Path.GetFullPath() does not add or remove it
                string fullRootPath = Path.GetFullPath(RootFolder);

                // Ensure trailing slash otherwise c:\bin appears to match part of c:\bin2\foo
                fullRootPath = FileUtilities.EnsureTrailingSlash(fullRootPath);

                string currentDirectory = Directory.GetCurrentDirectory();

                // check if the root folder is the same as the current directory
                // NOTE: the path returned from Directory.GetCurrentDirectory()
                // does not have a trailing slash, but fullRootPath does
                bool isRootFolderSameAsCurrentDirectory =
                    ((fullRootPath.Length - 1 /* exclude trailing slash */) == currentDirectory.Length)
                    &&
                    (String.Compare(
                         fullRootPath, 0,
                         currentDirectory, 0,
                         fullRootPath.Length - 1 /* don't compare trailing slash */,
                         StringComparison.OrdinalIgnoreCase) == 0);

                for (int i = 0; i < Files.Length; ++i)
                {
                    AssignedFiles[i] = new TaskItem(Files[i]);

                    // If TargetPath is already set, it takes priority.
                    // https://github.com/dotnet/msbuild/issues/2795
                    string targetPath = ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave16_10) ? Files[i].GetMetadata(ItemMetadataNames.targetPath) : null;

                    // If TargetPath not already set, fall back to default behavior.
                    if (string.IsNullOrEmpty(targetPath))
                    {
                        targetPath = Files[i].GetMetadata(ItemMetadataNames.link);
                    }

                    if (string.IsNullOrEmpty(targetPath))
                    {
                        if (// if the file path is relative
                            !Path.IsPathRooted(Files[i].ItemSpec) &&
                            // if the file path doesn't contain any relative specifiers
                            !Files[i].ItemSpec.Contains("." + Path.DirectorySeparatorChar) &&
                            // if the file path is already relative to the root folder
                            isRootFolderSameAsCurrentDirectory)
                        {
                            // then just use the file path as-is
                            // PERF NOTE: we do this to avoid calling Path.GetFullPath() below,
                            // because that method consumes a lot of memory, esp. when we have
                            // a lot of items coming through this task
                            targetPath = Files[i].ItemSpec;
                        }
                        else
                        {
                            // PERF WARNING: Path.GetFullPath() is expensive in terms of memory;
                            // we should avoid calling it whenever possible
                            string itemSpecFullFileNamePath = Path.GetFullPath(Files[i].ItemSpec);

                            if (String.Compare(fullRootPath, 0, itemSpecFullFileNamePath, 0, fullRootPath.Length, StringComparison.CurrentCultureIgnoreCase) == 0)
                            {
                                // The item spec file is in the "cone" of the RootFolder. Return the relative path from the cone root.
                                targetPath = itemSpecFullFileNamePath.Substring(fullRootPath.Length);
                            }
                            else
                            {
                                // The item spec file is not in the "cone" of the RootFolder. Return the filename only.
                                targetPath = Path.GetFileName(Files[i].ItemSpec);
                            }
                        }
                    }

                    AssignedFiles[i].SetMetadata(ItemMetadataNames.targetPath, EscapingUtilities.Escape(targetPath));
                }
            }

            return(true);
        }
Beispiel #29
0
        /// <summary>
        /// Execute the task.
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            _assignedFiles = new TaskItem[Files.Length];

            if (Files.Length > 0)
            {
                // Compose a file in the root folder.
                // NOTE: at this point fullRootPath may or may not have a trailing
                // slash because Path.GetFullPath() does not add or remove it
                string fullRootPath = Path.GetFullPath(this.RootFolder);

                // Ensure trailing slash otherwise c:\bin appears to match part of c:\bin2\foo
                fullRootPath = FileUtilities.EnsureTrailingSlash(fullRootPath);

                string currentDirectory = Directory.GetCurrentDirectory();

                // check if the root folder is the same as the current directory
                // NOTE: the path returned from Directory.GetCurrentDirectory()
                // does not have a trailing slash, but fullRootPath does
                bool isRootFolderSameAsCurrentDirectory =
                    ((fullRootPath.Length - 1 /* exclude trailing slash */) == currentDirectory.Length)
                    &&
                    (String.Compare(
                         fullRootPath, 0,
                         currentDirectory, 0,
                         (fullRootPath.Length - 1) /* don't compare trailing slash */,
                         StringComparison.OrdinalIgnoreCase) == 0);

                for (int i = 0; i < Files.Length; ++i)
                {
                    string link = Files[i].GetMetadata(ItemMetadataNames.link);
                    AssignedFiles[i] = new TaskItem(Files[i]);

                    // If file has a link, use that.
                    string targetPath = link;

                    if (link == null || link.Length == 0)
                    {
                        if (// if the file path is relative
                            !Path.IsPathRooted(Files[i].ItemSpec) &&
                            // if the file path doesn't contain any relative specifiers
                            !Files[i].ItemSpec.Contains(".\\") &&
                            // if the file path is already relative to the root folder
                            isRootFolderSameAsCurrentDirectory)
                        {
                            // then just use the file path as-is
                            // PERF NOTE: we do this to avoid calling Path.GetFullPath() below,
                            // because that method consumes a lot of memory, esp. when we have
                            // a lot of items coming through this task
                            targetPath = Files[i].ItemSpec;
                        }
                        else
                        {
                            // PERF WARNING: Path.GetFullPath() is expensive in terms of memory;
                            // we should avoid calling it whenever possible
                            string itemSpecFullFileNamePath = Path.GetFullPath(Files[i].ItemSpec);

                            if (String.Compare(fullRootPath, 0, itemSpecFullFileNamePath, 0, fullRootPath.Length, true, CultureInfo.CurrentCulture) == 0)
                            {
                                // The item spec file is in the "cone" of the RootFolder. Return the relative path from the cone root.
                                targetPath = itemSpecFullFileNamePath.Substring(fullRootPath.Length);
                            }
                            else
                            {
                                // The item spec file is not in the "cone" of the RootFolder. Return the filename only.
                                targetPath = Path.GetFileName(Files[i].ItemSpec);
                            }
                        }
                    }

                    AssignedFiles[i].SetMetadata(ItemMetadataNames.targetPath, EscapingUtilities.Escape(targetPath));
                }
            }

            return(true);
        }
Beispiel #30
0
 /// <summary>
 /// Adds a new item to the ItemGroup, optional treating the item Include as literal so that
 /// any special characters will be escaped before persisting it.
 /// </summary>
 public BuildItem AddNewItem(string itemName, string itemInclude, bool treatItemIncludeAsLiteral)
 {
     return(AddNewItem(itemName, treatItemIncludeAsLiteral ? EscapingUtilities.Escape(itemInclude) : itemInclude));
 }