public static UserStory ReadUserStoryFromPath(string filePath) { UserStory userStory = new UserStory(); if (!File.Exists(filePath)) { throw new FileNotFoundException($"The User Story file {Path.GetFileName(filePath)} was not found."); } string userStoryText = File.ReadAllText(filePath); //Not valid if first line isn't yaml if (!userStoryText.StartsWith(YamlStartToken)) { throw new Exception($"Invalid User Story. Must start with YAML delimiter {YamlStartToken}"); } //string yaml = userStoryText.GetUserStoryTextYaml(); //string body = userStoryText.GetUserStoryTextBody(); UserStoryYamlProperties yamlProperties = userStoryText.ToYamlProperties(); UserStoryBodyProperties bodyProperties = userStoryText.ToBodyProperties(); userStory.Id = yamlProperties.Id; userStory.CreatedOn = yamlProperties.CreatedOn; userStory.StartedOn = yamlProperties.StartedOn; userStory.CompletedOn = yamlProperties.CompletedOn; userStory.Status = yamlProperties.Status; userStory.Sequence = yamlProperties.Sequence; userStory.Estimate = yamlProperties.Estimate; userStory.Role = bodyProperties.Role; userStory.Want = bodyProperties.Want; userStory.Why = bodyProperties.Why; userStory.Discussion = bodyProperties.Discussion; userStory.AcceptanceCriteria = bodyProperties.AcceptanceCriteria; return(userStory); }
private static UserStoryBodyProperties ToBodyProperties(this string userStoryText) { UserStoryBodyProperties bodyProperties = new UserStoryBodyProperties(); string valueStartToken = "# As a "; string discussionStartToken = "## Discussion"; string acceptanceStartToken = "## Acceptance Criteria"; //string[] lines = userStoryText.Split(new [] { "\r\n" }, StringSplitOptions.None); //string[] lines = Regex.Split(userStoryText, "\r\n").Select(a => a.TrimEnd()).ToArray(); string[] lines = userStoryText.Split("\r\n"); bool foundValue = false; bool foundDiscussion = false; bool foundAcceptance = false; string valueString = ""; List <string> discussionString = new List <string>(); List <string> acceptanceString = new List <string>(); foreach (string line in lines) { if (line.StartsWith(valueStartToken)) { foundValue = true; } if (line.StartsWith(discussionStartToken)) { foundValue = false; foundDiscussion = true; continue; } if (line.StartsWith(acceptanceStartToken)) { foundValue = false; foundDiscussion = false; foundAcceptance = true; continue; } if (foundValue) { valueString += (line.Trim()); foundValue = false; } if (foundDiscussion) { discussionString.Add(line.Trim()); } if (foundAcceptance) { acceptanceString.Add(line.Trim()); } } //Parse the value line var tokenValues = valueString.GetStringsBetween("`", "`").ToArray(); bodyProperties.Role = tokenValues[0]; bodyProperties.Want = tokenValues[1]; if (tokenValues.Length > 2) { bodyProperties.Why = tokenValues[2]; } //Discussion and Acceptance //IMPORTANT: The template adds a newline to each of these properties when written to //file, so remove the last newline when converting back to the property. bodyProperties.Discussion = String.Join(Environment.NewLine, discussionString.Take(discussionString.Count() - 1)); bodyProperties.AcceptanceCriteria = String.Join(Environment.NewLine, acceptanceString.Take(acceptanceString.Count() - 1)); return(bodyProperties); }