@caioms/pre-git-auto-format 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ {
2
+ "*.{js,jsx,ts,tsx,mjs,cjs}": [
3
+ "npx biome format --write"
4
+ ]
5
+ }
package/package.json CHANGED
@@ -1,16 +1,30 @@
1
1
  {
2
2
  "name": "@caioms/pre-git-auto-format",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
+ "description": "Automatic pre-commit formatting with BiomeJS and lint-staged",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "postinstall": "node postinstall.js"
8
+ },
9
+ "files": [
10
+ ".lintstagedrc.json",
11
+ "postinstall.js"
12
+ ],
13
+ "keywords": [
14
+ "lint-staged",
15
+ "husky",
16
+ "biome",
17
+ "pre-commit",
18
+ "formatting",
19
+ "git-hooks"
20
+ ],
21
+ "author": "Caio Marques Silva",
4
22
  "license": "MIT",
5
- "main": "biome.json",
6
- "private": false,
7
- "bin": {
8
- "setup-caioms-hooks": "./bin/setup.js"
23
+ "dependencies": {
24
+ "@caioms/biomejs-config": "^1.1.1"
9
25
  },
10
- "files": ["bin/"],
11
26
  "peerDependencies": {
12
- "husky": "^9.1.6",
13
- "lint-staged": "^12.3.2",
14
- "@caioms/biomejs-config": "^1.0.0"
27
+ "lint-staged": "^15.0.0",
28
+ "husky": "^9.0.0"
15
29
  }
16
- }
30
+ }
package/postinstall.js ADDED
@@ -0,0 +1,190 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execSync } = require('child_process');
4
+
5
+ const YOUR_PACKAGE_NAME = '@caioms/pre-git-auto-format';
6
+
7
+ console.log('🚀 Configurando formatação automática pré-commit...\n');
8
+
9
+ // Função para verificar se um pacote está instalado
10
+ function isPackageInstalled(packageName) {
11
+ try {
12
+ require.resolve(packageName);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ // Função para instalar pacotes
20
+ function installPackage(packageName, isDev = true) {
21
+ const devFlag = isDev ? '--save-dev' : '';
22
+ console.log(`⚡ Instalando ${packageName}...`);
23
+ try {
24
+ execSync(`npm install ${packageName} ${devFlag}`, { stdio: 'inherit' });
25
+ console.log(`✅ ${packageName} instalado com sucesso`);
26
+ } catch (error) {
27
+ console.error(`❌ Erro ao instalar ${packageName}:`, error.message);
28
+ throw error;
29
+ }
30
+ }
31
+
32
+ // Função para executar comando
33
+ function runCommand(command, description) {
34
+ console.log(`⚡ ${description}...`);
35
+ try {
36
+ execSync(command, { stdio: 'inherit' });
37
+ console.log(`✅ ${description} concluído`);
38
+ } catch (error) {
39
+ console.error(`❌ Erro ao ${description.toLowerCase()}:`, error.message);
40
+ throw error;
41
+ }
42
+ }
43
+
44
+ // Função para criar/atualizar arquivo
45
+ function createOrUpdateFile(filePath, content, description) {
46
+ try {
47
+ const dir = path.dirname(filePath);
48
+ if (!fs.existsSync(dir)) {
49
+ fs.mkdirSync(dir, { recursive: true });
50
+ }
51
+
52
+ fs.writeFileSync(filePath, content);
53
+ console.log(`✅ ${description} criado/atualizado`);
54
+ } catch (error) {
55
+ console.error(`❌ Erro ao criar ${description}:`, error.message);
56
+ throw error;
57
+ }
58
+ }
59
+
60
+ // Função para copiar arquivo do pacote
61
+ function copyConfigFile(fileName, description) {
62
+ try {
63
+ const sourcePath = path.join(__dirname, fileName);
64
+ const targetPath = path.join(process.cwd(), fileName);
65
+
66
+ if (!fs.existsSync(targetPath)) {
67
+ const content = fs.readFileSync(sourcePath, 'utf8');
68
+ fs.writeFileSync(targetPath, content);
69
+ console.log(`✅ ${description} criado`);
70
+ } else {
71
+ console.log(`ℹ️ ${description} já existe - mantendo configuração atual`);
72
+ }
73
+ } catch (error) {
74
+ console.error(`❌ Erro ao copiar ${description}:`, error.message);
75
+ throw error;
76
+ }
77
+ }
78
+
79
+ try {
80
+ // 1. Verificar e instalar lint-staged
81
+ if (!isPackageInstalled('lint-staged')) {
82
+ installPackage('lint-staged');
83
+ } else {
84
+ console.log('✅ lint-staged já está instalado');
85
+ }
86
+
87
+ // 2. Verificar e instalar husky
88
+ if (!isPackageInstalled('husky')) {
89
+ installPackage('husky');
90
+ } else {
91
+ console.log('✅ husky já está instalado');
92
+ }
93
+
94
+ // 3. Copiar configuração do lint-staged
95
+ copyConfigFile('.lintstagedrc.json', 'Configuração do lint-staged');
96
+
97
+ // 4. Inicializar husky (cria .husky se não existir)
98
+ if (!fs.existsSync('.husky')) {
99
+ runCommand('npx husky init', 'Inicializando husky');
100
+ } else {
101
+ console.log('✅ Husky já está inicializado');
102
+ }
103
+
104
+ // 5. Verificar se existe repositório git
105
+ if (!fs.existsSync('.git')) {
106
+ console.log('⚠️ Repositório git não encontrado. Execute "git init" primeiro.');
107
+ }
108
+
109
+ // 6. Configurar pre-commit hook
110
+ const preCommitPath = path.join('.husky', 'pre-commit');
111
+ const preCommitContent = '#!/usr/bin/env sh\n. "$(dirname -- "$0")/_/husky.sh"\n\nnpx lint-staged\n';
112
+
113
+ if (!fs.existsSync(preCommitPath)) {
114
+ createOrUpdateFile(preCommitPath, preCommitContent, 'Hook pre-commit');
115
+ // Dar permissão de execução no hook (Unix/Linux/Mac)
116
+ try {
117
+ fs.chmodSync(preCommitPath, 0o755);
118
+ } catch (error) {
119
+ // Ignora erro de chmod no Windows
120
+ }
121
+ } else {
122
+ // Verificar se já contém o comando lint-staged
123
+ const existingContent = fs.readFileSync(preCommitPath, 'utf8');
124
+ if (!existingContent.includes('npx lint-staged')) {
125
+ // Adicionar ao final do arquivo existente
126
+ const updatedContent = existingContent.trim() + '\n\nnpx lint-staged\n';
127
+ createOrUpdateFile(preCommitPath, updatedContent, 'Hook pre-commit (atualizado)');
128
+ } else {
129
+ console.log('ℹ️ Hook pre-commit já contém lint-staged - nenhuma alteração necessária');
130
+ }
131
+ }
132
+
133
+ // 7. Verificar package.json para adicionar scripts úteis (opcional)
134
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
135
+ if (fs.existsSync(packageJsonPath)) {
136
+ try {
137
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
138
+ let updated = false;
139
+
140
+ if (!packageJson.scripts) {
141
+ packageJson.scripts = {};
142
+ }
143
+
144
+ // Adicionar script de prepare se não existir
145
+ if (!packageJson.scripts.prepare) {
146
+ packageJson.scripts.prepare = 'husky';
147
+ updated = true;
148
+ }
149
+
150
+ // Adicionar script de lint se não existir
151
+ if (!packageJson.scripts.lint) {
152
+ packageJson.scripts.lint = 'biome check .';
153
+ updated = true;
154
+ }
155
+
156
+ // Adicionar script de format se não existir
157
+ if (!packageJson.scripts.format) {
158
+ packageJson.scripts.format = 'biome format --write .';
159
+ updated = true;
160
+ }
161
+
162
+ if (updated) {
163
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
164
+ console.log('✅ Scripts úteis adicionados ao package.json');
165
+ }
166
+ } catch (error) {
167
+ console.log('⚠️ Não foi possível atualizar scripts no package.json:', error.message);
168
+ }
169
+ }
170
+
171
+ console.log('\n🎉 Configuração concluída com sucesso!');
172
+ console.log('\n📋 O que foi configurado:');
173
+ console.log(' • BiomeJS (via @caioms/biomejs-config)');
174
+ console.log(' • lint-staged com configuração para biome format');
175
+ console.log(' • Husky com hook pre-commit');
176
+ console.log(' • Scripts úteis no package.json');
177
+ console.log('\n🔧 Scripts disponíveis:');
178
+ console.log(' • npm run lint - Verificar código');
179
+ console.log(' • npm run format - Formatar código');
180
+ console.log(' • npm run prepare - Configurar husky');
181
+ console.log('\n✨ Agora seus commits serão formatados automaticamente!');
182
+
183
+ } catch (error) {
184
+ console.error('\n❌ Falha na configuração:', error.message);
185
+ console.log('\n🔧 Tente executar manualmente:');
186
+ console.log(' 1. npm install lint-staged husky --save-dev');
187
+ console.log(' 2. npx husky init');
188
+ console.log(' 3. echo "npx lint-staged" > .husky/pre-commit');
189
+ process.exit(1);
190
+ }
package/bin/setup.js DELETED
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env node
2
- // ^ Garante que o script seja executado com Node.js
3
-
4
- const fs = require('fs');
5
- const path = require('path');
6
- const { execSync } = require('child_process');
7
-
8
- const projectRoot = process.cwd(); // Diretório raiz do projeto consumidor
9
-
10
- function runCommand(command) {
11
- try {
12
- console.log(`Executando: ${command}`);
13
- execSync(command, { stdio: 'inherit', cwd: projectRoot });
14
- return true;
15
- } catch (error) {
16
- console.error(`Falha ao executar: ${command}`, error);
17
- return false;
18
- }
19
- }
20
-
21
- function fileExists(filePath) {
22
- return fs.existsSync(path.join(projectRoot, filePath));
23
- }
24
-
25
- function writeJsonFile(filePath, data) {
26
- fs.writeFileSync(path.join(projectRoot, filePath), JSON.stringify(data, null, 4));
27
- console.log(`Arquivo criado/atualizado: ${filePath}`);
28
- }
29
-
30
- function main() {
31
- console.log('Configurando hooks de pré-commit com @caioms/pre-git-auto-format...');
32
-
33
- // Etapa 0: Verificar se as peerDependencies estão instaladas (informativo)
34
- // Idealmente, o gerenciador de pacotes já cuidou disso ou emitiu avisos.
35
- // Uma verificação mais robusta poderia tentar importar os módulos.
36
- console.log('Verificando dependências peer necessárias (husky, lint-staged, @biomejs/biome, @caioms/biomejs-config)...');
37
- // (Você pode adicionar uma lógica mais sofisticada aqui para verificar se os pacotes existem em node_modules)
38
-
39
- // Etapa 1: Inicializar Husky (se não existir .husky)
40
- if (!fileExists('.husky')) {
41
- if (!runCommand('npx husky init')) {
42
- console.error('Falha ao inicializar o Husky. Por favor, verifique se o Husky está instalado e tente novamente.');
43
- process.exit(1);
44
- }
45
- } else {
46
- console.log('.husky já existe, pulando inicialização.');
47
- }
48
-
49
- // Etapa 2: Adicionar/Atualizar o hook pre-commit do Husky
50
- const preCommitHookPath = path.join('.husky', 'pre-commit');
51
- const preCommitCommand = 'npx lint-staged';
52
- // Poderíamos verificar se o comando já existe, mas para simplificar, vamos sobrescrever.
53
- // Em uma versão mais avançada, você poderia tentar adicionar ao invés de sobrescrever.
54
- console.log(`Configurando hook pre-commit para executar: "${preCommitCommand}"`);
55
- fs.writeFileSync(path.join(projectRoot, preCommitHookPath), `#!/usr/bin/env sh
56
- . "$(dirname -- "$0")/_/husky.sh"
57
-
58
- ${preCommitCommand}
59
- `);
60
- runCommand(`chmod +x ${preCommitHookPath}`); // Tornar executável
61
- console.log(`Hook pre-commit configurado em: ${preCommitHookPath}`);
62
-
63
-
64
- // Etapa 3: Criar/Atualizar o arquivo de configuração do lint-staged
65
- const lintStagedConfig = {
66
- "*.{js,jsx,ts,tsx,mjs,cjs}": ["npx biome format --write"],
67
- // Você pode adicionar mais padrões aqui se desejar, por exemplo, para JSON, Markdown, etc.
68
- // "*.{json,md}": ["npx biome format --write"]
69
- };
70
- // lint-staged suporta vários nomes de arquivo de configuração.
71
- // .lintstagedrc.json é uma boa escolha.
72
- writeJsonFile('.lintstagedrc.json', lintStagedConfig);
73
-
74
-
75
- // Etapa 4: Garantir que o biome.json do projeto estenda o seu @caioms/biomejs-config
76
- const biomeConfigPath = 'biome.json';
77
- let projectBiomeConfig = {};
78
-
79
- if (fileExists(biomeConfigPath)) {
80
- try {
81
- projectBiomeConfig = JSON.parse(fs.readFileSync(path.join(projectRoot, biomeConfigPath), 'utf-8'));
82
- } catch (e) {
83
- console.warn(`Aviso: Não foi possível ler o ${biomeConfigPath} existente. Ele será sobrescrito com a configuração base.`);
84
- projectBiomeConfig = {};
85
- }
86
- }
87
-
88
- const biomeExtendsValue = '@caioms/biomejs-config';
89
- if (projectBiomeConfig.extends) {
90
- if (Array.isArray(projectBiomeConfig.extends)) {
91
- if (!projectBiomeConfig.extends.includes(biomeExtendsValue)) {
92
- projectBiomeConfig.extends.push(biomeExtendsValue);
93
- }
94
- } else if (projectBiomeConfig.extends !== biomeExtendsValue) {
95
- // Se extends é uma string e não é a nossa, transforma em array
96
- projectBiomeConfig.extends = [projectBiomeConfig.extends, biomeExtendsValue];
97
- }
98
- // Se já for a string correta, não faz nada
99
- } else {
100
- projectBiomeConfig.extends = [biomeExtendsValue];
101
- }
102
-
103
- // Adiciona um $schema se não existir, para melhor autocompletar no editor
104
- if (!projectBiomeConfig.$schema) {
105
- projectBiomeConfig.$schema = "./node_modules/@biomejs/biome/configuration_schema.json";
106
- }
107
-
108
- writeJsonFile(biomeConfigPath, projectBiomeConfig);
109
-
110
-
111
- // Etapa 5: (Opcional) Adicionar script "prepare" ao package.json do consumidor
112
- // Isso é útil para Husky v7+ para instalar automaticamente os hooks após o `npm install`
113
- try {
114
- const packageJsonPath = path.join(projectRoot, 'package.json');
115
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
116
- if (!packageJson.scripts) {
117
- packageJson.scripts = {};
118
- }
119
- if (packageJson.scripts.prepare !== 'husky' && packageJson.scripts.prepare !== 'husky install') { // Evita conflitos se já existir
120
- // Se houver outro script prepare, avisa o usuário.
121
- // Para simplificar, aqui vamos apenas adicionar se não existir ou for diferente.
122
- // Uma solução mais robusta poderia tentar concatenar comandos.
123
- if (packageJson.scripts.prepare) {
124
- console.warn(`Aviso: O projeto já possui um script "prepare": "${packageJson.scripts.prepare}". Não foi possível adicionar "husky" automaticamente. Considere adicionar "husky" ou "husky install" manualmente ao seu script "prepare".`);
125
- } else {
126
- packageJson.scripts.prepare = 'husky'; // Para Husky v9+
127
- // ou 'husky install' para Husky v7/v8
128
- // Detectar a versão do Husky instalada pode ser mais robusto aqui.
129
- // Por simplicidade, vamos usar 'husky' assumindo v9+.
130
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
131
- console.log('Script "prepare": "husky" adicionado/atualizado no package.json.');
132
- }
133
- }
134
- } catch (error) {
135
- console.warn('Não foi possível modificar o package.json para adicionar o script "prepare".', error);
136
- }
137
-
138
- console.log('\nConfiguração concluída com sucesso!');
139
- console.log('Certifique-se de que as seguintes dependências estão instaladas no seu projeto:');
140
- console.log(' npm install --save-dev husky lint-staged @biomejs/biome @caioms/biomejs-config');
141
- console.log(' (ou use pnpm/yarn)');
142
- console.log('\nPróximos passos:');
143
- console.log('1. Adicione arquivos ao git stage (git add .).');
144
- console.log('2. Tente fazer um commit (git commit -m "test").');
145
- console.log('O Biome deve formatar seus arquivos automaticamente antes do commit.');
146
- }
147
-
148
- main();