feat(ide): ide configs for vs code in vitruvio update-ide
This commit is contained in:
@@ -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 };
|
||||
Reference in New Issue
Block a user