in core/src/main/java/jenkins/model/RunIdMigrator.java [192:270]
private void doMigrate(File dir) {
idToNumber = new TreeMap<>();
File[] kids = dir.listFiles();
// Need to process symlinks first so we can rename to them.
List<File> kidsList = new ArrayList<>(Arrays.asList(kids));
Iterator<File> it = kidsList.iterator();
while (it.hasNext()) {
File kid = it.next();
String name = kid.getName();
try {
Integer.parseInt(name);
} catch (NumberFormatException x) {
LOGGER.log(FINE, "ignoring nonnumeric entry {0}", name);
continue;
}
try {
if (Util.isSymlink(kid)) {
LOGGER.log(FINE, "deleting build number symlink {0} → {1}", new Object[] {name, Util.resolveSymlink(kid)});
} else if (kid.isDirectory()) {
LOGGER.log(FINE, "ignoring build directory {0}", name);
continue;
} else {
LOGGER.log(WARNING, "need to delete anomalous file entry {0}", name);
}
Util.deleteFile(kid);
it.remove();
} catch (Exception x) {
LOGGER.log(WARNING, "failed to process " + kid, x);
}
}
it = kidsList.iterator();
while (it.hasNext()) {
File kid = it.next();
try {
String name = kid.getName();
try {
Integer.parseInt(name);
LOGGER.log(FINE, "skipping new build dir {0}", name);
continue;
} catch (NumberFormatException x) {
// OK, next…
}
if (!kid.isDirectory()) {
LOGGER.log(FINE, "skipping non-directory {0}", name);
continue;
}
long timestamp;
try {
synchronized (legacyIdFormatter) {
timestamp = legacyIdFormatter.parse(name).getTime();
}
} catch (ParseException x) {
LOGGER.log(WARNING, "found unexpected dir {0}", name);
continue;
}
File buildXml = new File(kid, "build.xml");
if (!buildXml.isFile()) {
LOGGER.log(WARNING, "found no build.xml in {0}", name);
continue;
}
String xml = FileUtils.readFileToString(buildXml, Charsets.UTF_8);
Matcher m = NUMBER_ELT.matcher(xml);
if (!m.find()) {
LOGGER.log(WARNING, "could not find <number> in {0}/build.xml", name);
continue;
}
int number = Integer.parseInt(m.group(1));
String nl = m.group(2);
xml = m.replaceFirst(" <id>" + name + "</id>" + nl + " <timestamp>" + timestamp + "</timestamp>" + nl);
File newKid = new File(dir, Integer.toString(number));
move(kid, newKid);
FileUtils.writeStringToFile(new File(newKid, "build.xml"), xml, Charsets.UTF_8);
LOGGER.log(FINE, "fully processed {0} → {1}", new Object[] {name, number});
idToNumber.put(name, number);
} catch (Exception x) {
LOGGER.log(WARNING, "failed to process " + kid, x);
}
}
}