Skip to content

Commit

Permalink
lint: ensure all files are owned by someone
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Oct 21, 2017
1 parent 76a6e7b commit ac56db5
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 65 deletions.
230 changes: 169 additions & 61 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,69 +1,177 @@
# Angular Material components
src/lib/list/** @jelbourn @crisbeto
src/lib/tooltip/** @andrewseguin
src/lib/button-toggle/** @tinayuangao
src/lib/snack-bar/** @jelbourn @crisbeto @josephperrott
src/lib/radio/** @tinayuangao @devversion
src/lib/card/** @jelbourn
src/lib/input/** @mmalerba
src/lib/progress-spinner/** @jelbourn @crisbeto @josephperrott
src/lib/datepicker/** @mmalerba
src/lib/sort/** @andrewseguin
src/lib/autocomplete/** @kara @crisbeto
src/lib/chips/** @tinayuangao
src/lib/icon/** @jelbourn
src/lib/dialog/** @jelbourn @crisbeto
src/lib/progress-bar/** @jelbourn @crisbeto @josephperrott
src/lib/grid-list/** @kara @jelbourn
src/lib/select/** @kara @crisbeto
src/lib/expansion/** @josephperrott @jelbourn
src/lib/slide-toggle/** @devversion
src/lib/toolbar/** @devversion
src/lib/button/** @tinayuangao
src/lib/checkbox/** @tinayuangao @devversion
src/lib/table/** @andrewseguin
src/lib/slider/** @mmalerba
src/lib/sidenav/** @mmalerba
src/lib/menu/** @kara @crisbeto
src/lib/paginator/** @andrewseguin
src/lib/tabs/** @andrewseguin
/src/lib/* @jelbourn
/src/lib/autocomplete/** @kara @crisbeto
/src/lib/button-toggle/** @tinayuangao
/src/lib/button/** @tinayuangao
/src/lib/card/** @jelbourn
/src/lib/checkbox/** @tinayuangao @devversion
/src/lib/chips/** @tinayuangao
/src/lib/datepicker/** @mmalerba
/src/lib/dialog/** @jelbourn @crisbeto
/src/lib/expansion/** @josephperrott @jelbourn
/src/lib/form-field/** @mmalerba
/src/lib/grid-list/** @kara @jelbourn
/src/lib/icon/** @jelbourn
/src/lib/input/** @mmalerba
/src/lib/list/** @jelbourn @crisbeto
/src/lib/menu/** @kara @crisbeto
/src/lib/paginator/** @andrewseguin
/src/lib/progress-bar/** @jelbourn @crisbeto @josephperrott
/src/lib/progress-spinner/** @jelbourn @crisbeto @josephperrott
/src/lib/radio/** @tinayuangao @devversion
/src/lib/select/** @kara @crisbeto
/src/lib/sidenav/** @mmalerba
/src/lib/slide-toggle/** @devversion
/src/lib/slider/** @mmalerba
/src/lib/snack-bar/** @jelbourn @crisbeto @josephperrott
/src/lib/sort/** @andrewseguin
/src/lib/stepper/** @mmalerba
/src/lib/table/** @andrewseguin
/src/lib/tabs/** @andrewseguin
/src/lib/toolbar/** @devversion
/src/lib/tooltip/** @andrewseguin

# Angular Material core
src/lib/core/selection/** @tinayuangao @jelbourn
src/lib/core/selection/pseudo*/** @crisbeto @jelbourn
src/lib/core/theming/** @jelbourn
src/lib/core/option/** @kara @crisbeto
src/lib/core/rxjs/** @jelbourn
src/lib/core/ripple/** @devversion
src/lib/core/a11y/** @jelbourn @devversion
src/lib/core/compatibility/** @jelbourn
src/lib/core/overlay/** @jelbourn @crisbeto
src/lib/core/overlay/scroll/** @andrewseguin @crisbeto
src/lib/core/platform/** @jelbourn @devversion
src/lib/core/bidi/** @jelbourn
src/lib/core/placeholder/** @kara @mmalerba
src/lib/core/portal/** @jelbourn
src/lib/core/typography/** @crisbeto
src/lib/core/datetime/** @mmalerba
/src/lib/core/* @jelbourn
/src/lib/core/animation/** @jelbourn
/src/lib/core/common-behaviors/** @jelbourn
/src/lib/core/compatibility/** @jelbourn
/src/lib/core/datetime/** @mmalerba
/src/lib/core/error/** @crisbeto @mmalerba
/src/lib/core/gestures/** @jelbourn
/src/lib/core/line/** @jelbourn
/src/lib/core/option/** @kara @crisbeto
/src/lib/core/placeholder/** @kara @mmalerba
/src/lib/core/ripple/** @devversion
/src/lib/core/selection/** @tinayuangao @jelbourn
/src/lib/core/selection/pseudo*/** @crisbeto @jelbourn
/src/lib/core/style/** @jelbourn
/src/lib/core/testing/** @jelbourn
/src/lib/core/theming/** @jelbourn
/src/lib/core/typography/** @crisbeto
/src/lib/core/util/** @jelbourn

# CDK
src/cdk/coercion/** @jelbourn
src/cdk/rxjs/** @jelbourn
src/cdk/observers/** @jelbourn @crisbeto
src/cdk/collections/** @jelbourn @crisbeto @andrewseguin
src/cdk/a11y/** @jelbourn @devversion
src/cdk/platform/** @jelbourn @devversion
src/cdk/bidi/** @jelbourn
src/cdk/table/** @andrewseguin
src/cdk/portal/** @jelbourn
/src/cdk/* @jelbourn
/src/cdk/a11y/** @jelbourn @devversion
/src/cdk/accordion/** @josephperrott
/src/cdk/bidi/** @jelbourn
/src/cdk/coercion/** @jelbourn
/src/cdk/collections/** @jelbourn @crisbeto @andrewseguin
/src/cdk/keycodes/** @jelbourn
/src/cdk/layout/** @josephperrott
/src/cdk/observers/** @jelbourn @crisbeto
/src/cdk/overlay/** @jelbourn @crisbeto
/src/cdk/platform/** @jelbourn @devversion
/src/cdk/portal/** @jelbourn
/src/cdk/rxjs/** @jelbourn
/src/cdk/scrolling/** @andrewseguin @crisbeto
/src/cdk/stepper/** @mmalerba
/src/cdk/table/** @andrewseguin
/src/cdk/testing/** @devversion

# Tooling
tools/** @devversion @jelbourn
test/** @devversion @jelbourn
scripts/** @devversion @jelbourn
# Moment adapter package
/src/material-moment-adapter/** @mmalerba

# Docs examples
src/material-examples/** @amcdnl @jelbourn
# Docs examples & guides
/guides/** @amcdnl @jelbourn
/src/material-examples/** @amcdnl @jelbourn

# Moment adapter package
src/material-moment-adapter/** @mmalerba
# Demo app
/src/demo-app/* @jelbourn
/src/demo-app/a11y/** @tinayuangao
/src/demo-app/autocomplete/** @kara @crisbeto
/src/demo-app/baseline/** @mmalerba
/src/demo-app/button-toggle/** @tinayuangao
/src/demo-app/button/** @tinayuangao
/src/demo-app/card/** @jelbourn
/src/demo-app/checkbox/** @tinayuangao @devversion
/src/demo-app/chips/** @tinayuangao
/src/demo-app/dataset/** @andrewseguin
/src/demo-app/datepicker/** @mmalerba
/src/demo-app/demo-app/** @jelbourn
/src/demo-app/dialog/** @jelbourn @crisbeto
/src/demo-app/drawer/** @mmalerba
/src/demo-app/expansion/** @josephperrott
/src/demo-app/focus-origin/** @mmalerba
/src/demo-app/gestures/** @jelbourn
/src/demo-app/grid-list/** @kara @jelbourn
/src/demo-app/icon/** @jelbourn
/src/demo-app/input/** @mmalerba
/src/demo-app/list/** @jelbourn @crisbeto
/src/demo-app/live-announcer/** @jelbourn
/src/demo-app/menu/** @kara @crisbeto
/src/demo-app/overlay/** @jelbourn @crisbeto
/src/demo-app/platform/** @jelbourn @devversion
/src/demo-app/portal/** @jelbourn
/src/demo-app/progress-bar/** @jelbourn @crisbeto @josephperrott
/src/demo-app/progress-spinner/** @jelbourn @crisbeto @josephperrott
/src/demo-app/radio/** @tinayuangao @devversion
/src/demo-app/ripple/** @devversion
/src/demo-app/screen-type/** @josephperrott
/src/demo-app/select/** @kara @crisbeto
/src/demo-app/sidenav/** @mmalerba
/src/demo-app/slide-toggle/** @devversion
/src/demo-app/slider/** @mmalerba
/src/demo-app/snack-bar/** @jelbourn @crisbeto @josephperrott
/src/demo-app/stepper/** @mmalerba
/src/demo-app/table/** @andrewseguin
/src/demo-app/tabs/** @andrewseguin
/src/demo-app/toolbar/** @devversion
/src/demo-app/tooltip/** @andrewseguin
/src/demo-app/typography/** @crisbeto

# E2E app
/e2e/* @jelbourn
/e2e/components/block-scroll-strategy-e2e.spec.ts @andrewseguin @crisbeto
/e2e/components/button-e2e.spec.ts @tinayuangao
/e2e/components/button-toggle-e2e.spec.ts @tinayuangao
/e2e/components/card-e2e.spec.ts @jelbourn
/e2e/components/checkbox-e2e.spec.ts @tinayuangao @devversion
/e2e/components/dialog-e2e.spec.ts @jelbourn @crisbeto
/e2e/components/expansion-e2e.spec.ts @josephperrott @jelbourn
/e2e/components/fullscreen-e2e.spec.ts @jelbourn
/e2e/components/grid-list-e2e.spec.ts @kara @jelbourn
/e2e/components/icon-e2e.spec.ts @jelbourn
/e2e/components/input-e2e.spec.ts @mmalerba
/e2e/components/list-e2e.spec.ts @jelbourn @crisbeto
/e2e/components/menu-e2e.spec.ts @kara @crisbeto
/e2e/components/progress-bar-e2e.spec.ts @jelbourn @crisbeto @josephperrott
/e2e/components/progress-spinner-e2e.spec.ts @jelbourn @crisbeto @josephperrott
/e2e/components/radio-e2e.spec.ts @tinayuangao @devversion
/e2e/components/sidenav-e2e.spec.ts @mmalerba
/e2e/components/slide-toggle-e2e.spec.ts @devversion
/e2e/components/stepper-e2e.spec.ts @mmalerba
/e2e/components/tabs-e2e.spec.ts @andrewseguin
/e2e/components/toolbar-e2e.spec.ts @devversion
/e2e/util/** @jelbourn
/src/e2e-app/* @jelbourn
/src/e2e-app/block-scroll-strategy/** @andrewseguin @crisbeto
/src/e2e-app/button/** @tinayuangao
/src/e2e-app/checkbox/** @tinayuangao @devversion
/src/e2e-app/dialog/** @jelbourn @crisbeto
/src/e2e-app/e2e-app/** @jelbourn
/src/e2e-app/fullscreen/** @jelbourn
/src/e2e-app/grid-list/** @kara @jelbourn
/src/e2e-app/icon/** @jelbourn
/src/e2e-app/input/** @mmalerba
/src/e2e-app/menu/** @kara @crisbeto
/src/e2e-app/progress-bar/** @jelbourn @crisbeto @josephperrott
/src/e2e-app/progress-spinner/** @jelbourn @crisbeto @josephperrott
/src/e2e-app/radio/** @tinayuangao @devversion
/src/e2e-app/sidenav/** @mmalerba
/src/e2e-app/slide-toggle/** @devversion
/src/e2e-app/tabs/** @andrewseguin

# Universal app
/src/universal-app/** @jelbourn

# Tooling
/scripts/** @devversion @jelbourn
/test/** @devversion @jelbourn
/tools/** @devversion @jelbourn

# Misc
/* @jelbourn
/.github/** @jelbourn
/src/* @jelbourn
66 changes: 62 additions & 4 deletions tools/gulp/tasks/lint.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {red} from 'chalk';
import {readdirSync, readFileSync, statSync} from 'fs';
import {task} from 'gulp';
import {execNodeTask} from '../util/task_helpers';
import {join} from 'path';
import {buildConfig} from 'material2-build-tools';
import {red} from 'chalk';
import {IMinimatch, Minimatch} from 'minimatch';
import {join} from 'path';
import {execNodeTask} from '../util/task_helpers';

// These types lack of type definitions
const madge = require('madge');
Expand All @@ -19,7 +21,13 @@ const materialOutPath = join(buildConfig.outputDir, 'packages', 'material');
/** Path to the output of the CDK package. */
const cdkOutPath = join(buildConfig.outputDir, 'packages', 'cdk');

task('lint', ['tslint', 'stylelint', 'madge']);
/** Path for the Github owners file. */
const ownersFilePath = '.github/CODEOWNERS';

/** Paths that should be ignored when checking for owners coverage. */
const ignoreOwners = ['/node_modules/**', '/dist/**', '/.git/**', '/.idea/**'];

task('lint', ['tslint', 'stylelint', 'madge', 'ownerslint']);

/** Task to lint Angular Material's scss stylesheets. */
task('stylelint', execNodeTask(
Expand All @@ -46,6 +54,56 @@ task('madge', ['material:clean-build'], () => {
});
});

task('ownerslint', () => {
let errors = 0;

let ownedPaths = readFileSync(ownersFilePath, 'utf8').split('\n')
// Trim lines.
.map(line => line.trim())
// Remove empty lines and comments.
.filter(line => line && !line.startsWith('#'))
// Split off just the path glob and turn it into a regex.
.map(line => new Minimatch(line.split(/\s+/)[0], {dot: true, matchBase: true}))
// Add in the paths we're ignoring.
.concat(ignoreOwners.map(path => new Minimatch(path, {dot: true, matchBase: true})));

for (let paths = getChildPaths('.'); paths.length;) {
paths = Array.prototype.concat(...paths
// Remove paths that match an owned path.
.filter(path => !ownedPaths.reduce(
(isOwned, ownedPath) => isOwned || isOwnedBy(path, ownedPath), false))
// Report an error for any files that didn't match any owned paths.
.filter(path => {
if (statSync(path).isFile()) {
console.error(red(`No code owner found for "${path}".`));
errors++;
return false;
}
return true;
})
// Get the next level of children for any directories.
.map(path => getChildPaths(path)));
}

if (errors) {
throw Error(`Found ${errors} files with no owner.`);
}
});

/** Check if the given path is owned by the given owned path matcher. */
function isOwnedBy(path: string, ownedPath: IMinimatch) {
// If the owned path ends with `**` its safe to eliminate whole directories.
if (statSync(path).isFile() || ownedPath.pattern.endsWith('**')) {
return ownedPath.match('/' + path);
}
return false;
}

/** Get the immediate child paths of the given path. */
function getChildPaths(path: string) {
return readdirSync(path).map(child => join(path, child));
}

/** Returns a string that formats the graph of circular modules. */
function formatMadgeCircularModules(circularModules: string[][]): string {
return circularModules.map((modulePaths: string[]) => `\n - ${modulePaths.join(' > ')}`).join('');
Expand Down

0 comments on commit ac56db5

Please sign in to comment.