| /* |
| 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 path = require('path'); |
| const { promisify } = require('util'); |
| const pipeline = promisify(require('stream').pipeline); |
| const { Gunzip } = require('zlib'); |
| const got = require('got'); |
| const tar = require('tar-fs'); |
| const chalk = require('chalk'); |
| const optimist = require('optimist'); |
| const executil = require('./executil'); |
| const flagutil = require('./flagutil'); |
| const repoutil = require('./repoutil'); |
| |
| const COMMON_RAT_EXCLUDES = [ |
| // Binary Files |
| '*.wav', |
| '*.webloc', |
| |
| // iOS Related |
| '*.xcworkspacedata', |
| '*.xccheckout', |
| '*.xcscheme', |
| '*.xcodeproj', |
| '*-Info.plist', |
| 'Info.plist', |
| |
| // Other |
| '.*', |
| '*.json', // Excludes all JSON files because commenting is not supported. |
| '*.txt', // Excludes all text files because commenting is not supported. |
| 'VERSION', |
| 'node_modules', |
| 'thirdparty' |
| ]; |
| |
| module.exports = function * () { |
| let opt = flagutil.registerRepoFlag(optimist); |
| opt = flagutil.registerHelpFlag(opt); |
| |
| opt.usage('Uses Apache RAT to audit source files for license headers.\n' + |
| '\n' + |
| 'Usage: $0 audit-license-headers --repo=name [-r repos]'); |
| const argv = opt.argv; |
| |
| if (argv.h) { |
| optimist.showHelp(); |
| process.exit(1); |
| } |
| |
| const repos = flagutil.computeReposFromFlag(argv.r, { includeModules: true }); |
| yield module.exports.scrubRepos(repos); |
| }; |
| |
| module.exports.scrubRepos = function * (repos, silent, ignoreError, win, fail) { |
| const ratPath = yield getRatJar(); |
| |
| console.log(chalk.red('Note: ignore filters reside in a repo\'s .ratignore and in COMMON_RAT_EXCLUDES in audit-license-headers.js.')); |
| |
| yield repoutil.forEachRepo(repos, function * (repo) { |
| // NOTE: the CWD in a callback is the directory for its respective repo |
| const ratignorePatterns = readRatignorePatterns(process.cwd()); |
| const excludePatterns = COMMON_RAT_EXCLUDES.concat(ratignorePatterns); |
| |
| // run Rat |
| const args = executil.ARGS('java -jar', ratPath, '-d', '.', '-e').concat(excludePatterns); |
| yield executil.execHelper(args, silent, ignoreError, function (stdout) { |
| if (win) win(repo, stdout); |
| }); |
| }); |
| }; |
| |
| // Returns path to Apache RAT JAR; downloads it first if necessary |
| async function getRatJar () { |
| const RAT_ID = 'apache-rat-0.12'; |
| const RAT_URL = `https://archive.apache.org/dist/creadur/${RAT_ID}/${RAT_ID}-bin.tar.gz`; |
| |
| const cohoRoot = repoutil.getRepoDir(repoutil.getRepoById('coho')); |
| const ratJarPath = path.join(cohoRoot, RAT_ID, RAT_ID + '.jar'); |
| |
| if (!fs.existsSync(ratJarPath)) { |
| console.log('RAT tool not found, downloading to: ' + ratJarPath); |
| await pipeline( |
| got.stream(RAT_URL), new Gunzip(), tar.extract(cohoRoot) |
| ).catch(err => { |
| throw new Error('Failed to get RAT JAR:\n' + err.message); |
| }); |
| } |
| return ratJarPath; |
| } |
| |
| // Read in exclude patterns from .ratignore at dir |
| function readRatignorePatterns (dir) { |
| const ratignorePath = path.join(dir, '.ratignore'); |
| if (!fs.existsSync(ratignorePath)) return []; |
| |
| // return only non-empty and non-comment lines |
| return fs.readFileSync(ratignorePath, 'utf-8') |
| .split('\n') |
| .map(line => line.trim()) |
| .filter(line => line.length > 0 && !line.startsWith('#')); |
| } |