/** * Adds a usage reference to the build. * @param b {@link Run} to be referenced in {@link #usages} * @since 1.577 */ public synchronized void addFor(@Nonnull Run b) throws IOException { add(b.getParent().getFullName(), b.getNumber()); }
/** * Save the settings to a file. * @throws IOException Save error */ public synchronized void save() throws IOException { if(BulkChange.contains(this)) return; long start=0; if(logger.isLoggable(Level.FINE)) start = System.currentTimeMillis(); File file = getFingerprintFile(md5sum); save(file); SaveableListener.fireOnChange(this, getConfigFile(file)); if(logger.isLoggable(Level.FINE)) logger.fine("Saving fingerprint "+file+" took "+(System.currentTimeMillis()-start)+"ms"); }
private void record(Run<?,?> build, FilePath ws, TaskListener listener, Map<String,String> record, final String targets) throws IOException, InterruptedException { for (Record r : ws.act(new FindRecords(targets, build.getTimeInMillis()))) { Fingerprint fp = r.addRecord(build); if(fp==null) { listener.error(Messages.Fingerprinter_FailedFor(r.relativePath)); continue; } fp.addFor(build); record.put(r.relativePath,fp.getHashString()); } }
/** * Records that a build of a job has used this file. */ public synchronized void add(@Nonnull String jobFullName, int n) throws IOException { addWithoutSaving(jobFullName, n); save(); }
/** * Loads a {@link Fingerprint} from a file in the image. * @return Loaded {@link Fingerprint}. Null if the config file does not exist or * malformed. */ /*package*/ static @CheckForNull Fingerprint load(@Nonnull byte[] md5sum) throws IOException { return load(getFingerprintFile(md5sum)); } /*package*/ static @CheckForNull Fingerprint load(@Nonnull File file) throws IOException {
fingerprint.add(build); recordedFingerprints.put(fileIdentifier, fingerprint.getHashString());
/** * Gets the dependency relationship from this build (as the source) * and that project (as the sink.) * * @return * range of build numbers that represent which downstream builds are using this build. * The range will be empty if no build of that project matches this (or there is no {@link FingerprintAction}), but it'll never be null. */ public RangeSet getDownstreamRelationship(AbstractProject that) { RangeSet rs = new RangeSet(); FingerprintAction f = getAction(FingerprintAction.class); if (f==null) return rs; // look for fingerprints that point to this build as the source, and merge them all for (Fingerprint e : f.getFingerprints().values()) { if (upstreamCulprits) { // With upstreamCulprits, we allow downstream relationships // from intermediate jobs rs.add(e.getRangeSet(that)); } else { BuildPtr o = e.getOriginal(); if (o!=null && o.is(this)) rs.add(e.getRangeSet(that)); } } return rs; }
public Fingerprint(@CheckForNull Run build, @Nonnull String fileName, @Nonnull byte[] md5sum) throws IOException { this(build==null ? null : new BuildPtr(build), fileName, md5sum); save(); }
/** * Finds a facet of the specific type (including subtypes.) * @param <T> Class of the {@link FingerprintFacet} * @return First matching facet of the specified class * @since 1.556 */ public @CheckForNull <T extends FingerprintFacet> T getFacet(Class<T> type) { for (FingerprintFacet f : getFacets()) { if (type.isInstance(f)) return type.cast(f); } return null; }
/** * Save the settings to a file. */ public synchronized void save() throws IOException { if(BulkChange.contains(this)) return; long start=0; if(logger.isLoggable(Level.FINE)) start = System.currentTimeMillis(); File file = getFingerprintFile(md5sum); getConfigFile(file).write(this); SaveableListener.fireOnChange(this, getConfigFile(file)); if(logger.isLoggable(Level.FINE)) logger.fine("Saving fingerprint "+file+" took "+(System.currentTimeMillis()-start)+"ms"); }
logger.log(Level.FINE, "Saving trimmed {0}", getFingerprintFile(md5sum)); save();
/** * Examines the file and returns true if a file was deleted. */ private boolean check(File fingerprintFile, TaskListener listener) { try { Fingerprint fp = Fingerprint.load(fingerprintFile); if (fp == null || !fp.isAlive()) { listener.getLogger().println("deleting obsolete " + fingerprintFile); fingerprintFile.delete(); return true; } else { // get the fingerprint in the official map so have the changes visible to Jenkins // otherwise the mutation made in FingerprintMap can override our trimming. listener.getLogger().println("possibly trimming " + fingerprintFile); fp = Jenkins.getInstance()._getFingerprint(fp.getHashString()); return fp.trim(); } } catch (IOException e) { Functions.printStackTrace(e, listener.error("Failed to process " + fingerprintFile)); return false; } }
/** * @deprecated Use {@link #addFor(hudson.model.Run)} */ @Deprecated public synchronized void add(@Nonnull AbstractBuild b) throws IOException { addFor((Run) b); }
/** * Registers a fingerprint for the given workspace's id. * * @param exws the workspace to register the fingerprint for * @throws IOException if fingerprint load operation fails */ private void registerFingerprint(ExternalWorkspace exws) throws IOException { FingerprintMap map = Jenkins.getActiveInstance().getFingerprintMap(); Fingerprint f = map.getOrCreate(run, exws.getDisplayName(), exws.getId()); if (f.getFacet(WorkspaceBrowserFacet.class) == null) { f.getFacets().add(new WorkspaceBrowserFacet(f, System.currentTimeMillis(), exws)); } f.save(); }
/** * Adds the current run to the fingerprint's usages. * * @param workspaceId the workspace's id * @throws IOException if fingerprint load operation fails, * or if no fingerprint is found for the given workspace id */ private void updateFingerprint(String workspaceId) throws IOException { Fingerprint f = Jenkins.getActiveInstance()._getFingerprint(workspaceId); if (f == null) { throw new AbortException("Couldn't find any Fingerprint for: " + workspaceId); } Fingerprint.RangeSet set = f.getUsages().get(run.getParent().getFullName()); if (set == null || !set.includes(run.getNumber())) { f.addFor(run); f.save(); } }
@Override public String toString() { return "Fingerprint[original=" + original + ",hash=" + getHashString() + ",fileName=" + fileName + ",timestamp=" + DATE_CONVERTER.toString(timestamp) + ",usages=" + new TreeMap<String,RangeSet>(usages) + ",facets=" + facets + "]"; }
protected @Nonnull Fingerprint create(@Nonnull String md5sum, @Nonnull FingerprintParams createParams) throws IOException { return new Fingerprint(createParams.build, createParams.fileName, toByteArray(md5sum)); }
public RangeSet getRangeSet(Job job) { return getRangeSet(job.getFullName()); }
getConfigFile(file).write(this);
BuildPtr bp = fp.getOriginal(); if(bp==null) continue; // outside Hudson if(bp.is(build)) continue; // we are the owner