Create multiple workflows for different actions
This commit is contained in:
@@ -3,37 +3,52 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { ScriptCompiler, ScriptCompilerOptions, CompilationError, ICompilationLogger } from 'dcs-script-compiler';
|
||||
import { Logger } from './logger';
|
||||
import * as luaAddonsManager from './lua-addons-manager';
|
||||
|
||||
const luaWorkSpaceSettingKey = "Lua.workspace";
|
||||
const librarySettingsKey = "library";
|
||||
const diagnosticCollection = vscode.languages.createDiagnosticCollection('lua-transpiler');
|
||||
|
||||
let pluginPath : string | undefined;
|
||||
|
||||
const logger = new Logger();
|
||||
|
||||
const extensionName = 'dutchies-dcs-scripting-tools';
|
||||
const publisherName = 'dutchie031';
|
||||
const extensionSettingsFilter = `@ext:${publisherName}.${extensionName}`;
|
||||
|
||||
// State tracking for addon updates
|
||||
let extensionPath: string | undefined;
|
||||
let workspaceRoot: string | undefined;
|
||||
let currentExtensionVersion: string | undefined;
|
||||
let installedAddonPaths: Map<string, string> = new Map();
|
||||
let isUpdatingAddons = false;
|
||||
|
||||
//TODO:
|
||||
// - ENABLE/DISABLE with settings instead of commands (or both)
|
||||
|
||||
// This method is called when your extension is activated
|
||||
// Your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
pluginPath = context.asAbsolutePath('lua-addons');
|
||||
extensionPath = context.extensionPath;
|
||||
workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||||
|
||||
// Initialize extension version
|
||||
try {
|
||||
currentExtensionVersion = await luaAddonsManager.getExtensionVersion(extensionPath);
|
||||
logger.debug(`Extension version: ${currentExtensionVersion}`);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to determine extension version: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', async () => {
|
||||
enableIntellisense();
|
||||
await enableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', async () => {
|
||||
disableIntellisense();
|
||||
await disableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -71,20 +86,28 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const dcsTypesEnabled = config.get<boolean>('dcsTypes') || false;
|
||||
if (dcsTypesEnabled) {
|
||||
addPluginPathToSettings();
|
||||
await updateLuaAddons();
|
||||
} else {
|
||||
removePluginPathFromSettings();
|
||||
await disableIntellisense();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check and update lua-addons on activation if dcsTypes is enabled
|
||||
await checkAndUpdateAddonsOnStartup();
|
||||
|
||||
logger.info('Dutchies DCS Scripting Tools extension activated');
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
export function deactivate()
|
||||
export async function deactivate()
|
||||
{
|
||||
removePluginPathFromSettings();
|
||||
// Clean up addon paths from settings on deactivation
|
||||
try {
|
||||
await removeVersionedPluginPathsFromSettings();
|
||||
} catch (err) {
|
||||
logger.error(`Error cleaning up on deactivation: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
logger.info('Dutchies DCS Scripting Tools extension deactivated');
|
||||
}
|
||||
|
||||
@@ -162,11 +185,11 @@ async function enableIntellisense() {
|
||||
config.update("dcsTypes", true, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
addPluginPathToSettings();
|
||||
await updateLuaAddons();
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.');
|
||||
vscode.window.showInformationMessage(`DCS-Types installed. Version ${currentExtensionVersion}.`);
|
||||
}
|
||||
|
||||
async function disableIntellisense() {
|
||||
@@ -175,32 +198,252 @@ async function disableIntellisense() {
|
||||
config.update("dcsTypes", false, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
removePluginPathFromSettings();
|
||||
await removeVersionedPluginPathsFromSettings();
|
||||
|
||||
// Clean up all addon versions from workspace
|
||||
if (workspaceRoot) {
|
||||
try {
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath || '');
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
await luaAddonsManager.deleteAllVersionsOfAddon(workspaceRoot, addonName);
|
||||
logger.debug(`Deleted all versions of ${addonName} from workspace.`);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Failed to clean up addons: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.');
|
||||
}
|
||||
|
||||
function addPluginPathToSettings() {
|
||||
if (pluginPath) {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
const librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
if (!librarySettings.includes(pluginPath)) {
|
||||
librarySettings.push(pluginPath);
|
||||
luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
/**
|
||||
* Updates lua-addons by copying them from the extension bundle to the workspace
|
||||
* with versioned naming, cleaning old versions, and updating Lua settings
|
||||
*/
|
||||
async function updateLuaAddons(): Promise<void> {
|
||||
// Prevent concurrent update operations
|
||||
if (isUpdatingAddons) {
|
||||
logger.debug('Addon update already in progress, skipping.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!extensionPath || !workspaceRoot || !currentExtensionVersion) {
|
||||
logger.warn('Cannot update addons: extension path, workspace root, or version not available.');
|
||||
return;
|
||||
}
|
||||
|
||||
isUpdatingAddons = true;
|
||||
|
||||
try {
|
||||
logger.info('Starting lua-addons update...');
|
||||
|
||||
// Discover bundled addons
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath);
|
||||
|
||||
if (discoveredAddons.size === 0) {
|
||||
logger.info('No lua-addons found in extension bundle.');
|
||||
isUpdatingAddons = false;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(`Discovered ${discoveredAddons.size} lua-addon(s): ${Array.from(discoveredAddons.keys()).join(', ')}`);
|
||||
|
||||
// Copy addons with versioned names
|
||||
const copiedAddons = await luaAddonsManager.copyLuaAddons(
|
||||
extensionPath,
|
||||
workspaceRoot,
|
||||
currentExtensionVersion,
|
||||
discoveredAddons
|
||||
);
|
||||
|
||||
// Store paths for settings management
|
||||
installedAddonPaths = copiedAddons;
|
||||
logger.debug(`Copied ${copiedAddons.size} addon(s) to workspace.`);
|
||||
|
||||
// Clean up old versions
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
await luaAddonsManager.deleteOldVersions(workspaceRoot, addonName, currentExtensionVersion);
|
||||
logger.debug(`Cleaned old versions of ${addonName}.`);
|
||||
}
|
||||
|
||||
// Update Lua settings with new paths
|
||||
await addVersionedPluginPathsToSettings(copiedAddons);
|
||||
|
||||
logger.info(`Lua-addons update completed successfully (version ${currentExtensionVersion}).`);
|
||||
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : String(err);
|
||||
logger.error(`Failed to update lua-addons: ${errorMsg}`);
|
||||
vscode.window.showErrorMessage(`Failed to update Dcs Lua Types: ${errorMsg}`);
|
||||
} finally {
|
||||
isUpdatingAddons = false;
|
||||
}
|
||||
}
|
||||
|
||||
function removePluginPathFromSettings() {
|
||||
if (pluginPath) {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
const librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
const libIndex = librarySettings.indexOf(pluginPath);
|
||||
if (libIndex !== -1) {
|
||||
librarySettings.splice(libIndex, 1);
|
||||
luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
/**
|
||||
* Checks on extension startup if lua-addons need to be updated
|
||||
* Runs only if dcsTypes is enabled in the workspace
|
||||
*/
|
||||
async function checkAndUpdateAddonsOnStartup(): Promise<void> {
|
||||
if (!extensionPath || !workspaceRoot || !currentExtensionVersion) {
|
||||
logger.debug('Skipping addon version check on startup: missing initialization data.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const dcsTypesEnabled = config.get<boolean>('dcsTypes') || false;
|
||||
|
||||
if (!dcsTypesEnabled) {
|
||||
logger.debug('dcsTypes not enabled, skipping addon check on startup.');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug('Checking lua-addons versions on startup...');
|
||||
|
||||
// Get installed addons
|
||||
const installedAddons = await luaAddonsManager.getInstalledAddons(workspaceRoot);
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath);
|
||||
|
||||
// Check each discovered addon
|
||||
let updateNeeded = false;
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
const installed = installedAddons.get(addonName);
|
||||
const installedVersion = installed?.version;
|
||||
|
||||
if (luaAddonsManager.requiresUpdate(installedVersion, currentExtensionVersion)) {
|
||||
logger.info(
|
||||
`Version mismatch for ${addonName}: installed=${installedVersion || 'none'}, current=${currentExtensionVersion}`
|
||||
);
|
||||
updateNeeded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateNeeded) {
|
||||
logger.info('Lua-addons update needed, prompting user...');
|
||||
const userChoice = await vscode.window.showInformationMessage(
|
||||
'DCS-Types are not up to date with the current extension version. Do you want to update them?',
|
||||
{ modal: false },
|
||||
'Update'
|
||||
);
|
||||
|
||||
if (userChoice === 'Update') {
|
||||
await updateLuaAddons();
|
||||
vscode.window.showInformationMessage(`DCS-Types updated to version ${currentExtensionVersion}.`);
|
||||
} else {
|
||||
logger.info('User declined DCS-Types update.');
|
||||
}
|
||||
} else {
|
||||
logger.debug('Lua-addons versions are current, no update needed.');
|
||||
// Ensure paths are in settings even if no update needed
|
||||
const pathsMap = new Map<string, string>();
|
||||
for (const [name, info] of installedAddons.entries()) {
|
||||
pathsMap.set(name, info.path);
|
||||
}
|
||||
installedAddonPaths = pathsMap;
|
||||
await addVersionedPluginPathsToSettings(installedAddonPaths);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`Error checking lua-addons on startup: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
// Don't fail activation if check fails; user can manually enable/disable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an absolute path to a workspace-relative path using ${workspaceFolder}
|
||||
*/
|
||||
function convertToWorkspaceFolderPath(absolutePath: string): string {
|
||||
if (!workspaceRoot) {
|
||||
return absolutePath;
|
||||
}
|
||||
// Normalize paths for comparison (handle both forward and back slashes)
|
||||
const normalizedAbsolute = absolutePath.replace(/\\/g, '/');
|
||||
const normalizedWorkspace = workspaceRoot.replace(/\\/g, '/');
|
||||
|
||||
if (normalizedAbsolute.startsWith(normalizedWorkspace)) {
|
||||
const relativePath = normalizedAbsolute.substring(normalizedWorkspace.length);
|
||||
// Remove leading slash if present
|
||||
const cleanPath = relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
|
||||
return `\${workspaceFolder}/${cleanPath}`;
|
||||
}
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds versioned addon paths to the Lua workspace library settings
|
||||
* @param addonPaths - Map of addon name to installed path
|
||||
*/
|
||||
async function addVersionedPluginPathsToSettings(addonPaths?: Map<string, string>): Promise<void> {
|
||||
const pathsToAdd = addonPaths || installedAddonPaths;
|
||||
|
||||
if (pathsToAdd.size === 0) {
|
||||
logger.debug('No addon paths to add to settings.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
let librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
|
||||
// Add each addon path if not already present
|
||||
for (const addonPath of pathsToAdd.values()) {
|
||||
const workspaceFolderPath = convertToWorkspaceFolderPath(addonPath);
|
||||
if (!librarySettings.includes(workspaceFolderPath)) {
|
||||
librarySettings.push(workspaceFolderPath);
|
||||
logger.debug(`Added addon path to settings: ${workspaceFolderPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
await luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to add addon paths to settings: ${err instanceof Error ? err.message : String(err)}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all addon paths from the Lua workspace library settings
|
||||
*/
|
||||
async function removeVersionedPluginPathsFromSettings(): Promise<void> {
|
||||
try {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
let librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
|
||||
if (workspaceRoot) {
|
||||
// Get all installed addons to know what paths to remove
|
||||
const installedAddons = await luaAddonsManager.getInstalledAddons(workspaceRoot);
|
||||
|
||||
for (const addonInfo of installedAddons.values()) {
|
||||
// Try both absolute and workspace-relative paths for compatibility
|
||||
const absolutePath = addonInfo.path;
|
||||
const relativePath = convertToWorkspaceFolderPath(absolutePath);
|
||||
|
||||
// Remove absolute path if present
|
||||
let index = librarySettings.indexOf(absolutePath);
|
||||
if (index !== -1) {
|
||||
librarySettings.splice(index, 1);
|
||||
logger.debug(`Removed addon path from settings: ${absolutePath}`);
|
||||
}
|
||||
|
||||
// Remove relative path if present
|
||||
index = librarySettings.indexOf(relativePath);
|
||||
if (index !== -1) {
|
||||
librarySettings.splice(index, 1);
|
||||
logger.debug(`Removed addon path from settings: ${relativePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to remove addon paths from settings: ${err instanceof Error ? err.message : String(err)}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user