feat(ide): ide configs for vs code in vitruvio update-ide

This commit is contained in:
jb
2026-04-14 18:23:36 -03:00
parent 56b362a44a
commit 65472cdb98
2 changed files with 193 additions and 0 deletions
+2
View File
@@ -8,6 +8,7 @@ var initCmd = require('../src/commands/init');
var updateRepoCmd = require('../src/commands/update-repo');
var updateBaseCmd = require('../src/commands/update-base');
var docsCmd = require('../src/commands/docs');
var updateIdeCmd = require('../src/commands/update-ide');
var program = new Command();
@@ -20,5 +21,6 @@ initCmd.register(program);
updateRepoCmd.register(program);
updateBaseCmd.register(program);
docsCmd.register(program);
updateIdeCmd.register(program);
program.parse(process.argv);
+191
View File
@@ -0,0 +1,191 @@
'use strict';
var path = require('path');
var fs = require('fs');
var os = require('os');
var readline = require('readline');
var fse = require('fs-extra');
var { execSync } = require('child_process');
var { cloneWithFallback, cleanupTemp } = require('../utils/git');
var SSH_URL = 'ssh://git@git.davinti.com.br:2222/davinTI/ide-config.git';
var HTTPS_URL = 'https://git.davinti.com.br/davinTI/ide-config.git';
var SUPPORTED_IDES = ['vscode'];
/**
* Returns the VSCode User snippets directory for the current OS.
* Linux/macOS: ~/.config/Code/User/snippets/
* Windows: %APPDATA%\Code\User\snippets\
*/
function getSnippetsDir() {
if (process.platform === 'win32') {
var appData = process.env.APPDATA;
if (!appData) {
throw new Error('APPDATA environment variable is not set.');
}
return path.join(appData, 'Code', 'User', 'snippets');
}
return path.join(os.homedir(), '.config', 'Code', 'User', 'snippets');
}
/**
* Returns the `code` CLI binary name for the current OS.
* Windows ships it as `code.cmd` on PATH.
*/
function getCodeBin() {
return process.platform === 'win32' ? 'code.cmd' : 'code';
}
/**
* Checks whether a VSCode extension is currently installed.
* Returns true/false. Fails silently (returns false) if `code` is unavailable.
*/
function isExtensionInstalled(extensionId) {
try {
var codeBin = getCodeBin();
var output = execSync(codeBin + ' --list-extensions', { stdio: 'pipe' }).toString();
return output.split('\n').some(function (line) {
return line.trim().toLowerCase() === extensionId.toLowerCase();
});
} catch (_) {
return false;
}
}
/**
* Installs a .vsix file using the `code` CLI.
* Always passes --force so it also updates an already-installed extension.
*/
function installVsix(vsixPath) {
var codeBin = getCodeBin();
execSync(codeBin + ' --install-extension "' + vsixPath + '" --force', { stdio: 'inherit' });
}
/**
* Prompts the user to pick an IDE from a numbered list.
* Resolves with the chosen IDE string.
*/
function promptIde() {
return new Promise(function (resolve) {
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
console.log('');
console.log('IDEs disponíveis:');
SUPPORTED_IDES.forEach(function (ide, i) {
console.log(' ' + (i + 1) + '. ' + ide);
});
console.log('');
rl.question('Escolha a IDE [1]: ', function (answer) {
rl.close();
var trimmed = answer.trim();
var index;
if (trimmed === '' || trimmed === '1') {
index = 0;
} else {
index = parseInt(trimmed, 10) - 1;
}
if (isNaN(index) || index < 0 || index >= SUPPORTED_IDES.length) {
console.error('Opção inválida: ' + trimmed);
process.exit(1);
}
resolve(SUPPORTED_IDES[index]);
});
});
}
function register(program) {
program
.command('update-ide')
.description('Instala ou atualiza a extensão Vitruvio e os snippets na IDE escolhida')
.action(function () {
promptIde().then(function (ide) {
console.log('IDE selecionada: ' + ide);
console.log('Buscando repositório ide-config...');
var tmpDir = null;
try {
tmpDir = cloneWithFallback(SSH_URL, HTTPS_URL);
} catch (e) {
console.error('Erro: não foi possível clonar o repositório ide-config.');
console.error(e.message);
process.exit(1);
}
try {
var ideDir = path.join(tmpDir, ide); // e.g. <tmp>/vscode
if (!fs.existsSync(ideDir)) {
console.error('Erro: diretório "' + ide + '" não encontrado no repositório ide-config.');
process.exit(1);
}
// ── Extension ─────────────────────────────────────────────────────
var vsixFiles = fs.readdirSync(ideDir).filter(function (f) {
return f.endsWith('.vsix');
});
if (vsixFiles.length === 0) {
console.log('Aviso: nenhum arquivo .vsix encontrado em ' + ideDir + '. Pulando extensão.');
} else {
var vsixFile = vsixFiles[0];
var vsixPath = path.join(ideDir, vsixFile);
// Derive extension ID from the vsix filename (publisher.name.vsix → publisher.name)
var extId = vsixFile.replace(/\.vsix$/i, '');
var alreadyInstalled = isExtensionInstalled(extId);
if (alreadyInstalled) {
console.log('Extensão já instalada, atualizando ' + extId + '...');
} else {
console.log('Instalando extensão ' + extId + '...');
}
try {
installVsix(vsixPath);
console.log('Extensão instalada com sucesso.');
} catch (e) {
console.error('Erro ao instalar a extensão: ' + e.message);
console.error('Certifique-se de que o comando "code" está disponível no PATH.');
process.exit(1);
}
}
// ── Snippets ───────────────────────────────────────────────────────
var snippetFiles = fs.readdirSync(ideDir).filter(function (f) {
return f.endsWith('.code-snippets');
});
if (snippetFiles.length === 0) {
console.log('Aviso: nenhum arquivo .code-snippets encontrado em ' + ideDir + '. Pulando snippets.');
} else {
var snippetsDir;
try {
snippetsDir = getSnippetsDir();
} catch (e) {
console.error('Erro ao determinar diretório de snippets: ' + e.message);
process.exit(1);
}
fse.ensureDirSync(snippetsDir);
snippetFiles.forEach(function (snippetFile) {
var src = path.join(ideDir, snippetFile);
var dest = path.join(snippetsDir, snippetFile);
var action = fs.existsSync(dest) ? 'atualizado' : 'instalado';
fse.copySync(src, dest);
console.log('Snippet ' + snippetFile + ' ' + action + ' em ' + dest);
});
}
console.log('');
console.log('Configuração da IDE concluída.');
} finally {
cleanupTemp(tmpDir);
}
});
});
}
module.exports = { register: register };