diff --git a/README.md b/README.md
index 127cd11..f42ee45 100644
--- a/README.md
+++ b/README.md
@@ -9,24 +9,29 @@
-Utility to deal with Uber OSS licences
+**Utility to deal with Uber OSS licences**
## Example
-`uber-licence`
-
-Running the `uber-licence` binary adds licencing information
+```shell
+> uber-licence
+```
+Running the `uber-licence` binary adds licencing information
to every javascript file in your project.
-You can run `uber-licence --dry` where it does not
- mutate any files and instead outputs -1.
+You can run `uber-licence --dry` where it does not mutate
+ any files and instead outputs -1.
-You can use `--file` and `--dir` to specify your own file
- and directory filters to select source files to consider.
+You can use `--file` and `--dir` flags to specify your own
+ file and directory filters to select source files to consider.
-## Recommended usage
+Use the `-h` or `--help` flags to see all the available options.
-```js
+## Recommended Config
+
+We recommend that you add the following two scripts to your `package.json` and run `check-licence` in a git pre-commit.
+
+```json
// package.json
{
"scripts": {
@@ -45,22 +50,61 @@ You can use `--file` and `--dir` to specify your own file
}
```
-We recommend you add two scripts to your package and run
- `check-licence` in a git pre commit.
-
## Installation
-`npm install uber-licence`
+```shell
+> npm install uber-licence --save-dev
+```
+
+## CLI Usage
+
+```shell
+> uber-licence [options]
+```
+
+## NodeJS API
+
+```js
+var uberLicence = require('uber-licence');
+uberLicence(options);
+```
+
+## Options:
+
+| API | CLI | Type | Default | Description |
+| --- | --- | --- | --- | --- |
+|`dry` |`-d`, `--dry` |`Boolean`|`false` | does not write to files |
+|`file` |`-F`, `--file` |`String` |`*.js` | pattern of files to modify |
+| | |`Array`[*](#n0)| | |
+|`dir` |`-D`, `--dir` |`String` |`.*`[1](#n1)| list of directory patterns containing files |
+| | |`Array`[*](#n0)| | |
+|`license`|`-L`, `--license`|`String` |`undefined`| intended license template (file)[2](#n2) |
+| | |`Array`[*](#n0)| | |
+|`legacy` |`-O`, `--legacy` |`String` |`undefined`| list of licenses to replace |
+| | |`Array`[*](#n0)| | |
+|`verbose`|`-v`, `--verbose`|`Boolean`|`false` | log skipped and empty files |
+|`silent` |`-s`, `--silent `|`Boolean`|`false` | do not log fixed files |
+
+* *On CLI use comma to separate multiple values*
+eg: `--flag=a,b,c` or `--flag a,b,c`
+
+1 *The following directories are excluded by default:*
+`.git, node_modules, coverage, env, .tox, vendor, Godeps`
+
+2 *by default uses Uber's templates*
## Tests
-`npm test`
+```shell
+> npm test
+```
## Contributors
- [Raynos](https://github.com/raynos)
- [Kriskowal](https://github.com/kriskowal)
- [Dawsonbotsford](https://github.com/dawsonbotsford)
+ - [CxRes](https://github.com/cxres)
## MIT Licenced
diff --git a/bin/licence.js b/bin/licence.js
index 3c94ad7..b3db4e9 100755
--- a/bin/licence.js
+++ b/bin/licence.js
@@ -1,5 +1,5 @@
#!/usr/bin/env node
-// Copyright (c) 2017 Uber Technologies, Inc.
+// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -21,145 +21,60 @@
'use strict';
-var readdirp = require('readdirp');
var minimist = require('minimist');
-var fs = require('fs');
-var process = require('process');
-var console = require('console');
-// automatically prompt user to update if on older version
-var updateNotifier = require('update-notifier');
-var pkg = require('../package.json');
-updateNotifier({pkg: pkg}).notify();
-
-var LicenseFixer = require('../license-fixer');
-
-var VALID_LICENSES = require('../valid-licences.js');
-
-var argv = minimist(process.argv.slice(2));
-var cwd = process.cwd();
+var uberLicense = require('../index.js');
+
+var argv = minimist(process.argv.slice(2), {
+ boolean: [
+ 'dry',
+ 'verbose',
+ 'silent',
+ 'help'
+ ],
+ string: [
+ 'file',
+ 'dir',
+ 'license',
+ 'legacy'
+ ],
+ alias: {
+ license: ['licence', 'L'],
+ file: 'F',
+ dir: 'D',
+ legacy: 'O',
+ dry: 'd',
+ verbose: 'v',
+ silent: 's',
+ help: 'h'
+ }
+});
-/*eslint no-process-exit: 0, no-console: 0*/
+/*eslint no-console: 0*/
// jscs:disable maximumLineLength
-if (argv.help || argv.h) {
+if (argv.help) {
console.log('uber-licence');
console.log(' ');
console.log(' This binary will add a license to the top');
console.log(' of all your files');
console.log('');
console.log(' Options:');
- console.log(' --dry does not write to files');
- console.log(' --file pattern of files to modify');
- console.log(' --dir pattern for directories containing files');
- console.log(' --license intended license (file)');
- console.log(' --legacy licenses to replace');
- console.log(' --verbose log skipped and empty files');
- console.log(' --silent do not log fixed files');
- process.exit(0);
-}
-
-var fileFilter = ['*.js'];
-if (typeof argv.file === 'string') {
- fileFilter = [argv.file];
-} else if (Array.isArray(argv.file)) {
- fileFilter = argv.file;
-}
-
-var directoryFilter = ['!.git', '!node_modules', '!coverage', '!env', '!.tox', '!vendor', '!Godeps'];
-if (typeof argv.dir === 'string') {
- directoryFilter = [argv.dir];
-} else if (Array.isArray(argv.dir)) {
- directoryFilter = argv.dir;
-}
-
-var licenses = null;
-
-if (typeof argv.license === 'string') {
- licenses = licenses || [];
- licenses.push(argv.license);
-} else if (Array.isArray(argv.license)) {
- licenses = licenses || [];
- Array.prototype.push.apply(licenses, argv.license);
-}
-
-// licence non-American spelling
-if (typeof argv.licence === 'string') {
- licenses = licenses || [];
- licenses.push(argv.licence);
-} else if (Array.isArray(argv.licence)) {
- licenses = licenses || [];
- Array.prototype.push.apply(licenses, argv.licence);
-}
-
-if (typeof argv.legacy === 'string') {
- licenses = licenses || [];
- licenses.push(argv.legacy);
-} else if (Array.isArray(argv.legacy)) {
- licenses = licenses || [];
- Array.prototype.push.apply(licenses, argv.legacy);
-}
-
-if (licenses) {
- for (var i = 0; i < licenses.length; i++) {
- // Replace file names with content of files
- licenses[i] = fs.readFileSync(licenses[i], 'utf8');
- }
-} else {
- // In the absense of any command line arguments,
- // use the Uber defaults.
- licenses = VALID_LICENSES;
+ console.log(' -d, --dry does not write to files');
+ console.log(' -F, --file pattern of files to modify');
+ console.log(' -D, --dir pattern for directories containing files');
+ console.log(' -L, --license intended license template (file)');
+ console.log(' -O, --legacy licenses to replace');
+ console.log(' -v, --verbose log skipped and empty files');
+ console.log(' -s, --silent do not log fixed files');
}
-
-var licenseFixer = new LicenseFixer({
- dry: argv.dry,
- silent: argv.silent,
- verbose: argv.verbose
-});
-
-// Set the intended license text
-licenseFixer.setLicense(licenses[0]);
-// Add a license to match and replace.
-// There can be multiple recognized licenses, for migration purposes.
-for (var i = 0; i < licenses.length; i++) {
- licenseFixer.addLicense(licenses[i]);
-}
-
-readTree({
- root: cwd,
- fileFilter: fileFilter,
- directoryFilter: directoryFilter
-}, processFiles);
-
-function readTree(options, callback) {
- var stream = readdirp(options);
- var files = [];
- stream.on('data', onData);
- stream.on('end', onEnd);
- stream.on('error', onEnd);
- function onData(event) {
- files.push(event.path);
- }
- function onEnd(err) {
- callback(err, files);
- }
-}
-
-function processFiles(err, files) {
- if (err) {
- console.error(err.message);
- process.exit(1);
- return;
- }
-
- var fixed = 0;
- for (var filesIndex = 0; filesIndex < files.length; filesIndex++) {
- var file = files[filesIndex];
- fixed = fixed + licenseFixer.fixFile(file);
- }
-
- if (argv.dry) {
- process.exit(fixed);
- } else {
- process.exit(0);
- }
+else {
+ uberLicense({
+ dry: argv.dry,
+ silent: argv.silent,
+ verbose: argv.verbose,
+ fileFilter: argv.file && argv.file.split(','),
+ directoryFilter: argv.dir && argv.dir.split(','),
+ license: argv.license && argv.license.split(','),
+ legacy: argv.legacy && argv.legacy.split(',')
+ });
}
diff --git a/defaults.js b/defaults.js
new file mode 100644
index 0000000..5444b4b
--- /dev/null
+++ b/defaults.js
@@ -0,0 +1,35 @@
+// Copyright (c) 2018 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+module.exports = {
+ directoryFilter: [
+ '!.git',
+ '!node_modules',
+ '!coverage',
+ '!env',
+ '!.tox',
+ '!vendor',
+ '!Godeps'
+ ],
+
+ fileFilter: [
+ '*.js'
+ ]
+};
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..a342a8c
--- /dev/null
+++ b/index.js
@@ -0,0 +1,132 @@
+// Copyright (c) 2018 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+var fs = require('fs');
+var readdirp = require('readdirp');
+
+var defaults = require('./defaults');
+var LicenseFixer = require('./license-fixer');
+var VALID_LICENSES = require('./valid-licences');
+
+// automatically prompt user to update if on older version
+var updateNotifier = require('update-notifier');
+var pkg = require('./package.json');
+updateNotifier({pkg: pkg}).notify();
+
+function uberLicense(options) {
+ var dry = options.dry;
+ var silent = options.silent;
+ var verbose = options.verbose;
+
+ if (options.licence && !options.license) {
+ options.license = options.licence;
+ }
+
+ // If the user enter string when using the API version
+ var licenses = (typeof options.license === 'string') ?
+ [options.license] : options.license;
+
+ var legacy = (typeof options.legacy === 'string') ?
+ [options.legacy] : options.legacy;
+
+ if (licenses) {
+ for (var i = 0; i < licenses.length; i++) {
+ // Replace file names with content of files
+ licenses[i] = fs.readFileSync(licenses[i], 'utf8');
+ }
+ } else {
+ // In the absense of any command line arguments,
+ // use the Uber defaults.
+ licenses = VALID_LICENSES;
+ }
+
+ // Legacy should not override default license
+ if (legacy) {
+ for (var j = 0; j < legacy.length; j++) {
+ // Replace file names with content of files
+ licenses[licenses.length + j] = fs.readFileSync(legacy[j], 'utf8');
+ }
+ }
+
+ var licenseFixer = new LicenseFixer({
+ dry: dry,
+ silent: silent,
+ verbose: verbose
+ });
+
+ // Set the intended license text
+ licenseFixer.setLicense(licenses[0]);
+ // Add a license to match and replace.
+ // There can be multiple recognized licenses, for migration purposes.
+ licenses.forEach(function(license) {
+ licenseFixer.addLicense(license);
+ });
+
+ // If the user enters a string argument when using the API version
+ var fileFilter = (typeof options.fileFilter === 'string') ?
+ [options.fileFilter] : options.fileFilter;
+
+ var directoryFilter = (typeof options.directoryFilter === 'string') ?
+ [options.directoryFilter] : options.directoryFilter;
+
+ readTree({
+ root: process.cwd(),
+ fileFilter: fileFilter || defaults.fileFilter,
+ directoryFilter: directoryFilter || defaults.directoryFilter,
+ }, processFiles);
+
+ function readTree(opts, callback) {
+ var stream = readdirp(opts);
+ var files = [];
+ stream.on('data', onData);
+ stream.on('end', onEnd);
+ stream.on('error', onEnd);
+ function onData(event) {
+ files.push(event.path);
+ }
+ function onEnd(err) {
+ callback(err, files);
+ }
+ }
+
+
+ function processFiles(err, files) {
+ if (err) {
+ console.error(err.message);
+ process.exit(1);
+ return;
+ }
+
+ var fixed = 0;
+ for (var filesIndex = 0; filesIndex < files.length; filesIndex++) {
+ var file = files[filesIndex];
+ fixed = fixed + licenseFixer.fixFile(file);
+ }
+
+ if (dry) {
+ process.exit(fixed);
+ } else {
+ process.exit(0);
+ }
+ }
+}
+
+
+module.exports = uberLicense;
\ No newline at end of file
diff --git a/license-fixer.js b/license-fixer.js
index 15c9ddc..b86483b 100644
--- a/license-fixer.js
+++ b/license-fixer.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
+// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/package.json b/package.json
index 479a707..d5f0c43 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "uber-licence",
- "version": "3.1.1",
+ "version": "3.2.0",
"description": "Utility to deal with Uber OSS licences",
"keywords": [],
"author": "Raynos ",
diff --git a/test/index.js b/test/index.js
index c382dc1..86426e8 100644
--- a/test/index.js
+++ b/test/index.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
+// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -24,11 +24,12 @@ var fs = require('fs-extra');
var temp = require('temp');
var exec = require('child_process').exec;
var esc = require('escape-string-regexp');
+var os = require('os');
-// Automatically track and cleanup files at exit
-temp.track();
-
-var uberLicensePath = path.join(__dirname, '..', 'bin', 'licence.js');
+var uberLicenseCall = path.join(__dirname, '..', 'bin', 'licence.js');
+if (os.platform() === 'win32') {
+ uberLicenseCall = 'node ' + uberLicenseCall;
+}
tape('add-header', function (t) {
t.plan(2);
@@ -38,22 +39,25 @@ tape('add-header', function (t) {
var outputFileContent = fs.readFileSync(path.join(fixturePath, 'output.js'), 'utf8');
// remove the dynamic year portion of the header comment
- var consistentOutputString = "^".concat(esc(outputFileContent).replace(new RegExp(/\d{4}/), "\\d{4}"));
+ var consistentOutputString = "^".concat(
+ esc(outputFileContent).replace(new RegExp(/\d{4}/), "\\d{4}").replace(new RegExp(/\r?\n/g), "\\r?\\n")
+ );
var outputRegex = new RegExp(consistentOutputString);
temp.mkdir('add-header', function(mkTempErr, dirPath) {
if (mkTempErr) {
return console.error('mkTempErr: ' + mkTempErr);
}
- process.chdir(dirPath);
- fs.copySync(input1FilePath, 'input-1.js');
- fs.copySync(input2FilePath, 'input-2.js');
- exec(uberLicensePath, function(execErr) {
+
+ fs.copySync(input1FilePath, path.join(dirPath, 'input-1.js'));
+ fs.copySync(input2FilePath, path.join(dirPath, 'input-2.js'));
+ exec(uberLicenseCall, { cwd: dirPath }, function(execErr) {
if (execErr instanceof Error) {
throw execErr;
}
- var input1FileContent = fs.readFileSync('input-1.js', 'utf8');
- var input2FileContent = fs.readFileSync('input-2.js', 'utf8');
+ var input1FileContent = fs.readFileSync(path.join(dirPath, 'input-1.js'), 'utf8');
+ var input2FileContent = fs.readFileSync(path.join(dirPath, 'input-2.js'), 'utf8');
+ temp.cleanupSync();
t.true(outputRegex.test(input1FileContent), 'should prepend header to file without header');
t.true(outputRegex.test(input2FileContent), 'should replace old header (from 2016)');
@@ -73,28 +77,35 @@ tape('add-nonstandard-header', function (t) {
var output3FileContent = fs.readFileSync(path.join(fixturePath, 'output-3.js'), 'utf8');
// remove the dynamic year portion of the header comment
- var consistentOutputString = "^".concat(esc(output1FileContent).replace(new RegExp(/\d{4}/), "\\d{4}"));
+ var consistentOutputString = "^".concat(
+ esc(output1FileContent).replace(new RegExp(/\d{4}/), "\\d{4}").replace(new RegExp(/\r?\n/g), "\\r?\\n")
+ );
var output1Regex = new RegExp(consistentOutputString);
- consistentOutputString = "^".concat(esc(output2FileContent).replace(new RegExp(/\d{4}/), "\\d{4}"));
+ consistentOutputString = "^".concat(
+ esc(output2FileContent).replace(new RegExp(/\d{4}/), "\\d{4}").replace(new RegExp(/\r?\n/g), "\\r?\\n")
+ );
var output2Regex = new RegExp(consistentOutputString);
- consistentOutputString = "^".concat(esc(output3FileContent).replace(new RegExp(/\d{4}/), "\\d{4}"));
+ consistentOutputString = "^".concat(
+ esc(output3FileContent).replace(new RegExp(/\d{4}/), "\\d{4}").replace(new RegExp(/\r?\n/g), "\\r?\\n")
+ );
var output3Regex = new RegExp(consistentOutputString);
temp.mkdir('add-header', function(mkTempErr, dirPath) {
if (mkTempErr) {
return console.error('mkTempErr: ' + mkTempErr);
}
- process.chdir(dirPath);
- fs.copySync(input1FilePath, 'input-1.js');
- fs.copySync(input2FilePath, 'input-2.js');
- fs.copySync(input3FilePath, 'input-3.js');
- exec(uberLicensePath, function(execErr) {
+
+ fs.copySync(input1FilePath, path.join(dirPath, 'input-1.js'));
+ fs.copySync(input2FilePath, path.join(dirPath, 'input-2.js'));
+ fs.copySync(input3FilePath, path.join(dirPath, 'input-3.js'));
+ exec(uberLicenseCall, { cwd: dirPath }, function(execErr) {
if (execErr instanceof Error) {
throw execErr;
}
- var input1FileContent = fs.readFileSync('input-1.js', 'utf8');
- var input2FileContent = fs.readFileSync('input-2.js', 'utf8');
- var input3FileContent = fs.readFileSync('input-3.js', 'utf8');
+ var input1FileContent = fs.readFileSync(path.join(dirPath, 'input-1.js'), 'utf8');
+ var input2FileContent = fs.readFileSync(path.join(dirPath, 'input-2.js'), 'utf8');
+ var input3FileContent = fs.readFileSync(path.join(dirPath, 'input-3.js'), 'utf8');
+ temp.cleanupSync();
t.true(output1Regex.test(input1FileContent), 'should have flow, then blank line, then license');
t.true(output2Regex.test(input2FileContent), 'should have shebang, then blank line, then license');
@@ -111,20 +122,23 @@ tape('dont-add-header', function (t) {
var outputFileContent = fs.readFileSync(path.join(fixturePath, 'output.js'), 'utf8');
// remove the dynamic year portion of the header comment
- var consistentOutputString = "^".concat(esc(outputFileContent).replace(new RegExp(/\d{4}/), "\\d{4}"));
+ var consistentOutputString = "^".concat(
+ esc(outputFileContent).replace(new RegExp(/\d{4}/), "\\d{4}").replace(new RegExp(/\r?\n/g), "\\r?\\n")
+ );
var outputRegex = new RegExp(consistentOutputString);
temp.mkdir('dont-add-header', function(mkTempErr, dirPath) {
if (mkTempErr) {
return console.error('mkTempErr: ' + mkTempErr);
}
- process.chdir(dirPath);
- fs.copySync(inputFilePath, 'input.js');
- exec(uberLicensePath, function(execErr) {
+
+ fs.copySync(inputFilePath, path.join(dirPath, 'input.js'));
+ exec(uberLicenseCall, { cwd: dirPath }, function(execErr) {
if (execErr instanceof Error) {
throw execErr;
}
- var inputFileContent = fs.readFileSync('input.js', 'utf8');
+ var inputFileContent = fs.readFileSync(path.join(dirPath, 'input.js'), 'utf8');
+ temp.cleanupSync();
t.true(outputRegex.test(inputFileContent), 'should prepend header');
t.end();
diff --git a/valid-licences.js b/valid-licences.js
index cb48efc..5079ccf 100644
--- a/valid-licences.js
+++ b/valid-licences.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
+// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal