Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/exclude files #28

Merged
merged 6 commits into from
Aug 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 86 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
![Logo](https://raw.githubusercontent.com/kreuzerk/import-conductor/master/assets/logo.png)

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

# import-conductor
Expand Down Expand Up @@ -98,16 +100,89 @@ npx import-conductor -s customer.component.ts -p @myorg

## Options

| Option | Description | Default value |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------- |
| -V --version | Display the current version | `-` |
| -h --help | Show a help menu | `-` |
| -s --source | Regex to that matches the source files | `./src/**/*.ts` |
| -p --userLibPrefixes | The prefix of custom user libraries - this prefix is used to distinguish between third party libraries and company libs | `[]` |
| -d --autoAdd | Disable automatically adding the committed files when the staged option is used | `true` |
| -m --autoMerge | Automatically merge 2 import statements from the same source | `true` |
| --staged | Run against staged files | `false` |
| --silent | Run with minimal log output | `true` |
- `source` - Regex to that matches the source files: (defaults to `./src/**/*.ts`)

```shell script
import-conductor --source 'mySrc/**/*.ts'
import-conductor -s 'mySrc/**/*.ts'
import-conductor 'mySrc/**/*.ts'
```

- `ignore`\* - Ignore files that match the pattern: (defaults to `[]`)

```shell script
import-conductor --ignore 'mySrc/**/*some.ts' 'main.ts'
import-conductor -i 'mySrc/**/*some.ts' 'main.ts'
```

**\*Note**: you can also skip a file by adding the following comment at the top:

```typescript
// import-conductor-skip
shaharkazaz marked this conversation as resolved.
Show resolved Hide resolved
...
```

- `userLibPrefixes` - The prefix of custom user libraries - the prefix used to distinguish between third party libraries and company libs: (defaults to `[]`)

```shell script
import-conductor --userLibPrefixes @customA @customB
import-conductor -p @customA @customB
```

- `staged` - Run against staged files: (defaults to `false`)

```shell script
import-conductor --staged
```

- `noAutoMerge` - Disable automatically merging 2 import statements from the same source: (defaults to `false`)

```shell script
import-conductor --noAutoMerge
```

- `autoAdd` - Automatically adding the committed files when using the staged option: (defaults to `false`)

```shell script
import-conductor --autoAdd
import-conductor -a
```

- `dryRun` - Run without applying any changes: (defaults to `false`)

```shell script
import-conductor --dryRun
import-conductor -d
```

- `verbose` - Run with detailed log output: (defaults to `false`)

```shell script
import-conductor --verbose
import-conductor -v
```

- `version`:

```shell script
import-conductor --version
```

- `help`:

```shell script
import-conductor --help
import-conductor -h
```

## Core Team

<table>
<tr>
<td align="center"><a href="https://medium.com/@kevinkreuzer"><img src="https://avatars0.githubusercontent.com/u/5468954?v=4" width="100px;" alt=""/><br /><sub><b>Kevin Kreuzer</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/shaharkazaz"><img src="https://avatars2.githubusercontent.com/u/17194830?v=4" width="100px;" alt=""/><br /><sub><b>Shahar Kazaz</b></sub></a><br /></td>
</tr>
</table>

## Contributors ✨

Expand All @@ -118,14 +193,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://medium.com/@kevinkreuzer"><img src="https://avatars0.githubusercontent.com/u/5468954?v=4" width="100px;" alt=""/><br /><sub><b>Kevin Kreuzer</b></sub></a><br /><a href="https://github.com/kreuzerk/import-conductor/commits?author=kreuzerk" title="Code">💻</a> <a href="#design-kreuzerk" title="Design">🎨</a> <a href="https://github.com/kreuzerk/import-conductor/commits?author=kreuzerk" title="Documentation">📖</a> <a href="#ideas-kreuzerk" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-kreuzerk" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-kreuzerk" title="Maintenance">🚧</a> <a href="https://github.com/kreuzerk/import-conductor/commits?author=kreuzerk" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/shaharkazaz"><img src="https://avatars2.githubusercontent.com/u/17194830?v=4" width="100px;" alt=""/><br /><sub><b>Shahar Kazaz</b></sub></a><br /><a href="https://github.com/kreuzerk/import-conductor/commits?author=shaharkazaz" title="Code">💻</a> <a href="https://github.com/kreuzerk/import-conductor/commits?author=shaharkazaz" title="Documentation">📖</a> <a href="#ideas-shaharkazaz" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-shaharkazaz" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-shaharkazaz" title="Maintenance">🚧</a> <a href="https://github.com/kreuzerk/import-conductor/commits?author=shaharkazaz" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/laurenzcodes"><img src="https://avatars1.githubusercontent.com/u/8169746?v=4" width="100px;" alt=""/><br /><sub><b>Robert Laurenz</b></sub></a><br /><a href="https://github.com/kreuzerk/import-conductor/commits?author=laurenzcodes" title="Documentation">📖</a></td>
</tr>
</table>

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mergeImportStatements } from '../merge-import-statements';
import { mergeImportStatements } from '@ic/conductor/merge-import-statements';

describe('mergeImportStatements', () => {
it('should merge two imports together', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import { optimizeImports } from '../optimize-imports';
import * as config from '../config';
import { actions, optimizeImports } from '@ic/conductor/optimize-imports';
import * as config from '@ic/config';
import fs from 'fs';
import { Config } from '@ic/types';

jest.mock('fs');

describe('optimizeImports', () => {
const basicConfig = {
silent: true,
const basicConfig: Config = {
ignore: [],
dryRun: false,
verbose: false,
staged: false,
source: 'test.ts',
userLibPrefixes: ['@myorg'],
autoAdd: true,
thirdPartyDependencies: new Set<string>(['@angular/core', 'rxjs']),
autoAdd: false,
autoMerge: true,
thirdPartyDependencies: new Set<string>(['@angular/core', 'rxjs']),
};

const readmeExample = `import { Component, OnInit } from '@angular/core';
const readmeExample = `import fs from 'fs';
import { CustomerService } from './customer.service';
import { Customer } from './customer.model';
import { Order } from '../order/order.model';
import { Component, OnInit } from '@angular/core';
import { LoggerService } from '@myorg/logger';
import { Observable } from 'rxjs';`;
import { Observable } from 'rxjs';
import { spawn } from 'child_process';`;

const expectedResult = `import { Component, OnInit } from '@angular/core';
import { spawn } from 'child_process';
import fs from 'fs';
import { Observable } from 'rxjs';

import { LoggerService } from '@myorg/logger';
Expand All @@ -34,12 +41,20 @@ import { CustomerService } from './customer.service';`;

beforeEach(() => {
spyOn(config, 'getConfig').and.returnValue(basicConfig);
(fs.existsSync as any).mockReturnValue(true);
});

it.only('should work with a basic example', async () => {
(fs.readFileSync as any).mockReturnValue(new Buffer(readmeExample));
it('should work with a basic example', async () => {
(fs.readFileSync as any).mockReturnValue(Buffer.from(readmeExample));
const file = 'test.ts';
await optimizeImports(file);
expect(fs.writeFileSync).toHaveBeenCalledWith(file, expectedResult);
});

it('should skip the file when skip comment exists', async () => {
(fs.readFileSync as any).mockReturnValue(Buffer.from('// import-conductor-skip'));
const file = 'test.ts';
const result = await optimizeImports(file);
expect(result).toBe(actions.skipped);
});
});
57 changes: 57 additions & 0 deletions hooks/pre-commit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const gitChangedFiles = require('git-changed-files');

gitChangedFiles({ showCommitted: false }).then(({ unCommittedFiles }) => preCommit(unCommittedFiles));

function forbiddenTokens(stagedFiles) {
shaharkazaz marked this conversation as resolved.
Show resolved Hide resolved
const FILES_REGEX = { ts: /\.ts$/, spec: /\.spec\.ts$/ };
/** Map of forbidden tokens and their match regex */
const forbiddenTokens = {
fit: { rgx: /fit\(/, fileRgx: FILES_REGEX.spec },
fdescribe: { rgx: /fdescribe\(/, fileRgx: FILES_REGEX.spec },
'.skip': { rgx: /(describe|context|it)\.skip/, fileRgx: FILES_REGEX.spec },
'.only': { rgx: /(describe|context|it)\.only/, fileRgx: FILES_REGEX.spec },
debugger: { rgx: /(debugger);?/, fileRgx: FILES_REGEX.ts },
};

let status = 0;

for (let [term, value] of Object.entries(forbiddenTokens)) {
const { rgx, fileRgx, message } = value;
/* Filter relevant files using the files regex */
const relevantFiles = stagedFiles.filter((file) => fileRgx.test(file.trim()));
const failedFiles = relevantFiles.reduce((acc, fileName) => {
const filePath = path.resolve(process.cwd(), fileName);
if (fs.existsSync(filePath)) {
const content = fs.readFileSync(filePath).toString('utf-8');
if (rgx.test(content)) {
status = 1;
acc.push(fileName);
}
}
return acc;
}, []);

/* Log all the failed files for this token with the matching message */
if (failedFiles.length > 0) {
const msg = message || `The following files contains '${term}' in them:`;
console.log(chalk.bgRed.black.bold(msg));
console.log(chalk.bgRed.black(failedFiles.join('\n')));
}
}

return status;
}

function preCommit(stagedFiles) {
let status = 0;
const checks = [forbiddenTokens];
for (const check of checks) {
if (status !== 0) break;
status = check(stagedFiles);
}

process.exit(status);
}
11 changes: 10 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.spec');

module.exports = {
roots: ['<rootDir>/src'],
roots: ['<rootDir>'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
globals: {
'ts-jest': {
tsConfig: 'tsconfig.spec.json',
},
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),
testPathIgnorePatterns: ['<rootDir>/bin/help-menu.ts', '<rootDir>/bin/pretty-html-log.bin.ts'],
};
Loading