UNPKG

9.05 kBPlain TextView Raw
1import { Erro, Severity } from './models/Erro';
2import { Duplicados } from './models/Duplicados';
3import { Fonte, Funcao, Tipos } from './fonte';
4import { ItemModel } from './models/ItemProject';
5import * as globby from 'globby';
6import * as fileSystem from 'fs';
7import { ValidaAdvpl } from './validaAdvpl';
8import { version } from './package.json';
9
10export 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 // monta expressão para buscar arquivos
34 let globexp: any[] = [];
35 for (var i = 0; i < this.advplExtensions.length; i++) {
36 globexp.push(`**/*.${this.advplExtensions[i]}`);
37 }
38 // busca arquivos na pasta
39 let files: string[] = await globby.sync(globexp, {
40 cwd: pathProject,
41 caseSensitiveMatch: false
42 });
43
44 // valida arquivos
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 // verifica duplicados
86 this.verificaDuplicados().then(() => {
87 if (this.log) {
88 // calcula tempo gasto
89 let endTime: any = new Date();
90 let timeDiff = endTime - startTime; //in ms
91 // strip the ms
92 timeDiff /= 1000;
93
94 // get seconds
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 //verifica se o fonte ainda existe
114 try {
115 fileSystem.statSync(fonte.fonte);
116
117 fonte.funcoes.forEach((funcao: Funcao) => {
118 // não aponta como duplicadas as static Functions ou metodos
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 //monta lista de funções duplicadas
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 //monta lista de qrquivos duplicados
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 // guarda lista de duplicados
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 //Procura o que mudou
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 //adiciona o erro
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
262function 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}