-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add presetVersion flag for the create-nx-workspace (#16303)
Co-authored-by: FrozenPandaz <[email protected]>
- Loading branch information
1 parent
6428294
commit dc98485
Showing
4 changed files
with
113 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,14 @@ import { | |
import { Preset } from '../utils/presets'; | ||
import { newGenerator, NormalizedSchema } from './new'; | ||
|
||
const DEFAULT_PACKAGE_VERSION = '1.0.0'; | ||
jest.mock('./../utils/get-npm-package-version', () => ({ | ||
...jest.requireActual<any>('./../utils/get-npm-package-version'), | ||
getNpmPackageVersion: jest | ||
.fn() | ||
.mockImplementation((name, version) => version ?? DEFAULT_PACKAGE_VERSION), | ||
})); | ||
|
||
const defaultOptions: Omit< | ||
NormalizedSchema, | ||
'name' | 'directory' | 'appName' | 'isCustomPreset' | ||
|
@@ -94,6 +102,63 @@ describe('new', () => { | |
typescript: typescriptVersion, | ||
}); | ||
}); | ||
|
||
describe('custom presets', () => { | ||
let originalValue; | ||
beforeEach(() => { | ||
originalValue = process.env['NX_E2E_PRESET_VERSION']; | ||
}); | ||
|
||
afterEach(() => { | ||
if (originalValue) { | ||
process.env['NX_E2E_PRESET_VERSION'] = originalValue; | ||
} else { | ||
delete process.env['NX_E2E_PRESET_VERSION']; | ||
} | ||
}); | ||
// the process of actual resolving of a version relies on npm and is mocked here, | ||
// thus "package@2" is expected to be resolved with version "2" instead of "2.0.0" | ||
const versionAsPath = | ||
'/Users/username/3rd-party-pkg/dist/packages/3rd-party-pkg-1.12.5.tgz'; | ||
test.each` | ||
preset | presetVersion | expectedVersion | ||
${'3rd-party-package'} | ${undefined} | ${DEFAULT_PACKAGE_VERSION} | ||
${'[email protected]'} | ${undefined} | ${'1.1.2'} | ||
${'3rd-party-package@2'} | ${undefined} | ${'2'} | ||
${'3rd-party-package'} | ${'latest'} | ${'latest'} | ||
${'3rd-party-package'} | ${'1.1.1'} | ${'1.1.1'} | ||
${'3rd-party-package'} | ${versionAsPath} | ${versionAsPath} | ||
${'[email protected]'} | ${'1.1.1'} | ${'1.1.1'} | ||
`( | ||
'should add custom preset "$preset" with a correct expectedVersion "$expectedVersion" when presetVersion is "$presetVersion"', | ||
async ({ presetVersion, preset, expectedVersion }) => { | ||
if (presetVersion) { | ||
process.env['NX_E2E_PRESET_VERSION'] = presetVersion; | ||
} | ||
|
||
await newGenerator(tree, { | ||
...defaultOptions, | ||
name: 'my-workspace', | ||
directory: 'my-workspace', | ||
npmScope: 'npmScope', | ||
appName: 'app', | ||
preset, | ||
}); | ||
|
||
const { devDependencies, dependencies } = readJson( | ||
tree, | ||
'my-workspace/package.json' | ||
); | ||
expect(dependencies).toStrictEqual({ | ||
'3rd-party-package': expectedVersion, | ||
}); | ||
expect(devDependencies).toStrictEqual({ | ||
'@nrwl/workspace': nxVersion, | ||
nx: nxVersion, | ||
}); | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
it('should not modify any existing files', async () => { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,23 +92,40 @@ function validateOptions(options: Schema, host: Tree) { | |
} | ||
} | ||
|
||
function parsePresetName(input: string): { package: string; version?: string } { | ||
// If the preset already contains a version in the name | ||
// -- [email protected] | ||
// -- @scope/package@version | ||
const atIndex = input.indexOf('@', 1); // Skip the beginning @ because it denotes a scoped package. | ||
|
||
if (atIndex > 0) { | ||
return { | ||
package: input.slice(0, atIndex), | ||
version: input.slice(atIndex + 1), | ||
}; | ||
} else { | ||
if (!input) { | ||
throw new Error(`Invalid package name: ${input}`); | ||
} | ||
return { package: input }; | ||
} | ||
} | ||
|
||
function normalizeOptions(options: Schema): NormalizedSchema { | ||
const normalized: Partial<NormalizedSchema> = { ...options }; | ||
const normalized: Partial<NormalizedSchema> = { | ||
...options, | ||
}; | ||
|
||
normalized.name = names(options.name).fileName; | ||
if (!options.directory) { | ||
normalized.directory = options.name; | ||
} | ||
|
||
// If the preset already contains a version in the name | ||
// -- [email protected] | ||
// -- @scope/package@version | ||
const match = options.preset.match( | ||
/^(?<package>(@.+\/)?[^@]+)(@(?<version>\d+\.\d+\.\d+))?$/ | ||
); | ||
if (match) { | ||
normalized.preset = match.groups.package; | ||
normalized.presetVersion = match.groups.version; | ||
} | ||
const parsed = parsePresetName(options.preset); | ||
|
||
normalized.preset = parsed.package; | ||
// explicitly specified "presetVersion" takes priority over the one from the package name | ||
normalized.presetVersion ??= parsed.version; | ||
|
||
normalized.isCustomPreset = !Object.values(Preset).includes( | ||
options.preset as any | ||
|
24 changes: 17 additions & 7 deletions
24
packages/workspace/src/generators/utils/get-npm-package-version.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,26 @@ | ||
export function getNpmPackageVersion(packageName: string): string | null { | ||
export function getNpmPackageVersion( | ||
packageName: string, | ||
packageVersion?: string | ||
): string | null { | ||
try { | ||
const version = require('child_process').execSync( | ||
`npm view ${packageName} version`, | ||
`npm view ${packageName}${ | ||
packageVersion ? '@' + packageVersion : '' | ||
} version --json`, | ||
{ stdio: ['pipe', 'pipe', 'ignore'] } | ||
); | ||
|
||
if (version) { | ||
return version | ||
.toString() | ||
.trim() | ||
.replace(/^\n*|\n*$/g, ''); | ||
// [email protected] => ["1.12.0", "1.12.1"] | ||
// [email protected] => "1.12.1" | ||
// package@latest => "1.12.1" | ||
const versionOrArray = JSON.parse(version.toString()); | ||
|
||
if (typeof versionOrArray === 'string') { | ||
return versionOrArray; | ||
} | ||
return versionOrArray.pop(); | ||
} | ||
} catch (err) {} | ||
return null; | ||
return packageVersion ?? null; | ||
} |