1 | import { Erro, Severity } from './models/Erro';
|
2 | import { Duplicados } from './models/Duplicados';
|
3 | import { Fonte, Funcao, Tipos } from './fonte';
|
4 | import { ItemModel } from './models/ItemProject';
|
5 | import * as globby from 'globby';
|
6 | import * as fileSystem from 'fs';
|
7 | import { ValidaAdvpl } from './validaAdvpl';
|
8 | import { version } from './package.json';
|
9 |
|
10 | export class ValidaProjeto {
|
11 | public projeto: ItemModel[];
|
12 | public comentFontPad: string[];
|
13 | public ownerDb: string[];
|
14 | public empresas: string[];
|
15 | public local;
|
16 | public version: string = version;
|
17 | private advplExtensions = ['prw', 'prx', 'prg', 'apw', 'apl', 'tlpp'];
|
18 | protected listaDuplicados = { files: [], functions: [] };
|
19 |
|
20 | constructor(
|
21 | comentFontePad: string[],
|
22 | local: string,
|
23 | private log: boolean = true
|
24 | ) {
|
25 | this.local = local;
|
26 | this.comentFontPad = comentFontePad;
|
27 | this.ownerDb = [];
|
28 | this.empresas = [];
|
29 | }
|
30 | public async validaProjeto(pathProject: string): Promise<ValidaProjeto> {
|
31 | return new Promise(async (resolve: Function) => {
|
32 | this.projeto = [];
|
33 |
|
34 | let globexp: any[] = [];
|
35 | for (var i = 0; i < this.advplExtensions.length; i++) {
|
36 | globexp.push(`**/*.${this.advplExtensions[i]}`);
|
37 | }
|
38 |
|
39 | let files: string[] = await globby.sync(globexp, {
|
40 | cwd: pathProject,
|
41 | caseSensitiveMatch: false
|
42 | });
|
43 |
|
44 |
|
45 | let promisses: Promise<ValidaAdvpl>[] = [];
|
46 |
|
47 | let startTime: any = new Date();
|
48 | if (this.log) {
|
49 | console.log(startTime);
|
50 | console.log('Analise de Projeto: ' + pathProject);
|
51 | }
|
52 |
|
53 | files.forEach((fileName: string) => {
|
54 | let valida: ValidaAdvpl = new ValidaAdvpl(
|
55 | this.comentFontPad,
|
56 | this.local,
|
57 | this.log
|
58 | );
|
59 | valida.ownerDb = this.ownerDb;
|
60 | valida.empresas = this.empresas;
|
61 |
|
62 | if (this.log) {
|
63 | console.log('Arquivo: ' + fileName);
|
64 | }
|
65 | let conteudo = fileSystem.readFileSync(
|
66 | pathProject + '\\' + fileName,
|
67 | 'latin1'
|
68 | );
|
69 |
|
70 | promisses.push(
|
71 | valida.validacao(conteudo, pathProject + '\\' + fileName)
|
72 | );
|
73 | });
|
74 |
|
75 | Promise.all(promisses).then((validacoes: ValidaAdvpl[]) => {
|
76 | validacoes.forEach((validacao: ValidaAdvpl) => {
|
77 | let itemProjeto = new ItemModel();
|
78 | itemProjeto.content = validacao.conteudoFonte;
|
79 | itemProjeto.errors = validacao.aErros;
|
80 | itemProjeto.fonte = validacao.fonte;
|
81 |
|
82 | this.projeto.push(itemProjeto);
|
83 | });
|
84 |
|
85 |
|
86 | this.verificaDuplicados().then(() => {
|
87 | if (this.log) {
|
88 |
|
89 | let endTime: any = new Date();
|
90 | let timeDiff = endTime - startTime;
|
91 |
|
92 | timeDiff /= 1000;
|
93 |
|
94 |
|
95 | let seconds = Math.round(timeDiff);
|
96 | console.log('Terminou! (' + seconds + ' segundos)');
|
97 | }
|
98 | resolve(this);
|
99 | });
|
100 | });
|
101 | });
|
102 | }
|
103 |
|
104 | public verificaDuplicados(): Promise<Duplicados> {
|
105 | return new Promise((resolve: Function) => {
|
106 | let listaFuncoes: string[] = [];
|
107 | let funcoesDuplicadas: string[] = [];
|
108 | let listaArquivos: string[] = [];
|
109 | let arquivosDuplicados: string[] = [];
|
110 |
|
111 | this.projeto.forEach((item: ItemModel) => {
|
112 | let fonte: Fonte = item.fonte;
|
113 |
|
114 | try {
|
115 | fileSystem.statSync(fonte.fonte);
|
116 |
|
117 | fonte.funcoes.forEach((funcao: Funcao) => {
|
118 |
|
119 | if (
|
120 | funcao.tipo !== Tipos['Static Function'] &&
|
121 | funcao.tipo !== Tipos.Method
|
122 | ) {
|
123 | let functionName: string = (
|
124 | funcao.nome + funcao.tipo
|
125 | ).toUpperCase();
|
126 |
|
127 | if (listaFuncoes.indexOf(functionName) === -1) {
|
128 | listaFuncoes.push(functionName);
|
129 | } else if (funcoesDuplicadas.indexOf(functionName) === -1) {
|
130 | funcoesDuplicadas.push(functionName);
|
131 | }
|
132 | }
|
133 | });
|
134 |
|
135 | let fileName = fonte.fonte
|
136 | .replace(/\\/g, '/')
|
137 | .substring(fonte.fonte.replace(/\\/g, '/').lastIndexOf('/') + 1)
|
138 | .toUpperCase();
|
139 |
|
140 | if (listaArquivos.indexOf(fileName) === -1) {
|
141 | listaArquivos.push(fileName);
|
142 | } else if (arquivosDuplicados.indexOf(fileName) === -1) {
|
143 | arquivosDuplicados.push(fileName);
|
144 | }
|
145 | } catch (e) {
|
146 | if (e.code === 'ENOENT') {
|
147 | item.content = '';
|
148 | item.errors = [];
|
149 | item.fonte.funcoes = [];
|
150 | } else {
|
151 | console.log(`Erro ao validar : ${fonte.fonte}`);
|
152 | console.log(e);
|
153 | }
|
154 | }
|
155 | });
|
156 |
|
157 |
|
158 | let duplicadosOld = JSON.parse(JSON.stringify(this.listaDuplicados));
|
159 | this.listaDuplicados.files = JSON.parse(
|
160 | JSON.stringify(arquivosDuplicados)
|
161 | );
|
162 | this.listaDuplicados.functions = JSON.parse(
|
163 | JSON.stringify(funcoesDuplicadas)
|
164 | );
|
165 |
|
166 |
|
167 | let filesIncluidos = this.listaDuplicados.files.filter(
|
168 | x => duplicadosOld.files.indexOf(x) === -1
|
169 | );
|
170 | let filesExcluidos = duplicadosOld.files.filter(
|
171 | x => this.listaDuplicados.files.indexOf(x) === -1
|
172 | );
|
173 |
|
174 | let functionsIncluidos = this.listaDuplicados.functions.filter(
|
175 | x => duplicadosOld.functions.indexOf(x) === -1
|
176 | );
|
177 | let functionsExcluidos = duplicadosOld.functions.filter(
|
178 | x => this.listaDuplicados.functions.indexOf(x) === -1
|
179 | );
|
180 |
|
181 | // marca duplicados
|
182 | this.projeto.forEach((item: ItemModel) => {
|
183 | let fonte: Fonte = item.fonte;
|
184 |
|
185 | fonte.funcoes.forEach((funcao: Funcao) => {
|
186 | let functionName: string = (funcao.nome + funcao.tipo).toUpperCase();
|
187 | //adiciona o erro
|
188 | if (functionsIncluidos.indexOf(functionName) > -1) {
|
189 | item.errors.push(
|
190 | new Erro(
|
191 | funcao.linha,
|
192 | funcao.linha,
|
193 | traduz('validaAdvpl.functionDuplicate', this.local),
|
194 | Severity.Error
|
195 | )
|
196 | );
|
197 | }
|
198 | if (functionsExcluidos.indexOf(functionName) > -1) {
|
199 | item.errors = item.errors.filter((erro: Erro) => {
|
200 | return (
|
201 | erro.message !==
|
202 | traduz('validaAdvpl.functionDuplicate', this.local) ||
|
203 | funcao.linha !== erro.startLine
|
204 | );
|
205 | });
|
206 | }
|
207 | });
|
208 |
|
209 | let fileName = fonte.fonte
|
210 | .replace(/\\/g, '/')
|
211 | .substring(fonte.fonte.replace(/\\/g, '/').lastIndexOf('/') + 1)
|
212 | .toUpperCase();
|
213 |
|
214 | if (filesIncluidos.indexOf(fileName) > -1) {
|
215 | item.errors.push(
|
216 | new Erro(
|
217 | 0,
|
218 | 0,
|
219 | traduz('validaAdvpl.fileDuplicate', this.local),
|
220 | Severity.Error
|
221 | )
|
222 | );
|
223 | } else if (filesExcluidos.indexOf(fileName) > -1) {
|
224 | item.errors = item.errors.filter((erro: Erro) => {
|
225 | return (
|
226 | erro.message !== traduz('validaAdvpl.fileDuplicate', this.local)
|
227 | );
|
228 | });
|
229 | }
|
230 | });
|
231 | if (this.log) {
|
232 | let errosContagem: any = this.contaErros();
|
233 |
|
234 | console.log(`\t${errosContagem.errors} Errors`);
|
235 | console.log(`\t${errosContagem.warnings} Warnings`);
|
236 | console.log(`\t${errosContagem.information} Informations`);
|
237 | console.log(`\t${errosContagem.hint} Hints`);
|
238 | }
|
239 | resolve();
|
240 | });
|
241 | }
|
242 | public contaErros(): any {
|
243 | let erros: any = { errors: 0, warnings: 0, information: 0, hint: 0 };
|
244 |
|
245 | this.projeto.forEach((item: ItemModel) => {
|
246 | item.errors.forEach((erro: Erro) => {
|
247 | if (erro.severity === Severity.Error) {
|
248 | erros.errors++;
|
249 | } else if (erro.severity === Severity.Warning) {
|
250 | erros.warnings++;
|
251 | } else if (erro.severity === Severity.Information) {
|
252 | erros.information++;
|
253 | } else if (erro.severity === Severity.Hint) {
|
254 | erros.hint++;
|
255 | }
|
256 | });
|
257 | });
|
258 | return erros;
|
259 | }
|
260 | }
|
261 |
|
262 | function traduz(key, local) {
|
263 | let locales: string[] = ['en', 'pt-br'];
|
264 | let i18n = require('i18n');
|
265 | i18n.configure({
|
266 | locales: locales,
|
267 | directory: __dirname + '/locales'
|
268 | });
|
269 | i18n.setLocale(locales.indexOf(local) + 1 ? local : 'en');
|
270 | return i18n.__(key);
|
271 | }
|