Commit d829ee47 authored by Ivan Mazhukin's avatar Ivan Mazhukin

Fix VS Code extension path detection and build

parent 00cd32cb
.vscode/**
.gitignore
*.vsix
node_modules/**
......@@ -6,7 +6,7 @@
1. Откройте эту папку в VS Code: `vscode-extension`.
2. Нажмите `F5`, чтобы запустить Extension Development Host.
3. В открывшемся окне откройте репозиторий с `epm-docker-test.sh`.
3. В открывшемся окне откройте репозиторий `eepm` или любой его подкаталог.
4. Используйте панель `EPM Test` на боковой панели активности или кнопку `$(beaker) EPM Test` в строке состояния.
Расширение запускает команды в обычном терминале VS Code, поэтому вывод и интерактивные сообщения остаются видимыми.
......@@ -26,11 +26,12 @@ rsync -a --delete ./ ~/.vscode/extensions/eter.epm-docker-test-runner-0.1.0/
```bash
cd vscode-extension
npm install -g @vscode/vsce
vsce package
code --install-extension epm-docker-test-runner-0.1.0.vsix
npm install
npm run build
npm run package:install
```
Скрипт `npm run build` собирает файл `epm-docker-test-runner.vsix`.
Этот же VSIX можно установить через команду VS Code `Extensions: Install from VSIX...`.
## Действия
......@@ -78,7 +79,19 @@ code --install-extension epm-docker-test-runner-0.1.0.vsix
- `epmDockerTest.defaultMode`: `auto`, `local` или `remote`.
- `epmDockerTest.latest`: передавать `--latest`.
- `epmDockerTest.parallelJobs`: передавать `-j N`, если значение больше `1`.
- `epmDockerTest.localEpmRoot`: локальное дерево eepm для команд `./bin/epm play` вне контейнера.
- `epmDockerTest.localEpmRoot`: локальное дерево eepm для команд `./bin/epm play` вне контейнера; если пусто, путь определяется автоматически.
- `epmDockerTest.eepmDir`, `epmDockerTest.eepmSource`, `epmDockerTest.remoteHost`, `epmDockerTest.remoteUser`, `epmDockerTest.builderUser`, `epmDockerTest.builderPath`, `epmDockerTest.logRoot`: соответствуют одноимённым опциям скрипта.
Для Docker-тестов автоопределение предпочитает ближайший родительский каталог активного файла, в котором есть и `bin/epm`, и `epm-docker-test.sh`. Этот каталог используется как рабочий каталог команды, а его `epm-docker-test.sh` используется как запускаемый скрипт.
## Автоопределение путей
Если `epmDockerTest.scriptPath` и `epmDockerTest.localEpmRoot` не заданы, расширение ищет ближайший родительский каталог с `bin/epm`:
1. Сначала от активного файла.
2. Затем от корня открытого workspace.
3. Затем от каталога самого расширения в режиме разработки.
Найденный каталог считается корнем репозитория. Из него автоматически берутся:
- `./bin/epm` для команд `Local ./bin/epm play`.
- `./epm-docker-test.sh` для Docker-тестов.
- Рабочий каталог команды, если `epmDockerTest.workingDirectory` не задан.
......@@ -279,20 +279,18 @@ async function runExec() {
}
async function runLocalPlay(latest) {
const eepmRoot = resolveWorkspacePath(getConfig().get('localEpmRoot', '/home/vano/eter/static2/eepm'));
const epm = path.join(eepmRoot, 'bin', 'epm');
if (!fs.existsSync(epm)) {
vscode.window.showErrorMessage(`Could not find local epm: ${epm}`);
const repoRoot = resolveLocalEpmRoot();
if (!repoRoot) {
return;
}
const inferred = inferAppFromActiveEditor(eepmRoot);
const inferred = inferAppFromActiveEditor(repoRoot);
const app = await promptForApp({
title: latest ? 'Local epm play --latest' : 'Local epm play',
prompt: 'Application name for local ./bin/epm play',
fallbackKey: 'lastLocalApp',
inferred
inferred,
repoRoot
});
if (!app) {
......@@ -307,7 +305,7 @@ async function runLocalPlay(latest) {
const command = [
'cd',
shellQuote(eepmRoot),
shellQuote(repoRoot),
'&&',
'./bin/epm',
...args.map(shellQuote)
......@@ -320,7 +318,7 @@ async function runLocalPlay(latest) {
}
async function promptForApp(options) {
const inferred = options.inferred || inferAppFromActiveEditor(resolveWorkspacePath(getConfig().get('localEpmRoot', '/home/vano/eter/static2/eepm')));
const inferred = options.inferred || inferAppFromActiveEditor(options.repoRoot || findRepositoryRoot());
const fallback = getWorkspaceState(options.fallbackKey, getWorkspaceState('lastApp', ''));
const initialValue = inferred?.app || fallback;
......@@ -606,13 +604,14 @@ function configuredLogRoot() {
function resolvePaths() {
const config = getConfig();
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
const workspaceFolders = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath) || [];
const workspaceFolder = workspaceFolders[0];
const configuredScript = config.get('scriptPath', '').trim();
const configuredCwd = config.get('workingDirectory', '').trim();
const detectedEepmRoot = configuredCwd ? undefined : findEepmRootFromActiveEditor();
const detectedRepoRoot = configuredCwd ? findParentWithBinEpm(resolveWorkspacePath(configuredCwd)) : findRepositoryRoot();
const script = configuredScript
? resolveWorkspacePath(configuredScript)
: findScript(workspaceFolder, detectedEepmRoot);
: findScript(workspaceFolders, detectedRepoRoot);
if (!script || !fs.existsSync(script)) {
vscode.window.showErrorMessage('Could not find epm-docker-test.sh. Set epmDockerTest.scriptPath.');
......@@ -621,29 +620,71 @@ function resolvePaths() {
const cwd = configuredCwd
? resolveWorkspacePath(configuredCwd)
: detectedEepmRoot || workspaceFolder || path.dirname(script);
: detectedRepoRoot || workspaceFolder || path.dirname(script);
return { script, cwd };
}
function findScript(workspaceFolder, detectedEepmRoot) {
function findScript(workspaceFolders, detectedRepoRoot) {
const candidates = [];
if (detectedEepmRoot) {
candidates.push(path.join(detectedEepmRoot, 'epm-docker-test.sh'));
if (detectedRepoRoot) {
candidates.push(path.join(detectedRepoRoot, 'epm-docker-test.sh'));
}
if (workspaceFolder) {
for (const workspaceFolder of workspaceFolders) {
candidates.push(
path.join(workspaceFolder, 'epm-docker-test.sh'),
path.join(workspaceFolder, 'epm-docker-test', 'epm-docker-test.sh')
);
}
candidates.push(path.resolve(__dirname, '..', 'epm-docker-test.sh'));
const extensionRepoRoot = findParentWithBinEpm(__dirname);
if (extensionRepoRoot) {
candidates.push(path.join(extensionRepoRoot, 'epm-docker-test.sh'));
} else {
candidates.push(path.resolve(__dirname, '..', 'epm-docker-test.sh'));
}
return candidates.find((candidate) => fs.existsSync(candidate));
}
function findEepmRootFromActiveEditor() {
const editor = vscode.window.activeTextEditor;
const filePath = editor?.document?.uri?.scheme === 'file' ? editor.document.uri.fsPath : undefined;
function resolveLocalEpmRoot() {
const configuredRoot = getConfig().get('localEpmRoot', '').trim();
if (configuredRoot) {
const resolvedRoot = resolveWorkspacePath(configuredRoot);
const epm = path.join(resolvedRoot, 'bin', 'epm');
if (fs.existsSync(epm)) {
return resolvedRoot;
}
vscode.window.showErrorMessage(`Could not find local epm: ${epm}`);
return undefined;
}
const detectedRoot = findRepositoryRoot();
if (detectedRoot) {
return detectedRoot;
}
vscode.window.showErrorMessage('Could not find a repository root with bin/epm. Open the eepm repository or set epmDockerTest.localEpmRoot.');
return undefined;
}
function findRepositoryRoot() {
const candidates = [
getActiveEditorFilePath(),
...(vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath) || []),
__dirname
];
for (const candidate of candidates) {
const root = findParentWithBinEpm(candidate);
if (root) {
return root;
}
}
return undefined;
}
function findParentWithBinEpm(filePath) {
if (!filePath) {
return undefined;
}
......@@ -654,11 +695,9 @@ function findEepmRootFromActiveEditor() {
} catch {
return undefined;
}
while (current && current !== path.dirname(current)) {
if (
fs.existsSync(path.join(current, 'bin', 'epm')) &&
fs.existsSync(path.join(current, 'epm-docker-test.sh'))
) {
if (fs.existsSync(path.join(current, 'bin', 'epm'))) {
return current;
}
current = path.dirname(current);
......@@ -668,8 +707,7 @@ function findEepmRootFromActiveEditor() {
}
function inferAppFromActiveEditor(eepmRoot) {
const editor = vscode.window.activeTextEditor;
const filePath = editor?.document?.uri?.scheme === 'file' ? editor.document.uri.fsPath : undefined;
const filePath = getActiveEditorFilePath();
if (!filePath) {
return undefined;
}
......@@ -682,11 +720,16 @@ function inferAppFromActiveEditor(eepmRoot) {
const baseName = path.basename(filePath, path.extname(filePath));
const parsed = inferAppFromFileContent(filePath);
const app = parsed || baseName;
const relative = path.relative(eepmRoot, filePath);
const relative = eepmRoot ? path.relative(eepmRoot, filePath) : undefined;
const source = relative && !relative.startsWith('..') ? relative : filePath;
return { app, source };
}
function getActiveEditorFilePath() {
const editor = vscode.window.activeTextEditor;
return editor?.document?.uri?.scheme === 'file' ? editor.document.uri.fsPath : undefined;
}
function inferAppFromFileContent(filePath) {
try {
const text = fs.readFileSync(filePath, 'utf8').slice(0, 8192);
......
......@@ -4,9 +4,21 @@
"description": "VS Code buttons for running epm-docker-test.sh test commands.",
"version": "0.1.0",
"publisher": "eter",
"repository": {
"type": "git",
"url": "https://gitlab.eterfund.ru/vanomj/epm-docker-test.git"
},
"engines": {
"vscode": "^1.85.0"
},
"scripts": {
"build": "npm run package",
"package": "vsce package --no-dependencies --out epm-docker-test-runner.vsix",
"package:install": "code --install-extension ./epm-docker-test-runner.vsix"
},
"devDependencies": {
"@vscode/vsce": "^3.6.1"
},
"categories": [
"Other"
],
......@@ -22,7 +34,7 @@
"onCommand:epmDockerTest.runLocalPlay",
"onCommand:epmDockerTest.runLocalPlayLatest"
],
"main": "./extension.js",
"main": "extension.js",
"contributes": {
"commands": [
{
......@@ -76,12 +88,12 @@
"epmDockerTest.scriptPath": {
"type": "string",
"default": "",
"description": "Path to epm-docker-test.sh. Empty means auto-detect in the workspace."
"description": "Path to epm-docker-test.sh. Empty means auto-detect it from the nearest repository root with bin/epm."
},
"epmDockerTest.workingDirectory": {
"type": "string",
"default": "",
"description": "Working directory for test commands. Empty means the workspace folder or script directory."
"description": "Working directory for test commands. Empty means the detected repository root or the workspace folder."
},
"epmDockerTest.defaultSystems": {
"type": "string",
......@@ -160,8 +172,8 @@
},
"epmDockerTest.localEpmRoot": {
"type": "string",
"default": "/home/vano/eter/static2/eepm",
"description": "Path to the local eepm tree used by local ./bin/epm play commands."
"default": "",
"description": "Path to the local eepm tree used by local ./bin/epm play commands. Empty means auto-detect the nearest repository root with bin/epm."
},
"epmDockerTest.additionalArgs": {
"type": "array",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment