Skip to content

Commit

Permalink
Merge pull request #313 from DXHeroes/feat/fixer-ts-gitignore
Browse files Browse the repository at this point in the history
Add fixer for TS gitignore
  • Loading branch information
mergify[bot] authored Apr 9, 2020
2 parents aff1ba8 + 0cd8c66 commit c3aa5dd
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 13 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"table": "5.4.6",
"toposort": "2.0.2",
"ts-node": "8.8.1",
"tsconfig": "^7.0.0",
"tslib": "1.11.1",
"typescript": "3.8.3",
"update-notifier": "4.1.0",
Expand Down
74 changes: 74 additions & 0 deletions src/practices/TypeScript/TsGitignoreCorrectlySetPractice.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { TsGitignoreCorrectlySetPractice } from './TsGitignoreCorrectlySetPracti
import { gitignoreContent } from '../../detectors/__MOCKS__/JavaScript/gitignoreContent.mock';
import { PracticeEvaluationResult, ProgrammingLanguage } from '../../model';
import { TestContainerContext, createTestContainer } from '../../inversify.config';
import { load } from 'tsconfig';
jest.mock('tsconfig', () => ({
load: jest.fn(),
}));

const basicGitignore = `
build
Expand Down Expand Up @@ -87,4 +91,74 @@ describe('TsGitignoreCorrectlySetPractice', () => {
const result = await practice.isApplicable(containerCtx.practiceContext);
expect(result).toEqual(false);
});

describe('Fixer', () => {
beforeEach(() => {
(load as jest.Mock).mockReturnValue({
config: {
compilerOptions: {
outDir: './lib',
},
},
});
});

afterEach(async () => {
jest.clearAllMocks();
containerCtx.virtualFileSystemService.clearFileSystem();
});

it('Does not change correct .gitignore', async () => {
const gitignore = `${basicGitignore}\npackage-lock.json\n/lib\n`;
containerCtx.virtualFileSystemService.setFileSystem({
'.gitignore': gitignore,
});

await practice.evaluate(containerCtx.practiceContext);
await practice.fix(containerCtx.fixerContext);

const fixedGitignore = await containerCtx.virtualFileSystemService.readFile('.gitignore');
expect(fixedGitignore).toBe(gitignore);
});
it('Appends to .gitignore if entry is missing', async () => {
containerCtx.virtualFileSystemService.setFileSystem({
'.gitignore': '/node_modules\n/coverage\n/lib\n',
});

await practice.evaluate(containerCtx.practiceContext);
await practice.fix(containerCtx.fixerContext);

const fixedGitignore = await containerCtx.virtualFileSystemService.readFile('.gitignore');
expect(fixedGitignore).toBe('/node_modules\n/coverage\n/lib\n\n*.log\n');
});
it('Correctly ignores build folder', async () => {
containerCtx.virtualFileSystemService.setFileSystem({
'.gitignore': '/node_modules\n/coverage\n*.log\n',
});

await practice.evaluate(containerCtx.practiceContext);
await practice.fix(containerCtx.fixerContext);

const fixedGitignore = await containerCtx.virtualFileSystemService.readFile('.gitignore');
expect(fixedGitignore).toBe('/node_modules\n/coverage\n*.log\n\n/lib\n');
});
it('Correctly ignores build file', async () => {
(load as jest.Mock).mockReturnValue({
config: {
compilerOptions: {
outFile: './dist.ts',
},
},
});
containerCtx.virtualFileSystemService.setFileSystem({
'.gitignore': '/node_modules\n/coverage\n*.log\n',
});

await practice.evaluate(containerCtx.practiceContext);
await practice.fix(containerCtx.fixerContext);

const fixedGitignore = await containerCtx.virtualFileSystemService.readFile('.gitignore');
expect(fixedGitignore).toBe('/node_modules\n/coverage\n*.log\n\ndist.ts\n');
});
});
});
42 changes: 42 additions & 0 deletions src/practices/TypeScript/TsGitignoreCorrectlySetPractice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { DxPractice } from '../DxPracticeDecorator';
import { PracticeContext } from '../../contexts/practice/PracticeContext';
import { PracticeBase } from '../PracticeBase';
import { ReportDetailType } from '../../reporters/ReporterData';
import { FixerContext } from '../../contexts/fixer/FixerContext';
import { load as tsLoad } from 'tsconfig';
import * as path from 'path';

@DxPractice({
id: 'TypeScript.GitignoreCorrectlySet',
Expand All @@ -14,6 +17,8 @@ import { ReportDetailType } from '../../reporters/ReporterData';
dependsOn: { practicing: ['LanguageIndependent.GitignoreIsPresent'] },
})
export class TsGitignoreCorrectlySetPractice extends PracticeBase {
private parsedGitignore: string[] = [];

async isApplicable(ctx: PracticeContext): Promise<boolean> {
return ctx.projectComponent.language === ProgrammingLanguage.TypeScript;
}
Expand All @@ -31,6 +36,7 @@ export class TsGitignoreCorrectlySetPractice extends PracticeBase {
};
const content = await ctx.root.fileInspector.readFile('.gitignore');
const parsedGitignore = parseGitignore(content);
this.parsedGitignore = parsedGitignore;

// folders with compiled code
const buildRegex = parsedGitignore.find((value: string) => /build/.test(value));
Expand All @@ -55,6 +61,42 @@ export class TsGitignoreCorrectlySetPractice extends PracticeBase {
return PracticeEvaluationResult.notPracticing;
}

async fix(ctx: FixerContext) {
const inspector = ctx.fileInspector?.basePath ? ctx.fileInspector : ctx.root.fileInspector;
if (!inspector) return;
// node_modules
const nodeModulesRegex = this.parsedGitignore.find((value: string) => /node_modules/.test(value));
// misc
const coverageRegex = this.parsedGitignore.find((value: string) => /coverage/.test(value));
const errorLogRegex = this.parsedGitignore.find((value: string) => /\.log/.test(value));
const fixes = [
nodeModulesRegex ? undefined : '/node_modules',
coverageRegex ? undefined : '/coverage',
errorLogRegex ? undefined : '*.log',
]
.filter(Boolean)
.concat(''); // append newline if we add something

const tsConfig = await tsLoad(inspector.basePath || '.');
if (tsConfig) {
if (tsConfig.config.compilerOptions.outDir) {
const folderName = path.basename(tsConfig.config.compilerOptions.outDir);
if (!this.parsedGitignore.find((value: string) => new RegExp(folderName).test(value))) {
fixes.unshift(`/${folderName}`);
}
} else if (tsConfig.config.compilerOptions.outFile) {
const fileName = path.basename(tsConfig.config.compilerOptions.outFile);
if (!this.parsedGitignore.find((value: string) => new RegExp(fileName).test(value))) {
fixes.unshift(`${fileName}`);
}
}
}

if (fixes.length > 1) fixes.unshift(''); // if there is something to add, make sure we start with newline

await inspector.appendFile('.gitignore', fixes.join('\n'));
}

private setData() {
this.data.details = [
{
Expand Down
38 changes: 25 additions & 13 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,16 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==

"@types/strip-bom@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2"
integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=

"@types/strip-json-comments@0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==

"@types/table@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/table/-/table-5.0.0.tgz#67c3821138eb41d538c3d9286771c6cdeeac7172"
Expand Down Expand Up @@ -6989,7 +6999,6 @@ npm@^6.10.3:
cmd-shim "^3.0.3"
columnify "~1.5.4"
config-chain "^1.1.12"
debuglog "*"
detect-indent "~5.0.0"
detect-newline "^2.1.0"
dezalgo "~1.0.3"
Expand All @@ -7004,7 +7013,6 @@ npm@^6.10.3:
has-unicode "~2.0.1"
hosted-git-info "^2.8.8"
iferr "^1.0.2"
imurmurhash "*"
infer-owner "^1.0.4"
inflight "~1.0.6"
inherits "^2.0.4"
Expand All @@ -7023,14 +7031,8 @@ npm@^6.10.3:
libnpx "^10.2.2"
lock-verify "^2.1.0"
lockfile "^1.0.4"
lodash._baseindexof "*"
lodash._baseuniq "~4.6.0"
lodash._bindcallback "*"
lodash._cacheindexof "*"
lodash._createcache "*"
lodash._getnative "*"
lodash.clonedeep "~4.5.0"
lodash.restparam "*"
lodash.union "~4.6.0"
lodash.uniq "~4.5.0"
lodash.without "~4.4.0"
Expand Down Expand Up @@ -9370,16 +9372,16 @@ strip-indent@^2.0.0:
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=

strip-json-comments@^2.0.0, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=

strip-json-comments@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==

strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=

stubs@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b"
Expand Down Expand Up @@ -9759,6 +9761,16 @@ ts-node@8.8.1:
source-map-support "^0.5.6"
yn "3.1.1"

tsconfig@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7"
integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==
dependencies:
"@types/strip-bom" "^3.0.0"
"@types/strip-json-comments" "0.0.30"
strip-bom "^3.0.0"
strip-json-comments "^2.0.0"

tslib@1.11.1, tslib@^1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
Expand Down

0 comments on commit c3aa5dd

Please sign in to comment.