You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by GitBox <gi...@apache.org> on 2020/01/04 22:12:36 UTC

[GitHub] [netbeans] jlahoda opened a new pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

jlahoda opened a new pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845
 
 
   We have a sever for the language server protocol that supports Java editing, and there is also a VisualStudio Code extension wrapping the server so that it can be installed into the VS Code. This patch tries to add LICENSE/NOTICE for the binary of the extension, so that is a (hopefully) a valid convenience binary. I'd like to do a (preview) release of the extension sometime soon.
   
   Some enhancements are done to the CreateLicenseSummary task, so that the files can be generated conveniently. The "Prepare Bundles" tool (that packs npm packages and autodetects licenses, etc.) from https://github.com/apache/netbeans/pull/1692 is also enhanced and generalized, and is used to generate the LICENSE/NOTICE entries for the included npm packages.
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100600
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
 
 Review comment:
   This seems to be problematic. One sample I found from a quick look at the generated NOTICE file was this:
   
   ```
   /*! *****************************************************************************
   Copyright (c) Microsoft Corporation. All rights reserved. 
   Licensed 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  
    
   THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
   WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
   MERCHANTABLITY OR NON-INFRINGEMENT. 
    
   See the Apache Version 2.0 License for specific language governing permissions
   and limitations under the License.
   ***************************************************************************** */
   ```
   
   The author did not understand the purpose of the NOTICE file and if we'd integrate this file by hand, I'd request it to be completely removed, as nothing of the text has a place in the NOTICE file.
   
   I admit though, that it is difficult to detect and override. Maybe notices should only done by hand?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] jlahoda commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
jlahoda commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363119403
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
 
 Review comment:
   I thought this should be there for the "Copyright (c) Microsoft Corporation. All rights reserved." line. But I could either drop this (if not needed at all), or use a hardcoded set of notices if needed (e.g. with just the single line or so.)

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363099402
 
 

 ##########
 File path: java/java.lsp.server/build.xml
 ##########
 @@ -51,4 +51,65 @@
     <target name="clean" depends="projectized.clean">
         <delete dir="${lsp.build.dir}" />
     </target>
+    <target name="build-vscode-ext" depends="build-lsp-server" description="Build the Visual Studio Code extension.">
+        <exec executable="npm" failonerror="true" dir="vscode">
+            <arg value="install" />
+        </exec>
+
+        <exec executable="npm" failonerror="true" dir="vscode">
+            <arg value="run" />
+            <arg value="compile" />
+        </exec>
+
+        <delete dir="${build.dir}/vscode" />
+        <exec executable="cp" failonerror="true">
+            <arg value="-r" />
+            <arg value="vscode/" />
+            <arg value="${build.dir}/" />
+        </exec>
+
+        <delete dir="${build.dir}/bundles" />
+        <mkdir dir="${build.dir}/bundles/package" />
+        <copy file="vscode/package.json" todir="${build.dir}/bundles/package" />
+
+        <exec executable="mvn" failonerror="true" dir="${nb_all}/nbbuild/misc/prepare-bundles">
+            <arg value="install" />
 
 Review comment:
   Shouldn't package be enough? `exec:java` should use the build package from target, not the one from the local repository.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100759
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
+
+                if (Files.isReadable(noticestxt)) {
+                    project2Notice.put(module.getFileName().toString(), readString(noticestxt));
+                }
+
+                List<String> tokens = licenseTextToTokens(licenseText);
+                String licenseTextFin = licenseText;
+
+                tokens2Projects.computeIfAbsent(tokens, t -> new LicenseUses(licenseKey, licenseTextFin)).projects.add(module.getFileName().toString());
+                project2License.put(module.getFileName().toString(), new LicenseDescription(name, version, description, homepage, licenseKey, licenseText));
+
+                Path bundle = bundlesDir.resolve(module.getFileName() + "-" + version + ".zip");
+                try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(bundle));
+                     Stream<Path> files = Files.walk(module, FileVisitOption.FOLLOW_LINKS)) {
+                    files.forEach(p -> {
+                        if (p == module) return ;
+                        try {
+                            String relative = module.getParent().relativize(p).toString();
+                            boolean isDir = Files.isDirectory(p);
+                            ZipEntry ze = new ZipEntry(relative + (isDir ? "/" : ""));
+                            out.putNextEntry(ze);
+                            if (!isDir) {
+                                if (relative.equals("package.json")) {
+                                    out.write(packageJsonText.replace(targetDir.toString(), "").getBytes());
 
 Review comment:
   This should be `getBytes("UTF-8")`.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363099822
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
 
 Review comment:
   Just a thought: Would it be easier to use a (list of) case insenstive regular expression(s) to match this? I would bet there are "LICENSE-ALv2.txt", "LICENSE-EPL.txt" and so on out there and the special case for MIT will only catch the most probable one.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100834
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
+
+                if (Files.isReadable(noticestxt)) {
+                    project2Notice.put(module.getFileName().toString(), readString(noticestxt));
+                }
+
+                List<String> tokens = licenseTextToTokens(licenseText);
+                String licenseTextFin = licenseText;
+
+                tokens2Projects.computeIfAbsent(tokens, t -> new LicenseUses(licenseKey, licenseTextFin)).projects.add(module.getFileName().toString());
+                project2License.put(module.getFileName().toString(), new LicenseDescription(name, version, description, homepage, licenseKey, licenseText));
+
+                Path bundle = bundlesDir.resolve(module.getFileName() + "-" + version + ".zip");
+                try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(bundle));
+                     Stream<Path> files = Files.walk(module, FileVisitOption.FOLLOW_LINKS)) {
+                    files.forEach(p -> {
+                        if (p == module) return ;
+                        try {
+                            String relative = module.getParent().relativize(p).toString();
+                            boolean isDir = Files.isDirectory(p);
+                            ZipEntry ze = new ZipEntry(relative + (isDir ? "/" : ""));
+                            out.putNextEntry(ze);
+                            if (!isDir) {
+                                if (relative.equals("package.json")) {
+                                    out.write(packageJsonText.replace(targetDir.toString(), "").getBytes());
+                                } else {
+                                    Files.copy(p, out);
+                                }
+                            }
+                        } catch (IOException ex) {
+                            throw new UncheckedIOException(ex);
+                        }
+                    });
+                }
+                MessageDigest md = MessageDigest.getInstance("SHA1");
+                md.update(Files.readAllBytes(bundle));
+                StringBuilder hash = new StringBuilder();
+                for (byte b : md.digest()) {
+                    hash.append(String.format("%02X", b));
+                }
+                Path external = externalDir.resolve(hash + "-" + bundle.getFileName());
+                Files.copy(bundle, external);
+                binariesList.write(hash + " " + bundle.getFileName().toString() + nl);
+            }
+        }
+        
+        Map<String, String> project2LicenseKey = new HashMap<>();
+
+        Map<List<String>, String> knownLicenseTokens2LicenseKey = new HashMap<>();
+        Path nb_all = Paths.get(args[1]);
+
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(nb_all.resolve("nbbuild").resolve("licenses"))) {
+            for (Path license : ds) {
+                knownLicenseTokens2LicenseKey.put(licenseTextToTokens(readString(license)), license.getFileName().toString());
+            }
+        }
+
+        for (Entry<List<String>, LicenseUses> e : tokens2Projects.entrySet()) {
+            LicenseUses use = e.getValue();
+            String licenseName = knownLicenseTokens2LicenseKey.get(e.getKey());
+            if (licenseName == null) {
+                licenseName = use.key + "-" + use.projects.stream().collect(Collectors.joining("-"));
+                try (OutputStream out = Files.newOutputStream(licensesDir.resolve(licenseName))) {
+                    out.write(use.licenseText.getBytes("UTF-8"));
+                }
+            }
+            for (String prj : use.projects) {
+                project2LicenseKey.put(prj, licenseName);
+            }
+        }
+        for (Entry<String, LicenseDescription> e : project2License.entrySet()) {
+            LicenseDescription licenseDesc = e.getValue();
+            Path projectLicenseFile = bundlesDir.resolve(e.getKey() + "-" + licenseDesc.version + "-license.txt");
+            try (Writer w = new OutputStreamWriter(Files.newOutputStream(projectLicenseFile), "UTF-8")) {
+                w.write("Name: " + licenseDesc.name + nl);
+                w.write("Description: " + licenseDesc.description + nl);
+                w.write("Version: " + licenseDesc.version + nl);
+                w.write("License: " + project2LicenseKey.get(e.getKey()) + nl);
+                w.write("Origin: " + licenseDesc.homepage + nl);
+                w.write(nl);
+                w.write(licenseDesc.licenseText);
+            }
+            String notice = project2Notice.get(e.getKey());
+            if (notice != null) {
+                Path projectNoticeFile = bundlesDir.resolve(e.getKey() + "-" + licenseDesc.version + "-notice.txt");
+                try (Writer w = new OutputStreamWriter(Files.newOutputStream(projectNoticeFile), "UTF-8")) {
+                    w.write(notice);
+                }
+            }
+        }
+    }
+
+    private static String readString(Path p) throws IOException {
+        return new String(Files.readAllBytes(p), StandardCharsets.UTF_8);
+    }
+
+    private static List<String> licenseTextToTokens(String licenseText) {
+        return Arrays.asList(licenseText.replaceAll("[ \n\r\t]+", " ").split(" "));
+    }
+    private static class LicenseDescription {
+        private final String name;
+        private final String version;
+        private final String description;
+        private final String homepage;
+        private final String licenseKey;
+        private final String licenseText;
+        private final List<String> bundles = new ArrayList<>();
+
+        public LicenseDescription(String name, String version, String description, String homepage, String licenseKey, String licenseText) {
+            this.name = name;
+            this.version = version;
+            this.description = description;
+            this.homepage = homepage;
+            this.licenseKey = licenseKey;
+            this.licenseText = licenseText;
+        }
+
+        @Override
+        public String toString() {
+            return "LicenseDescription{" + "version=" + version + ", description=" + description + ", homepage=" + homepage + ", licenseKey=" + licenseKey + ", licenseText=" + licenseText + ", bundles=" + bundles + '}';
+        }
+
+    }
+    private static class LicenseUses {
+        private final String key;
+        private final String licenseText;
+        private final List<String> projects = new ArrayList<>();
 
 Review comment:
   Accessing a private field from outside the class looks strange to me. Would you consider moving the declarations here to `public final`?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] junichi11 commented on issue #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
junichi11 commented on issue #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#issuecomment-574950390
 
 
   @jlahoda It seems that Travis CI failed with the master branch after this was merged. Could you please take a look at it? 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] jlahoda commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
jlahoda commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363119526
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
 
 Review comment:
   Yes, the more libraries we handle, the more difficult this gets - but still hopefully easier than doing all this by hand. (Esp. the VS Code extensions uses a lot of libraries - much more than I'd expect.)

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100859
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
+
+                if (Files.isReadable(noticestxt)) {
+                    project2Notice.put(module.getFileName().toString(), readString(noticestxt));
+                }
+
+                List<String> tokens = licenseTextToTokens(licenseText);
+                String licenseTextFin = licenseText;
+
+                tokens2Projects.computeIfAbsent(tokens, t -> new LicenseUses(licenseKey, licenseTextFin)).projects.add(module.getFileName().toString());
+                project2License.put(module.getFileName().toString(), new LicenseDescription(name, version, description, homepage, licenseKey, licenseText));
+
+                Path bundle = bundlesDir.resolve(module.getFileName() + "-" + version + ".zip");
+                try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(bundle));
+                     Stream<Path> files = Files.walk(module, FileVisitOption.FOLLOW_LINKS)) {
+                    files.forEach(p -> {
+                        if (p == module) return ;
+                        try {
+                            String relative = module.getParent().relativize(p).toString();
+                            boolean isDir = Files.isDirectory(p);
+                            ZipEntry ze = new ZipEntry(relative + (isDir ? "/" : ""));
+                            out.putNextEntry(ze);
+                            if (!isDir) {
+                                if (relative.equals("package.json")) {
+                                    out.write(packageJsonText.replace(targetDir.toString(), "").getBytes());
+                                } else {
+                                    Files.copy(p, out);
+                                }
+                            }
+                        } catch (IOException ex) {
+                            throw new UncheckedIOException(ex);
+                        }
+                    });
+                }
+                MessageDigest md = MessageDigest.getInstance("SHA1");
+                md.update(Files.readAllBytes(bundle));
+                StringBuilder hash = new StringBuilder();
+                for (byte b : md.digest()) {
+                    hash.append(String.format("%02X", b));
+                }
+                Path external = externalDir.resolve(hash + "-" + bundle.getFileName());
+                Files.copy(bundle, external);
+                binariesList.write(hash + " " + bundle.getFileName().toString() + nl);
+            }
+        }
+        
+        Map<String, String> project2LicenseKey = new HashMap<>();
+
+        Map<List<String>, String> knownLicenseTokens2LicenseKey = new HashMap<>();
+        Path nb_all = Paths.get(args[1]);
+
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(nb_all.resolve("nbbuild").resolve("licenses"))) {
+            for (Path license : ds) {
+                knownLicenseTokens2LicenseKey.put(licenseTextToTokens(readString(license)), license.getFileName().toString());
+            }
+        }
+
+        for (Entry<List<String>, LicenseUses> e : tokens2Projects.entrySet()) {
+            LicenseUses use = e.getValue();
+            String licenseName = knownLicenseTokens2LicenseKey.get(e.getKey());
+            if (licenseName == null) {
+                licenseName = use.key + "-" + use.projects.stream().collect(Collectors.joining("-"));
+                try (OutputStream out = Files.newOutputStream(licensesDir.resolve(licenseName))) {
+                    out.write(use.licenseText.getBytes("UTF-8"));
+                }
+            }
+            for (String prj : use.projects) {
+                project2LicenseKey.put(prj, licenseName);
+            }
+        }
+        for (Entry<String, LicenseDescription> e : project2License.entrySet()) {
+            LicenseDescription licenseDesc = e.getValue();
+            Path projectLicenseFile = bundlesDir.resolve(e.getKey() + "-" + licenseDesc.version + "-license.txt");
+            try (Writer w = new OutputStreamWriter(Files.newOutputStream(projectLicenseFile), "UTF-8")) {
+                w.write("Name: " + licenseDesc.name + nl);
+                w.write("Description: " + licenseDesc.description + nl);
+                w.write("Version: " + licenseDesc.version + nl);
+                w.write("License: " + project2LicenseKey.get(e.getKey()) + nl);
+                w.write("Origin: " + licenseDesc.homepage + nl);
+                w.write(nl);
+                w.write(licenseDesc.licenseText);
+            }
+            String notice = project2Notice.get(e.getKey());
+            if (notice != null) {
+                Path projectNoticeFile = bundlesDir.resolve(e.getKey() + "-" + licenseDesc.version + "-notice.txt");
+                try (Writer w = new OutputStreamWriter(Files.newOutputStream(projectNoticeFile), "UTF-8")) {
+                    w.write(notice);
+                }
+            }
+        }
+    }
+
+    private static String readString(Path p) throws IOException {
+        return new String(Files.readAllBytes(p), StandardCharsets.UTF_8);
+    }
+
+    private static List<String> licenseTextToTokens(String licenseText) {
+        return Arrays.asList(licenseText.replaceAll("[ \n\r\t]+", " ").split(" "));
+    }
+    private static class LicenseDescription {
+        private final String name;
+        private final String version;
+        private final String description;
+        private final String homepage;
+        private final String licenseKey;
+        private final String licenseText;
+        private final List<String> bundles = new ArrayList<>();
 
 Review comment:
   Same comment as 287.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100423
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
 
 Review comment:
   I understand that this allows supplying license information for packages, that can't be correctly parsed. Looks ok, though I see potential problems in the future, if we get into the habit of bundling "many" JS libraries.
   
   I would consider removing the null check in 132. That way invalid license info could be overriden.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363100629
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
 
 Review comment:
   The `else` block is unnessary.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363099912
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
 
 Review comment:
   I would hardcode this to `\n`. That way it is not platform dependent and most editor deal perfectly fine with unix line endings.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] jlahoda merged pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
jlahoda merged pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845
 
 
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] jlahoda commented on issue #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
jlahoda commented on issue #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#issuecomment-570951233
 
 
   Thanks for the comments, Matthias! I'll work on them

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java

Posted by GitBox <gi...@apache.org>.
matthiasblaesing commented on a change in pull request #1845: Adding LICENSE/NOTICE for the VisualStudio Code extension for Java
URL: https://github.com/apache/netbeans/pull/1845#discussion_r363362983
 
 

 ##########
 File path: nbbuild/misc/prepare-bundles/src/main/java/org/netbeans/prepare/bundles/PrepareBundles.java
 ##########
 @@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+package org.netbeans.prepare.bundles;
+
+import com.google.gson.Gson;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/**
+ * Prepare bundles and license files for a group of node modules.
+ */
+public class PrepareBundles {
+
+    private static final String[] LICENSE_FILE_NAMES = {
+        "license",
+        "License",
+        "LICENSE",
+        "LICENSE.txt",
+        "LICENSE-MIT.txt",
+        "license.txt",
+        "License.txt",
+        "LICENSE.md",
+        "license.md"
+    };
+    private static final String nl = System.getProperty("line.separator");
+
+    public static void main(String... args) throws IOException, InterruptedException, NoSuchAlgorithmException {
+        if (args.length != 2) {
+            throw new IllegalStateException("Requires two parameters: location of the bundles directory, and the location of the NetBeans checkout.");
+        }
+
+        Path targetDir = Paths.get(args[0]);
+        Path packagesDir = targetDir.resolve("package");
+        new ProcessBuilder("npm", "install").directory(packagesDir.toFile()).inheritIO().start().waitFor();
+        Path bundlesDir = targetDir.resolve("bundles");
+        Files.createDirectories(bundlesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(bundlesDir)) {
+            for (Path bundle : ds) {
+                Files.delete(bundle);
+            }
+        }
+
+        Path licensesDir = targetDir.resolve("licenses");
+
+        Files.createDirectories(licensesDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(licensesDir)) {
+            for (Path license : ds) {
+                Files.delete(license);
+            }
+        }
+
+        Path externalDir = targetDir.resolve("external");
+        Files.createDirectories(externalDir);
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(externalDir)) {
+            for (Path external : ds) {
+                Files.delete(external);
+            }
+        }
+
+        Map<List<String>, LicenseUses> tokens2Projects = new HashMap<>();
+        Map<String, LicenseDescription> project2License = new HashMap<>();
+        Map<String, String> project2Notice = new HashMap<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(packagesDir.resolve("node_modules"));
+             Writer binariesList = new OutputStreamWriter(Files.newOutputStream(bundlesDir.resolve("binaries-list")), "UTF-8")) {
+            for (Path module : ds) {
+                if (".bin".equals(module.getFileName().toString())) continue;
+                if ("@types".equals(module.getFileName().toString())) continue;
+                Path packageJson = module.resolve("package.json");
+
+                if (!Files.isReadable(packageJson)) {
+                    throw new IllegalStateException("Cannot find package.json for: " + module.getFileName());
+                }
+
+                String packageJsonText = readString(packageJson);
+                Map<String, Object> packageJsonData = new Gson().fromJson(packageJsonText, HashMap.class);
+                String name = (String) packageJsonData.get("name");
+                String version = (String) packageJsonData.get("version");
+                String description = (String) packageJsonData.get("description");
+                String homepage = (String) packageJsonData.get("homepage");
+                String licenseKey = (String) packageJsonData.get("license");
+
+                String licenseText = null;
+
+                for (String l : LICENSE_FILE_NAMES) {
+                    if (Files.isReadable(module.resolve(l))) {
+                        licenseText = readString(module.resolve(l));
+                        break;
+                    }
+                }
+
+                if (licenseText == null) {
+                    String hardcodedLicenseName = name + "-" + version + "-license";
+                    URL hardcodedLicense = PrepareBundles.class.getResource(hardcodedLicenseName);
+                    if (hardcodedLicense == null ){
+                        throw new IllegalStateException("Cannot find license for: " + module.getFileName());
+                    }
+                    StringBuilder licenseTextBuffer = new StringBuilder();
+                    try (InputStream in = hardcodedLicense.openStream();
+                         Reader r = new InputStreamReader(in, StandardCharsets.UTF_8)) {
+                        int read;
+                        while ((read = r.read()) != (-1)) {
+                            licenseTextBuffer.append((char) read);
+                        }
+                    }
+                    licenseText = licenseTextBuffer.toString();
+                }
+                
+                Path thirdpartynoticestxt = module.resolve("thirdpartynotices.txt");
+
+                if (Files.isReadable(thirdpartynoticestxt)) {
+                    licenseText = "Parts of this work are licensed:\n" +
+                                  licenseText +
+                                  "\n\n" +
+                                  "Parts of this work are licensed:\n" +
+                                  readString(thirdpartynoticestxt);
+                } else {
+                    licenseText = licenseText;
+                }
+
+                Path noticestxt = module.resolve("CopyrightNotice.txt");
 
 Review comment:
   I read this as the normal license header for the application of licenses - you state the Copyright, the years you touched the file in, the copyright holder and the license. Nothing more - but it was only one of the entries, others were more suble but also held more information than necessary. I have not yet a good idea how to fix this...

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists