Compare commits

...

1 Commits

Author SHA1 Message Date
FrozenPandaz 69b6646119 feat(core): add powerpack functionality 2024-09-17 18:05:49 -04:00
13 changed files with 335 additions and 5 deletions
Generated
+138
View File
@@ -65,6 +65,21 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstyle"
version = "1.0.6"
@@ -238,6 +253,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytecheck"
version = "0.6.12"
@@ -290,6 +311,20 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.6",
]
[[package]]
name = "clang-sys"
version = "1.8.1"
@@ -332,6 +367,12 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "crossbeam-channel"
version = "0.5.12"
@@ -967,6 +1008,29 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "idna"
version = "0.5.0"
@@ -1086,6 +1150,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "js-sys"
version = "0.3.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kqueue"
version = "1.0.8"
@@ -1467,6 +1540,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"assert_fs",
"chrono",
"colored",
"crossbeam-channel",
"crossterm",
@@ -2686,6 +2760,61 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.53",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
[[package]]
name = "watchexec"
version = "3.0.1"
@@ -2808,6 +2937,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
+25
View File
@@ -0,0 +1,25 @@
---
title: 'activate-powerpack - CLI command'
description: 'Activate a Nx Powerpack license.'
---
# activate-powerpack
Activate a Nx Powerpack license.
## Usage
```shell
nx activate-powerpack <license>
```
Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.
## Options
| Option | Type | Description |
| ----------- | ------- | ---------------------------------------------------------------------- |
| `--help` | boolean | Show help. |
| `--license` | string | License Key. |
| `--verbose` | boolean | Prints additional information about the commands (e.g., stack traces). |
| `--version` | boolean | Show version number. |
+1
View File
@@ -14,6 +14,7 @@ strip = "none"
[dependencies]
anyhow = "1.0.71"
colored = "2"
chrono = "0.4.38"
crossbeam-channel = '0.5'
dashmap = { version = "5.5.3", features = ["rayon"] }
dunce = "1"
@@ -0,0 +1,19 @@
import { workspaceRoot } from '../../utils/workspace-root';
import { ActivatePowerpackOptions } from './command-object';
export async function handleActivatePowerpack(
options: ActivatePowerpackOptions
) {
try {
// @ts-ignore
const { activatePowerpack } = await import('@nx/powerpack-license');
activatePowerpack(workspaceRoot, options.license);
} catch (e) {
if ('code' in e && e.code === 'ERR_MODULE_NOT_FOUND') {
throw new Error('Please install the @nx/powerpack-license package', {
cause: e,
});
}
throw e;
}
}
@@ -0,0 +1,39 @@
import { CommandModule } from 'yargs';
import { withVerbose } from '../yargs-utils/shared-options';
import { handleErrors } from '../../utils/handle-errors';
export interface ActivatePowerpackOptions {
license: string;
verbose: boolean;
}
export const yargsActivatePowerpackCommand: CommandModule<
{},
ActivatePowerpackOptions
> = {
command: 'activate-powerpack <license>',
describe: 'Activate a Nx Powerpack license.',
builder: (yargs) =>
withVerbose(yargs)
.parserConfiguration({
'strip-dashed': true,
'unknown-options-as-args': true,
})
.positional('license', {
type: 'string',
description: 'License Key.',
required: true,
})
.example(
'$0 activate-powerpack <license key>',
'Activate powerpack license'
),
handler: async (args) => {
const exitCode = await handleErrors(args.verbose as boolean, async () => {
return (await import('./activate-powerpack')).handleActivatePowerpack(
args
);
});
process.exit(exitCode);
},
};
@@ -8,10 +8,7 @@ export interface AddOptions {
__overrides_unparsed__: string[];
}
export const yargsAddCommand: CommandModule<
Record<string, unknown>,
AddOptions
> = {
export const yargsAddCommand: CommandModule<{}, AddOptions> = {
command: 'add <packageSpecifier>',
describe: 'Install a plugin and initialize it.',
builder: (yargs) =>
@@ -12,6 +12,7 @@ import {
listPlugins,
} from '../../utils/plugins';
import { workspaceRoot } from '../../utils/workspace-root';
import { listPowerpackPlugins } from '../../utils/plugins/output';
export interface ListArgs {
/** The name of an installed plugin to query */
@@ -46,6 +47,7 @@ export async function listHandler(args: ListArgs): Promise<void> {
}
listPlugins(installedPlugins, 'Installed plugins:');
listAlsoAvailableCorePlugins(installedPlugins);
listPowerpackPlugins();
output.note({
title: 'Community Plugins',
@@ -1,6 +1,7 @@
import * as chalk from 'chalk';
import * as yargs from 'yargs';
import { yargsActivatePowerpackCommand } from './activate-powerpack/command-object';
import {
yargsAffectedBuildCommand,
yargsAffectedCommand,
@@ -63,6 +64,7 @@ export const commandsObject = yargs
.parserConfiguration(parserConfiguration)
.usage(chalk.bold('Smart Monorepos · Fast CI'))
.demandCommand(1, '')
.command(yargsActivatePowerpackCommand)
.command(yargsAddCommand)
.command(yargsAffectedBuildCommand)
.command(yargsAffectedCommand)
@@ -23,6 +23,7 @@ import { getNxRequirePaths } from '../../utils/installation-directory';
import { NxJsonConfiguration, readNxJson } from '../../config/nx-json';
import { ProjectGraph } from '../../config/project-graph';
import { ProjectGraphError } from '../../project-graph/error-types';
import { getPowerpackLicenseInformation } from '../../utils/powerpack';
const nxPackageJson = readJsonFile<typeof import('../../../package.json')>(
join(__dirname, '../../../package.json')
@@ -39,6 +40,7 @@ export const packagesWeCareAbout = [
export const patternsWeIgnoreInCommunityReport: Array<string | RegExp> = [
...packagesWeCareAbout,
new RegExp('@nx/powerpack*'),
'@schematics/angular',
new RegExp('@angular/*'),
'@nestjs/schematics',
@@ -58,7 +60,9 @@ export async function reportHandler() {
const {
pm,
pmVersion,
powerpackLicense,
localPlugins,
powerpackPlugins,
communityPlugins,
registeredPlugins,
packageVersionsWeCareAbout,
@@ -88,6 +92,36 @@ export async function reportHandler() {
);
});
if (powerpackLicense) {
bodyLines.push(LINE_SEPARATOR);
bodyLines.push(chalk.green('Nx Powerpack'));
bodyLines.push(
`Licensed to ${powerpackLicense.organizationName} for ${
powerpackLicense.seatCount
} user${powerpackLicense.seatCount > 1 ? 's' : ''} in ${
powerpackLicense.workspaceCount
} workspace${
powerpackLicense.workspaceCount > 1 ? 's' : ''
} until ${new Date(powerpackLicense.expiresAt).toLocaleDateString()}`
);
bodyLines.push('');
padding =
Math.max(
...powerpackPlugins.map(
(powerpackPlugin) => powerpackPlugin.name.length
)
) + 1;
for (const powerpackPlugin of powerpackPlugins) {
bodyLines.push(
`${chalk.green(powerpackPlugin.name.padEnd(padding))} : ${chalk.bold(
powerpackPlugin.version
)}`
);
}
}
if (registeredPlugins.length) {
bodyLines.push(LINE_SEPARATOR);
bodyLines.push('Registered Plugins:');
@@ -147,6 +181,9 @@ export async function reportHandler() {
export interface ReportData {
pm: PackageManager;
pmVersion: string;
// TODO(@FrozenPandaz): Provide the right type here.
powerpackLicense: any | null;
powerpackPlugins: PackageJson[];
localPlugins: string[];
communityPlugins: PackageJson[];
registeredPlugins: string[];
@@ -174,6 +211,7 @@ export async function getReportData(): Promise<ReportData> {
const nxJson = readNxJson();
const localPlugins = await findLocalPlugins(graph, nxJson);
const powerpackPlugins = findInstalledPowerpackPlugins();
const communityPlugins = findInstalledCommunityPlugins();
const registeredPlugins = findRegisteredPluginsBeingUsed(nxJson);
@@ -193,8 +231,15 @@ export async function getReportData(): Promise<ReportData> {
const native = isNativeAvailable();
let powerpackLicense = null;
try {
powerpackLicense = await getPowerpackLicenseInformation();
} catch {}
return {
pm,
powerpackLicense,
powerpackPlugins,
pmVersion,
localPlugins,
communityPlugins,
@@ -294,6 +339,13 @@ export function findMisalignedPackagesForPackage(
: undefined;
}
export function findInstalledPowerpackPlugins(): PackageJson[] {
const installedPlugins = findInstalledPlugins();
return installedPlugins.filter((dep) =>
new RegExp('@nx/powerpack*').test(dep.name)
);
}
export function findInstalledCommunityPlugins(): PackageJson[] {
const installedPlugins = findInstalledPlugins();
return installedPlugins.filter(
@@ -51,6 +51,7 @@ import { TasksRunner, TaskStatus } from './tasks-runner';
import { shouldStreamOutput } from './utils';
import chalk = require('chalk');
import type { Observable } from 'rxjs';
import { printPowerpackLicense } from '../utils/powerpack';
async function getTerminalOutputLifeCycle(
initiatingProject: string,
@@ -241,6 +242,8 @@ export async function runCommandForTasks(
await renderIsDone;
await printPowerpackLicense();
return taskResults;
}
+7
View File
@@ -61,6 +61,13 @@ export function listAlsoAvailableCorePlugins(
}
}
export function listPowerpackPlugins(): void {
const powerpackLink = 'https://nx.dev/plugin-registry';
output.log({
title: `Available Powerpack Plugins: ${powerpackLink}`,
});
}
export async function listPluginCapabilities(
pluginName: string,
projects: Record<string, ProjectConfiguration>
+44
View File
@@ -0,0 +1,44 @@
import { logger } from './logger';
import { getPackageManagerCommand } from './package-manager';
import { workspaceRoot } from './workspace-root';
export async function printPowerpackLicense() {
try {
const { organizationName, seatCount, workspaceCount } =
await getPowerpackLicenseInformation();
logger.log(
`Nx Powerpack Licensed to ${organizationName} for ${seatCount} user${
seatCount > 1 ? '' : 's'
} in ${workspaceCount} workspace${workspaceCount > 1 ? '' : 's'}`
);
} catch {}
}
export async function getPowerpackLicenseInformation() {
try {
const { getPowerpackLicenseInformation } = (await import(
// @ts-ignore
'@nx/powerpack-license'
// TODO(@FrozenPandaz): Provide the right type here.
)) as any;
// )) as typeof import('@nx/powerpack-license');
return getPowerpackLicenseInformation(workspaceRoot);
} catch (e) {
if ('code' in e && e.code === 'ERR_MODULE_NOT_FOUND') {
throw new NxPowerpackNotInstalledError(e);
}
throw e;
}
}
export class NxPowerpackNotInstalledError extends Error {
constructor(e: Error) {
super(
`The "@nx/powerpack-license" package is needed to use Nx Powerpack enabled features. Please install the @nx/powerpack-license with ${
getPackageManagerCommand().addDev
} @nx/powerpack-license`,
{ cause: e }
);
}
}
+2 -1
View File
@@ -212,7 +212,8 @@ function parseArgs() {
type: 'boolean',
description:
'Clear existing versions in the local registry so that you can republish the same version',
default: true,
// TODO(@FrozenPandaz): Change this back to true
default: false,
})
.option('local', {
type: 'boolean',