private boolean updateExistingJob(AbstractProject<?, ?> project, String config) { boolean created; // Leverage XMLUnit to perform diffs Diff diff; try { String oldJob = project.getConfigFile().asString(); diff = XMLUnit.compareXML(oldJob, config); if (diff.similar()) { LOGGER.log(Level.FINE, String.format("Project %s is identical", project.getName())); return false; } } catch (Exception e) { // It's not a big deal if we can't diff, we'll just move on LOGGER.warning(e.getMessage()); } // TODO Perform comparison between old and new, and print to console // TODO Print out, for posterity, what the user might have changed, in the format of the DSL LOGGER.log(Level.FINE, String.format("Updating project %s as %s", project.getName(), config)); StreamSource streamSource = new StreamSource(new StringReader(config)); // TODO use real xmlReader try { project.updateByXml(streamSource); created = true; } catch (IOException ioex) { LOGGER.log(Level.WARNING, String.format("Error writing updated project to file."), ioex); created = false; } return created; }
@DataBoundConstructor public JobIngredient(String name, String description) { this.name = name; this.description = description; AbstractProject i = Jenkins.getInstance().getItemByFullName(name, AbstractProject.class); if (i == null) throw new IllegalArgumentException("No such job: " + name); this.definition = XStreamDOM.from(i.getConfigFile().getXStream(), i); }
private String lookupJob(String jobName) throws IOException { LOGGER.log(Level.FINE, String.format("Looking up Job %s", jobName)); String jobXml = ""; AbstractProject<?, ?> project = (AbstractProject<?, ?>) Jenkins.getInstance().getItemByFullName(jobName); if (project != null) { XmlFile xmlFile = project.getConfigFile(); jobXml = xmlFile.asString(); } else { LOGGER.log(Level.WARNING, String.format("No Job called %s could be found.", jobName)); throw new IOException(String.format("No Job called %s could be found.", jobName)); } LOGGER.log(Level.FINE, String.format("Looked up Job with config %s", jobXml)); return jobXml; }
/** Uses generatedJobs as existing data, so call before updating generatedJobs. */ private Set<String> updateTemplates( AbstractBuild<?, ?> build, BuildListener listener, Set<GeneratedJob> freshJobs) throws IOException { AbstractProject<?, ?> seedJob = build.getProject(); Set<String> freshTemplates = getTemplates(freshJobs); Set<String> existingTemplates = getTemplates(extractGeneratedObjects(seedJob, GeneratedJobsAction.class)); Set<String> newTemplates = Sets.difference(freshTemplates, existingTemplates); Set<String> removedTemplates = Sets.difference(existingTemplates, freshTemplates); logItems(listener, "Existing templates", existingTemplates); logItems(listener, "New templates", newTemplates); logItems(listener, "Unreferenced templates", removedTemplates); // Collect information about the templates we loaded final String seedJobName = seedJob.getName(); DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); boolean descriptorMutated = false; // Clean up for (String templateName : removedTemplates) { Collection<SeedReference> seedJobReferences = descriptor.getTemplateJobMap().get(templateName); Collection<SeedReference> matching = Collections2.filter(seedJobReferences, new SeedNamePredicate(seedJobName)); if (!matching.isEmpty()) { seedJobReferences.removeAll(matching); descriptorMutated = true; } } // Ensure we have a reference for (String templateName : freshTemplates) { Collection<SeedReference> seedJobReferences = descriptor.getTemplateJobMap().get(templateName); Collection<SeedReference> matching = Collections2.filter(seedJobReferences, new SeedNamePredicate(seedJobName)); AbstractProject templateProject = getLookupStrategy().getItem(seedJob, templateName, AbstractProject.class); final String digest = Util.getDigestOf(new FileInputStream(templateProject.getConfigFile().getFile())); if (matching.size() == 1) { // Just update digest SeedReference ref = Iterables.get(matching, 0); if (digest.equals(ref.getDigest())) { ref.setDigest(digest); descriptorMutated = true; } } else { if (matching.size() > 1) { // Not sure how there could be more one, throw it all away and start over seedJobReferences.removeAll(matching); } seedJobReferences.add(new SeedReference(templateName, seedJobName, digest)); descriptorMutated = true; } } if (descriptorMutated) { descriptor.save(); } return freshTemplates; }