@caioms/pre-git-auto-format 1.0.0 → 1.2.1
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.
- package/.lintstagedrc.json +5 -0
- package/package.json +24 -10
- package/postinstall.js +190 -0
- package/bin/setup.js +0 -148
package/package.json
CHANGED
@@ -1,16 +1,30 @@
|
|
1
1
|
{
|
2
2
|
"name": "@caioms/pre-git-auto-format",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.2.1",
|
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
|
-
"
|
6
|
-
|
7
|
-
"bin": {
|
8
|
-
"setup-caioms-hooks": "./bin/setup.js"
|
23
|
+
"dependencies": {
|
24
|
+
"@caioms/biomejs-config": "latest"
|
9
25
|
},
|
10
|
-
"files": ["bin/"],
|
11
26
|
"peerDependencies": {
|
12
|
-
"
|
13
|
-
"
|
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();
|