Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions scripts/beachball/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AllPackageInfo, getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';
import { getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';

/**
* Reads package info from the monorepo and generates the scopes for beachball bump and release.
Expand All @@ -17,8 +17,7 @@ export function getConfig({ version }: { version: 'vNext' }): {
};
};
export function getConfig({ version }: { version: 'v8' | 'vNext' }) {
const allPackageInfo = getAllPackageInfo();
const vNextPackagePaths = getVNextPackagePaths(allPackageInfo);
const vNextPackagePaths = getVNextPackagePaths();

if (version === 'vNext') {
return {
Expand All @@ -32,22 +31,17 @@ export function getConfig({ version }: { version: 'v8' | 'vNext' }) {
}

if (version === 'v8') {
const ignoreVNextScope = vNextPackagePaths.map(path => `!${path}`);
const ignoreVNextScope = vNextPackagePaths.map(pkgPath => `!${pkgPath}`);

return { scope: [...ignoreVNextScope] };
}

throw new Error('Unsupported version scopes acquisition');
}

function getVNextPackagePaths(allPackageInfo: AllPackageInfo) {
return Object.values(allPackageInfo)
.map(packageInfo => {
if (isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) {
return packageInfo.packagePath;
}
function getVNextPackagePaths() {
const allProjects = getAllPackageInfo(isConvergedPackage);
const values = Object.values(allProjects);

return false;
})
.filter(Boolean) as string[];
return values.map(project => project.packagePath);
}
4 changes: 2 additions & 2 deletions scripts/executors/runPublished.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ function getLageArgs(options) {
// (which must be built and uploaded with each release). This is similar to "--scope \"!packages/fluentui/*\""
// in the root package.json's publishing-related scripts and will need to be updated if --scope changes.
const beachballPackageScopes = Object.values(workspacePackagesMetadata)
.filter(({ packageJson, packagePath }) => {
.filter(({ packageJson, projectConfig, packagePath }) => {
const isNorthstar = /[\\/]fluentui[\\/]/.test(packagePath);
const isWebComponents = packageJson.name === '@fluentui/web-components';

if (isNorthstar || isWebComponents) {
return false;
}

const isConverged = isConvergedPackage({ packagePathOrJson: packageJson });
const isConverged = isConvergedPackage({ packageJson, project: projectConfig });
if (releaseScope === 'v9' && isConverged) {
return packageJson.private !== true;
}
Expand Down
8 changes: 8 additions & 0 deletions scripts/executors/runPublished.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,26 @@ describe(`#runPublished`, () => {
'@fluentui/web-components': {
packagePath: 'packages/web-components',
packageJson: { name: '@fluentui/web-components', version: '1.0.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/web-components', root: 'packages/web-components', tags: [] },
},
'@fluentui/react': {
packagePath: 'packages/react',
packageJson: { name: '@fluentui/react', version: '8.0.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/react', root: 'packages/react', tags: [] },
},
'@fluentui/react-northstar': {
packagePath: 'packages/fluentui/react-northstar',
packageJson: { name: '@fluentui/react-northstar', version: '0.1.0', main: 'lib/index.js', private: false },
projectConfig: { name: '@fluentui/react-northstar', root: 'packages/fluentui/react-northstar', tags: [] },
},
'@fluentui/react-components': {
packagePath: 'packages/react-components/react-components',
packageJson: { name: '@fluentui/react-components', version: '9.0.0', main: 'lib/index.js', private: false },
projectConfig: {
name: '@fluentui/react-components',
root: 'packages/react-components/react-components',
tags: [],
},
},
};

Expand Down
10 changes: 6 additions & 4 deletions scripts/executors/tag-react-components.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { execSync } from 'child_process';
import * as semver from 'semver';
import yargs from 'yargs';

import { AllPackageInfo, getAllPackageInfo, isConvergedPackage } from '@fluentui/scripts-monorepo';
import * as semver from 'semver';
import yargs from 'yargs';

function tagPackages(npmToken: string) {
const packagesToTag = getPackagesToTag();
Expand Down Expand Up @@ -42,10 +42,10 @@ function tagPackage(name: string, version: string, npmToken: string): boolean {
}

function getPackagesToTag() {
const packageInfos: AllPackageInfo = getAllPackageInfo();
const packageInfos: AllPackageInfo = getAllPackageInfo(isConvergedPackage);
return Object.values(packageInfos)
.map(packageInfo => {
if (!packageInfo.packageJson.private && isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) {
if (!packageInfo.packageJson.private) {
return {
name: packageInfo.packageJson.name,
version: packageInfo.packageJson.version,
Expand All @@ -67,4 +67,6 @@ function main(argv: yargs.Arguments) {

if (require.main === module && process.env.RELEASE_VNEXT) {
main(yargs.argv);
} else {
console.log('"RELEASE_VNEXT" not set - skipping');
}
10 changes: 7 additions & 3 deletions scripts/generators/create-package/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { spawnSync } from 'child_process';
import * as path from 'path';

import { PackageJson, findGitRoot, flushTreeChanges, getProjectMetadata, tree } from '@fluentui/scripts-monorepo';
import { addProjectConfiguration } from '@nx/devkit';
import { PackageJson, findGitRoot, flushTreeChanges, tree } from '@fluentui/scripts-monorepo';
import { addProjectConfiguration, getProjects } from '@nx/devkit';
import chalk from 'chalk';
import * as fs from 'fs-extra';
import _ from 'lodash';
Expand Down Expand Up @@ -188,10 +188,14 @@ function replaceVersionsFromReference(

const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'] as const;

const projects = getProjects(tree);
// Read the package.json files of the given reference packages and combine into one object.
// This way if a dep is defined in any of them, it can easily be copied to newPackageJson.
const packageJsons = referencePackages.map(pkgName => {
const metadata = getProjectMetadata(pkgName);
const metadata = projects.get(pkgName);
if (!metadata) {
throw new Error(`Couldn't find metadata for package ${pkgName}`);
}

return fs.readJSONSync(path.join(metadata.root, 'package.json'));
});
Expand Down
16 changes: 13 additions & 3 deletions scripts/monorepo/src/getAllPackageInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ let cwdForPackageInfo;

/**
* @returns {typeof packageInfo}
* @param {(metadata:{project:import('@nx/devkit').ProjectConfiguration;packageJson:import('nx/src/utils/package-json').PackageJson})=>boolean} [predicate]
*/
function getAllPackageInfo() {
if (packageInfo && cwdForPackageInfo === process.cwd()) {
function getAllPackageInfo(predicate) {
if (!predicate && packageInfo && cwdForPackageInfo === process.cwd()) {
return packageInfo;
}

Expand All @@ -28,9 +29,18 @@ function getAllPackageInfo() {
cwdForPackageInfo = process.cwd();

for (const [projectName, projectConfig] of projects) {
const packageJson = JSON.parse(
fs.readFileSync(path.join(workspaceRoot, projectConfig.root, 'package.json'), 'utf-8'),
);

if (predicate && !predicate({ project: projectConfig, packageJson })) {
continue;
}

packageInfo[projectName] = {
packagePath: projectConfig.root,
packageJson: JSON.parse(fs.readFileSync(path.join(workspaceRoot, projectConfig.root, 'package.json'), 'utf-8')),
packageJson,
projectConfig,
};
}

Expand Down
17 changes: 17 additions & 0 deletions scripts/monorepo/src/getAllPackageInfo.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as path from 'path';

import getAllPackageInfo from './getAllPackageInfo';

describe(`#getAllPackageinfo`, () => {
Expand All @@ -9,13 +10,29 @@ describe(`#getAllPackageinfo`, () => {

expect(allPackages['@fluentui/noop']).toBe(undefined);
expect(packageName).toEqual(expect.stringMatching(/^@fluentui\/[a-z-]+/));

expect(packageMetadata).toEqual({
packagePath: expect.any(String),
packageJson: expect.objectContaining({
name: expect.any(String),
version: expect.any(String),
}),
projectConfig: expect.objectContaining({
$schema: expect.any(String),
implicitDependencies: expect.any(Array),
name: expect.any(String),
projectType: expect.any(String),
root: expect.any(String),
}),
});
expect(path.isAbsolute(packageMetadata.packagePath)).toBe(false);
});

it(`should accept predicate filter function`, () => {
const allPackages = getAllPackageInfo(metadata => {
return metadata.packageJson.name === '@fluentui/non-existent-package';
});

expect(allPackages).toEqual({});
});
});
4 changes: 2 additions & 2 deletions scripts/monorepo/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ export { getDependencies } from './getDependencies';
export { default as findGitRoot } from './findGitRoot';
export { default as findRepoDeps } from './findRepoDeps';
export { default as getAllPackageInfo } from './getAllPackageInfo';
export { isConvergedPackage, shipsAMD } from './isConvergedPackage';
export { isConvergedPackage } from './isConvergedPackage';
export { getAffectedPackages } from './getAffectedPackages';
export { getDefaultEnvironmentVars } from './getDefaultEnvironmentVars';
export { getProjectMetadata, workspaceRoot, getUncommittedFiles, getUntrackedFiles } from './utils';
export { workspaceRoot, getUncommittedFiles, getUntrackedFiles } from './utils';
export * as eslintConstants from './eslint-constants';
export { getNthCommit } from './getNthCommit';
export { tree, flushTreeChanges } from './tree';
Expand Down
78 changes: 4 additions & 74 deletions scripts/monorepo/src/isConvergedPackage.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,16 @@
const { readConfig } = require('@fluentui/scripts-utils');
const semver = require('semver');

const { getProjectMetadata } = require('./utils');

/**
* @typedef {string | import('./index').PackageJson} PathOrPackageJson
*/

/**
* Determines whether a package is converged, based on its version.
*
* @param {Object} [options]
* @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json
* (defaults to reading package.json from `process.cwd()`)
* @param {'library' | 'application' | 'all'} [options.projectType] - filter for what project types you wanna apply the condition
*
* @returns {boolean} true if it's a converged package (version >= 9)
* @param {{project:import('@nx/devkit').ProjectConfiguration;packageJson:import('nx/src/utils/package-json').PackageJson}} metadata
*/
function isConvergedPackage(options = {}) {
const { packagePathOrJson, projectType = 'all' } = options;
const packageJson =
!packagePathOrJson || typeof packagePathOrJson === 'string'
? readConfig('package.json', /** @type {string|undefined} */ (packagePathOrJson))
: packagePathOrJson;

if (!packageJson) {
throw new Error(`package.json doesn't exist`);
}

const metadata = getProjectMetadata(packageJson.name);

if (projectType !== 'all' && metadata.projectType !== projectType) {
return false;
}

const hasVNextTag = !!metadata.tags?.includes('vNext');
function isConvergedPackage(metadata) {
const { packageJson, project } = metadata;
const hasVNextTag = Boolean(project.tags?.includes('vNext'));

return semver.major(packageJson.version) >= 9 || isNightlyVersion(packageJson.version) || hasVNextTag;
}

/**
* @param {Object} [options]
* @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json
* (defaults to reading package.json from `process.cwd()`)
* @returns
*/
function shipsAMD(options = {}) {
const { packagePathOrJson } = options;
const packageJson =
!packagePathOrJson || typeof packagePathOrJson === 'string'
? readConfig('package.json', /** @type {string|undefined} */ (packagePathOrJson))
: packagePathOrJson;

if (!packageJson) {
throw new Error(`package.json doesn't exist`);
}

const metadata = getProjectMetadata(packageJson.name);

if (metadata.projectType !== 'library') {
return false;
}

const tags = new Set(metadata.tags ?? []);
const isV8 = tags.has('v8');
const isV9 = tags.has('vNext');
const needsAMD = tags.has('ships-amd');
const isMixedProject = isV9 && isV8;

if (needsAMD) {
return true;
}
if (isMixedProject) {
return true;
}
if (isV9) {
return false;
}
return true;
}

/**
* Determines if a version is the 0.0.0 nightly version used by converged packages
* @param {string} version
Expand All @@ -89,4 +20,3 @@ function isNightlyVersion(version) {
}

exports.isConvergedPackage = isConvergedPackage;
exports.shipsAMD = shipsAMD;
39 changes: 39 additions & 0 deletions scripts/monorepo/src/isConvergedPackage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { isConvergedPackage } from './isConvergedPackage';

describe(`#isConverged`, () => {
it(`should return true for vNext package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '9.0.0',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['vNext'] },
});

expect(actual).toBe(true);
});

it(`should return true for vNext nightly package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '0.0.0-nightly.20210101',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['vNext'] },
});

expect(actual).toBe(true);
});

it(`should return false for non vNext Package`, () => {
const actual = isConvergedPackage({
packageJson: {
name: '@proj/one',
version: '8.1.2',
},
project: { root: 'packages/foo/bar/one', projectType: 'library', tags: ['v8'] },
});

expect(actual).toBe(false);
});
});
1 change: 1 addition & 0 deletions scripts/monorepo/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface PackageInfo {
packagePath: string;
/** package.json contents */
packageJson: PackageJson;
projectConfig: import('@nx/devkit').ProjectConfiguration;
}

/**
Expand Down
14 changes: 1 addition & 13 deletions scripts/monorepo/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
const { execSync } = require('child_process');

const { workspaceRoot, readProjectConfiguration } = require('@nx/devkit');

const { tree } = require('./tree');
const { workspaceRoot } = require('@nx/devkit');

const TEN_MEGABYTES = 1024 * 10000;

/**
* Gets nx project metadata
* @param {string} projectName - package name
* @returns {import('@nx/devkit').ProjectConfiguration}
*/
function getProjectMetadata(projectName) {
return readProjectConfiguration(tree, projectName);
}

/**
*
* @param {string} command
Expand Down Expand Up @@ -46,5 +35,4 @@ function getUntrackedFiles() {

exports.getUncommittedFiles = getUncommittedFiles;
exports.getUntrackedFiles = getUntrackedFiles;
exports.getProjectMetadata = getProjectMetadata;
exports.workspaceRoot = workspaceRoot;
Loading