|  | #!/usr/bin/env node | 
|  | /* | 
|  | * 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. | 
|  | */ | 
|  |  | 
|  | const fs = require('fs'); | 
|  | const checker = require('license-checker'); | 
|  |  | 
|  | const LICENSES_FILE = '../licenses.yaml'; | 
|  | const START_MARKER_LINE = '# Web console modules start'; | 
|  | const END_MARKER_LINE = '# Web console modules end'; | 
|  | const SEPARATOR = '\n\n---\n\n'; | 
|  |  | 
|  | const extraLinesForLib = {}; | 
|  |  | 
|  | const extraPackages = { | 
|  | // This is a OSS font so it is not listed by the npm scraper but we still want to attribute it so pretend to inject it | 
|  | // as a phantom package | 
|  | 'opensans@1.101.0': { | 
|  | licenses: 'Apache-2.0', | 
|  | repository: 'https://github.com/google/fonts/tree/master/apache/opensans', | 
|  | publisher: 'Google', | 
|  | url: 'https://fonts.google.com/specimen/Open+Sans', | 
|  | }, | 
|  | }; | 
|  |  | 
|  | function injectConsoleLicenses(consoleLicenses) { | 
|  | const text = fs.readFileSync(LICENSES_FILE, 'utf-8'); | 
|  | const textLines = text.split('\n'); | 
|  |  | 
|  | // Extract the license for the file itself | 
|  | let beforeLines = []; | 
|  | let afterLines = []; | 
|  | let state = 'before'; | 
|  | for (let textLine of textLines) { | 
|  | switch (state) { | 
|  | case 'before': | 
|  | beforeLines.push(textLine); | 
|  | if (textLine === START_MARKER_LINE) { | 
|  | state = 'main'; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 'main': | 
|  | if (textLine === END_MARKER_LINE) { | 
|  | state = 'after'; | 
|  | afterLines.push(textLine); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 'after': | 
|  | afterLines.push(textLine); | 
|  | break; | 
|  | } | 
|  | } | 
|  | if (state === 'before') throw new Error(`missing starter marker '${START_MARKER_LINE}'`); | 
|  | if (state === 'main') throw new Error(`missing ending marker '${END_MARKER_LINE}'`); | 
|  |  | 
|  | // Write out the new file | 
|  | fs.writeFileSync( | 
|  | LICENSES_FILE, | 
|  | [beforeLines.join('\n'), consoleLicenses.join(SEPARATOR), afterLines.join('\n')].join('\n'), | 
|  | ); | 
|  | } | 
|  |  | 
|  | checker.init( | 
|  | { | 
|  | start: '.', | 
|  | production: true, | 
|  | }, | 
|  | function (err, packages) { | 
|  | if (err) { | 
|  | console.log('err', err); | 
|  | return; | 
|  | } | 
|  |  | 
|  | Object.assign(packages, extraPackages); | 
|  |  | 
|  | const seen = {}; | 
|  | const mapped = Object.keys(packages) | 
|  | .sort() | 
|  | .map(p => { | 
|  | const m = p.match(/^(.+)@(\d+\.\d+\.\d+.*)$/); | 
|  | if (!m) throw new Error(`Malformed name@version`); | 
|  | const name = m[1]; | 
|  | if (name === 'web-console') return; // This is me! | 
|  | if (seen[name]) return; // Dedupe | 
|  | seen[name] = true; | 
|  |  | 
|  | const version = m[2]; | 
|  | const meta = packages[p]; | 
|  | let { publisher, licenses, licenseFile } = meta; | 
|  | if (!licenses) throw new Error(`Package '${p} does not have a licenses`); | 
|  |  | 
|  | let properLicenseName; // Map the licenses to their proper name | 
|  | let licenseExt; // Map the licenses to the right extension | 
|  | switch (licenses) { | 
|  | case 'MIT': | 
|  | properLicenseName = 'MIT License'; | 
|  | licenseExt = 'MIT'; | 
|  | break; | 
|  |  | 
|  | case 'ISC': | 
|  | properLicenseName = 'ISC License'; | 
|  | licenseExt = 'ISC'; | 
|  | break; | 
|  |  | 
|  | case 'Apache-2.0': | 
|  | properLicenseName = 'Apache License version 2.0'; | 
|  | licenseExt = 'A2'; | 
|  | break; | 
|  |  | 
|  | case 'BSD-2-Clause': | 
|  | properLicenseName = 'BSD-2-Clause License'; | 
|  | licenseExt = 'BSD2'; | 
|  | break; | 
|  |  | 
|  | case 'BSD-3-Clause': | 
|  | properLicenseName = 'BSD-3-Clause License'; | 
|  | licenseExt = 'BSD3'; | 
|  | break; | 
|  |  | 
|  | case '0BSD': | 
|  | properLicenseName = 'Zero-Clause BSD'; | 
|  | licenseExt = '0BSD'; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | throw new Error(`Unknown license '${licenses}' in ${p}`); | 
|  | } | 
|  |  | 
|  | const simpleName = name.replace('/', '-'); | 
|  | const licenseDest = `licenses/bin/${simpleName}.${licenseExt}`; | 
|  |  | 
|  | let hasLicense = false; | 
|  | if (licenseExt !== 'A2') { | 
|  | if (licenseFile && licenseFile.match(/\/license(?:\.\w+)?/i)) { | 
|  | // If the file ends with license.ext? then copy it over | 
|  | try { | 
|  | fs.copyFileSync(licenseFile, `../${licenseDest}`); | 
|  | hasLicense = true; | 
|  | } catch (e) { | 
|  | console.log(`Could not copy license for '${p}': ${JSON.stringify(meta)}`); | 
|  | } | 
|  | } else { | 
|  | // See if the license is already there (manually) keep it | 
|  | try { | 
|  | fs.statSync(`../${licenseDest}`); | 
|  | hasLicense = true; | 
|  | } catch (e) { | 
|  | console.log(`Could not find license for '${p}': ${JSON.stringify(meta)}`); | 
|  | console.log(`Find and copy the package's license file to '../${licenseDest}'`); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!publisher && hasLicense) { | 
|  | // Extract copyright from license | 
|  | const licenseText = fs.readFileSync(`../${licenseDest}`, 'utf-8'); | 
|  | const m = licenseText.match( | 
|  | /(?:^|\n)\s*Copyright(?: (?:\(c\)|©))?(?: 2[0-9]{3}(?:-\w+)?,?)? ([^0-9][^\n]*)\n/m, | 
|  | ); | 
|  | if (m) { | 
|  | publisher = m[1] | 
|  | .replace(/All rights reserved./i, '') | 
|  | .replace(/[0-9-]{4,9}/, '') | 
|  | .trim(); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!publisher) { | 
|  | // Hand coded copyrights | 
|  | if (name === 'asap') publisher = 'Contributors'; | 
|  | if (name === 'diff-match-patch') publisher = 'Google'; | 
|  | if (name === 'esutils') publisher = 'Yusuke Suzuki'; // https://github.com/estools/esutils#license | 
|  | } | 
|  |  | 
|  | if (!publisher) { | 
|  | console.log(`No license for '${name}' ('${licenseDest}')`); | 
|  | } | 
|  |  | 
|  | // Make our blob | 
|  | const lines = [ | 
|  | `name: "${name}"`, | 
|  | `license_category: binary`, | 
|  | `module: web-console`, | 
|  | `license_name: ${properLicenseName}`, | 
|  | publisher ? `copyright: ${publisher}` : undefined, | 
|  | `version: ${version}`, | 
|  | hasLicense ? `license_file_path: ${licenseDest}` : undefined, | 
|  | extraLinesForLib[name], | 
|  | ]; | 
|  |  | 
|  | return lines.filter(Boolean).join('\n'); | 
|  | }) | 
|  | .filter(Boolean); | 
|  |  | 
|  | injectConsoleLicenses(mapped); | 
|  | }, | 
|  | ); |