From: Mathieu Baudier Date: Fri, 4 Feb 2022 08:18:01 +0000 (+0100) Subject: Start working on A2 factory. X-Git-Tag: argeo-slc-2.3.1~25 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=1b8b4c8443356a7a4adc632f391daa8c0ded8053;p=gpl%2Fargeo-slc.git Start working on A2 factory. --- diff --git a/.gitignore b/.gitignore index 492e809ea..d6fc805c7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ **/target/ **/generated/ **/MANIFEST.MF +/sdk.mk +/output/ diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d6bda7804 --- /dev/null +++ b/Makefile @@ -0,0 +1,89 @@ +include sdk.mk +.PHONY: clean all osgi + +all: osgi + +BUNDLE_PREFIX = org.argeo +A2_CATEGORY = org.argeo + +BUNDLES = \ +org.argeo.slc.api \ +org.argeo.slc.build \ + +BUILD_CLASSPATH = \ +/usr/share/java/osgi-core/osgi.core.jar:$\ +/usr/share/java/osgi-compendium/osgi.cmpn.jar:$\ +/usr/share/java/ecj/ecj.jar:$\ +/usr/share/java/aqute-bnd/biz.aQute.bndlib.jar:$\ +/usr/share/java/slf4j/api.jar:$\ +/usr/share/java/commons-io.jar:$\ +/usr/share/java/commons-cli.jar:$\ +/usr/share/java/commons-exec.jar:$\ + +# TODO relativize from SDK_SRC_BASE +BUILD_BASE = $(SDK_BUILD_BASE) + +# +# GENERIC +# +JVM := /usr/lib/jvm/jre-11/bin/java +JAVADOC := /usr/lib/jvm/jre-11/bin/javadoc +ECJ_JAR := /usr/share/java/ecj/ecj.jar +BND_TOOL := /usr/bin/bnd + +WORKSPACE_BNDS := $(shell cd $(SDK_SRC_BASE) && find cnf -name '*.bnd') +#BND_WORKSPACES := $(foreach bundle, $(BUNDLES), ./$(dir $(bundle))) +BUILD_WORKSPACE_BNDS := $(WORKSPACE_BNDS:%=$(SDK_BUILD_BASE)/%) + +cnf: $(BUILD_WORKSPACE_BNDS) + +A2_BUNDLES = $(BUNDLES:%=$(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/%.$(MAJOR).$(MINOR).jar) + +#JAVA_SRCS = $(shell find $(BUNDLE_PREFIX).* -name '*.java') +JAVA_SRCS = $(foreach bundle, $(BUNDLES), $(shell find $(bundle) -name '*.java')) +ECJ_SRCS = $(foreach bundle, $(BUNDLES), $(bundle)/src[-d $(BUILD_BASE)/$(bundle)/bin]) + +osgi: cnf $(A2_BUNDLES) + +clean: + rm -rf $(BUILD_BASE)/*-compiled + rm -rf $(BUILD_BASE)/{cnf,a2} + rm -rf $(BUILD_BASE)/$(BUNDLE_PREFIX).* + +# SDK level +$(SDK_BUILD_BASE)/cnf/%.bnd: cnf/%.bnd + mkdir -p $(dir $@) + cp $< $@ + +$(SDK_BUILD_BASE)/eclipse/cnf/%.bnd: cnf/%.bnd + mkdir -p $(dir $@) + cp $< $@ + +$(SDK_BUILD_BASE)/rcp/cnf/%.bnd: cnf/%.bnd + mkdir -p $(dir $@) + cp $< $@ + +$(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/%.$(MAJOR).$(MINOR).jar : $(BUILD_BASE)/%/bundle.jar + mkdir -p $(dir $@) + cp $< $@ + +# Build level +$(BUILD_BASE)/%/bundle.jar : %/bnd.bnd $(BUILD_BASE)/java-compiled + rsync -r --exclude "*.java" $(dir $<)src/ $(dir $@)bin + rsync -r $(dir $<)src/ $(dir $@)src + if [ -d "$(dir $<)OSGI-INF" ]; then rsync -r $(dir $<)OSGI-INF/ $(dir $@)/OSGI-INF; fi + cp $< $(dir $@) + cd $(dir $@) && $(BND_TOOL) build + mv $(dir $@)generated/*.jar $(dir $@)bundle.jar + +$(BUILD_BASE)/java-compiled : $(JAVA_SRCS) + $(JVM) -jar $(ECJ_JAR) -11 -nowarn -time -cp $(BUILD_CLASSPATH) \ + $(ECJ_SRCS) + touch $@ + +null := +space := $(null) # +pathsep := : + +#WITH_LIST := $(subst $(space),$(pathsep),$(strip $(WITH_LIST))) + diff --git a/branch.properties b/branch.properties new file mode 100644 index 000000000..7a7e579b7 --- /dev/null +++ b/branch.properties @@ -0,0 +1,2 @@ +MAJOR=2 +MINOR=3 diff --git a/configure b/configure new file mode 100644 index 000000000..4587bf45e --- /dev/null +++ b/configure @@ -0,0 +1,48 @@ +#!/bin/sh + +# We build where we are +SDK_BUILD_BASE=$(pwd -P)/output + +# Source are located where this script is +SDK_SRC_BASE="$(cd "$(dirname "$0")"; pwd -P)" + +SDK_MK=$SDK_SRC_BASE/sdk.mk + +#echo SDK_BUILD_BASE=$SDK_BUILD_BASE +#echo SDK_SRC_BASE=$SDK_SRC_BASE +#echo SDK_MK=$SDK_MK + +if [ -f "$SDK_MK" ]; +then + +echo "File $SDK_MK already exists. Remove it in order to configure a new build location:" +echo "rm $SDK_MK" +exit 1 + +else + +# Create build directory, so that it can be used right away +# and we check whether we have the rights +mkdir -p $SDK_BUILD_BASE +if [ -f "$SDK_MK" ]; +then +echo "Cannot create $SDK_BUILD_BASE, SDK configuration has failed." +exit 2 +fi + +# Generate sdk.mk +cat > "$SDK_MK" < + + + + + + diff --git a/org.argeo.slc.build/.project b/org.argeo.slc.build/.project new file mode 100644 index 000000000..29c4c9ef0 --- /dev/null +++ b/org.argeo.slc.build/.project @@ -0,0 +1,28 @@ + + + org.argeo.slc.build + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.slc.build/bnd.bnd b/org.argeo.slc.build/bnd.bnd new file mode 100644 index 000000000..e69de29bb diff --git a/org.argeo.slc.build/build.properties b/org.argeo.slc.build/build.properties new file mode 100644 index 000000000..5d082eaf6 --- /dev/null +++ b/org.argeo.slc.build/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . +additional.bundles = org.argeo.init diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java b/org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java new file mode 100644 index 000000000..f822e7f70 --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/A2DistributionUnit.java @@ -0,0 +1,9 @@ +package org.argeo.slc.build; + +import org.argeo.slc.DefaultCategoryNameVersion; + +public class A2DistributionUnit extends DefaultCategoryNameVersion { + private String originVersion; + + +} diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java b/org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java new file mode 100644 index 000000000..d53c5660f --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/A2Factory.java @@ -0,0 +1,295 @@ +package org.argeo.slc.build; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; + +import org.argeo.slc.DefaultNameVersion; +import org.argeo.slc.ManifestConstants; +import org.argeo.slc.NameVersion; + +public class A2Factory { + private final static Logger logger = System.getLogger(A2Factory.class.getName()); + + private Path originBase; + private Path factoryBase; + + /** key is URI prefix, value list of base URLs */ + private Map> mirrors = new HashMap>(); + + public A2Factory(Path originBase, Path factoryBase) { + super(); + this.originBase = originBase; + this.factoryBase = factoryBase; + + // TODO make it configurable + List eclipseMirrors = new ArrayList<>(); + eclipseMirrors.add("https://archive.eclipse.org/"); + + mirrors.put("http://www.eclipse.org/downloads", eclipseMirrors); + } + + public void processEclipseArchive(Path duDir) { + try { + String category = duDir.getParent().getFileName().toString(); + Path targetCategoryBase = factoryBase.resolve(category); + Files.createDirectories(targetCategoryBase); + Files.createDirectories(originBase); + + Path commonBnd = duDir.resolve("common.bnd"); + Properties commonProps = new Properties(); + try (InputStream in = Files.newInputStream(commonBnd)) { + commonProps.load(in); + } + Properties includes = new Properties(); + try (InputStream in = Files.newInputStream(duDir.resolve("includes.properties"))) { + includes.load(in); + } + String url = commonProps.getProperty(ManifestConstants.SLC_ORIGIN_URI.toString()); + Path downloaded = tryDownload(url, originBase); + + FileSystem zipFs = FileSystems.newFileSystem(downloaded, null); + + List pathMatchers = new ArrayList<>(); + for (Object pattern : includes.keySet()) { + PathMatcher pathMatcher = zipFs.getPathMatcher("glob:/" + pattern); + pathMatchers.add(pathMatcher); + } + + Files.walkFileTree(zipFs.getRootDirectories().iterator().next(), new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + pathMatchers: for (PathMatcher pathMatcher : pathMatchers) { + if (pathMatcher.matches(file)) { +// Path target = targetBase.resolve(file.getFileName().toString()); +// if (!Files.exists(target)) { +// Files.copy(file, target); +// logger.log(Level.DEBUG, () -> "Copied " + target + " from " + downloaded); +// } else { +// logger.log(Level.DEBUG, () -> target + " already exists."); +// +// } + if (file.getFileName().toString().contains(".source_")) { + processEclipseSourceJar(file, targetCategoryBase); + logger.log(Level.DEBUG, () -> "Processed source " + file); + + } else { + processBundleJar(file, targetCategoryBase); + logger.log(Level.DEBUG, () -> "Processed " + file); + } + continue pathMatchers; + } + } + return super.visitFile(file, attrs); + } + }); + } catch (IOException e) { + throw new RuntimeException("Cannot process " + duDir, e); + } + + } + + protected void processBundleJar(Path file, Path targetBase) throws IOException { + NameVersion nameVersion; + Path targetBundleDir; + try (JarInputStream jarIn = new JarInputStream(Files.newInputStream(file), false)) { + Manifest manifest = jarIn.getManifest(); + nameVersion = nameVersionFromManifest(manifest); + targetBundleDir = targetBase.resolve(nameVersion.getName() + "." + nameVersion.getBranch()); + + // TODO make it less dangerous? + if (Files.exists(targetBundleDir)) { + deleteDirectory(targetBundleDir); + } + + // copy entries + JarEntry entry; + entries: while ((entry = jarIn.getNextJarEntry()) != null) { + if (entry.isDirectory()) + continue entries; + Path target = targetBundleDir.resolve(entry.getName()); + Files.createDirectories(target.getParent()); + Files.copy(jarIn, target); + logger.log(Level.TRACE, () -> "Copied " + target); + } + + // copy MANIFEST + Path manifestPath = targetBundleDir.resolve("META-INF/MANIFEST.MF"); + Files.createDirectories(manifestPath.getParent()); + try (OutputStream out = Files.newOutputStream(manifestPath)) { + manifest.write(out); + } + } + + } + + protected void processEclipseSourceJar(Path file, Path targetBase) throws IOException { + // NameVersion nameVersion; + Path targetBundleDir; + try (JarInputStream jarIn = new JarInputStream(Files.newInputStream(file), false)) { + Manifest manifest = jarIn.getManifest(); + // nameVersion = nameVersionFromManifest(manifest); + + String[] relatedBundle = manifest.getMainAttributes().getValue("Eclipse-SourceBundle").split(";"); + String version = relatedBundle[1].substring("version=\"".length()); + version = version.substring(0, version.length() - 1); + NameVersion nameVersion = new DefaultNameVersion(relatedBundle[0], version); + targetBundleDir = targetBase.resolve(nameVersion.getName() + "." + nameVersion.getBranch()); + + Path targetSourceDir = targetBundleDir.resolve("OSGI-OPT/src"); + + // TODO make it less dangerous? + if (Files.exists(targetSourceDir)) { + deleteDirectory(targetSourceDir); + } else { + Files.createDirectories(targetSourceDir); + } + + // copy entries + JarEntry entry; + entries: while ((entry = jarIn.getNextJarEntry()) != null) { + if (entry.isDirectory()) + continue entries; + if (entry.getName().startsWith("META-INF"))// skip META-INF entries + continue entries; + Path target = targetSourceDir.resolve(entry.getName()); + Files.createDirectories(target.getParent()); + Files.copy(jarIn, target); + logger.log(Level.TRACE, () -> "Copied source " + target); + } + + // copy MANIFEST +// Path manifestPath = targetBundleDir.resolve("META-INF/MANIFEST.MF"); +// Files.createDirectories(manifestPath.getParent()); +// try (OutputStream out = Files.newOutputStream(manifestPath)) { +// manifest.write(out); +// } + } + + } + + static void deleteDirectory(Path path) throws IOException { + if (!Files.exists(path)) + return; + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult postVisitDirectory(Path directory, IOException e) throws IOException { + if (e != null) + throw e; + Files.delete(directory); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + }); + } + + protected NameVersion nameVersionFromManifest(Manifest manifest) { + Attributes attrs = manifest.getMainAttributes(); + // symbolic name + String symbolicName = attrs.getValue(ManifestConstants.BUNDLE_SYMBOLICNAME.toString()); + // make sure there is no directive + symbolicName = symbolicName.split(";")[0]; + + String version = attrs.getValue(ManifestConstants.BUNDLE_VERSION.toString()); + return new DefaultNameVersion(symbolicName, version); + } + + protected Path tryDownload(String uri, Path dir) throws IOException { + // find mirror + List urlBases = null; + String uriPrefix = null; + uriPrefixes: for (String uriPref : mirrors.keySet()) { + if (uri.startsWith(uriPref)) { + if (mirrors.get(uriPref).size() > 0) { + urlBases = mirrors.get(uriPref); + uriPrefix = uriPref; + break uriPrefixes; + } + } + } + if (urlBases == null) + try { + return download(uri, dir, null); + } catch (FileNotFoundException e) { + throw new FileNotFoundException("Cannot find " + uri); + } + + // try to download + for (String urlBase : urlBases) { + String relativePath = uri.substring(uriPrefix.length()); + String url = urlBase + relativePath; + try { + return download(url, dir, null); + } catch (FileNotFoundException e) { + logger.log(Level.WARNING, "Cannot download " + url + ", trying another mirror"); + } + } + throw new FileNotFoundException("Cannot find " + uri); + } + +// protected String simplifyName(URL u) { +// String name = u.getPath().substring(u.getPath().lastIndexOf('/') + 1); +// +// } + + public Path download(String url, Path dir, String name) throws IOException { + + Path dest; + URL u = new URL(url); + if (name == null) { + name = u.getPath().substring(u.getPath().lastIndexOf('/') + 1); + } + + dest = dir.resolve(name); + if (Files.exists(dest)) { + logger.log(Level.DEBUG, () -> "File " + dest + " already exists for " + url + ", not downloading again."); + return dest; + } + + try (InputStream in = u.openStream()) { + Files.copy(in, dest); + } + return dest; + } + + public static void main(String[] args) { + Path originBase = Paths.get("../output/origin"); + Path factoryBase = Paths.get("../output/a2"); + A2Factory factory = new A2Factory(originBase, factoryBase); + + Path descriptorsBase = Paths.get(System.getProperty("user.home"), "/dev/git/unstable/argeo-tp/migration"); + + factory.processEclipseArchive( + descriptorsBase.resolve("org.argeo.tp.eclipse.equinox").resolve("eclipse-equinox")); + factory.processEclipseArchive(descriptorsBase.resolve("org.argeo.tp.eclipse.rap").resolve("eclipse-rap")); + factory.processEclipseArchive(descriptorsBase.resolve("org.argeo.tp.eclipse.rcp").resolve("eclipse-rcp")); + } +} diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java b/org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java new file mode 100644 index 000000000..f988c9e9d --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/bnd/BndManifestFactory.java @@ -0,0 +1,5 @@ +package org.argeo.slc.build.bnd; + +public class BndManifestFactory { + +} diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java new file mode 100644 index 000000000..2d485b8de --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/m2/Artifact.java @@ -0,0 +1,24 @@ +package org.argeo.slc.build.m2; + +public interface Artifact { + String getGroupId(); + + String getArtifactId(); + + String getVersion(); + + default String getBaseVersion() { + return getVersion(); + } + +// boolean isSnapshot(); + + default String getClassifier() { + return ""; + } + + default String getExtension() { + return "jar"; + } + +} diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java new file mode 100644 index 000000000..922a0aa44 --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/m2/DefaultArtifact.java @@ -0,0 +1,17 @@ +package org.argeo.slc.build.m2; + +import org.argeo.slc.DefaultCategoryNameVersion; + +public class DefaultArtifact extends DefaultCategoryNameVersion implements Artifact { + + @Override + public String getGroupId() { + return getCategory(); + } + + @Override + public String getArtifactId() { + return getName(); + } + +} diff --git a/org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java b/org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java new file mode 100644 index 000000000..358e2ef8f --- /dev/null +++ b/org.argeo.slc.build/src/org/argeo/slc/build/m2/MavenConventionsUtils.java @@ -0,0 +1,198 @@ +package org.argeo.slc.build.m2; + +import java.io.File; +import java.util.Set; + +/** + * Static utilities around Maven which are NOT using the Maven APIs (conventions + * based). + */ +public class MavenConventionsUtils { + /** + * Path to the file identified by this artifact without using Maven + * APIs (convention based). Default location of repository + * (~/.m2/repository) is used here. + * + * @see MavenConventionsUtils#artifactToFile(String, Artifact) + */ + public static File artifactToFile(Artifact artifact) { + return artifactToFile(System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository", + artifact); + } + + /** + * Path to the file identified by this artifact without using Maven + * APIs (convention based). + * + * @param repositoryPath + * path to the related local repository location + * @param artifact + * the artifact + */ + public static File artifactToFile(String repositoryPath, Artifact artifact) { + return new File(repositoryPath + File.separator + artifact.getGroupId().replace('.', File.separatorChar) + + File.separator + artifact.getArtifactId() + File.separator + artifact.getVersion() + File.separator + + artifactFileName(artifact)).getAbsoluteFile(); + } + + /** The file name of this artifact when stored */ + public static String artifactFileName(Artifact artifact) { + return artifact.getArtifactId() + '-' + artifact.getVersion() + + (artifact.getClassifier().equals("") ? "" : '-' + artifact.getClassifier()) + '.' + + artifact.getExtension(); + } + + /** Absolute path to the file */ + public static String artifactPath(String artifactBasePath, Artifact artifact) { + return artifactParentPath(artifactBasePath, artifact) + '/' + artifactFileName(artifact); + } + + /** Absolute path to the file */ + public static String artifactUrl(String repoUrl, Artifact artifact) { + if (repoUrl.endsWith("/")) + return repoUrl + artifactPath("/", artifact).substring(1); + else + return repoUrl + artifactPath("/", artifact); + } + + /** Absolute path to the directories where the files will be stored */ + public static String artifactParentPath(String artifactBasePath, Artifact artifact) { + return artifactBasePath + (artifactBasePath.endsWith("/") ? "" : "/") + artifactParentPath(artifact); + } + + /** Absolute path to the directory of this group */ + public static String groupPath(String artifactBasePath, String groupId) { + return artifactBasePath + (artifactBasePath.endsWith("/") ? "" : "/") + groupId.replace('.', '/'); + } + + /** Relative path to the directories where the files will be stored */ + public static String artifactParentPath(Artifact artifact) { + return artifact.getGroupId().replace('.', '/') + '/' + artifact.getArtifactId() + '/' + + artifact.getBaseVersion(); + } + + public static String artifactsAsDependencyPom(Artifact pomArtifact, Set artifacts, Artifact parent) { + StringBuffer p = new StringBuffer(); + + // XML header + p.append("\n"); + p.append( + "\n"); + p.append("4.0.0\n"); + + // Artifact + if (parent != null) { + p.append("\n"); + p.append("").append(parent.getGroupId()).append("\n"); + p.append("").append(parent.getArtifactId()).append("\n"); + p.append("").append(parent.getVersion()).append("\n"); + p.append("\n"); + } + p.append("").append(pomArtifact.getGroupId()).append("\n"); + p.append("").append(pomArtifact.getArtifactId()).append("\n"); + p.append("").append(pomArtifact.getVersion()).append("\n"); + p.append("pom\n"); + + // Dependencies + p.append("\n"); + for (Artifact a : artifacts) { + p.append("\t"); + p.append("").append(a.getArtifactId()).append(""); + p.append("").append(a.getGroupId()).append(""); + if (!a.getExtension().equals("jar")) + p.append("").append(a.getExtension()).append(""); + p.append("\n"); + } + p.append("\n"); + + // Dependency management + p.append("\n"); + p.append("\n"); + for (Artifact a : artifacts) { + p.append("\t"); + p.append("").append(a.getArtifactId()).append(""); + p.append("").append(a.getVersion()).append(""); + p.append("").append(a.getGroupId()).append(""); + if (a.getExtension().equals("pom")) { + p.append("").append(a.getExtension()).append(""); + p.append("import"); + } + p.append("\n"); + } + p.append("\n"); + p.append("\n"); + + // Repositories + // p.append("\n"); + // p.append("argeohttp://maven.argeo.org/argeo\n"); + // p.append("\n"); + + p.append("\n"); + return p.toString(); + } + +// /** +// * Directly parses Maven POM XML format in order to find all artifacts +// * references under the dependency and dependencyManagement tags. This is +// * meant to migrate existing pom registering a lot of artifacts, not to +// * replace Maven resolving. +// */ +// public static void gatherPomDependencies(AetherTemplate aetherTemplate, Set artifacts, +// Artifact pomArtifact) { +// if (log.isDebugEnabled()) +// log.debug("Gather dependencies for " + pomArtifact); +// +// try { +// File file = aetherTemplate.getResolvedFile(pomArtifact); +// DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +// Document doc = documentBuilder.parse(file); +// +// // properties +// Properties props = new Properties(); +// props.setProperty("project.version", pomArtifact.getBaseVersion()); +// NodeList properties = doc.getElementsByTagName("properties"); +// if (properties.getLength() > 0) { +// NodeList propertiesElems = properties.item(0).getChildNodes(); +// for (int i = 0; i < propertiesElems.getLength(); i++) { +// if (propertiesElems.item(i) instanceof Element) { +// Element property = (Element) propertiesElems.item(i); +// props.put(property.getNodeName(), property.getTextContent()); +// } +// } +// } +// +// // dependencies (direct and dependencyManagement) +// NodeList dependencies = doc.getElementsByTagName("dependency"); +// for (int i = 0; i < dependencies.getLength(); i++) { +// Element dependency = (Element) dependencies.item(i); +// String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent().trim(); +// String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent().trim(); +// String version = dependency.getElementsByTagName("version").item(0).getTextContent().trim(); +// if (version.startsWith("${")) { +// String versionKey = version.substring(0, version.length() - 1).substring(2); +// if (!props.containsKey(versionKey)) +// throw new SlcException("Cannot interpret version " + version); +// version = props.getProperty(versionKey); +// } +// NodeList scopes = dependency.getElementsByTagName("scope"); +// if (scopes.getLength() > 0 && scopes.item(0).getTextContent().equals("import")) { +// // recurse +// gatherPomDependencies(aetherTemplate, artifacts, +// new DefaultArtifact(groupId, artifactId, "pom", version)); +// } else { +// // TODO: deal with scope? +// // TODO: deal with type +// String type = "jar"; +// Artifact artifact = new DefaultArtifact(groupId, artifactId, type, version); +// artifacts.add(artifact); +// } +// } +// } catch (Exception e) { +// throw new SlcException("Cannot process " + pomArtifact, e); +// } +// } + + /** Prevent instantiation */ + private MavenConventionsUtils() { + } +} diff --git a/org.argeo.slc.repo/src/org/argeo/slc/repo/FreeLicense.java b/org.argeo.slc.repo/src/org/argeo/slc/repo/FreeLicense.java index 1b8366692..5cb290c8a 100644 --- a/org.argeo.slc.repo/src/org/argeo/slc/repo/FreeLicense.java +++ b/org.argeo.slc.repo/src/org/argeo/slc/repo/FreeLicense.java @@ -12,69 +12,60 @@ public abstract class FreeLicense implements License { final static String RESOURCES = "/org/argeo/slc/repo/license/"; /** GNU */ - public final static FreeLicense GPL_v3 = new FreeLicense( - "GNU General Public License, version 3.0", - "http://www.gnu.org/licenses/gpl-3.0.txt", - "http://www.gnu.org/licenses/", RESOURCES + "gpl-3.0.txt") { + public final static FreeLicense GPL_v3 = new FreeLicense("GPL-3.0-or-later", + "http://www.gnu.org/licenses/gpl-3.0.txt", null, RESOURCES + "gpl-3.0.txt") { }; - public final static FreeLicense GPL_v2 = new FreeLicense( - "GNU General Public License, version 2.0", - "http://www.gnu.org/licenses/gpl-2.0.txt", - "http://www.gnu.org/licenses/", RESOURCES + "gpl-2.0.txt") { + public final static FreeLicense GPL_v2 = new FreeLicense("GPL-2.0-or-later", + "http://www.gnu.org/licenses/gpl-2.0.txt", null, RESOURCES + "gpl-2.0.txt") { }; public final static FreeLicense GPL = GPL_v3; - public final static FreeLicense LGPL_v3 = new FreeLicense( - "GNU Lesser General Public License, version 3.0", - "http://www.gnu.org/licenses/lgpl-3.0.txt", - "http://www.gnu.org/licenses/", RESOURCES + "lgpl-3.0.txt") { + public final static FreeLicense LGPL_v3 = new FreeLicense("LGPL-3.0-or-later", + "http://www.gnu.org/licenses/lgpl-3.0.txt", null, RESOURCES + "lgpl-3.0.txt") { }; - public final static FreeLicense LGPL_v2 = new FreeLicense( - "GNU Lesser General Public License, version 2.1", - "http://www.gnu.org/licenses/lgpl-2.1.txt", - "http://www.gnu.org/licenses/", RESOURCES + "lgpl-2.1.txt") { + public final static FreeLicense LGPL_v2 = new FreeLicense("LGPL-2.0-or-later", + "http://www.gnu.org/licenses/lgpl-2.1.txt", null, RESOURCES + "lgpl-2.1.txt") { }; public final static FreeLicense LGPL = LGPL_v3; /** Apache */ - public final static FreeLicense APACHE_v2 = new FreeLicense( - "Apache License, Version 2.0", - "http://www.apache.org/licenses/LICENSE-2.0.txt", - "http://www.apache.org/licenses/", RESOURCES + "apache-2.0.txt") { + public final static FreeLicense APACHE_v2 = new FreeLicense("Apache-2.0", + "http://www.apache.org/licenses/LICENSE-2.0.txt", null, RESOURCES + "apache-2.0.txt") { }; public final static FreeLicense APACHE = APACHE_v2; /** Eclipse */ - public final static FreeLicense EPL_v1 = new FreeLicense( - "Eclipse Public License, Version 1.0", - "http://www.eclipse.org/legal/epl-v10.html", - "http://www.eclipse.org/legal/eplfaq.php", RESOURCES - + "epl-1.0.txt") { + public final static FreeLicense EPL_v1 = new FreeLicense("EPL-1.0", "http://www.eclipse.org/legal/epl-v10.html", + null, RESOURCES + "epl-1.0.txt") { + }; + public final static FreeLicense EPL_v2 = new FreeLicense("EPL-2.0", "http://www.eclipse.org/legal/epl-v20.html", + null, RESOURCES + "epl-1.0.txt") { }; public final static FreeLicense EPL = EPL_v1; /** Miscellaneous */ - public final static FreeLicense MIT = new FreeLicense("The MIT License", - "http://opensource.org/licenses/MIT", null, RESOURCES + "mit.txt") { + public final static FreeLicense MIT = new FreeLicense("MIT", "http://opensource.org/licenses/MIT", null, + RESOURCES + "mit.txt") { }; - public final static FreeLicense BSD_NEW = new FreeLicense( - "The BSD 3-Clause License", - "http://opensource.org/licenses/BSD-3-Clause", null, RESOURCES - + "bsd-3-clause.txt") { + public final static FreeLicense BSD_NEW = new FreeLicense("BSD-3-Clause", + "http://opensource.org/licenses/BSD-3-Clause", null, RESOURCES + "bsd-3-clause.txt") { }; public final static FreeLicense BSD = BSD_NEW; - public final static FreeLicense CDDL_v1 = new FreeLicense( - "Common Development and Distribution License", - "http://opensource.org/licenses/CDDL-1.0", null, RESOURCES - + "cddl-1.0.txt") { + public final static FreeLicense CDDL_v1 = new FreeLicense("CDDL-1.0", "http://opensource.org/licenses/CDDL-1.0", + null, RESOURCES + "cddl-1.0.txt") { }; public final static FreeLicense CDDL = CDDL_v1; + public final static FreeLicense MOZILLA_v2 = new FreeLicense("MPL-2.0", "https://opensource.org/licenses/MPL-2.0", + null, RESOURCES + "cddl-1.0.txt") { + }; + public final static FreeLicense MOZILLA = MOZILLA_v2; + /** Public domain corner case */ public final static License PUBLIC_DOMAIN = new License() { @@ -140,8 +131,7 @@ public abstract class FreeLicense implements License { String text = IOUtils.toString(in); return text; } catch (Exception e) { - throw new SlcException("Cannot retrieve license " + name + " from " - + url, e); + throw new SlcException("Cannot retrieve license " + name + " from " + url, e); } finally { IOUtils.closeQuietly(in); } @@ -161,6 +151,11 @@ public abstract class FreeLicense implements License { @Override public String toString() { - return name + " (" + uri + ")"; + StringBuilder sb = new StringBuilder(name != null ? name : uri); +// if (link != null) +// sb.append(';').append("link=").append(link); +// else if (uri != null && name != null) +// sb.append(';').append("link=").append(uri); + return sb.toString(); } } diff --git a/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/ArgeoOsgiDistributionImpl.java b/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/ArgeoOsgiDistributionImpl.java index 3d6adcd7b..dbfd576b4 100644 --- a/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/ArgeoOsgiDistributionImpl.java +++ b/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/ArgeoOsgiDistributionImpl.java @@ -1,5 +1,8 @@ package org.argeo.slc.repo.osgi; +import static org.argeo.slc.ManifestConstants.SLC_ORIGIN_M2; +import static org.argeo.slc.ManifestConstants.SLC_ORIGIN_URI; + import java.io.IOException; import java.io.Writer; import java.nio.file.Files; @@ -17,12 +20,14 @@ import java.util.TreeSet; import org.argeo.api.cms.CmsLog; import org.argeo.slc.CategoryNameVersion; +import org.argeo.slc.ManifestConstants; import org.argeo.slc.ModuleSet; import org.argeo.slc.NameVersion; import org.argeo.slc.build.Distribution; import org.argeo.slc.execution.ExecutionFlow; import org.argeo.slc.repo.ArgeoOsgiDistribution; import org.argeo.slc.repo.ArtifactDistribution; +import org.argeo.slc.repo.FreeLicense; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; import org.osgi.framework.Constants; @@ -42,7 +47,7 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A public void init() { if (log.isDebugEnabled()) log.debug(describe()); - migrateTov2(Paths.get(System.getProperty("user.home"), "dev/git/unstable/argeo-tp/argeo-tp")); + migrateTov2(Paths.get(System.getProperty("user.home"), "dev/git/unstable/argeo-tp/migration")); } public void destroy() { @@ -100,14 +105,14 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A else log.warn("No license for " + cnv); if (bw.getDoNotModify()) { - props.put("SLC-Source-Original", "true"); + props.put(ManifestConstants.SLC_ORIGIN_MANIFEST_NOT_MODIFIED.toString(), "true"); } // props.put("SLC-Category", cnv.getCategory()); if (cnv instanceof MavenWrapper) { MavenWrapper mw = (MavenWrapper) cnv; String sourceCoords = mw.getSourceCoords(); - props.put("SLC-Source-M2", sourceCoords); + props.put(SLC_ORIGIN_M2.toString(), sourceCoords); Artifact mavenCnv = new DefaultArtifact(sourceCoords); if (mavenCnv.getArtifactId().equals(cnv.getName())) props.remove(Constants.BUNDLE_SYMBOLICNAME); @@ -115,11 +120,11 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A props.remove(Constants.BUNDLE_VERSION); } else if (cnv instanceof UriWrapper) { UriWrapper mw = (UriWrapper) cnv; - props.put("SLC-Source-URI", mw.getEffectiveUri()); + props.put(SLC_ORIGIN_URI.toString(), mw.getEffectiveUri()); if (mw.getUri() == null && mw.getBaseUri() != null) { log.warn("Base URI for " + cnv); - props.put("SLC-Source-BaseURI", mw.getBaseUri()); - props.put("SLC-Source-VersionSeparator", mw.getVersionSeparator()); + props.put("SLC-Origin-BaseURI", mw.getBaseUri()); + props.put("SLC-Origin-VersionSeparator", mw.getVersionSeparator()); } } else { log.warn("Unidentified BND wrapper " + cnv); @@ -160,6 +165,62 @@ public class ArgeoOsgiDistributionImpl extends ArtifactDistribution implements A log.debug(" includes: " + aw.getIncludes()); log.debug(" excludes: " + aw.getExcludes()); log.debug(" beans : " + aw.getWrappers()); + + String uri = aw.getUri(); + String duName = null; + String category = null; + String oldCategory = null; + if (uri.startsWith("http://www.eclipse.org/downloads/rt/rap/3.10/e4/rap-e4")) { + duName = "eclipse-rap"; + category = "org.argeo.tp.eclipse.rap"; + oldCategory = "org.argeo.tp.rap.e4"; + } else if (uri.startsWith("http://www.eclipse.org/downloads/equinox/")) { + duName = "eclipse-equinox"; + category = "org.argeo.tp.eclipse.equinox"; + oldCategory = "org.argeo.tp.equinox"; + } else if (uri.startsWith("http://www.eclipse.org/downloads/eclipse/downloads/drops4")) { + duName = "eclipse-rcp"; + category = "org.argeo.tp.eclipse.rcp"; + oldCategory = "org.argeo.tp.rcp.e4"; + } + + if (duName != null) { + try { + Path duDir = baseDir.resolve(category).resolve(duName); + Files.createDirectories(duDir); + Path bndPath = duDir.resolve("common.bnd"); + Path includesPath = duDir.resolve("includes.properties"); + + Map props = new TreeMap<>(); + props.put(ManifestConstants.SLC_ORIGIN_URI.toString(), aw.getUri()); + props.put(ManifestConstants.SLC_ORIGIN_MANIFEST_NOT_MODIFIED.toString(), "true"); + props.put(Constants.BUNDLE_LICENSE, FreeLicense.EPL.toString()); + // write BND file + try (Writer bndWriter = Files.newBufferedWriter(bndPath); + Writer includesWriter = Files.newBufferedWriter(includesPath);) { + // writer.write("# " + cnv + "\n"); + props: for (String key : props.keySet()) { + String value = props.get(key); + if (Constants.EXPORT_PACKAGE.equals(key) && "*".equals(value.trim())) + continue props; + + bndWriter.write(key + ": " + value + '\n'); + } + + for (String key : aw.getIncludes().keySet()) { + String value = aw.getIncludes().get(key); + if (value.equals(oldCategory)) + value = category; + includesWriter.write(key + "=" + value + '\n'); + } + if (log.isTraceEnabled()) + log.trace("Wrote " + bndPath); + } + } catch (IOException e) { + log.error("Could not process " + aw, e); + } + + } } } diff --git a/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/BndWrapper.java b/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/BndWrapper.java index efd1591cd..57d7a81d2 100644 --- a/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/BndWrapper.java +++ b/org.argeo.slc.repo/src/org/argeo/slc/repo/osgi/BndWrapper.java @@ -86,12 +86,7 @@ public class BndWrapper implements Constants, CategoryNameVersion, Distribution // License if (license != null) { - StringBuilder sb = new StringBuilder(license.getUri()); - if (license.getName() != null) - sb.append(';').append("description=").append(license.getName()); - if (license.getLink() != null) - sb.append(';').append("link=").append(license.getLink()); - properties.setProperty(BUNDLE_LICENSE, sb.toString()); + properties.setProperty(BUNDLE_LICENSE, license.toString()); // TODO add LICENSE.TXT } else { log.warn("No license set for " + toString()); diff --git a/sdk/includes.mk b/sdk/includes.mk new file mode 100644 index 000000000..e69de29bb