private void updateGeneratedJobMap( AbstractProject<?, ?> seedJob, Set<GeneratedJob> createdOrUpdatedJobs, Set<GeneratedJob> removedJobs) throws IOException { DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class); boolean descriptorMutated = false; Map<String, SeedReference> generatedJobMap = descriptor.getGeneratedJobMap(); for (GeneratedJob generatedJob : createdOrUpdatedJobs) { Item item = getLookupStrategy().getItem(seedJob, generatedJob.getJobName(), Item.class); if (item != null) { SeedReference newSeedReference = new SeedReference(seedJob.getFullName()); if (generatedJob.getTemplateName() != null) { Item template = getLookupStrategy().getItem(seedJob, generatedJob.getTemplateName(), Item.class); newSeedReference.setTemplateJobName(template.getFullName()); } newSeedReference.setDigest(Util.getDigestOf(Items.getConfigFile(item).getFile())); SeedReference oldSeedReference = generatedJobMap.get(item.getFullName()); if (!newSeedReference.equals(oldSeedReference)) { generatedJobMap.put(item.getFullName(), newSeedReference); descriptorMutated = true; } } } for (GeneratedJob removedJob : removedJobs) { Item removedItem = getLookupStrategy().getItem(seedJob, removedJob.getJobName(), Item.class); if (removedItem != null) { generatedJobMap.remove(removedItem.getFullName()); descriptorMutated = true; } } if (descriptorMutated) { descriptor.save(); } }
/** 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; }