Skip to content

Commit

Permalink
feat: add prompts to add nx to angular cli (#1254)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cammisuli authored Mar 18, 2022
1 parent 11a8f60 commit a669307
Show file tree
Hide file tree
Showing 21 changed files with 316 additions and 12 deletions.
5 changes: 4 additions & 1 deletion apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
getGenerators,
teardownTelemetry,
watchFile,
directoryExists,
fileExists,
} from '@nx-console/server';
import {
Expand Down Expand Up @@ -53,6 +52,7 @@ import {
ProjectJsonSchema,
} from '@nx-console/vscode/json-schema';
import { enableTypeScriptPlugin } from '@nx-console/typescript-plugin';
import { NxConversion } from '@nx-console/vscode/nx-conversion';

let runTargetTreeView: TreeView<RunTargetTreeItem>;
let nxProjectTreeView: TreeView<NxProjectTreeItem>;
Expand Down Expand Up @@ -121,6 +121,8 @@ export async function activate(c: ExtensionContext) {
new WorkspaceJsonSchema(context);
new ProjectJsonSchema(context);

NxConversion.createInstance(context);

await enableTypeScriptPlugin(context);

getTelemetry().extensionActivated((Date.now() - startTime) / 1000);
Expand Down Expand Up @@ -256,6 +258,7 @@ async function setWorkspace(workspacePath: string) {
} else if (!isNxWorkspace && isAngularWorkspace) {
workspaceType = 'angular';
}
WorkspaceConfigurationStore.instance.set('workspaceType', workspaceType);

getTelemetry().record('WorkspaceType', { workspaceType });
}
Expand Down
9 changes: 9 additions & 0 deletions apps/vscode/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@
"command": "nx.generate.ui.lib",
"when": "isNxWorkspace && nx.hasLibraryGenerators"
},
{
"command": "nxConsole.makeNgFaster",
"when": "isAngularWorkspace"
},
{
"command": "ng.run.target",
"when": "isAngularWorkspace"
Expand Down Expand Up @@ -583,6 +587,11 @@
"category": "Nx",
"title": "Nx generate library",
"command": "nx.generate.ui.lib.fileexplorer"
},
{
"category": "Nx",
"title": "Make ng Faster with Nx",
"command": "nxConsole.makeNgFaster"
}
],
"configuration": {
Expand Down
1 change: 1 addition & 0 deletions libs/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export {
export { watchFile } from './lib/utils/watch-file';
export { buildProjectPath } from './lib/utils/build-project-path';
export { findConfig } from './lib/utils/find-config';
export { getShellExecutionForConfig } from './lib/utils/shell-execution';
7 changes: 6 additions & 1 deletion libs/vscode/configuration/src/lib/configuration-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ export const GLOBAL_CONFIG_KEYS = [
*/
export type GlobalConfigKeys = typeof GLOBAL_CONFIG_KEYS[number];

export const WORKSPACE_CONFIG_KEYS = ['nxWorkspacePath'] as const;
export const WORKSPACE_CONFIG_KEYS = [
'nxWorkspacePath',
'nxConversionCount',
'nxConversionDoNotAskAgain',
'workspaceType',
] as const;
/**
* configuration Keys used for NxConsole on a vscode workspace level
*/
Expand Down
18 changes: 18 additions & 0 deletions libs/vscode/nx-conversion/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
7 changes: 7 additions & 0 deletions libs/vscode/nx-conversion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# vscode-nx-conversion

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test vscode-nx-conversion` to execute the unit tests via [Jest](https://jestjs.io).
15 changes: 15 additions & 0 deletions libs/vscode/nx-conversion/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
displayName: 'vscode-nx-conversion',
preset: '../../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../../coverage/libs/vscode/nx-conversion',
};
4 changes: 4 additions & 0 deletions libs/vscode/nx-conversion/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@nx-console/vscode/nx-conversion",
"version": "0.0.1"
}
34 changes: 34 additions & 0 deletions libs/vscode/nx-conversion/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"root": "libs/vscode/nx-conversion",
"sourceRoot": "libs/vscode/nx-conversion/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/node:package",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/vscode/nx-conversion",
"tsConfig": "libs/vscode/nx-conversion/tsconfig.lib.json",
"packageJson": "libs/vscode/nx-conversion/package.json",
"main": "libs/vscode/nx-conversion/src/index.ts",
"assets": ["libs/vscode/nx-conversion/*.md"]
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/vscode/nx-conversion/**/*.ts"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/libs/vscode/nx-conversion"],
"options": {
"jestConfig": "libs/vscode/nx-conversion/jest.config.js",
"passWithNoTests": true
}
}
},
"tags": []
}
1 change: 1 addition & 0 deletions libs/vscode/nx-conversion/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/vscode-nx-conversion';
159 changes: 159 additions & 0 deletions libs/vscode/nx-conversion/src/lib/vscode-nx-conversion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { getShellExecutionForConfig, getTelemetry } from '@nx-console/server';
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { pipe, Subject } from 'rxjs';
import { filter, scan, tap } from 'rxjs/operators';
import {
commands,
ExtensionContext,
ExtensionMode,
Task,
tasks,
TaskScope,
window,
} from 'vscode';

/**
* The amount of times the user should run commands before a prompt is shown.
*
* DevelopmentMode will change this to `1`.
*/
const PROMPT_COUNT = 5;
const PROMPT_MSG =
'Would you like to make ng commands faster by adding computation caching? [Learn more here](https://nx.dev/migration/migration-angular?utm_source=vscode-nx-conversion&utm_medium=prompt&utm_campaign=vscode-nx-conversion)';
const PROMPT_MSG_DONT_ASK_AGAIN =
'If you change your mind, you can run the `make ng faster with Nx` command through the command palette.';

/**
* Singleton class for helping with Nx Conversion.
*
* Get instances with `NxConversion.instance`
*/
export class NxConversion {
private static _instance: NxConversion;

public static get instance(): NxConversion {
if (!NxConversion._instance) {
throw 'NxConversion not created yet, please create an instance first with `NxConversion.createInstance(context)`';
}
return NxConversion._instance;
}
private static set instance(value: NxConversion) {
if (NxConversion._instance) {
console.warn(
'NxConversion already created, are you sure you want to create another instance?'
);
} else {
commands.registerCommand('nxConsole.makeNgFaster', makeNgFaster);
}

NxConversion._instance = value;
}

private _listener = new Subject<string>();

private constructor(private _context: ExtensionContext) {
const initialSeed = WorkspaceConfigurationStore.instance.get(
'nxConversionCount',
0
);

const promptCount =
_context.extensionMode === ExtensionMode.Development ? 1 : PROMPT_COUNT;

this._listener
.pipe(shouldPromptForConversion(initialSeed, promptCount, _context))
.subscribe(async (count) => {
makeNgFaster(count);
});
}

static createInstance(context: ExtensionContext) {
NxConversion.instance = new NxConversion(context);
return NxConversion.instance;
}

async trackEvent(eventName: string) {
if (eventName === 'generate') {
return;
}

this._listener.next(eventName);
}
}

async function makeNgFaster(count = 0) {
getTelemetry().screenViewed('Convert to Nx');

const options = ['Yes', 'No'];
if (count >= PROMPT_COUNT * 2) {
options.push(`Don't ask again`);
}

const answer = await window.showInformationMessage(PROMPT_MSG, ...options);

if (answer === undefined) {
return;
}

if (answer === 'Yes') {
getTelemetry().screenViewed('Convert to Nx - Yes');
getTelemetry().featureUsed('makeNgFaster');
tasks.executeTask(createMakeNgFasterTask());
} else if (answer === 'No') {
getTelemetry().screenViewed('Convert to Nx - No ');
getTelemetry().featureUsed('do-not makeNgFaster');
} else {
WorkspaceConfigurationStore.instance.set('nxConversionDoNotAskAgain', true);
getTelemetry().featureUsed('do-not-ask-again makeNgFaster');
window.showInformationMessage(PROMPT_MSG_DONT_ASK_AGAIN);
}
}

function createMakeNgFasterTask() {
const workspacePath = WorkspaceConfigurationStore.instance.get(
'nxWorkspacePath',
''
);
const displayCommand = 'make-angular-cli-faster';
const task = new Task(
{
type: 'nx',
},
TaskScope.Workspace,
displayCommand,
'nx',
getShellExecutionForConfig({
cwd: workspacePath,
displayCommand,
})
);
return task;
}

function shouldPromptForConversion(
initialSeed: number,
promptCount: number,
_context: ExtensionContext
) {
const askAgain: boolean =
!WorkspaceConfigurationStore.instance.get(
'nxConversionDoNotAskAgain',
false
) || _context.extensionMode === ExtensionMode.Development;

return pipe(
scan((acc) => acc + 1, initialSeed),
tap((value) => {
WorkspaceConfigurationStore.instance.set('nxConversionCount', value);
}),
filter((count) => count % promptCount === 0),
filter(
() =>
askAgain &&
(WorkspaceConfigurationStore.instance.get(
'workspaceType',
''
) as string) === 'angular'
)
);
}
13 changes: 13 additions & 0 deletions libs/vscode/nx-conversion/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
11 changes: 11 additions & 0 deletions libs/vscode/nx-conversion/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
"include": ["**/*.ts"]
}
19 changes: 19 additions & 0 deletions libs/vscode/nx-conversion/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.test.tsx",
"**/*.spec.tsx",
"**/*.test.js",
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
]
}
13 changes: 7 additions & 6 deletions libs/vscode/tasks/src/lib/cli-task-provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { WorkspaceJsonConfiguration } from '@nrwl/devkit';
import { WORKSPACE_GENERATOR_NAME_REGEX } from '@nx-console/schema';
import { getTelemetry } from '@nx-console/server';
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { NxConversion } from '@nx-console/vscode/nx-conversion';
import { verifyWorkspace } from '@nx-console/vscode/nx-workspace';
import { isAbsolute, join, relative } from 'path';
import {
ProviderResult,
Expand All @@ -6,15 +12,9 @@ import {
TaskProvider,
tasks,
} from 'vscode';

import { getTelemetry } from '@nx-console/server';
import { verifyWorkspace } from '@nx-console/vscode/nx-workspace';
import { CliTask } from './cli-task';
import { CliTaskDefinition } from './cli-task-definition';
import { NxTask } from './nx-task';
import { WORKSPACE_GENERATOR_NAME_REGEX } from '@nx-console/schema';
import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration';
import { WorkspaceJsonConfiguration } from '@nrwl/devkit';

export let cliTaskProvider: CliTaskProvider;

Expand Down Expand Up @@ -74,6 +74,7 @@ export class CliTaskProvider implements TaskProvider {
}

async executeTask(definition: CliTaskDefinition) {
NxConversion.instance.trackEvent(definition.command);
const isDryRun = definition.flags.includes('--dry-run');
if (isDryRun && this.currentDryRun) {
this.deferredDryRun = definition;
Expand Down
Loading

0 comments on commit a669307

Please sign in to comment.