UNPKG

@nstudio/focus

Version:

Focus helpers for monorepos in various IDEs

437 lines (436 loc) 21.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FocusHelpers = void 0; const xplat_utils_1 = require("@nstudio/xplat-utils"); const path_1 = require("path"); const fs_1 = require("fs"); const xml2js = require("xml2js"); const devkit_1 = require("@nx/devkit"); var FocusHelpers; (function (FocusHelpers) { function updateIDESettings(options) { return (tree, context) => { if ((0, xplat_utils_1.isTesting)()) { // ignore node file modifications when just testing return tree; } try { // console.log('workspace dir:', process.cwd()); // const dirName = process.cwd().split('/').slice(-1); const groupByName = (0, xplat_utils_1.getGroupByName)(); const framework = (0, xplat_utils_1.getFrontendFramework)(); let frameworkSuffix = framework ? `-${framework}` : ''; let isFullstack = false; let isExcluding = false; let appWildcards = []; const userUpdates = {}; if (!options.devMode || options.devMode === 'fullstack') { // show all isFullstack = true; if ((0, xplat_utils_1.isXplatWorkspace)()) { for (const p of xplat_utils_1.supportedPlatformsWithNx) { const appFilter = groupByName ? `*-${p}` : `${p}*`; userUpdates[`**/apps/${appFilter}`] = false; userUpdates[`**/libs/xplat/${p}`] = false; if (frameworkSuffix) { userUpdates[`**/libs/xplat/${p}${frameworkSuffix}`] = false; } } } else { for (const p of options.allApps) { userUpdates[p] = false; } for (const p of options.allLibs) { userUpdates[p] = false; } for (const p of options.allPackages) { userUpdates[p] = false; } } } else if (options.platforms) { const platforms = (0, xplat_utils_1.sanitizeCommaDelimitedArg)(options.platforms); if ((0, xplat_utils_1.isXplatWorkspace)()) { // switch on/off platforms for (const p of xplat_utils_1.supportedPlatformsWithNx) { const excluded = platforms.includes(p) ? false : true; const appFilter = groupByName ? `*-${p}` : `${p}*`; if (options.focusOnApps && options.focusOnApps.length) { // focusing on apps // fill up wildcards to use below (we will clear all app wildcards when focusing on apps) appWildcards.push(`**/apps/${appFilter}`); } else { // use wildcards for apps only if no project names were specified userUpdates[`**/apps/${appFilter}`] = excluded; } userUpdates[`**/libs/xplat/${p}`] = excluded; if (frameworkSuffix) { userUpdates[`**/libs/xplat/${p}${frameworkSuffix}`] = excluded; } if (excluded) { // if excluding any platform at all, set the flag // this is used for WebStorm support below isExcluding = true; } } } else { // switch on/off apps for (const p of options.allApps) { const appName = p.replace('**/apps/', ''); // first reset all in case no focusing userUpdates[p] = false; if (options.focusOnApps && options.focusOnApps.length) { userUpdates[p] = options.focusOnApps && options.focusOnApps.length && options.focusOnApps.includes(appName) ? false : true; } } // switch on/off libs/packages // support multiple lib/package focus so track what is handled per loop to not reset one already set const handledPlatforms = {}; for (const target of platforms) { for (const p of options.allLibs) { const libName = p.replace('**/libs/', ''); if (!handledPlatforms[libName]) { userUpdates[p] = libName === target ? false : true; } } for (const p of options.allPackages) { const packageName = p.replace('**/packages/', ''); if (!handledPlatforms[packageName]) { userUpdates[p] = packageName === target ? false : true; } } handledPlatforms[target] = true; } } } // VS Code const isVsCode = updateVSCode({ workspaceUpdates: userUpdates, allApps: options.allApps, focusOnApps: options.focusOnApps, appWildcards, allLibs: options.allLibs, allPackages: options.allPackages, isFullstack, }); // WebStorm let isWebStorm = updateWebStorm({ userUpdates, allApps: options.allApps, focusOnApps: options.focusOnApps, appWildcards, allLibs: options.allLibs, allPackages: options.allPackages, isFullstack, }); if ((0, xplat_utils_1.isXplatWorkspace)() && !options.devMode) { // only when not specifying a dev mode const workspaceUpdates = { '**/node_modules': true, '**/hooks': true, // '**/apps/nativescript-*/src/package.json': false, '**/apps/nativescript-*/hooks': true, '**/apps/nativescript-*/platforms': true, '**/apps/nativescript-*/report': true, '**/apps/nativescript-*/src/**/*.js': { when: '$(basename).ts', }, '**/apps/nativescript-*/src/**/*.d.ts': { when: '$(basename).ts', }, '**/apps/nativescript-*/src/**/*.css': { when: '$(basename).scss', }, // also add groupByName support // '**/apps/*-nativescript/src/package.json': false, '**/apps/*-nativescript/hooks': true, '**/apps/*-nativescript/platforms': true, '**/apps/*-nativescript/report': true, '**/apps/*-nativescript/app/**/*.js': { when: '$(basename).ts', }, '**/apps/*-nativescript/src/**/*.d.ts': { when: '$(basename).ts', }, '**/apps/*-nativescript/src/**/*.css': { when: '$(basename).scss', }, // libs/xplat // '**/libs/xplat/**/*.js': { // when: '$(basename).ts', // }, // '**/libs/xplat/**/*.d.ts': { // when: '$(basename).ts', // }, }; if (isVsCode) { updateVSCode({ workspaceUpdates, }); } if (isWebStorm) { } } } catch (err) { // console.warn('IDE Settings could not be updated at this time:', err); } return tree; }; } FocusHelpers.updateIDESettings = updateIDESettings; function generateVSCodeUpdatedSettings(currentSettings, updates, options) { const newSettings = { 'files.exclude': {}, 'search.exclude': {}, }; let exclude = currentSettings['files.exclude'] || {}; let searchExclude = currentSettings['search.exclude'] || {}; newSettings['files.exclude'] = Object.assign(Object.assign({}, exclude), updates); newSettings['search.exclude'] = Object.assign(Object.assign({}, searchExclude), updates); if ((0, xplat_utils_1.isXplatWorkspace)()) { if (options.allApps.length) { // always reset specific app filters for (const app of options.allApps) { delete newSettings['files.exclude'][app]; delete newSettings['search.exclude'][app]; } } if (!options.isFullstack && options.focusOnApps.length && options.allApps.length) { // when focusing on projects, clear all specific app wildcards first if they exist for (const wildcard of options.appWildcards) { delete newSettings['files.exclude'][wildcard]; delete newSettings['search.exclude'][wildcard]; } for (const focusApp of options.focusOnApps) { newSettings['files.exclude'][focusApp] = false; newSettings['search.exclude'][focusApp] = false; } // ensure all other apps are excluded (except for the one that's being focused on) // also support focusing on apps/{subfolder}/* // if focusing on specific apps but there's no direct match of the focus target in allApps listing, it's a subfolder const isFocusingOnAppSubFolder = options.focusOnApps.filter((a) => options.allApps.includes(a)) .length === 0; for (const app of options.allApps) { if (!options.focusOnApps.includes(app)) { let skipExcluding = false; if (isFocusingOnAppSubFolder) { // see if beginning path of app is in the focused subfolder for (const focus of options.focusOnApps) { if (app.indexOf(focus) === 0) { // console.log('found app in focused folder:', app) skipExcluding = true; } } } if (!skipExcluding) { // console.log('hiding app:', app) newSettings['files.exclude'][app] = true; newSettings['search.exclude'][app] = true; } } } } } return Object.assign(Object.assign({}, currentSettings), newSettings); } function updateVSCode(options) { // VS Code support let isVsCode; const isMac = process.platform == 'darwin'; if (options.userUpdates) { /** * User settings */ // const homedir = os.homedir(); // console.log('os.homedir():',homedir); let userSettingsVSCodePath = isMac ? process.env.HOME + `/Library/Application Support/Code/User/settings.json` : '/var/local/Code/User/settings.json'; const windowsHome = process.env.APPDATA; if (windowsHome) { userSettingsVSCodePath = (0, path_1.join)(windowsHome, 'Code', 'User', 'settings.json'); } // console.log('userSettingsVSCodePath:',userSettingsVSCodePath); isVsCode = (0, fs_1.existsSync)(userSettingsVSCodePath); let vscodeCreateSettingsNote = `It's possible you don't have a user settings.json yet. If so, open VS Code User settings and save any kind of setting to have it created.`; // console.log('isVsCode:',isVsCode); if (isVsCode) { const userSettings = (0, fs_1.readFileSync)(userSettingsVSCodePath, { encoding: 'utf-8', }); if (userSettings) { const userSettingsJson = (0, xplat_utils_1.jsonParse)(userSettings); const newSettings = generateVSCodeUpdatedSettings(userSettingsJson, options.userUpdates, options); (0, fs_1.writeFileSync)(userSettingsVSCodePath, (0, devkit_1.serializeJson)(newSettings)); // TODO: print out the updates made // Example of how the updates are represented // true === hidden // false === show // { // '**/apps/automated': false, // '**/apps/toolbox': false, // '**/apps/ui': false, // '**/packages/core': true, // '**/packages/core-compat': true, // '**/packages/types-android': true, // '**/packages/types-ios': true, // '**/packages/ui-mobile-base': true, // '**/packages/webpack': false // } // console.log( // `VS Code Updated.` // ); } else { console.warn(`Warning: xplat could not read your VS Code settings.json file therefore development mode has not been set. ${vscodeCreateSettingsNote}`); } } else { console.log(`Note to VS Code users: no development mode set. xplat could not find any VS Code settings in the standard location: ${userSettingsVSCodePath} ${vscodeCreateSettingsNote}`); } } else { /** * Workspace settings */ const workspaceSettingsPath = (0, path_1.join)(process.cwd(), '.vscode', 'settings.json'); // console.log('workspaceSettingsPath:',workspaceSettingsPath); let workspaceSettingsJson = {}; if ((0, fs_1.existsSync)(workspaceSettingsPath)) { const workspaceSettings = (0, fs_1.readFileSync)(workspaceSettingsPath, { encoding: 'utf-8', }); workspaceSettingsJson = (0, xplat_utils_1.jsonParse)(workspaceSettings); } else { // console.log('creating workspace settings...'); (0, fs_1.mkdirSync)('.vscode', { recursive: true // ignore error if exists }); } const newSettings = generateVSCodeUpdatedSettings(workspaceSettingsJson, options.workspaceUpdates, options); (0, fs_1.writeFileSync)(workspaceSettingsPath, (0, devkit_1.serializeJson)(newSettings)); } return isVsCode; } FocusHelpers.updateVSCode = updateVSCode; function updateWebStorm(options) { let isWebStorm = false; // list preferences to get correct webstorm prefs file // let preferencesFolder = isMac // ? process.env.HOME + // `/Library/Preferences` // : __dirname; // if (windowsHome) { // preferencesFolder = windowsHome; // } // const prefs = fs.readdirSync(preferencesFolder).filter(f => fs.statSync(join(preferencesFolder, f)).isDirectory()); // find first one // TODO: user may have multiple version installed (or at least older versions) so may need to handle if multiples // let webStormPrefFolderName = prefs.find(f => f.indexOf('WebStorm20') > -1); // if (webStormPrefFolderName) { // isWebStorm = true; // webStormPrefFolderName = webStormPrefFolderName.split('/').slice(-1)[0]; // // console.log('webStormPrefFolderName:',webStormPrefFolderName); // // ensure folders are excluded from project view // let projectViewWebStormPath = // isMac // ? process.env.HOME + // `/Library/Preferences/${webStormPrefFolderName}/options/projectView.xml` // : join(__dirname, webStormPrefFolderName, 'config'); // if (windowsHome) { // projectViewWebStormPath = join(windowsHome, webStormPrefFolderName, 'config'); // } // let projectView = fs.readFileSync(projectViewWebStormPath, "UTF-8"); // if (projectView) { // // console.log('projectView:', projectView); // xml2js.parseString(projectView, (err, settings) => { // // console.log(util.inspect(settings, false, null)); // if (settings && settings.application && settings.application.component && settings.application.component.length) { // const builder = new xml2js.Builder({ headless: true }); // const sharedSettingsIndex = (<Array<any>>settings.application.component).findIndex(c => c.$.name === 'ProjectViewSharedSettings'); // if (sharedSettingsIndex > -1) { // const sharedSettings = settings.application.component[sharedSettingsIndex]; // if (sharedSettings.option && sharedSettings.option.length) { // const showExcludedFilesIndex = sharedSettings.option.findIndex(o => o.$.name === 'showExcludedFiles'); // if (showExcludedFilesIndex > -1) { // settings.application.component[sharedSettingsIndex].option[showExcludedFilesIndex].$.value = `${!isExcluding}`; // } else { // settings.application.component[sharedSettingsIndex].option.push(webStormExcludedViewNode(isExcluding)); // } // } else { // settings.application.component[sharedSettingsIndex].option = [ // webStormExcludedViewNode(isExcluding) // ]; // } // settings = builder.buildObject(settings); // } else { // (<Array<any>>settings.application.component).push({ // $: 'ProjectViewSharedSettings', // option: [ // webStormExcludedViewNode(isExcluding) // ] // }); // settings = builder.buildObject(settings); // } // } else { // // create projectView.xml // settings = createWebStormProjectView(isExcluding); // } // // modify projectView // // console.log('settings:', settings); // fs.writeFileSync( // projectViewWebStormPath, // settings // ); // }); // } else { // // create projectView.xml // fs.writeFileSync( // projectViewWebStormPath, // createWebStormProjectView(isExcluding) // ); // } // } return isWebStorm; } FocusHelpers.updateWebStorm = updateWebStorm; function createWebStormProjectView(isExcluding) { const projectViewObject = { application: { component: [ { $: { name: 'ProjectViewSharedSettings', }, option: [webStormExcludedViewNode(isExcluding)], }, ], }, }; const builder = new xml2js.Builder({ headless: true }); return builder.buildObject(projectViewObject); } FocusHelpers.createWebStormProjectView = createWebStormProjectView; function webStormExcludedViewNode(isExcluding) { return { $: { name: 'showExcludedFiles', value: `${!isExcluding}`, }, }; } FocusHelpers.webStormExcludedViewNode = webStormExcludedViewNode; })(FocusHelpers || (exports.FocusHelpers = FocusHelpers = {}));