Skip to content

Commit

Permalink
Extracted getPackageRoots() (#152)
Browse files Browse the repository at this point in the history
* feature: Extracted getPackageRoots()

* chore: Added tests

* chore: Added documentation

* chore: Added changeset

---------

Co-authored-by: ijlee2 <[email protected]>
  • Loading branch information
ijlee2 and ijlee2 authored Feb 21, 2025
1 parent b2d32ac commit 3a17221
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/slow-lizards-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codemod-utils/files": minor
---

Extracted getPackageRoots()
27 changes: 27 additions & 0 deletions packages/files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,33 @@ const filePaths = findFiles([
</details>


### getPackageRoots

Returns the roots of all packages in a project.

<details>

<summary>Example</summary>

Analyze each package by reading `package.json`.

```ts
import { readPackageJson } from '@codemod-utils/json';

const packageRoots = getPackageRoots({
projectRoot,
});

packageRoots.forEach((packageRoot) => {
const packageJson = readPackageJson({ projectRoot: packageRoot });

// ...
});
```

</details>


### mapFilePaths

Creates a mapping of file paths, which can then be passed to [`copyFiles`](#copyfiles) or [`moveFiles`](#movefiles).
Expand Down
58 changes: 58 additions & 0 deletions packages/files/src/files/get-package-roots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { join } from 'node:path';

import type { Options } from '../types/index.js';
import { findFiles } from './find-files.js';
import { parseFilePath } from './parse-file-path.js';

/**
* Returns the roots of all packages in a project.
*
* @param options
*
* An object with `projectRoot`.
*
* @example
*
* Analyze each package by reading `package.json`.
*
* ```ts
* import { readPackageJson } from '@codemod-utils/json';
*
* const packageRoots = getPackageRoots({
* projectRoot,
* });
*
* packageRoots.forEach((packageRoot) => {
* const packageJson = readPackageJson({ projectRoot: packageRoot });
*
* // ...
* });
* ```
*/
export function getPackageRoots(
options: Options & {
projectRoot: string;
},
): string[] {
const { projectRoot } = options;

const filePaths = findFiles('**/package.json', {
ignoreList: ['**/{dist,node_modules}/**/*'],
projectRoot,
});

const packageRoots = filePaths.map((filePath) => {
const { dir } = parseFilePath(filePath);

return join(projectRoot, dir);
});

const isMonorepo = packageRoots.length > 1;

if (isMonorepo) {
// Exclude the workspace root
return packageRoots.filter((packageRoot) => packageRoot !== projectRoot);
}

return packageRoots;
}
1 change: 1 addition & 0 deletions packages/files/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './files/copy-files.js';
export * from './files/create-directory.js';
export * from './files/create-files.js';
export * from './files/find-files.js';
export * from './files/get-package-roots.js';
export * from './files/map-file-paths.js';
export * from './files/move-files.js';
export * from './files/parse-file-path.js';
Expand Down
18 changes: 18 additions & 0 deletions packages/files/tests/files/get-package-roots/base-case.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { assert, loadFixture, test } from '@codemod-utils/tests';

import { getPackageRoots } from '../../../src/index.js';
import { codemodOptions, options } from '../../shared-test-setups/index.js';

test('files | get-package-roots > base case', function () {
const inputProject = {
'package.json': '',
};

loadFixture(inputProject, codemodOptions);

const packageRoots = getPackageRoots({
projectRoot: options.projectRoot,
});

assert.deepStrictEqual(packageRoots, ['tmp/test-project']);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { assert, loadFixture, test } from '@codemod-utils/tests';

import { getPackageRoots } from '../../../src/index.js';
import { codemodOptions, options } from '../../shared-test-setups/index.js';

test('files | get-package-roots > edge case (file name is incorrect)', function () {
const inputProject = {
packagejson: '',
'package.json5': '',
'somepackage.json': '',
};

loadFixture(inputProject, codemodOptions);

const packageRoots = getPackageRoots({
projectRoot: options.projectRoot,
});

assert.deepStrictEqual(packageRoots, []);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { assert, loadFixture, test } from '@codemod-utils/tests';

import { getPackageRoots } from '../../../src/index.js';
import { codemodOptions, options } from '../../shared-test-setups/index.js';

test('files | get-package-roots > edge case (no packages)', function () {
const inputProject = {};

loadFixture(inputProject, codemodOptions);

const packageRoots = getPackageRoots({
projectRoot: options.projectRoot,
});

assert.deepStrictEqual(packageRoots, []);
});
43 changes: 43 additions & 0 deletions packages/files/tests/files/get-package-roots/monorepo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { assert, loadFixture, test } from '@codemod-utils/tests';

import { getPackageRoots } from '../../../src/index.js';
import { codemodOptions, options } from '../../shared-test-setups/index.js';

test('files | get-package-roots > monorepo', function () {
const inputProject = {
'docs-app': {
'package.json': '',
},
packages: {
'my-folder': {
'my-package-1': {
'package.json': '',
},
},
'my-package-2': {
'package.json': '',
},
'my-package-3': {
'package.json': '',
},
},
'test-app': {
'package.json': '',
},
'package.json': '',
};

loadFixture(inputProject, codemodOptions);

const packageRoots = getPackageRoots({
projectRoot: options.projectRoot,
});

assert.deepStrictEqual(packageRoots, [
'tmp/test-project/docs-app',
'tmp/test-project/packages/my-folder/my-package-1',
'tmp/test-project/packages/my-package-2',
'tmp/test-project/packages/my-package-3',
'tmp/test-project/test-app',
]);
});

0 comments on commit 3a17221

Please sign in to comment.