コード例 #1
0
        public static FileSpecMatcherTester Parse(string currentDirectory, string fileSpec)
        {
            string unescapedFileSpec = EscapingUtilities.UnescapeAll(fileSpec);
            Regex  regex             = EngineFileUtilities.FilespecHasWildcards(fileSpec) ? CreateRegex(unescapedFileSpec, currentDirectory) : null;

            return(new FileSpecMatcherTester(currentDirectory, unescapedFileSpec, regex));
        }
コード例 #2
0
ファイル: CreateItem.cs プロジェクト: Forgind/msbuild
        private (ITaskItem[] Element, bool NoLoggedErrors) TryExpandingWildcards(ITaskItem[] expand, string attributeType)
        {
            const string CreateItemTask = nameof(CreateItem);

            string fileSpec;

            FileMatcher.SearchAction searchAction;

            (expand, searchAction, fileSpec) = ExpandWildcards(expand);

            // Log potential drive enumeration glob anomalies when applicable.
            if (searchAction == FileMatcher.SearchAction.LogDriveEnumeratingWildcard)
            {
                Log.LogWarningWithCodeFromResources(
                    "WildcardResultsInDriveEnumeration",
                    EscapingUtilities.UnescapeAll(fileSpec),
                    attributeType,
                    CreateItemTask);
            }
            else if (searchAction == FileMatcher.SearchAction.FailOnDriveEnumeratingWildcard)
            {
                Log.LogErrorWithCodeFromResources(
                    "WildcardResultsInDriveEnumeration",
                    EscapingUtilities.UnescapeAll(fileSpec),
                    attributeType,
                    CreateItemTask);
            }

            return(expand, !Log.HasLoggedErrors);
        }
コード例 #3
0
        /// <summary>
        /// Given a build state try to find the parent target that caused this build state to
        /// come into being either via dependent, on error relationship or via IBuildEngine call
        /// </summary>
        internal TargetIdWrapper FindParentTarget
        (
            EngineCallback engineCallback,
            ProjectBuildState buildContext,
            Target target,
            out BuildRequest parentRequest
        )
        {
            // We need to find the parent target
            parentRequest = null;

            // Skip build states that have already been filled
            if (buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.RequestFilled)
            {
                return(null);
            }

            // Check if the target was called due to a onerror or depends on call
            if (buildContext.ContainsBlockingTarget(target.Name))
            {
                // Figure out the record for the parent target
                Project containingProject = target.ParentProject;
                Target  parentTarget      = containingProject.Targets[buildContext.GetParentTarget(target.Name)];
                return(new TargetIdWrapper(parentTarget));
            }
            else
            {
                // The build context must have formed due to IBuildEngine call
                ErrorUtilities.VerifyThrow(
                    String.Compare(EscapingUtilities.UnescapeAll(buildContext.NameOfTargetInProgress), target.Name, StringComparison.OrdinalIgnoreCase) == 0,
                    "The target should be the in progress target for the context");
                // This target is called due to IBuildEngine or host request
                return(FindParentTargetForBuildRequest(engineCallback, buildContext.BuildRequest, out parentRequest));
            }
        }
コード例 #4
0
ファイル: TaskItem.cs プロジェクト: 3F/IeXod
        /// <summary>
        /// Copy the metadata (but not the ItemSpec or other built-in metadata) to destinationItem. If a particular metadata
        /// already exists on the destination item, then it is not overwritten -- the original value wins.
        /// </summary>
        /// <owner>JomoF</owner>
        /// <param name="destinationItem"></param>
        public void CopyMetadataTo
        (
            ITaskItem destinationItem
        )
        {
            ErrorUtilities.VerifyThrowArgumentNull(destinationItem, "destinationItem");

            // Intentionally not _computed_ properties. These are slow and don't really
            // apply anyway.
            foreach (DictionaryEntry entry in item.GetAllCustomEvaluatedMetadata())
            {
                string key = (string)entry.Key;

                string destinationValue = destinationItem.GetMetadata(key);

                if ((destinationValue == null) || (destinationValue.Length == 0))
                {
                    destinationItem.SetMetadata(key, EscapingUtilities.UnescapeAll((string)entry.Value));
                }
            }

            // 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 ((originalItemSpec == null) || (originalItemSpec.Length == 0))
            {
                destinationItem.SetMetadata("OriginalItemSpec", ItemSpec);
            }
        }
コード例 #5
0
ファイル: BuildRequest.cs プロジェクト: vikassrivas/msbuild
        /// <summary>
        /// Initializes a build request with a parent context.
        /// </summary>
        /// <param name="submissionId">The id of the build submission.</param>
        /// <param name="nodeRequestId">The id of the node issuing the request</param>
        /// <param name="configurationId">The configuration id to use.</param>
        /// <param name="escapedTargets">The targets to be built</param>
        /// <param name="hostServices">Host services if any. May be null.</param>
        /// <param name="parentBuildEventContext">The build event context of the parent project.</param>
        /// <param name="parentRequest">The parent build request, if any.</param>
        /// <param name="buildRequestDataFlags">Additional flags for the request.</param>
        /// <param name="requestedProjectState">Filter for desired build results.</param>
        public BuildRequest(
            int submissionId,
            int nodeRequestId,
            int configurationId,
            ICollection <string> escapedTargets,
            HostServices hostServices,
            BuildEventContext parentBuildEventContext,
            BuildRequest parentRequest,
            BuildRequestDataFlags buildRequestDataFlags = BuildRequestDataFlags.None,
            RequestedProjectState requestedProjectState = null)
        {
            ErrorUtilities.VerifyThrowArgumentNull(escapedTargets, "targets");
            ErrorUtilities.VerifyThrowArgumentNull(parentBuildEventContext, "parentBuildEventContext");

            _submissionId    = submissionId;
            _configurationId = configurationId;

            // When targets come into a build request, we unescape them.
            _targets = new List <string>(escapedTargets.Count);
            foreach (string target in escapedTargets)
            {
                _targets.Add(EscapingUtilities.UnescapeAll(target));
            }

            HostServices             = hostServices;
            _buildEventContext       = BuildEventContext.Invalid;
            _parentBuildEventContext = parentBuildEventContext;
            _globalRequestId         = InvalidGlobalRequestId;
            _parentGlobalRequestId   = parentRequest?.GlobalRequestId ?? InvalidGlobalRequestId;

            _nodeRequestId         = nodeRequestId;
            _buildRequestDataFlags = buildRequestDataFlags;
            _requestedProjectState = requestedProjectState;
        }
コード例 #6
0
ファイル: BuildRequest.cs プロジェクト: Nirmal4G/msbuild
        public BuildRequest(
            int submissionId,
            int nodeRequestId,
            int configurationId,
            ICollection <string> escapedTargets,
            HostServices hostServices,
            BuildEventContext parentBuildEventContext,
            BuildRequest parentRequest,
            BuildRequestDataFlags buildRequestDataFlags = BuildRequestDataFlags.None,
            RequestedProjectState requestedProjectState = null,
            bool skipStaticGraphIsolationConstraints    = false,
            int projectContextId = BuildEventContext.InvalidProjectContextId)
            : this(submissionId, nodeRequestId, configurationId, hostServices, buildRequestDataFlags, requestedProjectState, projectContextId)
        {
            ErrorUtilities.VerifyThrowArgumentNull(escapedTargets, "targets");
            ErrorUtilities.VerifyThrowArgumentNull(parentBuildEventContext, nameof(parentBuildEventContext));

            // When targets come into a build request, we unescape them.
            _targets = new List <string>(escapedTargets.Count);
            foreach (string target in escapedTargets)
            {
                _targets.Add(EscapingUtilities.UnescapeAll(target));
            }

            _parentBuildEventContext = parentBuildEventContext;
            _parentGlobalRequestId   = parentRequest?.GlobalRequestId ?? InvalidGlobalRequestId;

            _skipStaticGraphIsolationConstraints = skipStaticGraphIsolationConstraints;
        }
コード例 #7
0
ファイル: BuildItemGroup.cs プロジェクト: maoxingda/msbuild-1
        /// <summary>
        /// Returns a list of all items in the provided item group whose itemspecs match the specification, after it is split and any wildcards are expanded.
        /// If not items match, returns null.
        /// </summary>
        internal static List <BuildItem> FindItemsMatchingSpecification(BuildItemGroup items, string specification, XmlAttribute attribute, Expander expander, string baseDirectory)
        {
            if (items.Count == 0 || specification.Length == 0)
            {
                return(null);
            }

            // This is a hashtable whose key is the filename for the individual items
            // in the Exclude list, after wildcard expansion.  The value in the hash table
            // is just an empty string.
            Hashtable specificationsToFind = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // Split by semicolons
            List <string> specificationPieces = expander.ExpandAllIntoStringListLeaveEscaped(specification, attribute);

            foreach (string piece in specificationPieces)
            {
                // Take each individual path or file expression, and expand any
                // wildcards.  Then loop through each file returned, and add it
                // to our hashtable.

                // Don't unescape wildcards just yet - if there were any escaped, the caller wants to treat them
                // as literals. Everything else is safe to unescape at this point, since we're only matching
                // against the file system.
                string[] fileList = EngineFileUtilities.GetFileListEscaped(baseDirectory, piece);

                foreach (string file in fileList)
                {
                    // Now unescape everything, because this is the end of the road for this filename.
                    // We're just going to compare it to the unescaped include path to filter out the
                    // file excludes.
                    specificationsToFind[EscapingUtilities.UnescapeAll(file)] = String.Empty;
                }
            }

            if (specificationsToFind.Count == 0)
            {
                return(null);
            }

            // Now loop through our list and filter out any that match a
            // filename in the remove list.
            List <BuildItem> itemsRemoved = new List <BuildItem>();

            foreach (BuildItem item in items)
            {
                // Even if the case for the excluded files is different, they
                // will still get excluded, as expected.  However, if the excluded path
                // references the same file in a different way, such as by relative
                // path instead of absolute path, we will not realize that they refer
                // to the same file, and thus we will not exclude it.
                if (specificationsToFind.ContainsKey(item.FinalItemSpec))
                {
                    itemsRemoved.Add(item);
                }
            }

            return(itemsRemoved);
        }
コード例 #8
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);
        }
コード例 #9
0
 internal static string Unescape
 (
     this string escapedString,
     out bool escapingWasNecessary
 )
 {
     return(EscapingUtilities.UnescapeAll(escapedString, out escapingWasNecessary));
 }
コード例 #10
0
        /// <summary>
        /// Retrieves one of the arbitrary metadata on the item.
        /// If not found, returns empty string.
        /// </summary>
        /// <comments>
        /// Returns the unescaped value of the metadata requested.
        /// </comments>
        /// <param name="metadataName">The name of the metadata to retrieve.</param>
        /// <returns>The metadata value.</returns>
        public string GetMetadata
        (
            string metadataName
        )
        {
            string metadataValue = (this as ITaskItem2).GetMetadataValueEscaped(metadataName);

            return(EscapingUtilities.UnescapeAll(metadataValue));
        }
コード例 #11
0
        /// <summary>
        /// Get the value of any metadata in the item that has the specified
        /// name, otherwise returns null
        /// </summary>
        public string GetMetadataValue(string name)
        {
            if (Link != null)
            {
                return(Link.GetMetadataValue(name));
            }

            string escapedValue = (this as IMetadataTable).GetEscapedValue(name);

            return((escapedValue == null) ? null : EscapingUtilities.UnescapeAll(escapedValue));
        }
コード例 #12
0
        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)));
        }
コード例 #13
0
        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)));
        }
コード例 #14
0
        void ProcessItemSpec(OperationBuilder operationBuilder, string itemSpec, ElementLocation itemSpecLocation)
        {
            //  Code corresponds to Evaluator.CreateItemsFromInclude

            // STEP 1: Expand properties in Include
            string evaluatedIncludeEscaped = _outerExpander.ExpandIntoStringLeaveEscaped(itemSpec, ExpanderOptions.ExpandProperties, itemSpecLocation);

            // STEP 2: Split Include on any semicolons, and take each split in turn
            if (evaluatedIncludeEscaped.Length > 0)
            {
                IList <string> includeSplitsEscaped = ExpressionShredder.SplitSemiColonSeparatedList(evaluatedIncludeEscaped);

                foreach (string includeSplitEscaped in includeSplitsEscaped)
                {
                    // STEP 3: If expression is "@(x)" copy specified list with its metadata, otherwise just treat as string
                    bool isItemListExpression;
                    ProcessSingleItemVectorExpressionForInclude(includeSplitEscaped, operationBuilder, itemSpecLocation, out isItemListExpression);

                    if (!isItemListExpression)
                    {
                        // The expression is not of the form "@(X)". Treat as string

                        //  Code corresponds to EngineFileUtilities.GetFileList
                        bool containsEscapedWildcards = EscapingUtilities.ContainsEscapedWildcards(includeSplitEscaped);
                        bool containsRealWildcards    = FileMatcher.HasWildcards(includeSplitEscaped);

                        if (containsEscapedWildcards && containsRealWildcards)
                        {
                            // Umm, this makes no sense.  The item's Include has both escaped wildcards and
                            // real wildcards.  What does he want us to do?  Go to the file system and find
                            // files that literally have '*' in their filename?  Well, that's not going to
                            // happen because '*' is an illegal character to have in a filename.

                            // Just return the original string.
                            operationBuilder.Operations.Add(Tuple.Create(ItemOperationType.Value, (object)includeSplitEscaped));
                        }
                        else if (!containsEscapedWildcards && containsRealWildcards)
                        {
                            // Unescape before handing it to the filesystem.
                            string filespecUnescaped = EscapingUtilities.UnescapeAll(includeSplitEscaped);
                            operationBuilder.Operations.Add(Tuple.Create(ItemOperationType.Glob, (object)filespecUnescaped));
                        }
                        else
                        {
                            // No real wildcards means we just return the original string.  Don't even bother
                            // escaping ... it should already be escaped appropriately since it came directly
                            // from the project file
                            operationBuilder.Operations.Add(Tuple.Create(ItemOperationType.Value, (object)includeSplitEscaped));
                        }
                    }
                }
            }
        }
コード例 #15
0
        public IDictionary CloneCustomMetadata()
        {
            CopyOnWriteDictionary <string, string> dictionary = new CopyOnWriteDictionary <string, string>(MSBuildNameIgnoreCaseComparer.Default);

            if (this.metadata != null)
            {
                foreach (KeyValuePair <string, string> pair in this.metadata)
                {
                    dictionary.Add(pair.Key, EscapingUtilities.UnescapeAll(pair.Value));
                }
            }
            return(dictionary);
        }
コード例 #16
0
            public IEnumerable <KeyValuePair <string, string> > EnumerateMetadata()
            {
                if (_customEscapedMetadata == null)
                {
                    yield break;
                }

                foreach (var kvp in _customEscapedMetadata)
                {
                    var unescaped = new KeyValuePair <string, string>(kvp.Key, EscapingUtilities.UnescapeAll(kvp.Value));
                    yield return(unescaped);
                }
            }
コード例 #17
0
ファイル: FileSpecMatchTester.cs プロジェクト: xen2/msbuild
        public static FileSpecMatcherTester Parse(string currentDirectory, string fileSpec)
        {
            string unescapedFileSpec = EscapingUtilities.UnescapeAll(fileSpec);
            string filenamePattern   = null;
            Regex  regex             = null;

            if (EngineFileUtilities.FilespecHasWildcards(fileSpec))
            {
                CreateRegexOrFilenamePattern(unescapedFileSpec, currentDirectory, out filenamePattern, out regex);
            }

            return(new FileSpecMatcherTester(currentDirectory, unescapedFileSpec, filenamePattern, regex));
        }
コード例 #18
0
            /// <summary>
            /// Get the collection of custom metadata. This does not include built-in metadata.
            /// </summary>
            /// <remarks>
            /// RECOMMENDED GUIDELINES FOR METHOD IMPLEMENTATIONS:
            /// 1) this method should return a clone of the metadata
            /// 2) writing to this dictionary should not be reflected in the underlying item.
            /// </remarks>
            /// <returns>Dictionary of cloned metadata</returns>
            public IDictionary CloneCustomMetadata()
            {
                IDictionary <string, string> clonedMetadata = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

                if (_customEscapedMetadata != null)
                {
                    foreach (KeyValuePair <string, string> metadatum in _customEscapedMetadata)
                    {
                        clonedMetadata.Add(metadatum.Key, EscapingUtilities.UnescapeAll(metadatum.Value));
                    }
                }

                return((IDictionary)clonedMetadata);
            }
コード例 #19
0
 internal virtual void OutputProperties(List <DictionaryEntry> list)
 {
     // Write the banner
     setColor(ConsoleColor.Green);
     WriteLinePretty(currentIndentLevel, ResourceUtilities.FormatResourceString("PropertyListHeader"));
     // Write each property name and its value, one per line
     foreach (DictionaryEntry prop in list)
     {
         setColor(ConsoleColor.Gray);
         WritePretty(String.Format(CultureInfo.CurrentCulture, "{0,-30} = ", prop.Key));
         setColor(ConsoleColor.DarkGray);
         WriteLinePretty(EscapingUtilities.UnescapeAll((string)prop.Value));
     }
     resetColor();
 }
コード例 #20
0
 /// <summary>
 /// Sets the given property in the given property group.
 /// </summary>
 private void SetProperty(ToolsetPropertyDefinition property, PropertyDictionary <ProjectPropertyInstance> propertyGroup, PropertyDictionary <ProjectPropertyInstance> globalProperties)
 {
     try
     {
         // Global properties cannot be overwritten
         if (globalProperties[property.Name] == null)
         {
             propertyGroup.Set(ProjectPropertyInstance.Create(property.Name, EscapingUtilities.UnescapeAll(property.Value), true /* may be reserved */, false /* not immutable */));
         }
     }
     catch (ArgumentException ex)
     {
         InvalidToolsetDefinitionException.Throw(ex, "InvalidPropertyNameInToolset", property.Name, property.Source.LocationString, ex.Message);
     }
 }
コード例 #21
0
        public void Unescape()
        {
            Assert.Equal("", EscapingUtilities.UnescapeAll(""));
            Assert.Equal("foo", EscapingUtilities.UnescapeAll("foo"));
            Assert.Equal("foo space", EscapingUtilities.UnescapeAll("foo%20space"));
            Assert.Equal("foo2;", EscapingUtilities.UnescapeAll("foo2%3B"));
            Assert.Equal(";foo3", EscapingUtilities.UnescapeAll("%3bfoo3"));
            Assert.Equal(";", EscapingUtilities.UnescapeAll("%3b"));
            Assert.Equal(";;;;;", EscapingUtilities.UnescapeAll("%3b%3B;%3b%3B"));
            Assert.Equal("%3B", EscapingUtilities.UnescapeAll("%253B"));
            Assert.Equal("===%ZZ %%%===", EscapingUtilities.UnescapeAll("===%ZZ%20%%%==="));
            Assert.Equal("hello; escaping% how( are) you?", EscapingUtilities.UnescapeAll("hello%3B escaping%25 how%28 are%29 you%3f"));

            Assert.Equal("%*?*%*", EscapingUtilities.UnescapeAll("%25*?*%25*"));
            Assert.Equal("%*?*%*", EscapingUtilities.UnescapeAll("%25%2a%3f%2a%25%2a"));

            Assert.Equal("*Star*craft or *War*cr@ft??", EscapingUtilities.UnescapeAll("%2aStar%2Acraft%20or %2aWar%2Acr%40ft%3f%3F"));
        }
コード例 #22
0
ファイル: TargetEntry.cs プロジェクト: hongli051/IronyTest
        /// <summary>
        /// Retrieves the error targets for this target.
        /// </summary>
        /// <param name="projectLoggingContext">The project logging context.</param>
        /// <returns>A list of error targets.</returns>
        internal List <TargetSpecification> GetErrorTargets(ProjectLoggingContext projectLoggingContext)
        {
            VerifyState(_state, TargetEntryState.ErrorExecution);
            ErrorUtilities.VerifyThrow(_legacyCallTargetScopes == null, "We should have already left any legacy call target scopes.");

            List <TargetSpecification> allErrorTargets = new List <TargetSpecification>(_target.OnErrorChildren.Count);

            foreach (ProjectOnErrorInstance errorTargetInstance in _target.OnErrorChildren)
            {
                bool condition = ConditionEvaluator.EvaluateCondition
                                 (
                    errorTargetInstance.Condition,
                    ParserOptions.AllowPropertiesAndItemLists,
                    _expander,
                    ExpanderOptions.ExpandPropertiesAndItems,
                    _requestEntry.ProjectRootDirectory,
                    errorTargetInstance.ConditionLocation,
                    projectLoggingContext.LoggingService,
                    projectLoggingContext.BuildEventContext
                                 );

                if (condition)
                {
                    IList <string> errorTargets = _expander.ExpandIntoStringListLeaveEscaped(errorTargetInstance.ExecuteTargets, ExpanderOptions.ExpandPropertiesAndItems, errorTargetInstance.ExecuteTargetsLocation);

                    foreach (string escapedErrorTarget in errorTargets)
                    {
                        string errorTargetName = EscapingUtilities.UnescapeAll(escapedErrorTarget);
                        allErrorTargets.Add(new TargetSpecification(errorTargetName, errorTargetInstance.ExecuteTargetsLocation));
                    }
                }
            }

            // If this target never executed (for instance, because one of its dependencies errored) then we need to
            // create a result for this target to report when it gets to the Completed state.
            if (null == _targetResult)
            {
                _targetResult = new TargetResult(new TaskItem[] { }, new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null));
            }

            _state = TargetEntryState.Completed;

            return(allErrorTargets);
        }
コード例 #23
0
ファイル: BuiltInMetadata.cs プロジェクト: 3F/IeXod
        /// <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);
        }
コード例 #24
0
            private IEnumerable <KeyValuePair <string, string> > EnumerateMetadataEager()
            {
                if (_customEscapedMetadata == null || _customEscapedMetadata.Count == 0)
                {
#if TASKHOST
                    // MSBuildTaskHost.dll compiles against .NET 3.5 which doesn't have Array.Empty()
                    return(new KeyValuePair <string, string> [0]);
#else
                    return(Array.Empty <KeyValuePair <string, string> >());
#endif
                }

                var result = new KeyValuePair <string, string> [_customEscapedMetadata.Count];
                int index  = 0;
                foreach (var kvp in _customEscapedMetadata)
                {
                    var unescaped = new KeyValuePair <string, string>(kvp.Key, EscapingUtilities.UnescapeAll(kvp.Value));
                    result[index++] = unescaped;
                }

                return(result);
            }
コード例 #25
0
ファイル: EngineFileUtilities.cs プロジェクト: enricosada/sln
        internal static Func <string, bool> GetFileSpecMatchTester(string filespec, string currentDirectory)
        {
            Debug.Assert(!string.IsNullOrEmpty(filespec));

            var unescapedSpec = EscapingUtilities.UnescapeAll(filespec);

            var regex = FilespecHasWildcards(filespec) ? CreateRegex(unescapedSpec, currentDirectory) : null;

            return(fileToMatch =>
            {
                Debug.Assert(!string.IsNullOrEmpty(fileToMatch));

                // check if there is a regex matching the file
                if (regex != null)
                {
                    var normalizedFileToMatch = FileUtilities.GetFullPathNoThrow(Path.Combine(currentDirectory, fileToMatch));
                    return regex.IsMatch(normalizedFileToMatch);
                }

                return FileUtilities.ComparePathsNoThrow(unescapedSpec, fileToMatch, currentDirectory);
            });
        }
コード例 #26
0
        internal static Func <string, bool> GetMatchTester(string filespec, string currentDirectory)
        {
            var   unescapedSpec = EscapingUtilities.UnescapeAll(filespec);
            Regex regex         = null;

            // TODO: assumption on file system case sensitivity: https://github.com/Microsoft/msbuild/issues/781

            if (FilespecHasWildcards(filespec))
            {
                Regex regexFileMatch;
                bool  isRecursive;
                bool  isLegal;

                //  TODO: If creating Regex's here ends up being expensive perf-wise, consider how to avoid it in common cases
                FileMatcher.GetFileSpecInfo(
                    unescapedSpec,
                    out regexFileMatch,
                    out isRecursive,
                    out isLegal,
                    FileMatcher.s_defaultGetFileSystemEntries);

                // If the spec is not legal, it doesn't match anything
                regex = isLegal ? regexFileMatch : null;
            }

            return(file =>
            {
                var unescapedFile = EscapingUtilities.UnescapeAll(file);

                // check if there is a regex matching the file
                if (regex != null)
                {
                    return regex.IsMatch(unescapedFile);
                }

                return FileUtilities.ComparePathsNoThrow(unescapedSpec, unescapedFile, currentDirectory);
            });
        }
コード例 #27
0
ファイル: TaskItem.cs プロジェクト: 3F/IeXod
        /// <summary>
        /// Get the collection of metadata. This does not include built-in metadata.
        /// </summary>
        /// <remarks>
        /// RECOMMENDED GUIDELINES FOR METHOD IMPLEMENTATIONS:
        /// 1) this method should return a clone of the metadata
        /// 2) writing to this dictionary should not be reflected in the underlying item.
        /// </remarks>
        /// <owner>JomoF</owner>
        public IDictionary CloneCustomMetadata()
        {
            IDictionary backingItemMetadata = item.CloneCustomMetadata();

            // Go through and escape the metadata as necessary.
            string[] keys = new string[backingItemMetadata.Count];
            backingItemMetadata.Keys.CopyTo(keys, 0);
            foreach (string singleMetadataName in keys)
            {
                string singleMetadataValue = (string)backingItemMetadata[singleMetadataName];

                bool   unescapingWasNecessary;
                string singleMetadataValueUnescaped = EscapingUtilities.UnescapeAll(singleMetadataValue, out unescapingWasNecessary);

                // It's very important for perf not to touch this IDictionary unless we really need to.  Touching
                // it in any way causes it to get cloned (in the implementation of CopyOnWriteHashtable).
                if (unescapingWasNecessary)
                {
                    backingItemMetadata[singleMetadataName] = singleMetadataValueUnescaped;
                }
            }

            return(backingItemMetadata);
        }
コード例 #28
0
ファイル: TargetEntry.cs プロジェクト: hongli051/IronyTest
        /// <summary>
        /// Retrieves the list of dependencies this target needs to have built and moves the target to the next state.
        /// Never returns null.
        /// </summary>
        /// <returns>A collection of targets on which this target depends.</returns>
        internal List <TargetSpecification> GetDependencies(ProjectLoggingContext projectLoggingContext)
        {
            VerifyState(_state, TargetEntryState.Dependencies);

            // Resolve the target now, since from this point on we are going to be doing work with the actual instance.
            GetTargetInstance();

            // We first make sure no batching was attempted with the target's condition.
            // UNDONE: (Improvement) We want to allow this actually.  In order to do this we need to determine what the
            // batching buckets are, and if there are any which aren't empty, return our list of dependencies.
            // Only in the case where all bucket conditions fail do we want to skip the target entirely (and
            // this skip building the dependencies.)
            if (ExpressionShredder.ContainsMetadataExpressionOutsideTransform(_target.Condition))
            {
                ProjectErrorUtilities.ThrowInvalidProject(_target.ConditionLocation, "TargetConditionHasInvalidMetadataReference", _target.Name, _target.Condition);
            }

            // If condition is false (based on propertyBag), set this target's state to
            // "Skipped" since we won't actually build it.
            bool condition = ConditionEvaluator.EvaluateCondition
                             (
                _target.Condition,
                ParserOptions.AllowPropertiesAndItemLists,
                _expander,
                ExpanderOptions.ExpandPropertiesAndItems,
                _requestEntry.ProjectRootDirectory,
                _target.ConditionLocation,
                projectLoggingContext.LoggingService,
                projectLoggingContext.BuildEventContext
                             );

            if (!condition)
            {
                _targetResult = new TargetResult(new TaskItem[0] {
                }, new WorkUnitResult(WorkUnitResultCode.Skipped, WorkUnitActionCode.Continue, null));
                _state        = TargetEntryState.Completed;

                if (!projectLoggingContext.LoggingService.OnlyLogCriticalEvents)
                {
                    // Expand the expression for the Log.
                    string expanded = _expander.ExpandIntoStringAndUnescape(_target.Condition, ExpanderOptions.ExpandPropertiesAndItems, _target.ConditionLocation);

                    // By design: Not building dependencies. This is what NAnt does too.
                    // NOTE: In the original code, this was logged from the target logging context.  However, the target
                    // hadn't been "started" by then, so you'd get a target message outside the context of a started
                    // target.  In the Task builder (and original Task Engine), a Task Skipped message would be logged in
                    // the context of the target, not the task.  This should be the same, especially given that we
                    // wish to allow batching on the condition of a target.
                    projectLoggingContext.LogComment(MessageImportance.Low, "TargetSkippedFalseCondition", _target.Name, _target.Condition, expanded);
                }

                return(new List <TargetSpecification>());
            }

            IList <string>             dependencies      = _expander.ExpandIntoStringListLeaveEscaped(_target.DependsOnTargets, ExpanderOptions.ExpandPropertiesAndItems, _target.DependsOnTargetsLocation);
            List <TargetSpecification> dependencyTargets = new List <TargetSpecification>(dependencies.Count);

            foreach (string escapedDependency in dependencies)
            {
                string dependencyTargetName = EscapingUtilities.UnescapeAll(escapedDependency);
                dependencyTargets.Add(new TargetSpecification(dependencyTargetName, _target.DependsOnTargetsLocation));
            }

            _state = TargetEntryState.Execution;

            return(dependencyTargets);
        }
コード例 #29
0
            protected override ImmutableList <I> SelectItems(OrderedItemDataCollection.Builder listBuilder, ImmutableHashSet <string> globsToIgnore)
            {
                var itemsToAdd = ImmutableList.CreateBuilder <I>();

                Lazy <Func <string, bool> > excludeTester = null;

                ImmutableList <string> .Builder excludePatterns = ImmutableList.CreateBuilder <string>();
                if (_excludes != null)
                {
                    // STEP 4: Evaluate, split, expand and subtract any Exclude
                    foreach (string exclude in _excludes)
                    {
                        string excludeExpanded = _expander.ExpandIntoStringLeaveEscaped(exclude, ExpanderOptions.ExpandPropertiesAndItems, _itemElement.ExcludeLocation);
                        var    excludeSplits   = ExpressionShredder.SplitSemiColonSeparatedList(excludeExpanded);
                        excludePatterns.AddRange(excludeSplits);
                    }

                    if (excludePatterns.Count > 0)
                    {
                        excludeTester = new Lazy <Func <string, bool> >(() => EngineFileUtilities.GetFileSpecMatchTester(excludePatterns, _rootDirectory));
                    }
                }

                ISet <string> excludePatternsForGlobs = null;

                foreach (var fragment in _itemSpec.Fragments)
                {
                    if (fragment is ItemSpec <P, I> .ItemExpressionFragment itemReferenceFragment)
                    {
                        // STEP 3: If expression is "@(x)" copy specified list with its metadata, otherwise just treat as string
                        var itemsFromExpression = _expander.ExpandExpressionCaptureIntoItems(
                            itemReferenceFragment.Capture,
                            _evaluatorData,
                            _itemFactory,
                            ExpanderOptions.ExpandItems,
                            includeNullEntries: false,
                            isTransformExpression: out _,
                            elementLocation: _itemElement.IncludeLocation);

                        itemsToAdd.AddRange(
                            excludeTester != null
                                ? itemsFromExpression.Where(item => !excludeTester.Value(item.EvaluatedInclude))
                                : itemsFromExpression);
                    }
                    else if (fragment is ValueFragment valueFragment)
                    {
                        string value = valueFragment.TextFragment;

                        if (excludeTester?.Value(EscapingUtilities.UnescapeAll(value)) != true)
                        {
                            var item = _itemFactory.CreateItem(value, value, _itemElement.ContainingProject.FullPath);
                            itemsToAdd.Add(item);
                        }
                    }
                    else if (fragment is GlobFragment globFragment)
                    {
                        // If this item is behind a false condition and represents a full drive/filesystem scan, expanding it is
                        // almost certainly undesired. It should be skipped to avoid evaluation taking an excessive amount of time.
                        bool skipGlob = !_conditionResult && globFragment.IsFullFileSystemScan && !Traits.Instance.EscapeHatches.AlwaysEvaluateDangerousGlobs;
                        if (!skipGlob)
                        {
                            string glob = globFragment.TextFragment;

                            if (excludePatternsForGlobs == null)
                            {
                                excludePatternsForGlobs = BuildExcludePatternsForGlobs(globsToIgnore, excludePatterns);
                            }

                            string[] includeSplitFilesEscaped;
                            if (MSBuildEventSource.Log.IsEnabled())
                            {
                                MSBuildEventSource.Log.ExpandGlobStart(_rootDirectory, glob, string.Join(", ", excludePatternsForGlobs));
                            }
                            using (_lazyEvaluator._evaluationProfiler.TrackGlob(_rootDirectory, glob, excludePatternsForGlobs))
                            {
                                includeSplitFilesEscaped = EngineFileUtilities.GetFileListEscaped(
                                    _rootDirectory,
                                    glob,
                                    excludePatternsForGlobs
                                    );
                            }
                            if (MSBuildEventSource.Log.IsEnabled())
                            {
                                MSBuildEventSource.Log.ExpandGlobStop(_rootDirectory, glob, string.Join(", ", excludePatternsForGlobs));
                            }

                            foreach (string includeSplitFileEscaped in includeSplitFilesEscaped)
                            {
                                itemsToAdd.Add(_itemFactory.CreateItem(includeSplitFileEscaped, glob, _itemElement.ContainingProject.FullPath));
                            }
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(fragment.GetType().ToString());
                    }
                }

                return(itemsToAdd.ToImmutable());
            }
コード例 #30
0
        /// <summary>
        /// Parse a ProjectTargetElement
        /// </summary>
        private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation element)
        {
            ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnTarget);
            ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.name);

            string targetName = ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.name);

            // Orcas compat: all target names are automatically unescaped
            targetName = EscapingUtilities.UnescapeAll(targetName);

            int indexOfSpecialCharacter = targetName.IndexOfAny(XMakeElements.illegalTargetNameCharacters);

            if (indexOfSpecialCharacter >= 0)
            {
                ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.name), "NameInvalid", targetName, targetName[indexOfSpecialCharacter]);
            }

            ProjectTargetElement  target  = new ProjectTargetElement(element, _project, _project);
            ProjectOnErrorElement onError = null;

            foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element))
            {
                ProjectElement child = null;

                switch (childElement.Name)
                {
                case XMakeElements.propertyGroup:
                    if (onError != null)
                    {
                        ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name);
                    }

                    child = ParseProjectPropertyGroupElement(childElement, target);
                    break;

                case XMakeElements.itemGroup:
                    if (onError != null)
                    {
                        ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name);
                    }

                    child = ParseProjectItemGroupElement(childElement, target);
                    break;

                case XMakeElements.onError:
                    onError = ParseProjectOnErrorElement(childElement, target);
                    child   = onError;
                    break;

                case XMakeElements.itemDefinitionGroup:
                    ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ItemDefinitionGroupNotLegalInsideTarget", childElement.Name);
                    break;

                default:
                    if (onError != null)
                    {
                        ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name);
                    }

                    child = ParseProjectTaskElement(childElement, target);
                    break;
                }

                target.AppendParentedChildNoChecks(child);
            }

            return(target);
        }