@netlify/build-info 6.2.2 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/bin.js +1 -1
  2. package/lib/browser/file-system.d.ts +25 -0
  3. package/lib/browser/file-system.js +70 -0
  4. package/lib/build-systems/bazel.d.ts +8 -0
  5. package/lib/build-systems/bazel.js +12 -0
  6. package/lib/build-systems/buck.d.ts +8 -0
  7. package/lib/build-systems/buck.js +12 -0
  8. package/lib/build-systems/build-system.d.ts +20 -0
  9. package/lib/build-systems/build-system.js +18 -0
  10. package/lib/build-systems/gradle.d.ts +8 -0
  11. package/lib/build-systems/gradle.js +12 -0
  12. package/lib/build-systems/index.d.ts +2 -0
  13. package/lib/build-systems/index.js +11 -0
  14. package/lib/build-systems/lage.d.ts +6 -0
  15. package/lib/build-systems/lage.js +6 -0
  16. package/lib/build-systems/moon.d.ts +8 -0
  17. package/lib/build-systems/moon.js +18 -0
  18. package/lib/build-systems/nix.d.ts +8 -0
  19. package/lib/build-systems/nix.js +12 -0
  20. package/lib/build-systems/nrwl.d.ts +11 -0
  21. package/lib/build-systems/nrwl.js +11 -0
  22. package/lib/build-systems/pants.d.ts +8 -0
  23. package/lib/build-systems/pants.js +12 -0
  24. package/lib/build-systems/rush.d.ts +6 -0
  25. package/lib/build-systems/rush.js +6 -0
  26. package/lib/build-systems/turbo.d.ts +6 -0
  27. package/lib/build-systems/turbo.js +6 -0
  28. package/lib/file-system.d.ts +69 -0
  29. package/lib/file-system.js +195 -0
  30. package/lib/index.d.ts +2 -1
  31. package/lib/index.js +2 -1
  32. package/lib/{bin.d.ts → node/bin.d.ts} +0 -0
  33. package/lib/{bin.js → node/bin.js} +2 -3
  34. package/lib/node/file-system.d.ts +19 -0
  35. package/lib/node/file-system.js +65 -0
  36. package/lib/node/get-build-info.d.ts +20 -0
  37. package/lib/node/get-build-info.js +46 -0
  38. package/lib/{detect-package-manager.d.ts → package-managers/detect-package-manager.d.ts} +2 -4
  39. package/lib/package-managers/detect-package-manager.js +75 -0
  40. package/lib/project.d.ts +33 -0
  41. package/lib/project.js +82 -0
  42. package/lib/workspaces/detect-workspace.d.ts +22 -0
  43. package/lib/workspaces/detect-workspace.js +56 -0
  44. package/lib/workspaces/get-workspace-packages.d.ts +3 -0
  45. package/lib/workspaces/get-workspace-packages.js +66 -0
  46. package/package.json +9 -4
  47. package/lib/context.d.ts +0 -11
  48. package/lib/context.js +0 -45
  49. package/lib/detect-build-system.d.ts +0 -5
  50. package/lib/detect-build-system.js +0 -145
  51. package/lib/detect-package-manager.js +0 -71
  52. package/lib/get-build-info.d.ts +0 -11
  53. package/lib/get-build-info.js +0 -34
  54. package/lib/workspaces.d.ts +0 -22
  55. package/lib/workspaces.js +0 -56
@@ -1,4 +1,4 @@
1
- import { exit, argv } from 'process';
1
+ import { argv, exit } from 'process';
2
2
  import yargs from 'yargs';
3
3
  import { hideBin } from 'yargs/helpers';
4
4
  import { getBuildInfo } from './get-build-info.js';
@@ -10,8 +10,7 @@ yargs(hideBin(argv))
10
10
  },
11
11
  }), async ({ projectDir, rootDir }) => {
12
12
  try {
13
- const buildInfo = await getBuildInfo({ projectDir, rootDir });
14
- console.log(JSON.stringify(buildInfo, null, 2));
13
+ console.log(JSON.stringify(await getBuildInfo(projectDir, rootDir), null, 2));
15
14
  }
16
15
  catch (error) {
17
16
  console.error(error);
@@ -0,0 +1,19 @@
1
+ import { DirType, FileSystem, findUpOptions } from '../file-system.js';
2
+ export declare class NodeFS extends FileSystem {
3
+ constructor();
4
+ isAbsolute(path: string): boolean;
5
+ dirname(path: string): string;
6
+ resolve(...paths: string[]): string;
7
+ relative(from: string, to: string): string;
8
+ basename(path: string): string;
9
+ join(...segments: string[]): string;
10
+ fileExists(path: string): Promise<boolean>;
11
+ /** Get a list of directory entries */
12
+ readDir(path: string): Promise<string[]>;
13
+ readDir(path: string, withFileTypes: true): Promise<Record<string, DirType>>;
14
+ readFile(path: string): Promise<string>;
15
+ /** Node implementation of finding a file or directory by walking up parent directories. */
16
+ findUp(name: string | readonly string[], options?: findUpOptions): Promise<string | undefined>;
17
+ /** Node implementation of finding files or directories by walking up parent directories. */
18
+ findUpMultiple(name: string | readonly string[], options?: findUpOptions): Promise<string[]>;
19
+ }
@@ -0,0 +1,65 @@
1
+ import { promises as fs } from 'fs';
2
+ import { basename, dirname, isAbsolute, join, relative, resolve } from 'path';
3
+ import { findUp, findUpMultiple } from 'find-up';
4
+ import { FileSystem } from '../file-system.js';
5
+ export class NodeFS extends FileSystem {
6
+ constructor() {
7
+ super();
8
+ this.cwd = process.cwd();
9
+ }
10
+ isAbsolute(path) {
11
+ return isAbsolute(path);
12
+ }
13
+ dirname(path) {
14
+ return dirname(path);
15
+ }
16
+ resolve(...paths) {
17
+ return resolve(...paths);
18
+ }
19
+ relative(from, to) {
20
+ return relative(from, to);
21
+ }
22
+ basename(path) {
23
+ return basename(path);
24
+ }
25
+ join(...segments) {
26
+ return join(...segments);
27
+ }
28
+ async fileExists(path) {
29
+ try {
30
+ await fs.stat(resolve(path));
31
+ return true;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ async readDir(path, withFileTypes) {
38
+ try {
39
+ if (!withFileTypes) {
40
+ return fs.readdir(resolve(path));
41
+ }
42
+ const result = await fs.readdir(resolve(path), { withFileTypes: true });
43
+ return result.reduce((prev, cur) => ({ ...prev, [cur.name]: cur.isDirectory() ? 'directory' : 'file' }), {});
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ async readFile(path) {
50
+ const storedFile = this.getFile(path);
51
+ // no need to read again (just use the already stored file)
52
+ if (storedFile?.type === 'text') {
53
+ return storedFile.content;
54
+ }
55
+ return (await fs.readFile(resolve(path), 'utf-8')).toString();
56
+ }
57
+ /** Node implementation of finding a file or directory by walking up parent directories. */
58
+ findUp(name, options = {}) {
59
+ return findUp(name, options);
60
+ }
61
+ /** Node implementation of finding files or directories by walking up parent directories. */
62
+ findUpMultiple(name, options = {}) {
63
+ return findUpMultiple(name, options);
64
+ }
65
+ }
@@ -0,0 +1,20 @@
1
+ import { Logger } from '../file-system.js';
2
+ import { PkgManagerFields } from '../package-managers/detect-package-manager.js';
3
+ import { WorkspaceInfo } from '../workspaces/detect-workspace.js';
4
+ export type Info = {
5
+ jsWorkspaces?: WorkspaceInfo;
6
+ packageManager?: PkgManagerFields;
7
+ frameworks: unknown[];
8
+ buildSystems?: {
9
+ name: string;
10
+ version?: string | undefined;
11
+ }[];
12
+ };
13
+ /** A noop logger that is used to not log anything (we use the stdout for parsing the json output) */
14
+ export declare class NoopLogger implements Logger {
15
+ debug(): void;
16
+ log(): void;
17
+ error(): void;
18
+ }
19
+ /** Get the build info object that is used inside buildbot */
20
+ export declare function getBuildInfo(projectDir?: string, rootDir?: string): Promise<Info>;
@@ -0,0 +1,46 @@
1
+ import { listFrameworks } from '@netlify/framework-info';
2
+ import { Project } from '../project.js';
3
+ import { NodeFS } from './file-system.js';
4
+ /** A noop logger that is used to not log anything (we use the stdout for parsing the json output) */
5
+ export class NoopLogger {
6
+ debug() {
7
+ /** noop */
8
+ }
9
+ log() {
10
+ /** noop */
11
+ }
12
+ error() {
13
+ /** noop */
14
+ }
15
+ }
16
+ /** Get the build info object that is used inside buildbot */
17
+ export async function getBuildInfo(projectDir, rootDir) {
18
+ const fs = new NodeFS();
19
+ // prevent logging in output as we use the stdout to capture the json
20
+ fs.logger = new NoopLogger();
21
+ const project = new Project(fs, projectDir, rootDir);
22
+ project.setEnvironment(process.env);
23
+ let frameworks = [];
24
+ try {
25
+ // if the framework detection is crashing we should not crash the build info and package-manager detection
26
+ frameworks = await listFrameworks({ projectDir: project.baseDirectory });
27
+ }
28
+ catch {
29
+ // TODO: build reporting to buildbot see: https://github.com/netlify/pillar-workflow/issues/1001
30
+ // noop
31
+ }
32
+ const info = {
33
+ frameworks,
34
+ buildSystems: await project.detectBuildSystem(),
35
+ };
36
+ const pkgJSONPath = await project.getPackageJSON();
37
+ // only if we find a root package.json we know this is a javascript workspace
38
+ if (Object.keys(pkgJSONPath).length) {
39
+ info.packageManager = await project.detectPackageManager();
40
+ const workspaceInfo = await project.detectWorkspaces();
41
+ if (workspaceInfo) {
42
+ info.jsWorkspaces = workspaceInfo;
43
+ }
44
+ }
45
+ return info;
46
+ }
@@ -1,3 +1,4 @@
1
+ import type { Project } from '../project.js';
1
2
  export declare const enum PkgManager {
2
3
  YARN = "yarn",
3
4
  PNPM = "pnpm",
@@ -22,8 +23,5 @@ export type PkgManagerFields = {
22
23
  * 1. packageManager field
23
24
  * 2. environment variable that forces the usage
24
25
  * 3. a lock file that is present in this directory or up in the tree for workspaces
25
- * @param cwd The current process working directory of the build
26
- * @param stopAt The repository root where it should stop looking up for package.json or lock files. (defaults to `path.parse(cwd).root`)
27
- * @returns The package manager that was detected
28
26
  */
29
- export declare const detectPackageManager: (cwd?: string, stopAt?: string) => Promise<PkgManagerFields>;
27
+ export declare const detectPackageManager: (project: Project) => Promise<PkgManagerFields>;
@@ -0,0 +1,75 @@
1
+ /** The definition of all available package managers */
2
+ const AVAILABLE_PACKAGE_MANAGERS = {
3
+ ["yarn" /* PkgManager.YARN */]: {
4
+ name: "yarn" /* PkgManager.YARN */,
5
+ installCommand: 'yarn install',
6
+ lockFile: 'yarn.lock',
7
+ forceEnvironment: 'NETLIFY_USE_YARN',
8
+ },
9
+ ["pnpm" /* PkgManager.PNPM */]: {
10
+ name: "pnpm" /* PkgManager.PNPM */,
11
+ installCommand: 'pnpm install',
12
+ lockFile: 'pnpm-lock.yaml',
13
+ forceEnvironment: 'NETLIFY_USE_PNPM',
14
+ },
15
+ ["npm" /* PkgManager.NPM */]: {
16
+ name: "npm" /* PkgManager.NPM */,
17
+ installCommand: 'npm install',
18
+ lockFile: 'package-lock.json',
19
+ },
20
+ };
21
+ /**
22
+ * generate a map out of key is lock file and value the package manager
23
+ * this is to reduce the complexity in loops
24
+ */
25
+ const lockFileMap = Object.values(AVAILABLE_PACKAGE_MANAGERS).reduce((cur, pkgManager) => ({ ...cur, [pkgManager.lockFile]: pkgManager }), {});
26
+ /**
27
+ * Detects the used package manager based on
28
+ * 1. packageManager field
29
+ * 2. environment variable that forces the usage
30
+ * 3. a lock file that is present in this directory or up in the tree for workspaces
31
+ */
32
+ export const detectPackageManager = async (project) => {
33
+ try {
34
+ const pkgPaths = await project.fs.findUpMultiple('package.json', {
35
+ cwd: project.baseDirectory,
36
+ stopAt: project.root,
37
+ });
38
+ for (const pkgPath of pkgPaths) {
39
+ const { packageManager } = await project.fs.readJSON(pkgPath);
40
+ if (packageManager) {
41
+ const [parsed] = packageManager.split('@');
42
+ if (AVAILABLE_PACKAGE_MANAGERS[parsed]) {
43
+ return AVAILABLE_PACKAGE_MANAGERS[parsed];
44
+ }
45
+ }
46
+ }
47
+ // the package manager can be enforced via an environment variable as well
48
+ for (const pkgManager of Object.values(AVAILABLE_PACKAGE_MANAGERS)) {
49
+ if (pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'true') {
50
+ return pkgManager;
51
+ }
52
+ }
53
+ // find the correct lock file the tree up
54
+ const lockFilePath = await project.fs.findUp(Object.keys(lockFileMap), {
55
+ cwd: project.baseDirectory,
56
+ stopAt: project.root,
57
+ });
58
+ // if we found a lock file and the usage is not prohibited through an environment variable
59
+ // return the found package manager
60
+ if (lockFilePath) {
61
+ const lockFile = project.fs.basename(lockFilePath);
62
+ const pkgManager = lockFileMap[lockFile];
63
+ // check if it not got disabled
64
+ if (!(pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'false')) {
65
+ return pkgManager;
66
+ }
67
+ }
68
+ }
69
+ catch {
70
+ // noop
71
+ }
72
+ // always default to npm
73
+ // TODO: add some reporting here to log that we fall backed
74
+ return AVAILABLE_PACKAGE_MANAGERS["npm" /* PkgManager.NPM */];
75
+ };
@@ -0,0 +1,33 @@
1
+ import type { PackageJson } from 'read-pkg';
2
+ import type { BuildSystem } from './build-systems/build-system.js';
3
+ import type { FileSystem } from './file-system.js';
4
+ import type { PkgManagerFields } from './package-managers/detect-package-manager.js';
5
+ /**
6
+ * The Project represents a Site in Netlify
7
+ * The only configuration here needed is the path to the repository root and the optional baseDirectory
8
+ */
9
+ export declare class Project {
10
+ #private;
11
+ fs: FileSystem;
12
+ /** An optional repository root that tells us where to stop looking up */
13
+ root?: string;
14
+ /** An absolute path */
15
+ baseDirectory: string;
16
+ packageManager: PkgManagerFields;
17
+ /** an absolute path of the root directory for js workspaces where the most top package.json is located */
18
+ jsWorkspaceRoot: string;
19
+ constructor(fs: FileSystem, baseDirectory?: string, root?: string);
20
+ /** Set's the environment for the project */
21
+ setEnvironment(env: Record<string, string | undefined>): this;
22
+ /** retrieves an environment variable */
23
+ getEnv(key: string): string | undefined;
24
+ /** retrieves the root package.json file */
25
+ getRootPackageJSON(): Promise<PackageJson>;
26
+ getPackageJSON(startDirectory?: string): Promise<PackageJson>;
27
+ /** Detects the used package Manager */
28
+ detectPackageManager(): Promise<PkgManagerFields>;
29
+ /** Detects the javascript workspace settings */
30
+ detectWorkspaces(): Promise<import("./workspaces/detect-workspace.js").WorkspaceInfo | undefined>;
31
+ /** Detects all used build systems */
32
+ detectBuildSystem(): Promise<BuildSystem[]>;
33
+ }
package/lib/project.js ADDED
@@ -0,0 +1,82 @@
1
+ import { buildSystems } from './build-systems/index.js';
2
+ import { detectPackageManager } from './package-managers/detect-package-manager.js';
3
+ import { detectWorkspaces } from './workspaces/detect-workspace.js';
4
+ /**
5
+ * The Project represents a Site in Netlify
6
+ * The only configuration here needed is the path to the repository root and the optional baseDirectory
7
+ */
8
+ export class Project {
9
+ fs;
10
+ /** An optional repository root that tells us where to stop looking up */
11
+ root;
12
+ /** An absolute path */
13
+ baseDirectory;
14
+ packageManager;
15
+ /** an absolute path of the root directory for js workspaces where the most top package.json is located */
16
+ jsWorkspaceRoot;
17
+ /** a representation of the current environment */
18
+ #environment = {};
19
+ constructor(fs, baseDirectory, root) {
20
+ this.fs = fs;
21
+ this.baseDirectory = fs.resolve(root || '', baseDirectory !== undefined ? baseDirectory : fs.cwd);
22
+ this.root = root ? fs.resolve(fs.cwd, root) : undefined;
23
+ // if the root and the base directory are the same unset the root again as its not a workspace
24
+ if (this.root === this.baseDirectory) {
25
+ this.root = undefined;
26
+ }
27
+ this.fs.cwd = this.baseDirectory;
28
+ }
29
+ /** Set's the environment for the project */
30
+ setEnvironment(env) {
31
+ this.#environment = env;
32
+ return this;
33
+ }
34
+ /** retrieves an environment variable */
35
+ getEnv(key) {
36
+ return this.#environment[key];
37
+ }
38
+ /** retrieves the root package.json file */
39
+ async getRootPackageJSON() {
40
+ // get the most upper json file
41
+ const rootJSONPath = (await this.fs.findUpMultiple('package.json', { cwd: this.baseDirectory, stopAt: this.root })).pop();
42
+ if (rootJSONPath) {
43
+ this.jsWorkspaceRoot = this.fs.dirname(rootJSONPath);
44
+ return this.fs.readJSON(rootJSONPath);
45
+ }
46
+ return {};
47
+ }
48
+ async getPackageJSON(startDirectory) {
49
+ const pkgPath = await this.fs.findUp('package.json', {
50
+ cwd: startDirectory || this.baseDirectory,
51
+ stopAt: this.root,
52
+ });
53
+ if (pkgPath) {
54
+ return this.fs.readJSON(pkgPath);
55
+ }
56
+ return {};
57
+ }
58
+ /** Detects the used package Manager */
59
+ async detectPackageManager() {
60
+ this.packageManager = await detectPackageManager(this);
61
+ return this.packageManager;
62
+ }
63
+ /** Detects the javascript workspace settings */
64
+ async detectWorkspaces() {
65
+ try {
66
+ return detectWorkspaces(this);
67
+ }
68
+ catch {
69
+ return;
70
+ }
71
+ }
72
+ /** Detects all used build systems */
73
+ async detectBuildSystem() {
74
+ try {
75
+ const detected = await Promise.all(buildSystems.map(async (BuildSystem) => (await new BuildSystem().detect(this))?.toJSON()));
76
+ return detected.filter(Boolean);
77
+ }
78
+ catch {
79
+ return [];
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,22 @@
1
+ import type { PackageJson } from 'read-pkg';
2
+ import { Project } from '../project.js';
3
+ export type WorkspaceInfo = {
4
+ /** if we are in the current workspace root or not */
5
+ isRoot: boolean;
6
+ /** the workspace root directory */
7
+ rootDir: string;
8
+ /** list of relative package paths inside the workspace */
9
+ packages: string[];
10
+ };
11
+ /**
12
+ * Get a list of globs about all the packages inside a pnpm workspace
13
+ * https://pnpm.io/pnpm-workspace_yaml
14
+ */
15
+ export declare function detectPnpmWorkspaceGlobs(project: Project): Promise<string[]>;
16
+ /** Get the workspace globs from the package.json file */
17
+ export declare function detectNpmOrYarnWorkspaceGlobs(pkgJSON: PackageJson): Promise<string[]>;
18
+ /**
19
+ * If it's a javascript workspace (npm, pnpm, yarn) it will retrieve a list of all
20
+ * package paths and will indicate if it's the root of the workspace
21
+ */
22
+ export declare function detectWorkspaces(project: Project): Promise<WorkspaceInfo | undefined>;
@@ -0,0 +1,56 @@
1
+ import { parse } from 'yaml';
2
+ import { getWorkspacePackages } from './get-workspace-packages.js';
3
+ /**
4
+ * Get a list of globs about all the packages inside a pnpm workspace
5
+ * https://pnpm.io/pnpm-workspace_yaml
6
+ */
7
+ export async function detectPnpmWorkspaceGlobs(project) {
8
+ const workspaceFile = await project.fs.findUp('pnpm-workspace.yaml', {
9
+ cwd: project.baseDirectory,
10
+ stopAt: project.root,
11
+ });
12
+ if (!workspaceFile) {
13
+ return [];
14
+ }
15
+ const { packages } = parse(await project.fs.readFile(workspaceFile));
16
+ return packages;
17
+ }
18
+ /** Get the workspace globs from the package.json file */
19
+ export async function detectNpmOrYarnWorkspaceGlobs(pkgJSON) {
20
+ if (Array.isArray(pkgJSON.workspaces)) {
21
+ return pkgJSON.workspaces;
22
+ }
23
+ if (typeof pkgJSON.workspaces === 'object') {
24
+ return pkgJSON.workspaces.packages || [];
25
+ }
26
+ return [];
27
+ }
28
+ /**
29
+ * If it's a javascript workspace (npm, pnpm, yarn) it will retrieve a list of all
30
+ * package paths and will indicate if it's the root of the workspace
31
+ */
32
+ export async function detectWorkspaces(project) {
33
+ if (!project.packageManager) {
34
+ throw new Error('Please run the packageManager detection before calling the workspace detection!');
35
+ }
36
+ const pkgJSON = await project.getRootPackageJSON();
37
+ const workspaceGlobs = project.packageManager.name === "pnpm" /* PkgManager.PNPM */
38
+ ? await detectPnpmWorkspaceGlobs(project)
39
+ : await detectNpmOrYarnWorkspaceGlobs(pkgJSON);
40
+ if (workspaceGlobs.length === 0) {
41
+ return;
42
+ }
43
+ const packages = await getWorkspacePackages(project, workspaceGlobs);
44
+ const isRoot = project.baseDirectory === project.jsWorkspaceRoot;
45
+ const relBaseDirectory = project.fs.relative(project.jsWorkspaceRoot, project.baseDirectory);
46
+ // if the current base directory is not part of the detected workspace packages it's not part of this workspace
47
+ // and therefore return no workspace info
48
+ if (!isRoot && !packages.includes(relBaseDirectory)) {
49
+ return;
50
+ }
51
+ return {
52
+ rootDir: project.jsWorkspaceRoot,
53
+ isRoot,
54
+ packages,
55
+ };
56
+ }
@@ -0,0 +1,3 @@
1
+ import type { Project } from '../project.js';
2
+ /** Get a list of all workspace package paths (absolute paths) */
3
+ export declare function getWorkspacePackages(project: Project, patterns: string[]): Promise<string[]>;
@@ -0,0 +1,66 @@
1
+ import minimatch, { Minimatch } from 'minimatch';
2
+ /** Get the base directory out of a glob pattern */
3
+ function getDirFromPattern(pattern) {
4
+ const dir = [];
5
+ const parts = pattern.globParts[0];
6
+ for (let i = 0, max = parts.length; i < max; i++) {
7
+ if (parts[i].includes('*')) {
8
+ // skip the rest
9
+ return { dir: dir.join('/'), depth: parts[i] };
10
+ }
11
+ dir.push(parts[i]);
12
+ }
13
+ return { dir: dir.join('/') };
14
+ }
15
+ /** Find all packages inside a provided directory */
16
+ async function findPackages(project, dir, depth) {
17
+ const found = [];
18
+ let content = {};
19
+ try {
20
+ const startDir = project.root ? project.fs.resolve(project.root, dir) : project.fs.resolve(dir);
21
+ content = await project.fs.readDir(startDir, true);
22
+ }
23
+ catch (err) {
24
+ // noop
25
+ }
26
+ for (const [part, type] of Object.entries(content)) {
27
+ if (part === 'package.json') {
28
+ found.push(dir);
29
+ }
30
+ if (depth && type === 'directory') {
31
+ found.push(...(await findPackages(project, project.fs.join(dir, part), depth === '**' ? depth : undefined)));
32
+ }
33
+ }
34
+ return found;
35
+ }
36
+ /** Get a list of all workspace package paths (absolute paths) */
37
+ export async function getWorkspacePackages(project, patterns) {
38
+ const results = [];
39
+ if (!patterns.length) {
40
+ return results;
41
+ }
42
+ for (const pattern of patterns) {
43
+ const matcher = new Minimatch(pattern);
44
+ // skip negated pattern for exploring as we filter at the end
45
+ if (matcher.negate) {
46
+ continue;
47
+ }
48
+ const { dir, depth } = getDirFromPattern(matcher);
49
+ results.push(...(await findPackages(project, dir, depth)));
50
+ }
51
+ // initially add all results to the set
52
+ // and filter out then the negated patterns
53
+ const filtered = new Set();
54
+ for (const result of results) {
55
+ for (const pattern of patterns) {
56
+ const matcher = new Minimatch(pattern);
57
+ if (minimatch(result, matcher.pattern)) {
58
+ filtered.add(project.fs.join(result));
59
+ if (matcher.negate) {
60
+ filtered.delete(project.fs.join(result));
61
+ }
62
+ }
63
+ }
64
+ }
65
+ return [...filtered];
66
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@netlify/build-info",
3
- "version": "6.2.2",
3
+ "version": "6.3.0",
4
4
  "description": "Build info utility",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./lib/index.js"
8
8
  },
9
+ "browser": "./lib/index.js",
9
10
  "main": "./lib/index.js",
10
11
  "types": "./lib/index.d.ts",
11
12
  "bin": {
@@ -18,6 +19,7 @@
18
19
  "scripts": {
19
20
  "prebuild": "rm -rf lib",
20
21
  "build": "tsc",
22
+ "e2e": "playwright test",
21
23
  "test": "vitest run",
22
24
  "test:dev": "vitest --ui",
23
25
  "test:ci": "vitest run --reporter=default"
@@ -34,27 +36,30 @@
34
36
  },
35
37
  "author": "Netlify Inc.",
36
38
  "dependencies": {
37
- "@netlify/framework-info": "^9.8.0",
38
- "@npmcli/map-workspaces": "^2.0.0",
39
+ "@netlify/framework-info": "^9.8.2",
39
40
  "find-up": "^6.3.0",
41
+ "minimatch": "^6.2.0",
40
42
  "read-pkg": "^7.1.0",
41
43
  "yaml": "^2.1.3",
42
44
  "yargs": "^17.6.0"
43
45
  },
44
46
  "devDependencies": {
47
+ "@playwright/test": "^1.30.0",
45
48
  "@types/node": "^14.18.31",
46
49
  "@types/semver": "^7.3.13",
47
50
  "@vitest/coverage-c8": "^0.24.1",
48
51
  "@vitest/ui": "^0.24.3",
49
52
  "execa": "^6.0.0",
50
53
  "memfs": "^3.4.7",
54
+ "node-fetch": "^3.3.0",
51
55
  "semver": "^7.3.8",
52
56
  "typescript": "^4.8.4",
53
57
  "unionfs": "^4.4.0",
58
+ "vite": "^4.1.1",
54
59
  "vitest": "^0.24.1"
55
60
  },
56
61
  "engines": {
57
62
  "node": "^14.16.0 || >=16.0.0"
58
63
  },
59
- "gitHead": "d78a65c209ed987d3475cd1f37cf357693b99e3c"
64
+ "gitHead": "ade6e389937eb921779b5af7268547a59741de5a"
60
65
  }
package/lib/context.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { PackageJson } from 'read-pkg';
2
- export type ContextOptions = {
3
- projectDir?: string;
4
- rootDir?: string;
5
- };
6
- export type Context = {
7
- projectDir: string;
8
- rootDir?: string;
9
- rootPackageJson: PackageJson;
10
- };
11
- export declare const getContext: (config?: ContextOptions) => Promise<Context>;
package/lib/context.js DELETED
@@ -1,45 +0,0 @@
1
- import { existsSync } from 'fs';
2
- import { dirname, join, resolve } from 'path';
3
- import { cwd } from 'process';
4
- import { findUp } from 'find-up';
5
- import { readPackage } from 'read-pkg';
6
- /**
7
- * Collects the root package.json if there is one.
8
- */
9
- const getRootPackageJson = async (projectDir, rootDir) => {
10
- if (existsSync(join(rootDir, 'package.json'))) {
11
- return await readPackage({ cwd: rootDir, normalize: false });
12
- }
13
- const json = await findUp('package.json', { cwd: projectDir, stopAt: rootDir });
14
- if (json) {
15
- return await readPackage({ cwd: dirname(json), normalize: false });
16
- }
17
- return {};
18
- };
19
- export const getContext = async (config = {}) => {
20
- const { projectDir = cwd(), rootDir = '' } = config;
21
- // Get the absolute dirs for both project and root
22
- // We resolve the projectDir from the rootDir
23
- const absoluteProjectDir = resolve(rootDir, projectDir);
24
- // If a relative absolute path is given we rely on cwd
25
- const absoluteRootDir = rootDir ? resolve(cwd(), rootDir) : undefined;
26
- // We only pass through the root dir if it was provided and is actually different
27
- // from the project dir
28
- const validRootDir = absoluteRootDir && absoluteRootDir !== absoluteProjectDir ? absoluteRootDir : undefined;
29
- // If rootDir equals projectDir we'll be getting the projectDir package.json
30
- // Later on if we also need the projectDir package.json we can check for it
31
- // and only perform one resolution
32
- let rootPackageJson = {};
33
- try {
34
- rootPackageJson = await getRootPackageJson(absoluteProjectDir, validRootDir || absoluteProjectDir);
35
- }
36
- catch {
37
- // gracefully handle un-parseable package.json files
38
- //noop
39
- }
40
- return {
41
- projectDir: absoluteProjectDir,
42
- rootDir: validRootDir,
43
- rootPackageJson,
44
- };
45
- };
@@ -1,5 +0,0 @@
1
- export type BuildSystem = {
2
- name: string;
3
- version?: string | undefined;
4
- };
5
- export declare const detectBuildSystems: (baseDir: string, rootDir?: string) => Promise<BuildSystem[]>;