String getChanges(AbstractBuild r) { if (!r.hasChangeSetComputed()) { logger.info("No change set computed..."); return null; } ChangeLogSet changeSet = r.getChangeSet(); List<Entry> entries = new LinkedList<Entry>(); Set<AffectedFile> files = new HashSet<AffectedFile>(); for (Object o : changeSet.getItems()) { Entry entry = (Entry) o; logger.info("Entry " + o); entries.add(entry); files.addAll(entry.getAffectedFiles()); } if (entries.isEmpty()) { logger.info("Empty change..."); return null; } Set<String> authors = new HashSet<String>(); for (Entry entry : entries) { authors.add(entry.getAuthor().getDisplayName()); } MessageBuilder message = new MessageBuilder(notifier, r); message.append("Started by changes from "); message.append(StringUtils.join(authors, ", ")); message.append(" ("); message.append(files.size()); message.append(" file(s) changed)"); return message.toString(); }
/** * Returns a set of paths in the workspace that was affected by this change. * * <p>Noted: since this is a new interface, some of the SCMs may not have implemented this * interface. The default implementation for this interface is throw * UnsupportedOperationException * * <p>It doesn't throw NoSuchMethodException because I rather to throw a runtime exception * * @return AffectedFile never null. * @since 1.309 */ public Collection<? extends AffectedFile> getAffectedFiles() { String scm = "this SCM"; ChangeLogSet parent = getParent(); if (null != parent) { String kind = parent.getKind(); if (null != kind && kind.trim().length() > 0) scm = kind; } throw new UnsupportedOperationException("getAffectedFiles() is not implemented by " + scm); }
public ChangeLogSet createChangeLog(String message) { ChangeLogSet changes = mock(ChangeLogSet.class); List<ChangeLogSet.Entry> entries = new LinkedList<ChangeLogSet.Entry>(); ChangeLogSet.Entry entry = new ChangeLogEntry(message, "Ash Lux"); entries.add(entry); when(changes.iterator()).thenReturn(entries.iterator()); return changes; }
private ChangeLogSet<? extends Entry> calcChangeSet() { File changelogFile = new File(getRootDir(), "changelog.xml"); if (!changelogFile.exists()) return ChangeLogSet.createEmpty(this); try { return scm.parse(this, changelogFile); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } return ChangeLogSet.createEmpty(this); }
// Append the changelog if we should and can private String createBuildNotes(String buildNotes, final ChangeLogSet<?> changeSet) { if (appendChangelog) { StringBuilder stringBuilder = new StringBuilder(); // Show the build notes first stringBuilder.append(buildNotes); // Then append the changelog stringBuilder .append("\n\n") .append( changeSet.isEmptySet() ? Messages.TestflightRecorder_EmptyChangeSet() : Messages.TestflightRecorder_Changelog()) .append("\n"); int entryNumber = 1; for (Entry entry : changeSet) { stringBuilder.append("\n").append(entryNumber).append(". "); stringBuilder.append(entry.getMsg()).append(" \u2014 ").append(entry.getAuthor()); entryNumber++; } buildNotes = stringBuilder.toString(); } return buildNotes; }
/** * Gets the changes incorporated into this build. * * @return never null. */ @Exported public ChangeLogSet<? extends Entry> getChangeSet() { if (scm == null) { // for historical reason, null means CVS. try { Class<?> c = Hudson.getInstance() .getPluginManager() .uberClassLoader .loadClass("hudson.scm.CVSChangeLogParser"); scm = (ChangeLogParser) c.newInstance(); } catch (ClassNotFoundException e) { // if CVS isn't available, fall back to something non-null. scm = new NullChangeLogParser(); } catch (InstantiationException e) { scm = new NullChangeLogParser(); throw (Error) new InstantiationError().initCause(e); } catch (IllegalAccessException e) { scm = new NullChangeLogParser(); throw (Error) new IllegalAccessError().initCause(e); } } if (changeSet == null) // cached value try { changeSet = calcChangeSet(); } finally { // defensive check. if the calculation fails (such as through an exception), // set a dummy value so that it'll work the next time. the exception will // be still reported, giving the plugin developer an opportunity to fix it. if (changeSet == null) changeSet = ChangeLogSet.createEmpty(this); } return changeSet; }
private void populateWithChangeInformation(Run build, String id) { if (build instanceof AbstractBuild) { ChangeLogSet changeSet = ((AbstractBuild) build).getChangeSet(); if (changeSet != null) { Object[] items = changeSet.getItems(); if (items != null) { for (Object item : items) { if (item != null && item instanceof ChangeLogSet.Entry) { ChangeLogSet.Entry changeSetItem = (ChangeLogSet.Entry) item; populateChangeEntry(id, changeSetItem); } } } } } }
@Override protected int act(List<AbstractBuild<?, ?>> builds) throws IOException { // Loading job for this CLI command requires Item.READ permission. // No other permission check needed. switch (format) { case XML: PrintWriter w = new PrintWriter(stdout); w.println("<changes>"); for (AbstractBuild build : builds) { w.println("<build number='" + build.getNumber() + "'>"); ChangeLogSet<?> cs = build.getChangeSet(); Model p = new ModelBuilder().get(cs.getClass()); p.writeTo(cs, Flavor.XML.createDataWriter(cs, w)); w.println("</build>"); } w.println("</changes>"); w.flush(); break; case CSV: for (AbstractBuild build : builds) { ChangeLogSet<?> cs = build.getChangeSet(); for (Entry e : cs) { stdout.printf( "%s,%s%n", QuotedStringTokenizer.quote(e.getAuthor().getId()), QuotedStringTokenizer.quote(e.getMsg())); } } break; case PLAIN: for (AbstractBuild build : builds) { ChangeLogSet<?> cs = build.getChangeSet(); for (Entry e : cs) { stdout.printf("%s\t%s%n", e.getAuthor(), e.getMsg()); for (String p : e.getAffectedPaths()) stdout.println(" " + p); } } break; } return 0; }
/* * (non-Javadoc) * * @see hudson.scm.ChangeLogParser#parse(hudson.model.AbstractBuild, * java.io.File) */ @Override public ChangeLogSet<? extends Entry> parse(AbstractBuild build, File changelogFile) throws IOException, SAXException { return ChangeLogSet.createEmpty(build); }