Skip to content

Commit

Permalink
fix eslint issues in botbuilder-repo-utils (#4838)
Browse files Browse the repository at this point in the history
  • Loading branch information
JhontSouth authored Jan 6, 2025
1 parent 9198d2a commit 75ed816
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 162 deletions.
10 changes: 0 additions & 10 deletions libraries/botbuilder-repo-utils/eslint.config.cjs

This file was deleted.

3 changes: 1 addition & 2 deletions libraries/botbuilder-repo-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"dayjs": "^1.11.13",
"fast-glob": "^3.3.2",
"lodash": "^4.17.20",
"eslint-plugin-only-warn": "^1.1.0",
"minimatch": "^9.0.5",
"minimist": "^1.2.6",
"p-map": "^4.0.0"
Expand All @@ -27,7 +26,7 @@
"typescript": "~4.7"
},
"scripts": {
"lint": "eslint .",
"lint": "eslint . --config ../../eslint.config.cjs",
"test": "mocha -r ts-node/register tests/*.test.ts",
"update-versions": "ts-node src/updateVersions.ts"
}
Expand Down
2 changes: 0 additions & 2 deletions libraries/botbuilder-repo-utils/src/file.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/* eslint-disable security/detect-non-literal-fs-filename */

import fs from 'fs';
import util from 'util';

Expand Down
194 changes: 98 additions & 96 deletions libraries/botbuilder-repo-utils/src/updateVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface PackageVersionOptions {
export const getPackageVersion = (
pkg: Partial<Package>,
newVersion: string,
options: PackageVersionOptions
options: PackageVersionOptions,
): string => {
const prerelease = [];

Expand All @@ -59,109 +59,111 @@ export const getPackageVersion = (
return compact([newVersion, compact(prerelease).join('.')]).join('-');
};

export const command = (argv: string[], quiet = false) => async (): Promise<Result> => {
// Obtain the path of the repo root, useful for constructing absolute paths
const repoRoot = await gitRoot();

const packageFile = await readJsonFile<Package>(path.join(repoRoot, 'package.json'));
if (!packageFile) {
return failure('package.json not found', 20);
}

// Parse process.argv for all configuration options
const {
_: [maybeNewVersion],
...flags
} = minimist(argv, {
default: {
deprecated: 'deprecated',
git: 'false',
internal: 'internal',
preview: 'preview',
},
string: ['buildLabel', 'date', 'deprecated', 'git', 'internal', 'preview'],
});

// If `maybeNewVersion` is falsy use version from the root packge.json file
const newVersion = maybeNewVersion || packageFile.version;
if (!newVersion) {
return failure('unable to resolve new version', 21);
}

// Fetch and format date, if instructed
const date = flags.date ? dayjs().format(flags.date) : undefined;

// Read git commit sha if instructed (JSON.parse properly coerces strings to boolean)
const commitSha = JSON.parse(flags.git) ? await gitSha('HEAD') : undefined;
export const command =
(argv: string[], quiet = false) =>
async (): Promise<Result> => {
// Obtain the path of the repo root, useful for constructing absolute paths
const repoRoot = await gitRoot();

const packageFile = await readJsonFile<Package>(path.join(repoRoot, 'package.json'));
if (!packageFile) {
return failure('package.json not found', 20);
}

// Parse process.argv for all configuration options
const {
_: [maybeNewVersion],
...flags
} = minimist(argv, {
default: {
deprecated: 'deprecated',
git: 'false',
internal: 'internal',
preview: 'preview',
},
string: ['buildLabel', 'date', 'deprecated', 'git', 'internal', 'preview'],
});

// If `maybeNewVersion` is falsy use version from the root packge.json file
const newVersion = maybeNewVersion || packageFile.version;
if (!newVersion) {
return failure('unable to resolve new version', 21);
}

// Fetch and format date, if instructed
const date = flags.date ? dayjs().format(flags.date) : undefined;

// Read git commit sha if instructed (JSON.parse properly coerces strings to boolean)
const commitSha = JSON.parse(flags.git) ? await gitSha('HEAD') : undefined;

const projects: string[] = [
...(packageFile.workspaces?.packages || []),
...(packageFile.workspaces?.generators || []),
];

// Collect all workspaces from the repo root. Returns workspaces with absolute paths.
const workspaces = await collectWorkspacePackages(repoRoot, projects);

// Build an object mapping a package name to its new, updated version
const workspaceVersions = workspaces.reduce<Record<string, string>>(
(acc, { pkg }) => ({
...acc,
[pkg.name]: getPackageVersion(pkg, pkg.private ? pkg.version : newVersion, {
buildLabel: flags.buildLabel,
commitSha,
date,
deprecated: flags.deprecated,
internal: flags.internal,
preview: flags.preview,
// Collect all workspaces from the repo root. Returns workspaces with absolute paths.
const workspaces = await collectWorkspacePackages(repoRoot, projects);

// Build an object mapping a package name to its new, updated version
const workspaceVersions = workspaces.reduce<Record<string, string>>(
(acc, { pkg }) => ({
...acc,
[pkg.name]: getPackageVersion(pkg, pkg.private ? pkg.version : newVersion, {
buildLabel: flags.buildLabel,
commitSha,
date,
deprecated: flags.deprecated,
internal: flags.internal,
preview: flags.preview,
}),
}),
}),
{}
);

// Rewrites the version for any dependencies found in `workspaceVersions`
const rewriteWithNewVersions = (dependencies: Record<string, string>) =>
Object.entries(dependencies)
.map(([dependency, version]) => [dependency, workspaceVersions[dependency] ?? version])
.reduce<Record<string, string>>((acc, [dependency, version]) => {
acc[dependency] = version;
return acc;
}, {});

// Rewrite package.json files by updating version as well as dependencies, devDependencies and peerDependencies.
const results = await Promise.all<Result>(
workspaces.map(async ({ absPath, pkg }) => {
const newVersion = workspaceVersions[pkg.name];

if (newVersion) {
if (!quiet) {
console.log(`Updating ${pkg.name} to ${newVersion}`);
{},
);

// Rewrites the version for any dependencies found in `workspaceVersions`
const rewriteWithNewVersions = (dependencies: Record<string, string>) =>
Object.entries(dependencies)
.map(([dependency, version]) => [dependency, workspaceVersions[dependency] ?? version])
.reduce<Record<string, string>>((acc, [dependency, version]) => {
acc[dependency] = version;
return acc;
}, {});

// Rewrite package.json files by updating version as well as dependencies, devDependencies and peerDependencies.
const results = await Promise.all<Result>(
workspaces.map(async ({ absPath, pkg }) => {
const newVersion = workspaceVersions[pkg.name];

if (newVersion) {
if (!quiet) {
console.log(`Updating ${pkg.name} to ${newVersion}`);
}
pkg.version = newVersion.toString();
}
pkg.version = newVersion.toString();
}

if (pkg.dependencies) {
pkg.dependencies = rewriteWithNewVersions(pkg.dependencies);
}

if (pkg.devDependencies) {
pkg.devDependencies = rewriteWithNewVersions(pkg.devDependencies);
}

if (pkg.peerDependencies) {
pkg.peerDependencies = rewriteWithNewVersions(pkg.peerDependencies);
}

try {
await writeJsonFile(absPath, pkg);
return success();
} catch (err: any) {
return failure(err instanceof Error ? err.message : err, 22);
}
})
);

return results.find(isFailure) ?? success();
};

if (pkg.dependencies) {
pkg.dependencies = rewriteWithNewVersions(pkg.dependencies);
}

if (pkg.devDependencies) {
pkg.devDependencies = rewriteWithNewVersions(pkg.devDependencies);
}

if (pkg.peerDependencies) {
pkg.peerDependencies = rewriteWithNewVersions(pkg.peerDependencies);
}

try {
await writeJsonFile(absPath, pkg);
return success();
} catch (err: any) {
return failure(err instanceof Error ? err.message : err, 22);
}
}),
);

return results.find(isFailure) ?? success();
};

if (require.main === module) {
run(command(process.argv.slice(2)));
Expand Down
94 changes: 46 additions & 48 deletions libraries/botbuilder-repo-utils/src/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface Filters {
export async function collectWorkspacePackages(
repoRoot: string,
workspaces: string[] = [],
filters: Partial<Filters> = {}
filters: Partial<Filters> = {},
): Promise<Array<Workspace>> {
// Note: posix is required, this emits absolute paths that are platform specific
const paths = await glob(
Expand All @@ -48,54 +48,52 @@ export async function collectWorkspacePackages(
);

const maybeWorkspaces = await Promise.all(
paths.map(
async (absPath): Promise<Workspace | undefined> => {
let relPath = absPath.replace(repoRoot, '');
if (relPath[0] === path.sep) {
relPath = relPath.slice(1);
}

// Strip `package.json` filename for path filters
const relWorkspacePath = path.dirname(relPath);

if (filters.path?.length && !filters.path.some((path) => minimatch(relWorkspacePath, path))) {
return;
}

if (
filters.ignorePath?.length &&
filters.ignorePath.some((ignorePath) => minimatch(relWorkspacePath, ignorePath))
) {
return;
}

const pkg = await readJsonFile<Package>(absPath);
if (!pkg) {
return undefined;
}

if (filters.noPrivate && pkg.private) {
return;
}

if (filters.script && !(pkg.scripts ?? {})[filters.script]) {
return;
}

if (filters.name?.length && !filters.name.some((name) => minimatch(pkg.name, name))) {
return;
}

if (
filters.ignoreName?.length &&
filters.ignoreName.some((ignoreName) => minimatch(pkg.name, ignoreName))
) {
return;
}

return { absPath, pkg, relPath };
paths.map(async (absPath): Promise<Workspace | undefined> => {
let relPath = absPath.replace(repoRoot, '');
if (relPath[0] === path.sep) {
relPath = relPath.slice(1);
}
)

// Strip `package.json` filename for path filters
const relWorkspacePath = path.dirname(relPath);

if (filters.path?.length && !filters.path.some((path) => minimatch(relWorkspacePath, path))) {
return;
}

if (
filters.ignorePath?.length &&
filters.ignorePath.some((ignorePath) => minimatch(relWorkspacePath, ignorePath))
) {
return;
}

const pkg = await readJsonFile<Package>(absPath);
if (!pkg) {
return undefined;
}

if (filters.noPrivate && pkg.private) {
return;
}

if (filters.script && !(pkg.scripts ?? {})[filters.script]) {
return;
}

if (filters.name?.length && !filters.name.some((name) => minimatch(pkg.name, name))) {
return;
}

if (
filters.ignoreName?.length &&
filters.ignoreName.some((ignoreName) => minimatch(pkg.name, ignoreName))
) {
return;
}

return { absPath, pkg, relPath };
}),
);

return compact(maybeWorkspaces);
Expand Down
9 changes: 5 additions & 4 deletions libraries/botbuilder-repo-utils/tests/updateVersions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import assert from 'assert';
import dayjs from 'dayjs';
import path from 'path';
import semver from 'semver';
import sinon from 'sinon';
import { createSandbox, match } from 'sinon';
import { Package } from '../src/package';
import { command, getPackageVersion } from '../src/updateVersions';
import { isSuccess } from '../src/run';
Expand Down Expand Up @@ -147,8 +147,9 @@ describe('updateVersions', function () {

describe('command', function () {
let sandbox: sinon.SinonSandbox;

beforeEach(function () {
sandbox = sinon.createSandbox();
sandbox = createSandbox();
});

afterEach(function () {
Expand Down Expand Up @@ -223,10 +224,10 @@ describe('updateVersions', function () {
),
});

let packageMatch = sinon.match.hasOwn('version', workspace.expectedVersion);
let packageMatch = match.hasOwn('version', workspace.expectedVersion);
if (workspace.expectedDependencies) {
packageMatch = packageMatch.and(
sinon.match.hasOwn('dependencies', sinon.match(workspace.expectedDependencies)),
match.hasOwn('dependencies', match(workspace.expectedDependencies)),
);
}

Expand Down

0 comments on commit 75ed816

Please sign in to comment.