Skip to content

Commit 051e3c3

Browse files
authored
Allow for copyrights to be assigned to Google LLC (#2665)
* Allow for copyrights assigned to Google LLC Current guidance at go/copyright calls for copyright to be assigned to Google LLC, like so: Copyright 2020 Google LLC This change makes this the default without changing existing files. * Add missing license header to license.js * Remove unused chalk import * Do license validation in a single pass * Rewrite old-form copyrights * Compute changed files once. * [AUTOMATED]: License Headers
1 parent 94e2ead commit 051e3c3

File tree

3 files changed

+90
-52
lines changed

3 files changed

+90
-52
lines changed

tools/gitHooks/license.js

Lines changed: 76 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
1-
const { promisify } = require('util');
1+
/**
2+
* @license
3+
* Copyright 2017 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
218
const { resolve } = require('path');
319
const simpleGit = require('simple-git/promise');
4-
const chalk = require('chalk');
5-
const globRaw = require('glob');
620
const fs = require('mz/fs');
721
const ora = require('ora');
822

9-
const glob = promisify(globRaw);
1023
const root = resolve(__dirname, '../..');
1124
const git = simpleGit(root);
1225
const licenseHeader = `/**
1326
* @license
14-
* Copyright 2020 Google Inc.
27+
* Copyright 2020 Google LLC
1528
*
1629
* Licensed under the Apache License, Version 2.0 (the "License");
1730
* you may not use this file except in compliance with the License.
@@ -28,49 +41,72 @@ const licenseHeader = `/**
2841
2942
`;
3043

31-
async function doLicenseCommit() {
32-
const licenseSpinner = ora(' Validating License Headers').start();
44+
const copyrightPattern = /Copyright \d{4} Google (Inc\.|LLC)/;
45+
const oldCopyrightPattern = /(\s*\*\s*Copyright \d{4}) Google Inc\./;
3346

34-
const paths = await glob('**/*.+(ts|js)', {
35-
ignore: ['**/node_modules/**', '**/dist/**']
47+
async function readFiles(paths) {
48+
const fileContents = await Promise.all(paths.map(path => fs.readFile(path)));
49+
return fileContents.map((buffer, idx) => ({
50+
contents: String(buffer),
51+
path: paths[idx]
52+
}));
53+
}
54+
55+
function addLicenceTag(contents) {
56+
const lines = contents.split('\n');
57+
let newLines = [];
58+
for (const line of lines) {
59+
if (line.match(copyrightPattern)) {
60+
const indent = line.split('*')[0]; // Get whitespace to match
61+
newLines.push(indent + '* @license');
62+
}
63+
newLines.push(line);
64+
}
65+
return newLines.join('\n');
66+
}
67+
68+
function rewriteCopyrightLine(contents) {
69+
const lines = contents.split('\n');
70+
let newLines = lines.map(line => {
71+
return line.replace(oldCopyrightPattern, (_, leader) => {
72+
return leader + ' Google LLC';
73+
});
3674
});
75+
return newLines.join('\n');
76+
}
3777

38-
// Files with no license block at all.
39-
const fileContents = await Promise.all(paths.map(path => fs.readFile(path)));
40-
const filesMissingLicensePaths = fileContents
41-
.map((buffer, idx) => ({ buffer, path: paths[idx] }))
42-
.filter(
43-
({ buffer }) =>
44-
String(buffer).match(/Copyright \d{4} Google Inc\./) == null
45-
);
78+
async function doLicenseCommit(changedFiles) {
79+
const licenseSpinner = ora(' Validating License Headers').start();
4680

47-
await Promise.all(
48-
filesMissingLicensePaths.map(({ buffer, path }) => {
49-
const contents = Buffer.concat([new Buffer(licenseHeader), buffer]);
50-
return fs.writeFile(path, contents, 'utf8');
51-
})
52-
);
81+
const paths = changedFiles.filter(line => line.match(/(js|ts)$/));
82+
if (paths.length === 0) return;
5383

54-
// Files with no @license tag.
55-
const appendedFileContents = await Promise.all(
56-
paths.map(path => fs.readFile(path))
57-
);
58-
const filesMissingTagPaths = appendedFileContents
59-
.map((buffer, idx) => ({ buffer, path: paths[idx] }))
60-
.filter(({ buffer }) => String(buffer).match(/@license/) == null);
84+
const files = await readFiles(paths);
6185

6286
await Promise.all(
63-
filesMissingTagPaths.map(({ buffer, path }) => {
64-
const lines = String(buffer).split('\n');
65-
let newLines = [];
66-
for (const line of lines) {
67-
if (line.match(/Copyright \d{4} Google Inc\./)) {
68-
const indent = line.split('*')[0]; // Get whitespace to match
69-
newLines.push(indent + '* @license');
70-
}
71-
newLines.push(line);
87+
files.map(({ contents, path }) => {
88+
let result = contents;
89+
90+
// Files with no license block at all.
91+
if (result.match(copyrightPattern) == null) {
92+
result = licenseHeader + result;
93+
}
94+
95+
// Files with no @license tag.
96+
if (result.match(/@license/) == null) {
97+
result = addLicenceTag(result);
98+
}
99+
100+
// Files with the old form of copyright notice.
101+
if (result.match(oldCopyrightPattern) != null) {
102+
result = rewriteCopyrightLine(result);
103+
}
104+
105+
if (contents !== result) {
106+
return fs.writeFile(path, result, 'utf8');
107+
} else {
108+
return Promise.resolve();
72109
}
73-
return fs.writeFile(path, newLines.join('\n'), 'utf8');
74110
})
75111
);
76112

tools/gitHooks/prepush.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright 2017 Google Inc.
3+
* Copyright 2017 Google LLC
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -44,11 +44,18 @@ $ git stash pop
4444
return process.exit(1);
4545
}
4646

47+
const diff = await git.diff([
48+
'--name-only',
49+
'--diff-filter=d',
50+
'origin/master...HEAD'
51+
]);
52+
const changedFiles = diff.split('\n');
53+
4754
// Style the code
48-
await doPrettierCommit();
55+
await doPrettierCommit(changedFiles);
4956

5057
// Validate License headers exist
51-
await doLicenseCommit();
58+
await doLicenseCommit(changedFiles);
5259

5360
console.log(chalk`
5461
Pre-Push Validation Succeeded

tools/gitHooks/prettier.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright 2017 Google Inc.
3+
* Copyright 2017 Google LLC
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -56,21 +56,16 @@ function checkVersion() {
5656
});
5757
}
5858

59-
async function doPrettierCommit() {
59+
async function doPrettierCommit(changedFiles) {
6060
try {
6161
await checkVersion();
6262
} catch (e) {
6363
console.error(e);
6464
return process.exit(1);
6565
}
66-
const diff = await git.diff([
67-
'--name-only',
68-
'origin/master...HEAD',
69-
'--diff-filter',
70-
'd'
71-
]);
66+
7267
// Only run on .js or .ts files.
73-
const targetFiles = diff.split('\n').filter(line => line.match(/(js|ts)$/));
68+
const targetFiles = changedFiles.filter(line => line.match(/(js|ts)$/));
7469
if (targetFiles.length === 0) return;
7570

7671
const stylingSpinner = ora(

0 commit comments

Comments
 (0)