示例#1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BisectResult"/> class.
        /// </summary>
        /// <param name="revision">
        /// The revision the <see cref="BisectCommand"/> is currently at in the repository.
        /// </param>
        /// <param name="done">
        /// If <c>true</c>, then <paramref name="revision"/> specifies the first good changeset in the
        /// repository; otherwise <paramref name="revision"/> specifies the current changeset that should
        /// be tested and marked good or bad by executing another <see cref="BisectCommand"/>.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="revision"/> is <c>null</c>.</para>
        /// </exception>
        public BisectResult(RevSpec revision, bool done)
        {
            if (revision == null)
            {
                throw new ArgumentNullException("revision");
            }

            _Revision = revision;
            _Done     = done;
        }
示例#2
0
        /// <summary>
        /// Attempts to parse the results indicating that further testing is required and that the
        /// repository has now been updated to a new revision for testing and subsequent marking of
        /// good or bad.
        /// </summary>
        /// <param name="standardOutput">
        /// The standard output from executing the command.
        /// </param>
        /// <returns>
        /// <c>true</c> if this method was able to parse the results correctly;
        /// otherwise <c>false</c> to continue testing other ways to parse it.
        /// </returns>
        private bool ParseTestingResult(string standardOutput)
        {
            var   re = new Regex(@"^Testing changeset (?<revno>\d+):", RegexOptions.IgnoreCase);
            Match ma = re.Match(standardOutput);

            if (ma.Success)
            {
                int currentlyAtRevision = int.Parse(ma.Groups["revno"].Value, CultureInfo.InvariantCulture);
                Result = new BisectResult(RevSpec.Single(currentlyAtRevision), false);
            }

            return(ma.Success);
        }
示例#3
0
        /// <summary>
        /// Attempts to parse the results that indicate that the first good changeset was found.
        /// </summary>
        /// <param name="standardOutput">
        /// The standard output from executing the command.
        /// </param>
        /// <returns>
        /// <c>true</c> if this method was able to parse the results correctly;
        /// otherwise <c>false</c> to continue testing other ways to parse it.
        /// </returns>
        private bool ParseFoundResult(string standardOutput)
        {
            var   re = new Regex(@"^The first good revision is:\s+changeset:\s+(?<revno>\d+):", RegexOptions.IgnoreCase);
            Match ma = re.Match(standardOutput);

            if (ma.Success)
            {
                int foundAtRevision = int.Parse(ma.Groups["revno"].Value, CultureInfo.InvariantCulture);
                Result = new BisectResult(RevSpec.Single(foundAtRevision), true);
            }

            return(ma.Success);
        }
示例#4
0
        /// <summary>
        /// This method should parse and store the appropriate execution result output
        /// according to the type of data the command line client would return for
        /// the command.
        /// </summary>
        /// <param name="exitCode">
        /// The exit code from executing the command line client.
        /// </param>
        /// <param name="standardOutput">
        /// The standard output from executing the command line client.
        /// </param>
        /// <remarks>
        /// Note that as long as you descend from <see cref="MercurialCommandBase{T}"/> you're not required to call
        /// the base method at all.
        /// </remarks>
        protected override void ParseStandardOutputForResults(int exitCode, string standardOutput)
        {
            if (exitCode != 0)
            {
                return;
            }

            Match ma = Regex.Match(standardOutput, @"^(?<hash>[a-f0-9]{12,40}).*$", RegexOptions.IgnoreCase);

            if (ma.Success)
            {
                Result = RevSpec.Single(ma.Groups["hash"].Value);
            }
        }
示例#5
0
        /// <summary>
        /// This method should parse and store the appropriate execution result output
        /// according to the type of data the command line client would return for
        /// the command.
        /// </summary>
        /// <param name="exitCode">
        /// The exit code from executing the command line client.
        /// </param>
        /// <param name="standardOutput">
        /// The standard output from executing the command line client.
        /// </param>
        /// <remarks>
        /// Note that as long as you descend from <see cref="MercurialCommandBase{T}"/> you're not required to call
        /// the base method at all.
        /// </remarks>
        protected override void ParseStandardOutputForResults(int exitCode, string standardOutput)
        {
            base.ParseStandardOutputForResults(exitCode, standardOutput);
            var re = new Regex(@"^committed\s+changeset\s+\d+:(?<hash>[0-9a-f]{40})$", RegexOptions.IgnoreCase);

            foreach (Match ma in standardOutput.Split(
                         new[]
            {
                '\n', '\r'
            }, StringSplitOptions.RemoveEmptyEntries).Select(line => re.Match(line)).Where(ma => ma.Success))
            {
                Result = RevSpec.Single(ma.Groups["hash"].Value);
                return;
            }

            Result = null;
        }
示例#6
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="ArchiveCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="Revision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="ArchiveCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public ArchiveCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }
示例#7
0
 /// <summary>
 /// Adds the value to the <see cref="BranchRevisions"/> collection property and
 /// returns this <see cref="HeadsCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to add to the <see cref="BranchRevisions"/> collection property.
 /// </param>
 /// <returns>
 /// This <see cref="HeadsCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public HeadsCommand WithBranchRevision(RevSpec value)
 {
     BranchRevisions.Add(value);
     return(this);
 }
示例#8
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="HeadsCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="Revision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="HeadsCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public HeadsCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }
示例#9
0
 /// <summary>
 /// Sets the <see cref="ParentRevision"/> property to the specified value and
 /// returns this <see cref="BackoutCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="ParentRevision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="BackoutCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public BackoutCommand WithParentRevision(RevSpec value)
 {
     ParentRevision = value;
     return(this);
 }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BisectResult"/> class.
 /// </summary>
 public BisectResult()
 {
     _Revision = null;
     _Done     = true;
 }
示例#11
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="UpdateCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="Revision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="UpdateCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public UpdateCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }
示例#12
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="ManifestCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="Revision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="ManifestCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public ManifestCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }
示例#13
0
 /// <summary>
 /// Adds the specified value to the <see cref="Revisions"/> property and
 /// returns this <see cref="DiffCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to add to the <see cref="Revisions"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="DiffCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public DiffCommand WithRevisions(RevSpec value)
 {
     Revisions.Add(value);
     return(this);
 }
示例#14
0
 /// <summary>
 /// Sets the <see cref="ChangeIntroducedByRevision"/> property to the specified value and
 /// returns this <see cref="DiffCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="ChangeIntroducedByRevision"/> property,
 /// defaults to <c>true</c>.
 /// </param>
 /// <returns>
 /// This <see cref="DiffCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public DiffCommand WithChangeIntroducedByRevision(RevSpec value)
 {
     ChangeIntroducedByRevision = value;
     return(this);
 }
示例#15
0
 /// <summary>
 /// Sets the <see cref="UpdateToRevision"/> property to the specified value and
 /// returns this <see cref="CloneCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="UpdateToRevision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="CloneCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public CloneCommand WithUpdateToRevision(RevSpec value)
 {
     UpdateToRevision = value;
     return(this);
 }
示例#16
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="RevertCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The new value for the <see cref="Revision"/> property.
 /// </param>
 /// <returns>
 /// This <see cref="RevertCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public RevertCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }
示例#17
0
 /// <summary>
 /// Sets the <see cref="Revision"/> property to the specified value and
 /// returns this <see cref="IdentifyCommand"/> instance.
 /// </summary>
 /// <param name="revision">Specified revision to identify.</param>
 /// <returns>
 /// This <see cref="IdentifyCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public IdentifyCommand WithRevision(RevSpec revision)
 {
     Revision = revision;
     return(this);
 }
示例#18
0
 /// <summary>
 /// Adds the value to the <see cref="Revisions"/> collection property and
 /// returns this <see cref="PushCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to add to the <see cref="Revisions"/> collection property.
 /// </param>
 /// <returns>
 /// This <see cref="PushCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public PushCommand WithRevision(RevSpec value)
 {
     Revisions.Add(value);
     return(this);
 }
示例#19
0
        /// <summary>
        /// Parse the given XML lazily and return a collection of <see cref="Changeset"/>
        /// objects for the information contained in it, in the order the changesets
        /// appear in the xml.
        /// </summary>
        /// <param name="xml">
        /// The XML to parse.
        /// </param>
        /// <returns>
        /// A collection of <see cref="Changeset"/> objects.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// <para>An unknown path action character was detected in the log output.</para>
        /// <para>- or -</para>
        /// <para>The XML content was not legal according to the expected format.</para>
        /// </exception>
        public static IEnumerable <Changeset> LazyParse(string xml)
        {
            if (StringEx.IsNullOrWhiteSpace(xml))
            {
                yield break;
            }

            var serializer = new XmlSerializer(typeof(LogEntryNode));

            foreach (string entryXml in LazyExtractChangesetXmlPieces(xml))
            {
                var entry     = (LogEntryNode)serializer.Deserialize(new StringReader(entryXml));
                var changeset = new Changeset
                {
                    Timestamp          = entry.Timestamp,
                    AuthorName         = (entry.Author ?? new LogEntryAuthorNode()).Name,
                    AuthorEmailAddress = (entry.Author ?? new LogEntryAuthorNode()).Email,
                    CommitMessage      = entry.CommitMessage ?? string.Empty,
                    Branch             = entry.Branch ?? "default",
                    Hash           = entry.Hash,
                    RevisionNumber = entry.Revision,
                    Revision       = RevSpec.Single(entry.Hash),
                    Tags           = entry.Tags.Select(t => t.Name).ToArray(),
                };

                switch (entry.Parents.Count)
                {
                case 2:
                    changeset.RightParentHash     = entry.Parents[1].Hash;
                    changeset.RightParentRevision = entry.Parents[1].Revision;
                    goto case 1;

                case 1:
                    changeset.LeftParentHash     = entry.Parents[0].Hash;
                    changeset.LeftParentRevision = entry.Parents[0].Revision;
                    break;

                case 0:
                    changeset.LeftParentRevision = changeset.RevisionNumber - 1;
                    break;
                }

                foreach (LogEntryPathNode action in entry.PathActions)
                {
                    var pathAction = new ChangesetPathAction
                    {
                        Path = action.Path,
                    };
                    switch (action.Action)
                    {
                    case "M":
                        pathAction.Action = ChangesetPathActionType.Modify;
                        break;

                    case "A":
                        pathAction.Action = ChangesetPathActionType.Add;
                        LogEntryCopyNode copySource = entry.Copies.Where(c => c.Destination == action.Path).FirstOrDefault();
                        if (copySource != null)
                        {
                            pathAction.Source = copySource.Source;
                        }
                        break;

                    case "R":
                        pathAction.Action = ChangesetPathActionType.Remove;
                        break;

                    default:
                        throw new InvalidOperationException("Unknown path action: " + action.Action);
                    }
                    changeset.PathActions.Add(pathAction);
                }

                yield return(changeset);
            }
        }
示例#20
0
 /// <summary>
 /// Adds the value to the <see cref="Revisions"/> collection property and
 /// returns this <see cref="OutgoingCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to add to the <see cref="Revisions"/> collection property.
 /// </param>
 /// <returns>
 /// This <see cref="OutgoingCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public OutgoingCommand WithRevision(RevSpec value)
 {
     Revisions.Add(value);
     return(this);
 }
示例#21
0
 /// <summary>
 /// Adds the value to the <see cref="BaseRevisions"/> collection property and
 /// returns this <see cref="BundleCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to add to the <see cref="BaseRevisions"/> collection property.
 /// </param>
 /// <returns>
 /// This <see cref="BundleCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public BundleCommand WithBaseRevision(RevSpec value)
 {
     BaseRevisions.Add(value);
     return(this);
 }
示例#22
0
 /// <summary>
 /// Sets the value of the <see cref="Revision"/> property to the
 /// specified value and returns this <see cref="BookmarkCommand"/> instance.
 /// </summary>
 /// <param name="value">
 /// The value to set the <see cref="Revision"/> property to.
 /// </param>
 /// <returns>
 /// This <see cref="BookmarkCommand"/> instance.
 /// </returns>
 /// <remarks>
 /// This method is part of the fluent interface.
 /// </remarks>
 public BookmarkCommand WithRevision(RevSpec value)
 {
     Revision = value;
     return(this);
 }