Skip to content

Commit 1575dda

Browse files
authored
fix(dotnet): dotnet watch --project ... test should work (#426)
Fixes #425
1 parent 6e084ea commit 1575dda

File tree

4 files changed

+27
-194
lines changed

4 files changed

+27
-194
lines changed

e2e/core-e2e/tests/nx-dotnet.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
uniq,
1616
updateFile,
1717
} from '@nrwl/nx-plugin/testing';
18+
import { runCommandUntil } from '../../utils';
1819

1920
import { readFileSync, unlinkSync, writeFileSync } from 'fs';
2021
import { join } from 'path';
@@ -422,6 +423,23 @@ public class UnitTest1
422423

423424
expect(() => runNxCommand(`test ${testProject}`)).toThrow();
424425
});
426+
427+
it('should work with watch', async () => {
428+
const appProject = uniq('app');
429+
const testProject = `${appProject}-test`;
430+
runNxCommand(
431+
`generate @nx-dotnet/core:app ${appProject} --language="C#" --template="webapi" --test-runner xunit`,
432+
);
433+
const p = runCommandUntil(
434+
`test ${testProject} --watch`,
435+
(output) =>
436+
output.includes(
437+
'Waiting for a file to change before restarting dotnet...',
438+
),
439+
{ kill: true },
440+
);
441+
await expect(p).resolves.not.toThrow();
442+
});
425443
});
426444
});
427445

e2e/utils/index.ts

Lines changed: 6 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
2-
1+
import { tmpProjPath } from '@nrwl/nx-plugin/testing';
32
import { ChildProcess, exec, execSync } from 'child_process';
43
import {
54
copySync,
@@ -17,155 +16,23 @@ import * as path from 'path';
1716
import { dirSync } from 'tmp';
1817

1918
import isCI = require('is-ci');
19+
import { workspaceConfigName } from 'nx/src/config/workspaces';
20+
import { detectPackageManager } from '@nrwl/devkit';
2021
interface RunCmdOpts {
2122
silenceError?: boolean;
2223
env?: Record<string, string> | NodeJS.ProcessEnv;
2324
cwd?: string;
2425
silent?: boolean;
2526
}
2627

27-
export function currentCli() {
28-
return process.env.SELECTED_CLI ?? 'nx';
29-
}
30-
31-
export const e2eRoot = isCI ? dirSync({ prefix: 'nx-e2e-' }).name : `./tmp`;
32-
export const e2eCwd = `${e2eRoot}/${currentCli()}`;
33-
ensureDirSync(e2eCwd);
34-
35-
let projName: string;
36-
3728
export function uniq(prefix: string) {
3829
return `${prefix}${Math.floor(Math.random() * 10000000)}`;
3930
}
4031

41-
export function workspaceConfigName() {
42-
return currentCli() === 'angular' ? 'angular.json' : 'workspace.json';
43-
}
44-
45-
export function updateWorkspaceConfig(
46-
callback: (json: { [key: string]: any }) => Object,
47-
) {
48-
const file = workspaceConfigName();
49-
updateFile(file, JSON.stringify(callback(readJson(file)), null, 2));
50-
}
51-
52-
export function runCreateWorkspace(
53-
name: string,
54-
{
55-
preset,
56-
appName,
57-
style,
58-
base,
59-
packageManager,
60-
cli,
61-
extraArgs,
62-
}: {
63-
preset: string;
64-
appName?: string;
65-
style?: string;
66-
base?: string;
67-
packageManager?: 'npm' | 'yarn' | 'pnpm';
68-
cli?: string;
69-
extraArgs?: string;
70-
},
71-
) {
72-
projName = name;
73-
74-
const pm = getPackageManagerCommand({ packageManager });
75-
76-
const linterArg =
77-
preset === 'angular' || preset === 'angular-nest' ? ' --linter=tslint' : '';
78-
let command = `${pm.createWorkspace} ${name} --cli=${
79-
cli || currentCli()
80-
} --preset=${preset} ${linterArg} --no-nxCloud --no-interactive`;
81-
if (appName) {
82-
command += ` --appName=${appName}`;
83-
}
84-
if (style) {
85-
command += ` --style=${style}`;
86-
}
87-
88-
if (base) {
89-
command += ` --defaultBase="${base}"`;
90-
}
91-
92-
if (packageManager) {
93-
command += ` --package-manager=${packageManager}`;
94-
}
95-
96-
if (extraArgs) {
97-
command += ` ${extraArgs}`;
98-
}
99-
100-
const create = execSync(command, {
101-
cwd: e2eCwd,
102-
stdio: [0, 1, 2],
103-
env: process.env,
104-
});
105-
return create ? create.toString() : '';
106-
}
107-
108-
export function packageInstall(pkg: string, projName?: string) {
109-
const cwd = projName ? `${e2eCwd}/${projName}` : tmpProjPath();
110-
const pm = getPackageManagerCommand({ path: cwd });
111-
const install = execSync(`${pm.addDev} ${pkg}`, {
112-
cwd,
113-
// ...{ stdio: ['pipe', 'pipe', 'pipe'] },
114-
...{ stdio: [0, 1, 2] },
115-
env: process.env,
116-
});
117-
return install ? install.toString() : '';
118-
}
119-
120-
export function runNgNew(): string {
121-
return execSync(`../../node_modules/.bin/ng new proj --no-interactive`, {
122-
cwd: e2eCwd,
123-
env: process.env,
124-
}).toString();
125-
}
126-
12732
export function getSelectedPackageManager(): 'npm' | 'yarn' | 'pnpm' {
12833
return process.env.SELECTED_PM as 'npm' | 'yarn' | 'pnpm';
12934
}
13035

131-
/**
132-
* Sets up a new project in the temporary project path
133-
* for the currently selected CLI.
134-
*/
135-
export function newProject({ name = uniq('proj') } = {}): string {
136-
const packageManager = getSelectedPackageManager();
137-
138-
try {
139-
const useBackupProject = packageManager !== 'pnpm';
140-
const projScope = useBackupProject ? 'proj' : name;
141-
142-
if (!useBackupProject || !directoryExists(tmpBackupProjPath())) {
143-
runCreateWorkspace(projScope, { preset: 'empty', packageManager });
144-
145-
// Temporary hack to prevent installing with `--frozen-lockfile`
146-
if (isCI && packageManager === 'pnpm') {
147-
updateFile('.npmrc', 'prefer-frozen-lockfile=false');
148-
}
149-
150-
const packages = [`@nx-dotnet/core`, `@nx-dotnet/typescript`];
151-
packageInstall(packages.join(` `), projScope);
152-
153-
if (useBackupProject) {
154-
moveSync(`${e2eCwd}/proj`, `${tmpBackupProjPath()}`);
155-
}
156-
}
157-
projName = name;
158-
if (useBackupProject) {
159-
copySync(`${tmpBackupProjPath()}`, `${tmpProjPath()}`);
160-
}
161-
return projScope;
162-
} catch (e: any) {
163-
console.log(`Failed to set up project for e2e tests.`);
164-
console.log(e.message);
165-
throw e;
166-
}
167-
}
168-
16936
// Useful in order to cleanup space during CI to prevent `No space left on device` exceptions
17037
export function removeProject({ onlyOnCI = false } = {}) {
17138
if (onlyOnCI && !isCI) {
@@ -255,38 +122,6 @@ export function runCLIAsync(
255122
);
256123
}
257124

258-
export function runNgAdd(
259-
command?: string,
260-
opts: RunCmdOpts = {
261-
silenceError: false,
262-
env: process.env as Record<string, string>,
263-
cwd: tmpProjPath(),
264-
},
265-
): string {
266-
try {
267-
packageInstall('@nrwl/workspace');
268-
return execSync(
269-
`./node_modules/.bin/ng g @nrwl/workspace:ng-add ${command}`,
270-
{
271-
cwd: tmpProjPath(),
272-
env: opts.env as any,
273-
},
274-
)
275-
.toString()
276-
.replace(
277-
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
278-
'',
279-
);
280-
} catch (e: any) {
281-
if (opts.silenceError) {
282-
return e.stdout.toString();
283-
} else {
284-
console.log(e.stdout.toString(), e.stderr.toString());
285-
throw e;
286-
}
287-
}
288-
}
289-
290125
export function runCLI(
291126
command?: string,
292127
opts: RunCmdOpts = {
@@ -354,7 +189,7 @@ export function runCommand(command: string): string {
354189
*/
355190
function setMaxWorkers() {
356191
if (isCI) {
357-
const workspaceFile = workspaceConfigName();
192+
const workspaceFile = workspaceConfigName(tmpProjPath());
358193
const workspace = readJson(workspaceFile);
359194

360195
Object.keys(workspace.projects).forEach((appName) => {
@@ -466,17 +301,9 @@ export function getSize(filePath: string): number {
466301
return statSync(filePath).size;
467302
}
468303

469-
export function tmpProjPath(path?: string) {
470-
return path ? `${e2eCwd}/${projName}/${path}` : `${e2eCwd}/${projName}`;
471-
}
472-
473-
function tmpBackupProjPath(path?: string) {
474-
return path ? `${e2eCwd}/proj-backup/${path}` : `${e2eCwd}/proj-backup`;
475-
}
476-
477304
export function getPackageManagerCommand({
478-
path = tmpProjPath(),
479-
packageManager = detectPackageManager(path),
305+
p = tmpProjPath() as string,
306+
packageManager = detectPackageManager(p),
480307
scriptsPrependNodePath = true,
481308
} = {}): {
482309
createWorkspace: string;

packages/dotnet/src/lib/core/dotnet.client.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ export class DotNetClient {
7373
if (!watch) {
7474
return this.logAndExecute(params);
7575
} else {
76-
const slicedParams = params.slice(1).filter((x) => x.length);
77-
return this.logAndSpawn(slicedParams);
76+
return this.logAndSpawn(params);
7877
}
7978
}
8079

@@ -182,17 +181,6 @@ export class DotNetClient {
182181
}
183182
}
184183

185-
private execute(params: string[]): Buffer {
186-
return spawnSync(this.cliCommand.command, params, {
187-
cwd: this.cwd || process.cwd(),
188-
})
189-
.output.filter((buf) => buf !== null)
190-
.reduce(
191-
(acc, buf) => Buffer.concat([acc as Buffer, buf as Buffer]),
192-
Buffer.from(''),
193-
) as Buffer;
194-
}
195-
196184
private logAndSpawn(params: string[]): ChildProcess {
197185
console.log(
198186
`Executing Command: ${this.cliCommand.command} "${params.join('" "')}"`,

tools/scripts/e2e.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { execSync } from 'child_process';
22
import { copySync, removeSync } from 'fs-extra';
33

4-
import { e2eRoot } from '../../e2e/utils';
4+
import { tmpProjPath } from '@nrwl/nx-plugin/testing';
55
import { startCleanVerdaccioInstance } from './local-registry/setup';
66
import { publishAll } from './publish-all';
77

@@ -40,7 +40,7 @@ async function runTest() {
4040

4141
if (process.argv[5] != '--rerun') {
4242
removeSync('./dist');
43-
removeSync(e2eRoot);
43+
removeSync(tmpProjPath());
4444
}
4545

4646
try {

0 commit comments

Comments
 (0)