}
// sources
- for (String bundle : bundles) {
+ boolean atLeastOneBundleToCompile = false;
+ bundles: for (String bundle : bundles) {
StringBuilder sb = new StringBuilder();
Path bundlePath = execDirectory.resolve(bundle);
if (!Files.exists(bundlePath)) {
} else
throw new IllegalArgumentException("Bundle " + bundle + " not found in " + execDirectory);
}
- sb.append(bundlePath.resolve("src"));
+ Path bundleSrc = bundlePath.resolve("src");
+ if (!Files.exists(bundleSrc)) {
+ logger.log(WARNING, bundleSrc + " does not exist, skipping it, as this is not a Java bundle");
+ continue bundles;
+ }
+ sb.append(bundleSrc);
sb.append("[-d");
compilerArgs.add(sb.toString());
sb = new StringBuilder();
sb.append(buildBase.resolve(bundle).resolve("bin"));
sb.append("]");
compilerArgs.add(sb.toString());
+ atLeastOneBundleToCompile = true;
}
+ if (!atLeastOneBundleToCompile)
+ return;
+
if (logger.isLoggable(INFO))
compilerArgs.add("-time");
/** Package a single bundle. */
void createBundle(String branch, String bundle, String category) throws IOException {
- final Path source;
+ final Path bundleSourceBase;
if (!Files.exists(execDirectory.resolve(bundle))) {
logger.log(WARNING,
"Bundle " + bundle + " not found in " + execDirectory + ", assuming this is this directory.");
- source = execDirectory;
+ bundleSourceBase = execDirectory;
} else {
- source = execDirectory.resolve(bundle);
+ bundleSourceBase = execDirectory.resolve(bundle);
}
- Path srcP = source.resolve("src");
+ Path srcP = bundleSourceBase.resolve("src");
Path compiled = buildBase.resolve(bundle);
- String bundleSymbolicName = source.getFileName().toString();
+ String bundleSymbolicName = bundleSourceBase.getFileName().toString();
// Metadata
Properties properties = new Properties();
}
}
- Path bndBnd = source.resolve("bnd.bnd");
+ Path bndBnd = bundleSourceBase.resolve("bnd.bnd");
if (Files.exists(bndBnd))
try (InputStream in = Files.newInputStream(bndBnd)) {
properties.load(in);
});
// add resources
- Files.walkFileTree(source, new SimpleFileVisitor<Path>() {
+ Files.walkFileTree(bundleSourceBase, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
// skip output directory if it happens to be within the sources
return FileVisitResult.SKIP_SUBTREE;
// skip excluded patterns
- Path relativeP = source.relativize(dir);
+ Path relativeP = bundleSourceBase.relativize(dir);
for (PathMatcher exclude : excludes)
if (exclude.matches(relativeP))
return FileVisitResult.SKIP_SUBTREE;
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Path relativeP = source.relativize(file);
+ Path relativeP = bundleSourceBase.relativize(file);
for (PathMatcher exclude : excludes)
if (exclude.matches(relativeP))
return FileVisitResult.CONTINUE;
+ // skip JavaScript source maps
+ if (sourceBundles && file.getFileName().toString().endsWith(".map"))
+ return FileVisitResult.CONTINUE;
+
JarEntry entry = new JarEntry(relativeP.toString());
jarOut.putNextEntry(entry);
Files.copy(file, jarOut);
}
});
- // Add all resources from src/
- Files.walkFileTree(srcP, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- if (file.getFileName().toString().endsWith(".java")
- || file.getFileName().toString().endsWith(".class"))
+ if (Files.exists(srcP)) {
+ // Add all resources from src/
+ Files.walkFileTree(srcP, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ // skip directories ending with .js
+ // TODO find something more robust?
+ if (dir.getFileName().toString().endsWith(".js"))
+ return FileVisitResult.SKIP_SUBTREE;
+ return super.preVisitDirectory(dir, attrs);
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ if (file.getFileName().toString().endsWith(".java")
+ || file.getFileName().toString().endsWith(".class"))
+ return FileVisitResult.CONTINUE;
+ jarOut.putNextEntry(new JarEntry(srcP.relativize(file).toString()));
+ if (!Files.isDirectory(file))
+ Files.copy(file, jarOut);
return FileVisitResult.CONTINUE;
- jarOut.putNextEntry(new JarEntry(srcP.relativize(file).toString()));
- if (!Files.isDirectory(file))
- Files.copy(file, jarOut);
- return FileVisitResult.CONTINUE;
+ }
+ });
+
+ // add sources
+ // TODO add effective BND, Eclipse project file, etc., in order to be able to
+ // repackage
+ if (!sourceBundles) {
+ copySourcesToJar(srcP, jarOut, "OSGI-OPT/src/");
}
- });
+ }
// add legal notices and licenses
- for (Path p : listLegalFilesToInclude(source).values()) {
+ for (Path p : listLegalFilesToInclude(bundleSourceBase).values()) {
jarOut.putNextEntry(new JarEntry(p.getFileName().toString()));
Files.copy(p, jarOut);
}
-
- // add sources
- // TODO add effective BND, Eclipse project file, etc., in order to be able to
- // repackage
- if (!sourceBundles) {
- copySourcesToJar(srcP, jarOut, "OSGI-OPT/src/");
- }
}
if (sourceBundles) {// create separate sources jar
: a2srcOutput.resolve(category);
Files.createDirectories(a2srcJarDirectory);
Path srcJarP = a2srcJarDirectory.resolve(compiled.getFileName() + "." + major + "." + minor + ".src.jar");
- Manifest srcManifest = new Manifest();
- srcManifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
- srcManifest.getMainAttributes().putValue("Bundle-SymbolicName", bundleSymbolicName + ".src");
- srcManifest.getMainAttributes().putValue("Bundle-Version",
- manifest.getMainAttributes().getValue("Bundle-Version").toString());
+ createSourceBundle(bundleSymbolicName, manifest, bundleSourceBase, srcP, srcJarP);
+ }
+ }
+
+ /** Create a separate bundle containing the sources. */
+ void createSourceBundle(String bundleSymbolicName, Manifest manifest, Path bundleSourceBase, Path srcP,
+ Path srcJarP) throws IOException {
+ Manifest srcManifest = new Manifest();
+ srcManifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ srcManifest.getMainAttributes().putValue("Bundle-SymbolicName", bundleSymbolicName + ".src");
+ srcManifest.getMainAttributes().putValue("Bundle-Version",
+ manifest.getMainAttributes().getValue("Bundle-Version").toString());
+
+ boolean isJsBundle = bundleSymbolicName.endsWith(".js");
+ if (!isJsBundle) {
srcManifest.getMainAttributes().putValue("Eclipse-SourceBundle",
bundleSymbolicName + ";version=\"" + manifest.getMainAttributes().getValue("Bundle-Version"));
try (JarOutputStream srcJarOut = new JarOutputStream(Files.newOutputStream(srcJarP), srcManifest)) {
copySourcesToJar(srcP, srcJarOut, "");
// add legal notices and licenses
- for (Path p : listLegalFilesToInclude(source).values()) {
+ for (Path p : listLegalFilesToInclude(bundleSourceBase).values()) {
srcJarOut.putNextEntry(new JarEntry(p.getFileName().toString()));
Files.copy(p, srcJarOut);
}
}
+ } else {// JavaScript source maps
+ srcManifest.getMainAttributes().putValue("Fragment-Host", bundleSymbolicName + ";bundle-version=\""
+ + manifest.getMainAttributes().getValue("Bundle-Version"));
+ try (JarOutputStream srcJarOut = new JarOutputStream(Files.newOutputStream(srcJarP), srcManifest)) {
+ Files.walkFileTree(bundleSourceBase, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Path relativeP = bundleSourceBase.relativize(file);
+ if (!file.getFileName().toString().endsWith(".map"))
+ return FileVisitResult.CONTINUE;
+ JarEntry entry = new JarEntry(relativeP.toString());
+ srcJarOut.putNextEntry(entry);
+ Files.copy(file, srcJarOut);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
}
}
List<CompletableFuture<Void>> toDos = new ArrayList<>();
for (int i = 1; i < args.length; i++) {
- Path p = Paths.get(args[i]);
- if (sequential)
- factory.processCategory(p);
+ Path categoryPath = Paths.get(args[i]);
+ factory.cleanPreviousFailedBuild(categoryPath);
+ if (sequential) // sequential processing happens here
+ factory.processCategory(categoryPath);
else
- toDos.add(CompletableFuture.runAsync(() -> factory.processCategory(p)));
+ toDos.add(CompletableFuture.runAsync(() -> factory.processCategory(categoryPath)));
}
- if (!sequential)
+ if (!sequential)// parallel processing
CompletableFuture.allOf(toDos.toArray(new CompletableFuture[toDos.size()])).join();
// Summary
logger.log(INFO, "# License summary:\n" + sb);
}
+ /** Deletes remaining sub directories. */
+ void cleanPreviousFailedBuild(Path categoryPath) {
+ Path outputCategoryPath = a2Base.resolve(categoryPath);
+ if (!Files.exists(outputCategoryPath))
+ return;
+ // clean previous failed build
+ try {
+ for (Path subDir : Files.newDirectoryStream(outputCategoryPath, (d) -> Files.isDirectory(d))) {
+ if (Files.exists(subDir)) {
+ logger.log(WARNING, "Bundle dir " + subDir
+ + " already exists, probably from a previous failed build, deleting it...");
+ deleteDirectory(subDir);
+ }
+ }
+ } catch (IOException e) {
+ logger.log(ERROR, "Cannot clean previous build", e);
+ }
+ }
+
/** MANIFEST headers. */
enum ManifestHeader {
// OSGi
} else if (entry.getName().startsWith("org/apache/batik/")) {
logger.log(TRACE, "Skip " + entry.getName());
continue entries;
+ } else if (entry.getName().startsWith("META-INF/NOTICE")) {
+ logger.log(WARNING, "Skip " + entry.getName() + " from " + artifact);
+ // TODO merge them?
+ continue entries;
} else {
throw new IllegalStateException("File " + target + " from " + artifact + " already exists");
}
map.put(key.toString(), commonProps.getProperty(key.toString()));
A2Origin origin = new A2Origin();
Path bundleDir = processBundleJar(file, targetCategoryBase, map, origin);
+ if (bundleDir == null) {
+ logger.log(WARNING, "No bundle dir created for " + file + ", skipping...");
+ return FileVisitResult.CONTINUE;
+ }
origins.put(bundleDir, origin);
logger.log(DEBUG, () -> "Processed " + file);
}
Manifest sourceManifest;
try (JarInputStream jarIn = new JarInputStream(Files.newInputStream(file), false)) {
sourceManifest = jarIn.getManifest();
+ if (sourceManifest == null)
+ logger.log(WARNING, file + " has no manifest");
manifest = sourceManifest != null ? new Manifest(sourceManifest) : new Manifest();
String rawSourceSymbolicName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME.toString());
nameVersion = new NameVersion(ourSymbolicName, ourVersion);
} else {
nameVersion = nameVersionFromManifest(manifest);
+ if (nameVersion == null)
+ throw new IllegalStateException("Could not compute name/version from Manifest");
if (ourVersion != null && !nameVersion.getVersion().equals(ourVersion)) {
logger.log(WARNING,
"Original version is " + nameVersion.getVersion() + " while new version is " + ourVersion);
nameVersion.setName(ourSymbolicName);
}
}
+
bundleDir = targetBase.resolve(nameVersion.getName() + "." + nameVersion.getBranch());
// copy original MANIFEST
arch = libRelativePath.getName(1).toString();
}
-// if (!embed) {
// copy entries
JarEntry entry;
entries: while ((entry = jarIn.getNextJarEntry()) != null) {
origin.deleted.add(bundleDir.relativize(target).toString());
}
logger.log(TRACE, () -> "Copied " + target);
-// }
}
}
entries.get(BUNDLE_SYMBOLICNAME.toString()) + ";singleton:=true");
}
-// if (embed) {// copy embedded jar
-// Files.copy(file, bundleDir.resolve(file.getFileName()));
-// entries.put(ManifestHeader.BUNDLE_CLASSPATH.toString(), file.getFileName().toString());
-// }
-
// Final MANIFEST decisions
// We also check the original OSGi metadata and compare with our changes
for (String key : entries.keySet()) {