Skip to content

Commit 5a404ea

Browse files
committed
refactor(semver): 🧹 tiddy up
1 parent 77d5cd9 commit 5a404ea

File tree

3 files changed

+79
-43
lines changed

3 files changed

+79
-43
lines changed

packages/semver/src/executors/version/index.spec.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as git from './utils/git';
1414
import { executePostTargets } from './utils/post-target';
1515
import { tryBump } from './utils/try-bump';
1616
import * as workspace from './utils/workspace';
17-
import { getProjectDependencies } from './utils/get-project-dependencies';
17+
import { getDependencyRoots } from './utils/get-project-dependencies';
1818

1919
jest.mock('child_process');
2020
jest.mock('standard-version', () => jest.fn());
@@ -38,10 +38,9 @@ describe('@jscutlery/semver:version', () => {
3838
const mockStandardVersion = standardVersion as jest.MockedFunction<
3939
typeof standardVersion
4040
>;
41-
const mockGetProjectDependencies =
42-
getProjectDependencies as jest.MockedFunction<
43-
typeof getProjectDependencies
44-
>;
41+
const mockGetDependencyRoots = getDependencyRoots as jest.MockedFunction<
42+
typeof getDependencyRoots
43+
>;
4544
const mockExecutePostTargets = executePostTargets as jest.MockedFunction<
4645
typeof executePostTargets
4746
>;
@@ -83,6 +82,7 @@ describe('@jscutlery/semver:version', () => {
8382
jest.spyOn(git, 'addToStage').mockReturnValue(of(undefined));
8483

8584
mockExecutePostTargets.mockReturnValue(of(undefined));
85+
mockGetDependencyRoots.mockReturnValue(Promise.resolve([]));
8686

8787
/* Mock a dependency, don't ask me which one. */
8888
mockExecFile.mockImplementation(
@@ -146,11 +146,13 @@ describe('@jscutlery/semver:version', () => {
146146
});
147147

148148
it('should run standard-version independently on a project with dependencies', async () => {
149-
mockGetProjectDependencies.mockReturnValue(
150-
Promise.resolve(['lib1', 'lib2'])
149+
mockGetDependencyRoots.mockReturnValue(
150+
Promise.resolve(['/root/libs/lib1', '/root/libs/lib2'])
151+
);
152+
const { success } = await version(
153+
{ ...options, trackDeps: true },
154+
context
151155
);
152-
const tempOptions = { ...options, trackDeps: true };
153-
const { success } = await version(tempOptions, context);
154156

155157
expect(success).toBe(true);
156158
expect(mockTryBump).toBeCalledWith(
@@ -174,17 +176,11 @@ describe('@jscutlery/semver:version', () => {
174176
});
175177

176178
it('should run standard-version independently on a project with failure on dependencies', async () => {
177-
mockGetProjectDependencies.mockReturnValue(
178-
Promise.reject('thrown error')
179-
);
180-
const tempOptions = { ...options, trackDeps: true };
181-
let error;
182-
try {
183-
await version(tempOptions, context);
184-
} catch (e) {
185-
error = e;
186-
}
187-
expect(error).toEqual('thrown error');
179+
mockGetDependencyRoots.mockReturnValue(Promise.reject('thrown error'));
180+
181+
expect(await version({ ...options, trackDeps: true }, context)).toEqual({
182+
success: false,
183+
});
188184
expect(logger.error).toBeCalledWith('Failed to determine dependencies.');
189185
expect(standardVersion).not.toBeCalled();
190186
});
@@ -466,7 +462,21 @@ describe('@jscutlery/semver:version', () => {
466462
);
467463

468464
expect(success).toBe(true);
469-
expect(mockExecutePostTargets).toBeCalled();
465+
expect(mockExecutePostTargets).toBeCalledWith(
466+
expect.objectContaining({
467+
resolvableOptions: {
468+
baseBranch: 'main',
469+
dryRun: false,
470+
noVerify: false,
471+
notes: '',
472+
project: 'a',
473+
remote: 'origin',
474+
tag: 'a-2.1.0',
475+
tagPrefix: 'a-',
476+
version: '2.1.0',
477+
},
478+
})
479+
);
470480
});
471481

472482
it('should handle post targets failure', async () => {

packages/semver/src/executors/version/index.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ import { SchemaError } from '@nrwl/tao/src/shared/params';
33
import { concat, defer, lastValueFrom, of } from 'rxjs';
44
import { catchError, concatMap, reduce, switchMap } from 'rxjs/operators';
55

6-
import {
7-
calculateChangelogChanges,
8-
defaultHeader,
9-
getChangelogPath,
10-
} from './utils/changelog';
11-
import { getProjectDependencies } from './utils/get-project-dependencies';
6+
import { calculateChangelogChanges, defaultHeader, getChangelogPath } from './utils/changelog';
7+
import { getDependencyRoots } from './utils/get-project-dependencies';
128
import { tryPushToGitRemote } from './utils/git';
139
import { executePostTargets } from './utils/post-target';
1410
import { resolveTagPrefix } from './utils/resolve-tag-prefix';
@@ -51,22 +47,20 @@ export default async function version(
5147
syncVersions,
5248
});
5349

54-
const projectRoot = getProjectRoot(context);
55-
5650
let dependencyRoots: string[] = [];
57-
if (trackDeps && !releaseAs) {
58-
// Include any depended-upon libraries in determining the version bump.
59-
try {
60-
const dependencyLibs = await getProjectDependencies(projectName);
61-
dependencyRoots = dependencyLibs.map(
62-
(name) => context.workspace.projects[name].root
63-
);
64-
} catch (e) {
65-
logger.error('Failed to determine dependencies.');
66-
return Promise.reject(e);
67-
}
51+
try {
52+
dependencyRoots = await getDependencyRoots({
53+
projectName,
54+
releaseAs,
55+
trackDeps,
56+
context,
57+
});
58+
} catch (e) {
59+
logger.error('Failed to determine dependencies.');
60+
return { success: false };
6861
}
6962

63+
const projectRoot = getProjectRoot(context);
7064
const newVersion$ = tryBump({
7165
preset,
7266
projectRoot,
@@ -80,7 +74,7 @@ export default async function version(
8074
switchMap((newVersion) => {
8175
if (newVersion == null) {
8276
logger.info('⏹ Nothing changed since last release.');
83-
return of({ success: true });
77+
return of({ success: true } as const);
8478
}
8579

8680
const options: CommonVersionOptions = {
@@ -118,6 +112,13 @@ export default async function version(
118112
})
119113
);
120114

115+
/**
116+
* 1. Calculate new version
117+
* 2. Release (create changelog -> add to stage -> commit -> tag)
118+
* 3. Calculate changelog changes
119+
* 4. Push to Git
120+
* 5. Run post targets
121+
*/
121122
return runStandardVersion$.pipe(
122123
calculateChangelogChanges({
123124
changelogHeader,
@@ -161,7 +162,7 @@ export default async function version(
161162
logger.error(error.stack ?? error.toString());
162163
}
163164

164-
return of({ success: false });
165+
return of({ success: false } as const);
165166
})
166167
)
167168
);

packages/semver/src/executors/version/utils/get-project-dependencies.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
// The shape of the project graph is still subject to changes, but
22
// can still be used, according to the NX devs. That's why we're
33
// doing a deep import here.
4-
import { createProjectGraphAsync, ProjectGraphDependency } from '@nrwl/workspace/src/core/project-graph';
4+
import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph';
5+
6+
import { ExecutorContext } from '@nrwl/devkit';
7+
import type { ProjectGraphDependency } from '@nrwl/workspace/src/core/project-graph';
8+
9+
import type { VersionBuilderSchema } from '../schema';
10+
11+
export async function getDependencyRoots({
12+
trackDeps,
13+
releaseAs,
14+
projectName,
15+
context,
16+
}: Required<Pick<VersionBuilderSchema, 'trackDeps'>> &
17+
Pick<VersionBuilderSchema, 'releaseAs'> & {
18+
projectName: string;
19+
context: ExecutorContext;
20+
}): Promise<string[]> {
21+
if (trackDeps && !releaseAs) {
22+
// Include any depended-upon libraries in determining the version bump.
23+
return (await getProjectDependencies(projectName)).map(
24+
(name) => context.workspace.projects[name].root
25+
);
26+
}
27+
28+
return [];
29+
}
530

631
/**
732
* Returns a list of in-repo dependencies based on NX's dependency graph.

0 commit comments

Comments
 (0)