public static SemanticReleaseNotes Parse(string releaseNotes) { var releases = new List<SemanticRelease>(); var lines = releaseNotes.Replace("\r", string.Empty).Split('\n'); var currentRelease = new SemanticRelease(); foreach (var line in lines) { if (line.TrimStart().StartsWith("# ")) { var match = ReleaseRegex.Match(line); if (line != lines.First()) { releases.Add(currentRelease); } currentRelease = new SemanticRelease { ReleaseName = match.Groups["Title"].Value }; if (currentRelease.ReleaseName == "vNext") { currentRelease.ReleaseName = null; } if (match.Groups["Date"].Success) { DateTime parsed; var toParse = match.Groups["Date"].Value; if (DateTime.TryParse(toParse, out parsed)) { currentRelease.When = parsed; } if (DateTime.TryParseExact(toParse, "dd MMMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed)) { currentRelease.When = parsed; } else if (DateTime.TryParseExact(toParse, "MMMM dd, yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed)) { currentRelease.When = parsed; } else { // We failed to parse the date, just append to the end currentRelease.ReleaseName += " (" + toParse + ")"; } } } else if (line.StartsWith("Commits: ")) { var commitText = line.Replace("Commits: ", string.Empty); var linkMatch = LinkRegex.Match(commitText); if (linkMatch.Success) { commitText = linkMatch.Groups["Text"].Value; currentRelease.DiffInfo.DiffUrlFormat = linkMatch.Groups["Link"].Value; } var commits = commitText.Split(new[] { "..." }, StringSplitOptions.None); currentRelease.DiffInfo.BeginningSha = commits[0]; currentRelease.DiffInfo.EndSha = commits[1]; } else if (line.StartsWith(" - ")) { // Improve this parsing to extract issue numbers etc var title = line.StartsWith(" - ") ? line.Substring(3) : line; var releaseNoteItem = new ReleaseNoteItem(title, null, null, null, currentRelease.When, new Contributor[0]); currentRelease.ReleaseNoteLines.Add(releaseNoteItem); } else if (string.IsNullOrWhiteSpace(line)) { currentRelease.ReleaseNoteLines.Add(new BlankLine()); } else { // This picks up comments and such var title = line.StartsWith(" - ") ? line.Substring(3) : line; var releaseNoteItem = new ReleaseNoteLine(title); currentRelease.ReleaseNoteLines.Add(releaseNoteItem); } } releases.Add(currentRelease); // Remove additional blank lines foreach (var semanticRelease in releases) { for (int i = 0; i < semanticRelease.ReleaseNoteLines.Count; i++) { if (semanticRelease.ReleaseNoteLines[i] is BlankLine) { semanticRelease.ReleaseNoteLines.RemoveAt(i--); } else { break; } } for (int i = semanticRelease.ReleaseNoteLines.Count - 1; i >= 0; i--) { if (semanticRelease.ReleaseNoteLines[i] is BlankLine) { semanticRelease.ReleaseNoteLines.RemoveAt(i); } else { break; } } } return new SemanticReleaseNotes(releases, new Categories()); }
public static SemanticReleaseNotes Parse(string releaseNotes) { var releases = new List <SemanticRelease>(); var lines = releaseNotes.Replace("\r", string.Empty).Split('\n'); var currentRelease = new SemanticRelease(); foreach (var line in lines) { if (line.TrimStart().StartsWith("# ")) { var match = ReleaseRegex.Match(line); if (line != lines.First()) { releases.Add(currentRelease); } currentRelease = new SemanticRelease { ReleaseName = match.Groups["Title"].Value }; if (currentRelease.ReleaseName == "vNext") { currentRelease.ReleaseName = null; } if (match.Groups["Date"].Success) { DateTime parsed; var toParse = match.Groups["Date"].Value; if (DateTime.TryParse(toParse, out parsed)) { currentRelease.When = parsed; } if (DateTime.TryParseExact(toParse, "dd MMMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed)) { currentRelease.When = parsed; } else if (DateTime.TryParseExact(toParse, "MMMM dd, yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed)) { currentRelease.When = parsed; } else { // We failed to parse the date, just append to the end currentRelease.ReleaseName += " (" + toParse + ")"; } } } else if (line.StartsWith("Commits: ")) { var commitText = line.Replace("Commits: ", string.Empty); var linkMatch = LinkRegex.Match(commitText); if (linkMatch.Success) { commitText = linkMatch.Groups["Text"].Value; currentRelease.DiffInfo.DiffUrlFormat = linkMatch.Groups["Link"].Value; } var commits = commitText.Split(new[] { "..." }, StringSplitOptions.None); currentRelease.DiffInfo.BeginningSha = commits[0]; currentRelease.DiffInfo.EndSha = commits[1]; } else if (line.StartsWith(" - ")) { // Improve this parsing to extract issue numbers etc var title = line.StartsWith(" - ") ? line.Substring(3) : line; var releaseNoteItem = new ReleaseNoteItem(title, null, null, null, currentRelease.When, new Contributor[0]); currentRelease.ReleaseNoteLines.Add(releaseNoteItem); } else if (string.IsNullOrWhiteSpace(line)) { currentRelease.ReleaseNoteLines.Add(new BlankLine()); } else { // This picks up comments and such var title = line.StartsWith(" - ") ? line.Substring(3) : line; var releaseNoteItem = new ReleaseNoteLine(title); currentRelease.ReleaseNoteLines.Add(releaseNoteItem); } } releases.Add(currentRelease); // Remove additional blank lines foreach (var semanticRelease in releases) { for (int i = 0; i < semanticRelease.ReleaseNoteLines.Count; i++) { if (semanticRelease.ReleaseNoteLines[i] is BlankLine) { semanticRelease.ReleaseNoteLines.RemoveAt(i--); } else { break; } } for (int i = semanticRelease.ReleaseNoteLines.Count - 1; i >= 0; i--) { if (semanticRelease.ReleaseNoteLines[i] is BlankLine) { semanticRelease.ReleaseNoteLines.RemoveAt(i); } else { break; } } } return(new SemanticReleaseNotes(releases, new Categories())); }