geertjanw closed pull request #494: Adding LICENSE/NOTICE/DISCLAIMER to NBMs, packing OSGi jars into NBMs… URL: https://github.com/apache/incubator-netbeans/pull/494
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/apisupport.harness/build.xml b/apisupport.harness/build.xml index 45ccec305..b305b9a8b 100644 --- a/apisupport.harness/build.xml +++ b/apisupport.harness/build.xml @@ -24,14 +24,14 @@ <import file="../nbbuild/templates/projectized.xml"/> <target name="nbantext" depends="build-init"> - <jar jarfile="${cluster}/tasks.jar" compress="${build.package.compress}" index="${build.package.index}"> + <nb-ext-jar jarfile="${cluster}/tasks.jar" compress="${build.package.compress}" index="${build.package.index}"> <manifest> <attribute name="NetBeans-Own-Library" value="true"/> </manifest> <!-- XXX would be more maintainable to use depfind.sf.net / genjar.sf.net / sadun-util.sf.net/pack.html --> <zipfileset src="${nbantext.jar}" includes="${bundled.tasks}"/> <zipfileset file="taskdefs.properties" fullpath="org/netbeans/nbbuild/taskdefs.properties"/> - </jar> + </nb-ext-jar> </target> <target name="compile-jnlp-launcher" depends="init,compile"> diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java b/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java index ad0ae3bac..f8524e387 100644 --- a/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java +++ b/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java @@ -39,6 +39,7 @@ import java.util.Date; import java.util.Enumeration; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -46,6 +47,7 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; +import java.util.function.Supplier; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; import java.util.jar.JarEntry; @@ -301,12 +303,13 @@ public void setAlias(String s) { private boolean isStandardInclude = true; private ArrayList<ExternalPackage> externalPackages = null; private ArrayList<String> locales = null; - private ArrayList<Attributes> moduleAttributes = null; private Attributes englishAttr = null; private Path updaterJar; private FileSet executablesSet; + private ZipFileSet extraNBMFiles; private boolean usePack200; private String pack200excludes; + private boolean alwaysCreateNBM; /** Try to find and create localized info.xml files */ public void setLocales(String s) { @@ -340,11 +343,19 @@ public void setPack200Excludes(String pack200excludes) { this.pack200excludes = pack200excludes; } + public void setAlwaysCreateNBM(boolean alwaysCreateNBM) { + this.alwaysCreateNBM = alwaysCreateNBM; + } + /** List of executable files in NBM concatinated by ${line.separator}. */ public FileSet createExecutables() { return (executablesSet = new FileSet()); } + public ZipFileSet createExtraNBMFiles() { + return (extraNBMFiles = new ZipFileSet()); + } + /** Module manifest needed for versioning. * @deprecated Use {@link #setModule} instead. */ @@ -496,6 +507,8 @@ private Attributes getModuleAttributesForLocale(String locale) throws BuildExcep try { try (JarFile mjar = new JarFile(mfile)) { if (mjar.getManifest().getMainAttributes().getValue("Bundle-SymbolicName") != null) { + englishAttr = new Attributes(); + englishAttr.putValue("OpenIDE-Module", JarWithModuleAttributes.extractCodeName(mjar.getManifest().getMainAttributes())); // #181025: treat bundles specially. return null; } @@ -581,25 +594,30 @@ public void execute () throws BuildException { overrideLicenseIfNeeded() ; - moduleAttributes = new ArrayList<> (); + Map<String, Supplier<Document>> moduleAttributes = new LinkedHashMap<>(); File module = new File( productDir, moduleName ); Attributes attr = getModuleAttributesForLocale(""); if (attr == null) { - // #181025: OSGi bundle, copy unmodified. - Copy copy = new Copy(); - copy.setProject(getProject()); - copy.setOwningTarget(getOwningTarget()); - copy.setFile(module); - copy.setTofile(new File(nbm.getAbsolutePath().replaceFirst("[.]nbm$", ".jar"))); - copy.execute(); - // XXX possibly sign it - // XXX could try to run pack200, though not if it was signed - return; + if (!alwaysCreateNBM) { + // #181025: OSGi bundle, copy unmodified. + Copy copy = new Copy(); + copy.setProject(getProject()); + copy.setOwningTarget(getOwningTarget()); + copy.setFile(module); + copy.setTofile(new File(nbm.getAbsolutePath().replaceFirst("[.]nbm$", ".jar"))); + copy.execute(); + // XXX possibly sign it + // XXX could try to run pack200, though not if it was signed + return; + } else { + moduleAttributes.put("", () -> createFakeOSGiInfo(module)); + } + } else { + moduleAttributes.put("", () -> createInfoXml(attr)); } - moduleAttributes.add(attr); for (String locale : locales) { Attributes a = getModuleAttributesForLocale(locale); - if (a != null) moduleAttributes.add(a); + if (a != null) moduleAttributes.put(locale, () -> createInfoXml(a)); } // Will create a file Info/info.xml to be stored in tmp @@ -615,10 +633,10 @@ public void execute () throws BuildException { } ArrayList<ZipFileSet> infoXMLFileSets = new ArrayList<>(); - for (Attributes modAttr : moduleAttributes) { - Document infoXmlContents = createInfoXml(modAttr); + for (Map.Entry<String, Supplier<Document>> modAttr : moduleAttributes.entrySet()) { + Document infoXmlContents = modAttr.getValue().get(); File infofile; - String loc = modAttr.getValue("locale"); + String loc = modAttr.getKey(); if (loc == null) throw new BuildException("Found attributes without assigned locale code", getLocation()); try { @@ -643,7 +661,6 @@ public void execute () throws BuildException { String codename = englishAttr.getValue("OpenIDE-Module"); if (codename == null) new BuildException( "Can't get codenamebase" ); - UpdateTracking tracking = new UpdateTracking(productDir.getAbsolutePath()); Set<String> _files = new LinkedHashSet<>(Arrays.asList(tracking.getListOfNBM(codename))); List<String> __files = new ArrayList<>(_files); @@ -731,6 +748,10 @@ public void execute () throws BuildException { jar.addFileset(zfs); } + if (extraNBMFiles != null) { + jar.addZipfileset(extraNBMFiles); + } + if (main != null) { // Add the main dir main.setPrefix("main"); // use main prefix jar.addZipfileset(main); @@ -941,14 +962,7 @@ private Document createInfoXml(final Attributes attr) throws BuildException { } else { throw new BuildException("NBM distribution URL is not set", getLocation()); } - // Here we only write a name for the license. - if (license != null) { - String name = license.getName(); - if (name == null) { - throw new BuildException("Every license must have a name or file attribute", getLocation()); - } - module.setAttribute("license", name); - } + maybeAddLicenseName(module); module.setAttribute("downloadsize", "0"); if (needsrestart != null) { module.setAttribute("needsrestart", needsrestart); @@ -1008,13 +1022,7 @@ private Document createInfoXml(final Attributes attr) throws BuildException { } } module.appendChild(el); - // Maybe write out license text. - if (license != null) { - el = doc.createElement("license"); - el.setAttribute("name", license.getName()); - el.appendChild(license.getTextNode(doc)); - module.appendChild(el); - } + maybeAddLicense(module); if (updaterJar != null && updaterJar.size() > 0) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -1029,6 +1037,53 @@ private Document createInfoXml(final Attributes attr) throws BuildException { return doc; } + private Document createFakeOSGiInfo(File osgiJar) { + DOMImplementation domimpl; + try { + domimpl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation(); + } catch (ParserConfigurationException x) { + throw new BuildException(x, getLocation()); + } + + log("Creating fake info.xml for OSGi bundle", Project.MSG_VERBOSE); + + String pub = "-//NetBeans//DTD Autoupdate Module Info 2.5//EN"; + String sys = "http://www.netbeans.org/dtds/autoupdate-info-2_5.dtd"; + Document doc = domimpl.createDocument(null, "module", domimpl.createDocumentType("module", pub, sys)); + + try (JarFile jf = new JarFile(osgiJar)) { + MakeUpdateDesc.fakeOSGiInfoXml(jf, osgiJar, doc); + maybeAddLicenseName(doc.getDocumentElement()); + maybeAddLicense(doc.getDocumentElement()); + } catch (IOException x) { + throw new BuildException(x, getLocation()); + } + + return doc; + } + + private void maybeAddLicenseName(Element module) { + // Here we only write a name for the license. + if (license != null) { + String name = license.getName(); + if (name == null) { + throw new BuildException("Every license must have a name or file attribute", getLocation()); + } + module.setAttribute("license", name); + } + } + + private void maybeAddLicense(Element module) { + // Maybe write out license text. + if (license != null) { + Document doc = module.getOwnerDocument(); + Element el = doc.createElement("license"); + el.setAttribute("name", license.getName()); + el.appendChild(license.getTextNode(doc)); + module.appendChild(el); + } + } + static void validateAgainstAUDTDs(InputSource input, final Path updaterJar, final Task task) throws IOException, SAXException { XMLUtil.parse(input, true, false, XMLUtil.rethrowHandler(), new EntityResolver() { ClassLoader loader = new AntClassLoader(task.getProject(), updaterJar); diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java b/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java index 8ae5d48f7..825ffba2f 100644 --- a/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java +++ b/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java @@ -35,6 +35,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.nio.file.Files; import java.text.Collator; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -111,6 +112,13 @@ public void setDesc(File d) { desc = d; } + private File descLicense; + + /** Description file license to use. */ + public void setDescLicense(File d) { + descLicense = d; + } + /** Module group to create **/ public Group createGroup () { Group g = new Group (); @@ -275,6 +283,9 @@ private static String xmlEscape(String s) { PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF-8")); //NOI18N pw.println ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //NOI18N pw.println (); + if (descLicense != null) { + pw.println(new String(Files.readAllBytes(descLicense.toPath()), "UTF-8")); + } DateFormat format = new SimpleDateFormat("ss/mm/HH/dd/MM/yyyy"); //NOI18N format.setTimeZone(TimeZone.getTimeZone("GMT")); //NOI18N String date = format.format(new Date()); @@ -664,7 +675,11 @@ private long externalSize(InputStream is) throws IOException { * @return a {@code <module ...><manifest .../></module>} valid according to * <a href="http://www.netbeans.org/dtds/autoupdate-info-2_5.dtd">DTD</a> */ - private Element fakeOSGiInfoXml(JarFile jar, File whereFrom) throws IOException { + private static Element fakeOSGiInfoXml(JarFile jar, File whereFrom) throws IOException { + return fakeOSGiInfoXml(jar, whereFrom, XMLUtil.createDocument("module")); + } + //TODO: javadoc + public static Element fakeOSGiInfoXml(JarFile jar, File whereFrom, Document doc) throws IOException { Attributes attr = jar.getManifest().getMainAttributes(); Properties localized = new Properties(); String bundleLocalization = attr.getValue("Bundle-Localization"); @@ -673,10 +688,12 @@ private Element fakeOSGiInfoXml(JarFile jar, File whereFrom) throws IOException localized.load(is); } } - return fakeOSGiInfoXml(attr, localized, whereFrom); + return fakeOSGiInfoXml(attr, localized, whereFrom, doc); + } + static Element fakeOSGiInfoXml(Attributes attr, Properties localized, File whereFrom) { //tests + return fakeOSGiInfoXml(attr, localized, whereFrom, XMLUtil.createDocument("module")); } - static Element fakeOSGiInfoXml(Attributes attr, Properties localized, File whereFrom) { - Document doc = XMLUtil.createDocument("module"); + private static Element fakeOSGiInfoXml(Attributes attr, Properties localized, File whereFrom, Document doc) { Element module = doc.getDocumentElement(); String cnb = JarWithModuleAttributes.extractCodeName(attr); module.setAttribute("codenamebase", cnb); diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/extlibs/CreateLicenseSummary.java b/nbbuild/antsrc/org/netbeans/nbbuild/extlibs/CreateLicenseSummary.java index 945a32f7c..69089c9bf 100644 --- a/nbbuild/antsrc/org/netbeans/nbbuild/extlibs/CreateLicenseSummary.java +++ b/nbbuild/antsrc/org/netbeans/nbbuild/extlibs/CreateLicenseSummary.java @@ -50,6 +50,8 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.selectors.SelectorUtils; import org.netbeans.nbbuild.JUnitReportWriter; import org.netbeans.nbbuild.extlibs.licenseinfo.Fileset; @@ -122,6 +124,11 @@ public void setBinary(boolean binary) { this.binary = binary; } + private FileSet moduleFiles; + public FileSet createModuleFiles() { + return (moduleFiles = new FileSet()); + } + private Map<String, String> pseudoTests; public @Override @@ -289,6 +296,17 @@ private void evaluateBinaries(final PrintWriter licenseWriter, final PrintWriter List<String> ignoredPatterns = VerifyLibsAndLicenses.loadPatterns("ignored-binary-overlaps"); if (build != null) findBinaries(build, binaries2LicenseHeaders, crc2License, new HashMap<>(), "", testBinariesAreUnique, ignoredPatterns); + if (moduleFiles != null) { + for (Resource r : moduleFiles) { + try (InputStream is = r.getInputStream()) { + long crc = computeCRC32(is); + Map<String, String> headers = crc2License.get(crc); + if (headers != null) { + binaries2LicenseHeaders.put(r.getName(), headers); + } + } + } + } if (binaries2LicenseHeaders.isEmpty()) return ; pseudoTests.put("testBinariesAreUnique", testBinariesAreUnique.length() > 0 ? "Some binaries are duplicated (edit nbbuild/antsrc/org/netbeans/nbbuild/extlibs/ignored-binary-overlaps as needed)" + testBinariesAreUnique : null); diff --git a/nbbuild/build.xml b/nbbuild/build.xml index a1c5a3633..07fa60f4e 100644 --- a/nbbuild/build.xml +++ b/nbbuild/build.xml @@ -211,6 +211,7 @@ <subant-junit target="nbm" failonerror="${nbms.fail.on.error}" report="${nb.build.dir}/build-nbms.xml" inheritall="false"> <buildpath path="${modules.sorted}"/> <property name="base.nbm.target.dir" value="${base.nbm.target.dir}"/> + <property name="nbm.always.create" value="true" /> </subant-junit> </target> @@ -1894,9 +1895,10 @@ It is possible to use -Ddebug.port=3234 -Ddebug.pause=y to start the system in d <property name="catalog.notification.url" value=""/> <property name="catalog.content.description" value=""/> <property name="catalog.content.description.url" value=""/> + <property name="catalog.license.header" value="${nb_all}/nbbuild/catalog-license-header.txt"/> <!-- <genau config="ausrc/modules.setup" nbmLocation="${nbms.location}" catalog="${catalog.file}" catalogDeploymentLocation="${catalog.base.url}"/>--> - <makeupdatedesc desc="${catalog.file}" distbase="${catalog.base.url}" automaticgrouping="true" uselicenseurl="${use.license.url.in.catalog}" notificationmessage="${catalog.notification.message}" notificationurl="${catalog.notification.url}" contentdescription="${catalog.content.description}" contentdescriptionurl="${catalog.content.description.url}"> + <makeupdatedesc desc="${catalog.file}" distbase="${catalog.base.url}" automaticgrouping="true" uselicenseurl="${use.license.url.in.catalog}" notificationmessage="${catalog.notification.message}" notificationurl="${catalog.notification.url}" contentdescription="${catalog.content.description}" contentdescriptionurl="${catalog.content.description.url}" desclicense="${catalog.license.header}"> <fileset dir="${nbms.location}"> <include name="**/*.nbm"/> <include name="**/*.jar"/> diff --git a/nbbuild/catalog-license-header.txt b/nbbuild/catalog-license-header.txt new file mode 100644 index 000000000..a0eb9fbf8 --- /dev/null +++ b/nbbuild/catalog-license-header.txt @@ -0,0 +1,20 @@ +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> diff --git a/nbbuild/templates/common.xml b/nbbuild/templates/common.xml index 252dc7f5e..afe5635ea 100644 --- a/nbbuild/templates/common.xml +++ b/nbbuild/templates/common.xml @@ -427,7 +427,11 @@ <fileset dir="${cluster}" id="module.executable.files" includes="${nbm.executable.files}"/> </target> - <target name="nbm" depends="init,netbeans,-nbm-prompt-for-storepass,-init-executables" description="Build NBM archive."> + <target name="-init-extra.nbm.files" unless="extra.nbm.files.provided"> <!-- fallback --> + <zipfileset dir="${cluster}" id="extra.nbm.files" includes="[NOTHING]"/> + </target> + + <target name="nbm" depends="init,netbeans,-nbm-prompt-for-storepass,-init-executables,-init-extra.nbm.files" description="Build NBM archive."> <mkdir dir="${build.dir}"/> <property name="nbm.target.cluster" value=""/> <!-- fallback --> <property name="license.file.override" value="${license.file}"/> @@ -444,6 +448,7 @@ preferredupdate="${nbm.is.preferredupdate}" usepack200="${use.pack200}" pack200excludes="${pack200.excludes}" + alwayscreatenbm="${nbm.always.create}" targetcluster="${nbm.target.cluster}" releasedate="${nbm.release.date}" moduleauthor="${nbm.module.author}" @@ -458,6 +463,7 @@ </pathfileset> </updaterjar> <executables refid="module.executable.files"/> + <extranbmfiles refid="extra.nbm.files"/> </makenbm> </target> diff --git a/nbbuild/templates/projectized.xml b/nbbuild/templates/projectized.xml index b112e65cf..6a1727994 100644 --- a/nbbuild/templates/projectized.xml +++ b/nbbuild/templates/projectized.xml @@ -409,11 +409,42 @@ If you are sure you want to build with JDK 9+ anyway, use: -Dpermit.jdk9.builds= </target> <target name="-create-license.file" depends="init"> - <mkdir dir="${build.dir}"/> - <property name="license.file.override" location="${build.dir}/license"/> + <mkdir dir="${build.dir}/nbm-extras/META-INF"/> + <taskdef name="createlicensesummary" classname="org.netbeans.nbbuild.extlibs.CreateLicenseSummary" classpath="${nbantext.jar}"/> + <property name="module.name.temp" location="." /> + <basename property="module.name" file="${module.name.temp}" /> + <createlicensesummary licenseStub="${nb_all}/LICENSE" + noticeStub="${nb_all}/nbbuild/notice-stub.txt" + nball="${nb_all}" + license="${build.dir}/nbm-extras/META-INF/LICENSE" + notice="${build.dir}/notice-temp" + binary="true" + modules="${module.name}" + > + <moduleFiles dir="${cluster}"> + <patternset refid="module.files"/> + </moduleFiles> + </createlicensesummary> + + <concat destfile="${build.dir}/nbm-extras/META-INF/NOTICE"> + <fileset file="${build.dir}/notice-temp" /> + <fileset dir="." + includes="notice.txt" /> + <filterchain> + <tokenfilter> + <filetokenizer /> + <replaceregex pattern="(\r?\n)(\r?\n)+" + replace="\1\1" + flags="g" /> + </tokenfilter> + </filterchain> + </concat> + + <copy file="${nb_all}/DISCLAIMER" todir="${build.dir}/nbm-extras/META-INF/" /> + <property name="license.file.override" location="${build.dir}/nbm-extras/META-INF/LICENSE"/> <property name="extra.license.files" value=""/> - <taskdef name="releasefileslicense" classname="org.netbeans.nbbuild.extlibs.ReleaseFilesLicense" classpath="${nbantext.jar}"/> - <releasefileslicense license="${license.file.override}" standardlicense="${nb_all}/nbbuild/standard-nbm-license.txt" extralicensefiles="${extra.license.files}"/> + <zipfileset id="extra.nbm.files" dir="${build.dir}/nbm-extras/" /> + <property name="extra.nbm.files.provided" value=""/> </target> <target name="nbm" depends="-create-dest-dir-nbm,-create-license.file,projectized-common.nbm"/> ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org For additional commands, e-mail: notifications-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists