Skip to content

Commit

Permalink
feat: add ignore porjects and languages files
Browse files Browse the repository at this point in the history
Close #5
  • Loading branch information
Raman Lauryniuk committed Jun 4, 2019
1 parent 06cf709 commit 7c99fb9
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 58 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"@semantic-release/changelog": "^3.0.2",
"@semantic-release/git": "^7.0.8",
"@types/chai": "^4.1.7",
"@types/chalk": "^2.2.0",
"@types/commander": "^2.12.2",
"@types/glob": "^7.1.1",
"@types/lodash": "^4.14.132",
Expand Down
15 changes: 14 additions & 1 deletion src/cli/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ const options: OptionModel[] = [
ErrorTypes.warning,
ErrorTypes.error
]
}),
new OptionModel({
short: 'i',
name: 'ignore',
required: false,
type: OptionsTypes.glob,
describe: `Ignore projects and languages files`,
description: ``,
possibaleValues: [
'relative path',
'absolute path'
]
})
];

Expand All @@ -86,14 +98,15 @@ Examples:
$ ${name} -p '${config.defaultValues.projectPath}' -l '${config.defaultValues.languagesPath}'
$ ${name} -p '${config.defaultValues.projectPath}' -z '${ErrorTypes.disable}' -v '${ErrorTypes.error}'
$ ${name} -p '${config.defaultValues.projectPath}' -i './src/assets/i18n/EN-us.json, ./stc/app/app.*.{html,ts}'
`);
});

commander.parse(process.argv);

if (commander.project && commander.languages) {
runLint(commander.project, commander.languages, commander.zombies, commander.views);
runLint(commander.project, commander.languages, commander.zombies, commander.views, commander.ignore);
} else {
const requiredOptions: OptionModel[] = options.filter((option: OptionModel) => option.required);
const missingRequiredOption: boolean = requiredOptions.reduce((acum: boolean, option: OptionModel) => {
Expand Down
7 changes: 4 additions & 3 deletions src/cli/interface/IArgv.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
interface IArgv {
project?: string;
languages?: string;
views: string;
project: string;
languages: string;
views?: string;
zombies?: string;
help?: boolean;
version?: boolean;
ignore?: string;
}

export { IArgv };
4 changes: 2 additions & 2 deletions src/cli/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ const logger: ILogger = {
},
};

function runLint(project: string, languages: string, zombies?: ErrorTypes, views?: ErrorTypes): void {
function runLint(project: string, languages: string, zombies?: ErrorTypes, views?: ErrorTypes, ignore?: string): void {
try {
const errorConfig: IRulesConfig = {
keysOnViews: views || ErrorTypes.error,
zombieKeys: zombies || ErrorTypes.warning
};
const validationModel: NgxTranslateLint = new NgxTranslateLint(project, languages, errorConfig);
const validationModel: NgxTranslateLint = new NgxTranslateLint(project, languages, ignore, errorConfig);
const validationResult: ResultErrorModel[] = validationModel.lint();
const hasError: boolean = some<ResultErrorModel[]>(validationResult, { 'errorType': ErrorTypes.error });
const hasWarning: boolean = some<ResultErrorModel[]>(validationResult, { 'errorType': ErrorTypes.warning });
Expand Down
7 changes: 5 additions & 2 deletions src/core/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ class NgxTranslateLint {
public projectPath: string;
public languagesPath: string;
public rules: IRulesConfig;
public ignore?: string;

constructor (
projectPath: string = config.defaultValues.projectPath,
languagesPath: string = config.defaultValues.languagesPath,
ignore?: string,
rulesConfig: IRulesConfig = config.defaultValues.rules,
) {
this.languagesPath = languagesPath;
this.projectPath = projectPath;
this.rules = rulesConfig;
this.ignore = ignore;
}

public lint(): ResultErrorModel[] {
Expand All @@ -30,10 +33,10 @@ class NgxTranslateLint {
throw new Error('Error config is incorrect');
}

const languagesKeys: FileLanguageModel = new FileLanguageModel(this.languagesPath).getKeys();
const languagesKeys: FileLanguageModel = new FileLanguageModel(this.languagesPath, [], [], this.ignore).getKeys();
const languagesKeysNames: string[] = flatMap(languagesKeys.keys, (key: KeyModel) => key.name);
const viewsRegExp: RegExp = config.findKeysList(languagesKeysNames);
const views: FileViewModel = new FileViewModel(this.projectPath).getKeys(viewsRegExp);
const views: FileViewModel = new FileViewModel(this.projectPath, [], [], this.ignore).getKeys(viewsRegExp);

const result: ResultErrorModel[] = [];

Expand Down
13 changes: 9 additions & 4 deletions src/core/models/files/FileLanguageModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { KeyModel } from '../KeyModel';
import { FileModel } from './FileModel';

class FileLanguageModel extends FileModel {
constructor(path: string, files: string[] = [], keys: KeyModel[] = []) {
super(path, files, keys);
constructor(
path: string,
files: string[] = [],
keys: KeyModel[] = [],
ignore: string = '',
) {
super(path, files, keys, ignore);
}

public getKeys(): FileLanguageModel {
this.validatePath();
this.setKeys((fileData: string, filePath: string): KeyModel[] => {
this.files = this.getNormalizeFiles();
this.keys = this.parseKeys((fileData: string, filePath: string): KeyModel[] => {
const fileKeysNames: string[] = this.getLanguageKeys(JSON.parse(fileData));
return !fileKeysNames ? [] : fileKeysNames
.filter(x => !!x)
Expand Down
15 changes: 10 additions & 5 deletions src/core/models/files/FileModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,39 @@ abstract class FileModel {
public path: string;
public keys: KeyModel[];
public files: string[];
public ignore: string | undefined;

constructor(
path: string,
files: string[] = [],
keys: KeyModel[] = [],
ignore: string | undefined = undefined,
) {
this.path = path;
this.keys = keys;
this.files = files;
this.ignore = ignore;
}

public validatePath(): void {
this.files = PathUtils.getNormalizeFiles(this.path);
public getNormalizeFiles(): string[] {
const ignorePathList: string[] = this.ignore && this.ignore !== '' ? this.ignore.split(',') : [];
const resultFilesList: string[] = PathUtils.getNormalizeFiles(this.path, ignorePathList);

if (!this.files.length) {
if (!resultFilesList.length) {
throw Error(`Cannot found files for path: '${this.path}'`);
}
return resultFilesList;
}


public setKeys(identity: Function): void {
public parseKeys(identity: Function): KeyModel[] {
const keysModels: KeyModel[] = this.files.reduce((acum: KeyModel[], filePath: string) => {
const fileData: string = fs.readFileSync(filePath).toString();
const models: KeyModel[] = identity(fileData, filePath);
acum.push(...models);
return acum;
}, []);
this.keys = KeysUtils.groupKeysByName(keysModels);
return KeysUtils.groupKeysByName(keysModels);
}
}

Expand Down
13 changes: 9 additions & 4 deletions src/core/models/files/FileViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { FileModel } from "./FileModel";
import { KeyModel } from "./../KeyModel";

class FileViewModel extends FileModel {
constructor(path: string, files: string[] = [], keys: KeyModel[] = []) {
super(path, files, keys);
constructor(
path: string,
files: string[] = [],
keys: KeyModel[] = [],
ignore: string = '',
) {
super(path, files, keys, ignore);
}

public getKeys(regExp: RegExp): FileViewModel {
this.validatePath();
this.setKeys((fileData: string, filePath: string): KeyModel[] => {
this.files = this.getNormalizeFiles();
this.keys = this.parseKeys((fileData: string, filePath: string): KeyModel[] => {
const fileKeysNames: string[] = fileData.match(regExp) as string[];
return !fileKeysNames ? [] : fileKeysNames
.filter(x => !!x)
Expand Down
10 changes: 7 additions & 3 deletions src/core/utils/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ class PathUtils {
return path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath);
}

public static getNormalizeFiles(folder: string): string[] {
const correctPath: string = PathUtils.resolvePath(folder);
return glob.sync(correctPath).map((filePath: string) => {
public static getNormalizeFiles(folder: string, ignores: string[] = []): string[] {
const correctFilesPath: string = PathUtils.resolvePath(folder);
const correctIgnorePath: string[] = ignores.map((path: string) => PathUtils.resolvePath(path.trim()));

return glob.sync(correctFilesPath, {
ignore: correctIgnorePath,
}).map((filePath: string) => {
return path.normalize(filePath);
});
}
Expand Down
44 changes: 39 additions & 5 deletions test/integration/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,42 @@ import {
} from './../../src/core';

import { assertFullModel } from './results/arguments.full';
import { assertDefaultModel } from './results/default.full';
import { assertCustomConfig } from './results/custom.config';

describe('Integration', () => {
const ignorePath: string = '';
const relativePathProject: string = './test/integration/inputs/views/*.{html,ts}';
const relativePathLanguages: string = './test/integration/inputs/locales/*.json';
const ignoreRelativeProject: string = './test/integration/inputs/views/pipe.keys.html';
const ignoreRelativeLanguage: string = './test/integration/inputs/locales/EN-eu.json';

describe('Ignore', () => {
it('should be relative and absolute and have projects and languages files', () => {
// Arrage
const ignoreAbsolutePorjectPath: string = path.resolve(__dirname, process.cwd(), ignoreRelativeProject);
const ignorePath: string = `${ignoreRelativeLanguage}, ${ignoreAbsolutePorjectPath}`;

// Act
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, ignorePath);
const result: ResultErrorModel[] = model.lint();

// Assert
assert.deepEqual(assertFullModel, result);
});

it('should be empty or incorrect', () => {
// Arrage
const ignorePath: string = `null, 0, undefined, '',`;

// Act
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, ignorePath);
const result: ResultErrorModel[] = model.lint();

// Assert
assert.deepEqual(assertDefaultModel, result);
});
});
describe('Path', () => {
it('should be relative and absolute', () => {
// Arrange
Expand All @@ -25,7 +55,7 @@ describe('Integration', () => {
const result: ResultErrorModel[] = model.lint();

// Assert
assert.deepEqual(assertFullModel, result);
assert.deepEqual(assertDefaultModel, result);
});

it('should be empty and incorect', () => {
Expand All @@ -48,7 +78,7 @@ describe('Integration', () => {
const result: ResultErrorModel[] = model.lint();

// Assert
assert.deepEqual(assertFullModel, result);
assert.deepEqual(assertDefaultModel, result);
});
it('should be inccorect', () => {
// Arrage
Expand All @@ -57,8 +87,9 @@ describe('Integration', () => {
anotherInccorectKey: ErrorTypes.disable
};


// Act
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, errorConfig as IRulesConfig);
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, ignorePath, errorConfig as IRulesConfig);

// Assert
expect(() => { model.lint(); }).to.throw();
Expand All @@ -71,7 +102,7 @@ describe('Integration', () => {
};

// Act
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, errorConfig);
const model: NgxTranslateLint = new NgxTranslateLint(relativePathProject, relativePathLanguages, ignorePath, errorConfig);
const result: ResultErrorModel[] = model.lint();

// Assert
Expand All @@ -86,10 +117,13 @@ describe('Integration', () => {
zombieKeys: ErrorTypes.warning,
};
const absolutePathProject: string = path.resolve(__dirname, process.cwd(), relativePathProject);
const ignoreAbsolutePorjectPath: string = path.resolve(__dirname, process.cwd(), ignoreRelativeProject);
const ignorePath: string = `${ignoreRelativeLanguage}, ${ignoreAbsolutePorjectPath}`;

// Act
const model: NgxTranslateLint = new NgxTranslateLint(absolutePathProject, relativePathLanguages, errorConfig);
const model: NgxTranslateLint = new NgxTranslateLint(absolutePathProject, relativePathLanguages, ignorePath, errorConfig);
const result: ResultErrorModel[] = model.lint();

// Assert
assert.deepEqual(assertFullModel, result);
});
Expand Down
36 changes: 7 additions & 29 deletions test/integration/results/arguments.full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { getAbsolutePath, languagesFolder, projectFolder } from '../utils';

const assertFullModel: ResultErrorModel[]= [
new ResultErrorModel(
'OBJECT.KEY_FROM_LOCALE.ABSENT_IN_ALL_VIEWS',
'STRING.KEY_FROM_PIPE_VIEW.EXIST_IN_ALL_LOCALES',
ErrorFlow.zombie, ErrorTypes.warning,
getAbsolutePath(languagesFolder, 'EN-eu.json'),
getAbsolutePath(languagesFolder, 'EN-us.json'),
),
new ResultErrorModel(
'OBJECT.KEY_FROM_PIPE_VIEW.EXIST_IN_ALL_LOCALES',
ErrorFlow.zombie, ErrorTypes.warning,
getAbsolutePath(languagesFolder, 'EN-us.json'),
),
new ResultErrorModel(
'STRING.KEY_FROM_DIRECTIVE_VIEW.EXIST_IN_ONE_LOCALE',
Expand All @@ -23,7 +28,6 @@ const assertFullModel: ResultErrorModel[]= [
ErrorFlow.views, ErrorTypes.error,
getAbsolutePath(projectFolder, 'directive.keys.html'),
[
'EN-eu.json',
'EN-us.json'
]
),
Expand All @@ -40,32 +44,6 @@ const assertFullModel: ResultErrorModel[]= [
ErrorFlow.views, ErrorTypes.error,
getAbsolutePath(projectFolder, 'directive.keys.html'),
[
'EN-eu.json',
'EN-us.json'
]
),
new ResultErrorModel(
'STRING.KEY_FROM_ENUM.EXIST_IN_ONE_LOCALE',
ErrorFlow.views, ErrorTypes.error,
getAbsolutePath(projectFolder, 'enum.keys.ts'),
[
'EN-us.json'
]
),
new ResultErrorModel(
'STRING.KEY_FROM_PIPE_VIEW.EXIST_IN_ONE_LOCALE',
ErrorFlow.views, ErrorTypes.error,
getAbsolutePath(projectFolder, 'pipe.keys.html'),
[
'EN-us.json'
]
),
new ResultErrorModel(
'STRING.KEY_FROM_PIPE_VIEW.ABSENT_IN_ALL_LOCALES',
ErrorFlow.views, ErrorTypes.error,
getAbsolutePath(projectFolder, 'pipe.keys.html'),
[
'EN-eu.json',
'EN-us.json'
]
),
Expand Down
Loading

0 comments on commit 7c99fb9

Please sign in to comment.