Skip to content

Commit

Permalink
chore(core): handle project configurations errors
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz committed Apr 15, 2024
1 parent 6a6186a commit 20287fa
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
NX_NATIVE_LOGGING: 'false'
NX_E2E_RUN_E2E: 'true'
NX_CI_EXECUTION_ENV: 'linux'
NX_CLOUD_DTE_V2: 'false'
NX_CLOUD_DTE_V2: 'true'
steps:
- checkout
- nx/set-shas:
Expand Down
6 changes: 3 additions & 3 deletions docs/shared/migration/adding-to-existing-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ Running this command will ask you a few questions about your workspace and then
process detects tools which are used in your workspace and suggests installing Nx plugins to integrate the tools you use
with Nx. Running those tools through Nx will have caching enabled when possible, providing you with a faster alternative
for running those tools. You can start with a few to see how it works and then add more with
the [`nx add`](/cli/commands/add) command later. You can also decide to add them all and get the full experience right
the [`nx add`](/nx-api/nx/documents/add) command later. You can also decide to add them all and get the full experience
right
away because adding plugins will not break your existing workflow.

The first thing you may notice is that Nx updates your `package.json` scripts during the setup process. Nx Plugins setup
Expand Down Expand Up @@ -236,8 +237,7 @@ configuration values are being set.
If you want to run one of your existing scripts with Nx, you need to tell Nx about it.

1. Preface the script with `nx exec -- ` to have `npm run test` invoke the command with Nx.
2. Add the script to `includedScripts`.
3. Define caching settings.
2. Define caching settings.

The `nx exec` command allows you to keep using `npm test` or `npm run test` (or other package manager's alternatives) as
you're accustomed to. But still get the benefits of making those operations cacheable. Configuring the `test` script
Expand Down
6 changes: 3 additions & 3 deletions docs/shared/migration/adding-to-monorepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ Running this command will ask you a few questions about your workspace and then
process detects tools which are used in your workspace and suggests installing Nx plugins to integrate the tools you use
with Nx. Running those tools through Nx will have caching enabled when possible, providing you with a faster alternative
for running those tools. You can start with a few to see how it works and then add more with
the [`nx add`](/cli/commands/add) command later. You can also decide to add them all and get the full experience right
the [`nx add`](/nx-api/nx/documents/add) command later. You can also decide to add them all and get the full experience
right
away because adding plugins will not break your existing workflow.

The first thing you may notice is that Nx updates your `package.json` scripts during the setup process. Nx Plugins setup
Expand Down Expand Up @@ -239,8 +240,7 @@ configuration values are being set.
If you want to run one of your existing scripts with Nx, you need to tell Nx about it.

1. Preface the script with `nx exec -- ` to have `npm run test` invoke the command with Nx.
2. Add the script to `includedScripts`.
3. Define caching settings.
2. Define caching settings.

The `nx exec` command allows you to keep using `npm test` or `npm run test` (or other package manager's alternatives) as
you're accustomed to. But still get the benefits of making those operations cacheable. Configuring the `test` script
Expand Down
17 changes: 10 additions & 7 deletions e2e/detox/src/detox-legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ import {

describe('@nx/detox (legacy)', () => {
const appName = uniq('myapp');
let originalEnv: string;

beforeAll(() => {
originalEnv = process.env.NX_ADD_PLUGINS;
process.env.NX_ADD_PLUGINS = 'false';
newProject();
});

afterAll(() => cleanupProject());
afterAll(() => {
process.env.NX_ADD_PLUGINS = originalEnv;
cleanupProject();
});

it('should create files and run lint command for react-native apps', async () => {
runCLI(
`generate @nx/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint --install=false`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint --install=false`
);
checkFilesExist(`apps/${appName}-e2e/.detoxrc.json`);
checkFilesExist(`apps/${appName}-e2e/tsconfig.json`);
Expand All @@ -38,8 +43,7 @@ describe('@nx/detox (legacy)', () => {
it('should create files and run lint command for expo apps', async () => {
const expoAppName = uniq('myapp');
runCLI(
`generate @nx/expo:app ${expoAppName} --e2eTestRunner=detox --linter=eslint`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/expo:app ${expoAppName} --e2eTestRunner=detox --linter=eslint`
);
checkFilesExist(`apps/${expoAppName}-e2e/.detoxrc.json`);
checkFilesExist(`apps/${expoAppName}-e2e/tsconfig.json`);
Expand All @@ -57,8 +61,7 @@ describe('@nx/detox (legacy)', () => {
const appName = uniq('app1');

runCLI(
`generate @nx/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint --install=false --project-name-and-root-format=as-provided --interactive=false`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint --install=false --project-name-and-root-format=as-provided --interactive=false`
);

// check files are generated without the layout directory ("apps/") and
Expand Down
19 changes: 12 additions & 7 deletions e2e/expo/src/expo-legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ describe('@nx/expo (legacy)', () => {
let proj: string;
let appName = uniq('my-app');
let libName = uniq('lib');
let originalEnv: string;

beforeAll(() => {
proj = newProject({ packages: ['@nx/expo'] });
// we create empty preset above which skips creation of `production` named input

originalEnv = process.env.NX_ADD_PLUGINS;
process.env.NX_ADD_PLUGINS = 'false';

updateJson('nx.json', (nxJson) => {
nxJson.namedInputs = {
default: ['{projectRoot}/**/*', 'sharedGlobals'],
Expand All @@ -36,14 +41,16 @@ describe('@nx/expo (legacy)', () => {
return nxJson;
});
runCLI(
`generate @nx/expo:application ${appName} --e2eTestRunner=cypress --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/expo:application ${appName} --e2eTestRunner=cypress --no-interactive`
);
runCLI(
`generate @nx/expo:library ${libName} --buildable --publishable --importPath=${proj}/${libName}`
);
});
afterAll(() => cleanupProject());
afterAll(() => {
process.env.NX_ADD_PLUGINS = originalEnv;
cleanupProject();
});

it('should test and lint', async () => {
const componentName = uniq('Component');
Expand Down Expand Up @@ -193,8 +200,7 @@ describe('@nx/expo (legacy)', () => {
const libName = uniq('@my-org/lib1');

runCLI(
`generate @nx/expo:application ${appName} --project-name-and-root-format=as-provided --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/expo:application ${appName} --project-name-and-root-format=as-provided --no-interactive`
);

// check files are generated without the layout directory ("apps/") and
Expand Down Expand Up @@ -268,8 +274,7 @@ describe('@nx/expo (legacy)', () => {
it('should run e2e for playwright', async () => {
const appName2 = uniq('my-app');
runCLI(
`generate @nx/expo:application ${appName2} --e2eTestRunner=playwright --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/expo:application ${appName2} --e2eTestRunner=playwright --no-interactive`
);
if (runE2ETests()) {
const results = runCLI(`e2e ${appName2}-e2e`, { verbose: true });
Expand Down
18 changes: 11 additions & 7 deletions e2e/react-native/src/react-native-legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ describe('@nx/react-native (legacy)', () => {
let proj: string;
let appName = uniq('my-app');
let libName = uniq('lib');
let originalEnv: string;

beforeAll(() => {
originalEnv = process.env.NX_ADD_PLUGINS;
process.env.NX_ADD_PLUGINS = 'false';

proj = newProject();
// we create empty preset above which skips creation of `production` named input
updateJson('nx.json', (nxJson) => {
Expand All @@ -36,14 +40,16 @@ describe('@nx/react-native (legacy)', () => {
return nxJson;
});
runCLI(
`generate @nx/react-native:application ${appName} --bunlder=webpack --e2eTestRunner=cypress --install=false --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/react-native:application ${appName} --bunlder=webpack --e2eTestRunner=cypress --install=false --no-interactive`
);
runCLI(
`generate @nx/react-native:library ${libName} --buildable --publishable --importPath=${proj}/${libName} --no-interactive`
);
});
afterAll(() => cleanupProject());
afterAll(() => {
process.env.NX_ADD_PLUGINS = originalEnv;
cleanupProject();
});

it('should build for web', async () => {
const results = runCLI(`build ${appName}`);
Expand Down Expand Up @@ -269,8 +275,7 @@ describe('@nx/react-native (legacy)', () => {
const libName = uniq('@my-org/lib1');

runCLI(
`generate @nx/react-native:application ${appName} --project-name-and-root-format=as-provided --install=false --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/react-native:application ${appName} --project-name-and-root-format=as-provided --install=false --no-interactive`
);

// check files are generated without the layout directory ("apps/") and
Expand Down Expand Up @@ -306,8 +311,7 @@ describe('@nx/react-native (legacy)', () => {
it('should run build with vite bundler and e2e with playwright', async () => {
const appName2 = uniq('my-app');
runCLI(
`generate @nx/react-native:application ${appName2} --bundler=vite --e2eTestRunner=playwright --install=false --no-interactive`,
{ env: { NX_ADD_PLUGINS: 'false' } }
`generate @nx/react-native:application ${appName2} --bundler=vite --e2eTestRunner=playwright --install=false --no-interactive`
);
const buildResults = runCLI(`build ${appName2}`);
expect(buildResults).toContain('Successfully ran target build');
Expand Down
49 changes: 28 additions & 21 deletions packages/devkit/src/utils/add-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ import type { PackageJson } from 'nx/src/utils/package-json';
import * as yargs from 'yargs-parser';
import { requireNx } from '../../nx';

const nx = requireNx();
const {
readJson,
writeJson,
readNxJson,
updateNxJson,
retrieveProjectConfigurations,
} = nx;

// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { LoadedNxPlugin } from 'nx/src/devkit-internals';
LoadedNxPlugin,
ProjectConfigurationsError,
} = requireNx();

import type { ConfigurationResult } from 'nx/src/project-graph/utils/project-configuration-utils';

Expand Down Expand Up @@ -55,22 +53,31 @@ export async function addPlugin<PluginOptions>(
return;
}
global.NX_GRAPH_CREATION = true;
projConfigs = await retrieveProjectConfigurations(
[
new LoadedNxPlugin(
{
name: pluginName,
createNodes: createNodesTuple,
},
{
plugin: pluginName,
options: pluginOptions,
}
),
],
tree.root,
nxJson
);
try {
projConfigs = await retrieveProjectConfigurations(
[
new LoadedNxPlugin(
{
name: pluginName,
createNodes: createNodesTuple,
},
{
plugin: pluginName,
options: pluginOptions,
}
),
],
tree.root,
nxJson
);
} catch (e) {
// Errors are okay for this because we're only running 1 plugin
if (e instanceof ProjectConfigurationsError) {
projConfigs = e.partialProjectConfigurationsResult;
} else {
throw e;
}
}
global.NX_GRAPH_CREATION = false;

for (const projConfig of Object.values(projConfigs.projects)) {
Expand Down
6 changes: 4 additions & 2 deletions packages/eslint/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { createProjectGraphAsync, GeneratorCallback, Tree } from '@nx/devkit';
import {
addDependenciesToPackageJson,
createProjectGraphAsync,
GeneratorCallback,
readNxJson,
removeDependenciesFromPackageJson,
runTasksInSerial,
Tree,
updateNxJson,
} from '@nx/devkit';
import { addPlugin } from '@nx/devkit/src/utils/add-plugin';
import { eslintVersion, nxVersion } from '../../utils/versions';
import { findEslintFile } from '../utils/eslint-file';
import { EslintPluginOptions, createNodes } from '../../plugins/plugin';
import { createNodes } from '../../plugins/plugin';
import { hasEslintPlugin } from '../utils/plugin';

export interface LinterInitOptions {
Expand Down
6 changes: 5 additions & 1 deletion packages/next/src/generators/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ export async function nextInitGeneratorInternal(
startTargetName: ['start', 'next:start', 'next-start'],
buildTargetName: ['build', 'next:build', 'next-build'],
devTargetName: ['dev', 'next:dev', 'next-dev'],
serveStaticTargetName: ['serve', 'next:serve', 'next-serve'],
serveStaticTargetName: [
'serve-static',
'next:serve-static',
'next-serve-static',
],
},
schema.updatePackageScripts
);
Expand Down

0 comments on commit 20287fa

Please sign in to comment.