package hudson.plugins.bazaar; import hudson.model.AbstractBuild; import hudson.scm.ChangeLogParser; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; /** * Parses the output of bzr log. * * @author Trond Norbye */ public class BazaarChangeLogParser extends ChangeLogParser { public BazaarChangeSetList parse(AbstractBuild build, File changelogFile) throws IOException { List<BazaarChangeSet> entries = new ArrayList<BazaarChangeSet>(); BufferedReader in = new BufferedReader(new FileReader(changelogFile)); StringBuilder message = new StringBuilder(); String s; BazaarChangeSet entry = null; int state = 0; int ident = 0; while ((s = in.readLine()) != null) { int nident = 0; int len = s.length(); while (nident < len && s.charAt(nident) == ' ') { ++nident; } s = s.trim(); if ("------------------------------------------------------------".equals(s)) { if (entry != null && state > 2) { if (message.length() != 0) { entry.setMsg(message.toString()); } entries.add(entry); } entry = new BazaarChangeSet(); state = 0; message.setLength(0); ident = nident; continue; } switch (state) { case 0: if (ident == nident && s.startsWith("revno:")) { String rev = s.substring("revno:".length()).trim(); entry.setRevno(rev); ++state; } break; case 1: if (ident == nident && s.startsWith("revision-id:")) { String rev = s.substring("revision-id:".length()).trim(); entry.setRevid(rev); ++state; } break; case 2: if (ident == nident && s.startsWith("committer:")) { int endIndex = s.indexOf('<'); if (endIndex < 0) { endIndex = len; } String author = s.substring("committer:".length(), endIndex).trim(); entry.setAuthor(author); ++state; } break; case 3: if (ident == nident && s.startsWith("timestamp:")) { entry.setDate(s.substring("timestamp:".length()).trim()); ++state; } break; case 4: if (!(ident == nident && s.startsWith("message:"))) { if (ident == nident && (s.startsWith("modified:") || s.startsWith("added:") || s.startsWith("removed:") || s.startsWith("renamed:"))) { if (s.startsWith("modified")) { state = 5; } else if (s.startsWith("added:")) { state = 6; } else if (s.startsWith("removed:")) { state = 7; } else if (s.startsWith("renamed:")){ state = 8; } entry.setMsg(message.toString()); message.setLength(0); } else { message.append(s); message.append("\n"); } } break; case 5: // modified if (s.startsWith("modified")) { state = 5; } else if (s.startsWith("added:")) { state = 6; } else if (s.startsWith("removed:")) { state = 7; } else if (s.startsWith("renamed:")){ state = 8; } else { entry.getModifiedPaths().add(s); } break; case 6: // added if (s.startsWith("modified")) { state = 5; } else if (s.startsWith("added:")) { state = 6; } else if (s.startsWith("removed:")) { state = 7; } else if (s.startsWith("renamed:")){ state = 8; } else { entry.getAddedPaths().add(s); } break; case 7: // removed if (s.startsWith("modified")) { state = 5; } else if (s.startsWith("added:")) { state = 6; } else if (s.startsWith("removed:")) { state = 7; } else if (s.startsWith("renamed:")){ state = 8; } else { entry.getDeletedPaths().add(s); } break; case 8: // renamed if (s.startsWith("modified")) { state = 5; } else if (s.startsWith("added:")) { state = 6; } else if (s.startsWith("removed:")) { state = 7; } else if (s.startsWith("renamed:")){ state = 8; } else { entry.getModifiedPaths().add(s); } break; default: { Logger logger = Logger.getLogger(BazaarChangeLogParser.class.getName()); logger.warning("Unknown parser state: " + state); } } } if (entry != null && state > 2) { if (message.length() != 0) { entry.setMsg(message.toString()); } entries.add(entry); } // Remove current revision entry entries = entries.subList(0, Math.max(0 ,entries.size() -1)); return new BazaarChangeSetList(build, entries); } }