@netlify/build-info 6.2.2 → 6.2.3-rc.1
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.
- package/bin.js +1 -1
- package/lib/src/browser/file-system.d.ts +25 -0
- package/lib/src/browser/file-system.js +70 -0
- package/lib/src/build-systems/bazel.d.ts +7 -0
- package/lib/src/build-systems/bazel.js +15 -0
- package/lib/src/build-systems/buck.d.ts +7 -0
- package/lib/src/build-systems/buck.js +15 -0
- package/lib/src/build-systems/build-system.d.ts +29 -0
- package/lib/src/build-systems/build-system.js +25 -0
- package/lib/src/build-systems/gradle.d.ts +7 -0
- package/lib/src/build-systems/gradle.js +15 -0
- package/lib/src/build-systems/index.d.ts +2 -0
- package/lib/src/build-systems/index.js +11 -0
- package/lib/src/build-systems/lage.d.ts +6 -0
- package/lib/src/build-systems/lage.js +6 -0
- package/lib/src/build-systems/moon.d.ts +7 -0
- package/lib/src/build-systems/moon.js +18 -0
- package/lib/src/build-systems/nix.d.ts +7 -0
- package/lib/src/build-systems/nix.js +15 -0
- package/lib/src/build-systems/nrwl.d.ts +16 -0
- package/lib/src/build-systems/nrwl.js +55 -0
- package/lib/src/build-systems/pants.d.ts +7 -0
- package/lib/src/build-systems/pants.js +15 -0
- package/lib/src/build-systems/rush.d.ts +6 -0
- package/lib/src/build-systems/rush.js +6 -0
- package/lib/src/build-systems/turbo.d.ts +6 -0
- package/lib/src/build-systems/turbo.js +6 -0
- package/lib/src/file-system.d.ts +54 -0
- package/lib/src/file-system.js +160 -0
- package/lib/src/frameworks/angular.d.ts +24 -0
- package/lib/src/frameworks/angular.js +22 -0
- package/lib/src/frameworks/assemble.d.ts +16 -0
- package/lib/src/frameworks/assemble.js +16 -0
- package/lib/src/frameworks/astro.d.ts +25 -0
- package/lib/src/frameworks/astro.js +23 -0
- package/lib/src/frameworks/blitz.d.ts +23 -0
- package/lib/src/frameworks/blitz.js +21 -0
- package/lib/src/frameworks/brunch.d.ts +24 -0
- package/lib/src/frameworks/brunch.js +22 -0
- package/lib/src/frameworks/cecil.d.ts +23 -0
- package/lib/src/frameworks/cecil.js +21 -0
- package/lib/src/frameworks/docpad.d.ts +18 -0
- package/lib/src/frameworks/docpad.js +16 -0
- package/lib/src/frameworks/docusaurus.d.ts +30 -0
- package/lib/src/frameworks/docusaurus.js +44 -0
- package/lib/src/frameworks/eleventy.d.ts +24 -0
- package/lib/src/frameworks/eleventy.js +22 -0
- package/lib/src/frameworks/ember.d.ts +24 -0
- package/lib/src/frameworks/ember.js +22 -0
- package/lib/src/frameworks/expo.d.ts +24 -0
- package/lib/src/frameworks/expo.js +22 -0
- package/lib/src/frameworks/framework.d.ts +84 -0
- package/lib/src/frameworks/framework.js +89 -0
- package/lib/src/frameworks/gatsby.d.ts +32 -0
- package/lib/src/frameworks/gatsby.js +44 -0
- package/lib/src/frameworks/gridsome.d.ts +24 -0
- package/lib/src/frameworks/gridsome.js +22 -0
- package/lib/src/frameworks/grunt.d.ts +16 -0
- package/lib/src/frameworks/grunt.js +16 -0
- package/lib/src/frameworks/gulp.d.ts +16 -0
- package/lib/src/frameworks/gulp.js +16 -0
- package/lib/src/frameworks/harp.d.ts +23 -0
- package/lib/src/frameworks/harp.js +21 -0
- package/lib/src/frameworks/hexo.d.ts +24 -0
- package/lib/src/frameworks/hexo.js +22 -0
- package/lib/src/frameworks/hugo.d.ts +23 -0
- package/lib/src/frameworks/hugo.js +21 -0
- package/lib/src/frameworks/hydrogen.d.ts +23 -0
- package/lib/src/frameworks/hydrogen.js +21 -0
- package/lib/src/frameworks/index.d.ts +5 -0
- package/lib/src/frameworks/index.js +95 -0
- package/lib/src/frameworks/jekyll.d.ts +23 -0
- package/lib/src/frameworks/jekyll.js +21 -0
- package/lib/src/frameworks/metalsmith.d.ts +16 -0
- package/lib/src/frameworks/metalsmith.js +16 -0
- package/lib/src/frameworks/middleman.d.ts +23 -0
- package/lib/src/frameworks/middleman.js +21 -0
- package/lib/src/frameworks/next.d.ts +24 -0
- package/lib/src/frameworks/next.js +32 -0
- package/lib/src/frameworks/nuxt.d.ts +25 -0
- package/lib/src/frameworks/nuxt.js +40 -0
- package/lib/src/frameworks/parcel.d.ts +23 -0
- package/lib/src/frameworks/parcel.js +21 -0
- package/lib/src/frameworks/phenomic.d.ts +23 -0
- package/lib/src/frameworks/phenomic.js +21 -0
- package/lib/src/frameworks/quasar.d.ts +25 -0
- package/lib/src/frameworks/quasar.js +36 -0
- package/lib/src/frameworks/qwik.d.ts +23 -0
- package/lib/src/frameworks/qwik.js +24 -0
- package/lib/src/frameworks/react-static.d.ts +24 -0
- package/lib/src/frameworks/react-static.js +22 -0
- package/lib/src/frameworks/react.d.ts +30 -0
- package/lib/src/frameworks/react.js +16 -0
- package/lib/src/frameworks/redwoodjs.d.ts +25 -0
- package/lib/src/frameworks/redwoodjs.js +26 -0
- package/lib/src/frameworks/remix.d.ts +20 -0
- package/lib/src/frameworks/remix.js +20 -0
- package/lib/src/frameworks/roots.d.ts +23 -0
- package/lib/src/frameworks/roots.js +21 -0
- package/lib/src/frameworks/sapper.d.ts +24 -0
- package/lib/src/frameworks/sapper.js +22 -0
- package/lib/src/frameworks/solid-start.d.ts +23 -0
- package/lib/src/frameworks/solid-start.js +21 -0
- package/lib/src/frameworks/solid.d.ts +24 -0
- package/lib/src/frameworks/solid.js +22 -0
- package/lib/src/frameworks/stencil.d.ts +28 -0
- package/lib/src/frameworks/stencil.js +26 -0
- package/lib/src/frameworks/svelte-kit.d.ts +24 -0
- package/lib/src/frameworks/svelte-kit.js +22 -0
- package/lib/src/frameworks/svelte.d.ts +25 -0
- package/lib/src/frameworks/svelte.js +23 -0
- package/lib/src/frameworks/vite.d.ts +24 -0
- package/lib/src/frameworks/vite.js +22 -0
- package/lib/src/frameworks/vue.d.ts +23 -0
- package/lib/src/frameworks/vue.js +21 -0
- package/lib/src/frameworks/vuepress.d.ts +23 -0
- package/lib/src/frameworks/vuepress.js +21 -0
- package/lib/src/frameworks/wintersmith.d.ts +24 -0
- package/lib/src/frameworks/wintersmith.js +22 -0
- package/lib/src/frameworks/wmr.d.ts +23 -0
- package/lib/src/frameworks/wmr.js +21 -0
- package/lib/src/frameworks/zola.d.ts +18 -0
- package/lib/src/frameworks/zola.js +16 -0
- package/lib/src/index.d.ts +2 -0
- package/lib/src/index.js +2 -0
- package/lib/{bin.js → src/node/bin.js} +4 -3
- package/lib/src/node/file-system.d.ts +19 -0
- package/lib/src/node/file-system.js +60 -0
- package/lib/src/node/get-build-info.d.ts +20 -0
- package/lib/src/node/get-build-info.js +47 -0
- package/lib/{detect-package-manager.d.ts → src/package-managers/detect-package-manager.d.ts} +4 -4
- package/lib/src/package-managers/detect-package-manager.js +82 -0
- package/lib/src/project.d.ts +53 -0
- package/lib/src/project.js +207 -0
- package/lib/src/workspaces/detect-workspace.d.ts +22 -0
- package/lib/src/workspaces/detect-workspace.js +61 -0
- package/lib/src/workspaces/get-workspace-packages.d.ts +20 -0
- package/lib/src/workspaces/get-workspace-packages.js +80 -0
- package/lib/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +14 -10
- package/lib/context.d.ts +0 -11
- package/lib/context.js +0 -45
- package/lib/detect-build-system.d.ts +0 -5
- package/lib/detect-build-system.js +0 -145
- package/lib/detect-package-manager.js +0 -71
- package/lib/get-build-info.d.ts +0 -11
- package/lib/get-build-info.js +0 -34
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/workspaces.d.ts +0 -22
- package/lib/workspaces.js +0 -56
- /package/lib/{bin.d.ts → src/node/bin.d.ts} +0 -0
package/lib/{detect-package-manager.d.ts → src/package-managers/detect-package-manager.d.ts}
RENAMED
|
@@ -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",
|
|
@@ -8,6 +9,8 @@ export type PkgManagerFields = {
|
|
|
8
9
|
name: PkgManager;
|
|
9
10
|
/** The package managers install command */
|
|
10
11
|
installCommand: string;
|
|
12
|
+
/** The package managers run command prefix */
|
|
13
|
+
runCommand: string;
|
|
11
14
|
/** The lock file a package manager is using */
|
|
12
15
|
lockFile: string;
|
|
13
16
|
/** Environment variable that can be used to force the usage of a package manager even though there is no lock file or a different lock file */
|
|
@@ -22,8 +25,5 @@ export type PkgManagerFields = {
|
|
|
22
25
|
* 1. packageManager field
|
|
23
26
|
* 2. environment variable that forces the usage
|
|
24
27
|
* 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
28
|
*/
|
|
29
|
-
export declare const detectPackageManager: (
|
|
29
|
+
export declare const detectPackageManager: (project: Project) => Promise<PkgManagerFields | null>;
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
runCommand: 'yarn',
|
|
7
|
+
lockFile: 'yarn.lock',
|
|
8
|
+
forceEnvironment: 'NETLIFY_USE_YARN',
|
|
9
|
+
},
|
|
10
|
+
["pnpm" /* PkgManager.PNPM */]: {
|
|
11
|
+
name: "pnpm" /* PkgManager.PNPM */,
|
|
12
|
+
installCommand: 'pnpm install',
|
|
13
|
+
runCommand: 'pnpm run',
|
|
14
|
+
lockFile: 'pnpm-lock.yaml',
|
|
15
|
+
forceEnvironment: 'NETLIFY_USE_PNPM',
|
|
16
|
+
},
|
|
17
|
+
["npm" /* PkgManager.NPM */]: {
|
|
18
|
+
name: "npm" /* PkgManager.NPM */,
|
|
19
|
+
installCommand: 'npm install',
|
|
20
|
+
runCommand: 'npm run',
|
|
21
|
+
lockFile: 'package-lock.json',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* generate a map out of key is lock file and value the package manager
|
|
26
|
+
* this is to reduce the complexity in loops
|
|
27
|
+
*/
|
|
28
|
+
const lockFileMap = Object.values(AVAILABLE_PACKAGE_MANAGERS).reduce((cur, pkgManager) => ({ ...cur, [pkgManager.lockFile]: pkgManager }), {});
|
|
29
|
+
/**
|
|
30
|
+
* Detects the used package manager based on
|
|
31
|
+
* 1. packageManager field
|
|
32
|
+
* 2. environment variable that forces the usage
|
|
33
|
+
* 3. a lock file that is present in this directory or up in the tree for workspaces
|
|
34
|
+
*/
|
|
35
|
+
export const detectPackageManager = async (project) => {
|
|
36
|
+
try {
|
|
37
|
+
const pkgPaths = await project.fs.findUpMultiple('package.json', {
|
|
38
|
+
cwd: project.baseDirectory,
|
|
39
|
+
stopAt: project.root,
|
|
40
|
+
});
|
|
41
|
+
// if there is no package json than there is no package manager to detect
|
|
42
|
+
if (!pkgPaths.length) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
for (const pkgPath of pkgPaths) {
|
|
46
|
+
const { packageManager } = await project.fs.readJSON(pkgPath);
|
|
47
|
+
if (packageManager) {
|
|
48
|
+
const [parsed] = packageManager.split('@');
|
|
49
|
+
if (AVAILABLE_PACKAGE_MANAGERS[parsed]) {
|
|
50
|
+
return AVAILABLE_PACKAGE_MANAGERS[parsed];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// the package manager can be enforced via an environment variable as well
|
|
55
|
+
for (const pkgManager of Object.values(AVAILABLE_PACKAGE_MANAGERS)) {
|
|
56
|
+
if (pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'true') {
|
|
57
|
+
return pkgManager;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// find the correct lock file the tree up
|
|
61
|
+
const lockFilePath = await project.fs.findUp(Object.keys(lockFileMap), {
|
|
62
|
+
cwd: project.baseDirectory,
|
|
63
|
+
stopAt: project.root,
|
|
64
|
+
});
|
|
65
|
+
// if we found a lock file and the usage is not prohibited through an environment variable
|
|
66
|
+
// return the found package manager
|
|
67
|
+
if (lockFilePath) {
|
|
68
|
+
const lockFile = project.fs.basename(lockFilePath);
|
|
69
|
+
const pkgManager = lockFileMap[lockFile];
|
|
70
|
+
// check if it not got disabled
|
|
71
|
+
if (!(pkgManager.forceEnvironment && project.getEnv(pkgManager.forceEnvironment) === 'false')) {
|
|
72
|
+
return pkgManager;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// noop
|
|
78
|
+
}
|
|
79
|
+
// always default to npm
|
|
80
|
+
// TODO: add some reporting here to log that we fall backed
|
|
81
|
+
return AVAILABLE_PACKAGE_MANAGERS["npm" /* PkgManager.NPM */];
|
|
82
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { PackageJson } from 'read-pkg';
|
|
2
|
+
import { SemVer } from 'semver';
|
|
3
|
+
import type { BuildSystem } from './build-systems/build-system.js';
|
|
4
|
+
import type { FileSystem } from './file-system.js';
|
|
5
|
+
import { Framework } from './frameworks/framework.js';
|
|
6
|
+
import type { PkgManagerFields } from './package-managers/detect-package-manager.js';
|
|
7
|
+
import { WorkspaceInfo } from './workspaces/detect-workspace.js';
|
|
8
|
+
/**
|
|
9
|
+
* The Project represents a Site in Netlify
|
|
10
|
+
* The only configuration here needed is the path to the repository root and the optional baseDirectory
|
|
11
|
+
*/
|
|
12
|
+
export declare class Project {
|
|
13
|
+
#private;
|
|
14
|
+
fs: FileSystem;
|
|
15
|
+
/** An optional repository root that tells us where to stop looking up */
|
|
16
|
+
root?: string;
|
|
17
|
+
/** An absolute path */
|
|
18
|
+
baseDirectory: string;
|
|
19
|
+
/** the detected package manager (if null it's not a javascript project, undefined indicates that id did not run yet) */
|
|
20
|
+
packageManager: PkgManagerFields | null;
|
|
21
|
+
/** an absolute path of the root directory for js workspaces where the most top package.json is located */
|
|
22
|
+
jsWorkspaceRoot: string;
|
|
23
|
+
workspace: WorkspaceInfo | null;
|
|
24
|
+
/** The detected build-systems */
|
|
25
|
+
buildSystems: BuildSystem[];
|
|
26
|
+
/** The detected frameworks for each path in a project */
|
|
27
|
+
frameworks: Map<string, Framework[]>;
|
|
28
|
+
/** The current nodeVersion (can be set by node.js environments) */
|
|
29
|
+
private _nodeVersion;
|
|
30
|
+
setNodeVersion(version: string): this;
|
|
31
|
+
getCurrentNodeVersion(): Promise<SemVer | null>;
|
|
32
|
+
constructor(fs: FileSystem, baseDirectory?: string, root?: string);
|
|
33
|
+
/** Set's the environment for the project */
|
|
34
|
+
setEnvironment(env: Record<string, string | undefined>): this;
|
|
35
|
+
/** retrieves an environment variable */
|
|
36
|
+
getEnv(key: string): string | undefined;
|
|
37
|
+
/** retrieves the root package.json file */
|
|
38
|
+
getRootPackageJSON(): Promise<PackageJson>;
|
|
39
|
+
/** Retrieves the package.json and if one found with it's pkgPath */
|
|
40
|
+
getPackageJSON(startDirectory?: string): Promise<PackageJson & {
|
|
41
|
+
pkgPath: string | null;
|
|
42
|
+
}>;
|
|
43
|
+
/** Detects the used package Manager */
|
|
44
|
+
detectPackageManager(): Promise<PkgManagerFields | null>;
|
|
45
|
+
/** Detects the javascript workspace settings */
|
|
46
|
+
detectWorkspaces(): Promise<WorkspaceInfo | null>;
|
|
47
|
+
/** Detects all used build systems */
|
|
48
|
+
detectBuildSystem(): Promise<any[]>;
|
|
49
|
+
/** Detects all used build systems */
|
|
50
|
+
detectFrameworks(): Promise<Framework[] | null>;
|
|
51
|
+
private detectFrameworksInPath;
|
|
52
|
+
getDevServerSettings(): Promise<void>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { parse, coerce } from 'semver';
|
|
2
|
+
import { buildSystems } from './build-systems/index.js';
|
|
3
|
+
import { frameworks } from './frameworks/index.js';
|
|
4
|
+
import { detectPackageManager } from './package-managers/detect-package-manager.js';
|
|
5
|
+
import { detectWorkspaces } from './workspaces/detect-workspace.js';
|
|
6
|
+
/**
|
|
7
|
+
* The Project represents a Site in Netlify
|
|
8
|
+
* The only configuration here needed is the path to the repository root and the optional baseDirectory
|
|
9
|
+
*/
|
|
10
|
+
export class Project {
|
|
11
|
+
fs;
|
|
12
|
+
/** An optional repository root that tells us where to stop looking up */
|
|
13
|
+
root;
|
|
14
|
+
/** An absolute path */
|
|
15
|
+
baseDirectory;
|
|
16
|
+
/** the detected package manager (if null it's not a javascript project, undefined indicates that id did not run yet) */
|
|
17
|
+
packageManager;
|
|
18
|
+
/** an absolute path of the root directory for js workspaces where the most top package.json is located */
|
|
19
|
+
jsWorkspaceRoot;
|
|
20
|
+
/* the detected javascript workspace information (if null it's not a workspace, undefined indicates that id did not run yet) */
|
|
21
|
+
workspace;
|
|
22
|
+
/** The detected build-systems */
|
|
23
|
+
buildSystems;
|
|
24
|
+
/** The detected frameworks for each path in a project */
|
|
25
|
+
frameworks;
|
|
26
|
+
/** a representation of the current environment */
|
|
27
|
+
#environment = {};
|
|
28
|
+
/** The current nodeVersion (can be set by node.js environments) */
|
|
29
|
+
_nodeVersion = null;
|
|
30
|
+
setNodeVersion(version) {
|
|
31
|
+
this._nodeVersion = parse(version);
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
async getCurrentNodeVersion() {
|
|
35
|
+
if (this._nodeVersion) {
|
|
36
|
+
return this._nodeVersion;
|
|
37
|
+
}
|
|
38
|
+
const nodeEnv = parse(coerce(this.getEnv('NODE_VERSION')), {
|
|
39
|
+
loose: true,
|
|
40
|
+
});
|
|
41
|
+
if (nodeEnv) {
|
|
42
|
+
return nodeEnv;
|
|
43
|
+
}
|
|
44
|
+
// TODO: parse .nvm file as well
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
constructor(fs, baseDirectory, root) {
|
|
48
|
+
this.fs = fs;
|
|
49
|
+
this.baseDirectory = fs.resolve(root || '', baseDirectory !== undefined ? baseDirectory : fs.cwd);
|
|
50
|
+
this.root = root ? fs.resolve(fs.cwd, root) : undefined;
|
|
51
|
+
// if the root and the base directory are the same unset the root again as its not a workspace
|
|
52
|
+
if (this.root === this.baseDirectory) {
|
|
53
|
+
this.root = undefined;
|
|
54
|
+
}
|
|
55
|
+
this.fs.cwd = this.baseDirectory;
|
|
56
|
+
}
|
|
57
|
+
/** Set's the environment for the project */
|
|
58
|
+
setEnvironment(env) {
|
|
59
|
+
this.#environment = env;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
/** retrieves an environment variable */
|
|
63
|
+
getEnv(key) {
|
|
64
|
+
return this.#environment[key];
|
|
65
|
+
}
|
|
66
|
+
/** retrieves the root package.json file */
|
|
67
|
+
async getRootPackageJSON() {
|
|
68
|
+
// get the most upper json file
|
|
69
|
+
const rootJSONPath = (await this.fs.findUpMultiple('package.json', { cwd: this.baseDirectory, stopAt: this.root })).pop();
|
|
70
|
+
if (rootJSONPath) {
|
|
71
|
+
this.jsWorkspaceRoot = this.fs.dirname(rootJSONPath);
|
|
72
|
+
return this.fs.readJSON(rootJSONPath);
|
|
73
|
+
}
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
/** Retrieves the package.json and if one found with it's pkgPath */
|
|
77
|
+
async getPackageJSON(startDirectory) {
|
|
78
|
+
const pkgPath = await this.fs.findUp('package.json', {
|
|
79
|
+
cwd: startDirectory || this.baseDirectory,
|
|
80
|
+
stopAt: this.root,
|
|
81
|
+
});
|
|
82
|
+
if (pkgPath) {
|
|
83
|
+
const json = await this.fs.readJSON(pkgPath);
|
|
84
|
+
return {
|
|
85
|
+
...json,
|
|
86
|
+
pkgPath,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return { pkgPath: null };
|
|
90
|
+
}
|
|
91
|
+
/** Detects the used package Manager */
|
|
92
|
+
async detectPackageManager() {
|
|
93
|
+
// if the packageManager is undefined, the detection was not run.
|
|
94
|
+
// if it is an object or null it has already run
|
|
95
|
+
if (this.packageManager !== undefined) {
|
|
96
|
+
return this.packageManager;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
this.packageManager = await detectPackageManager(this);
|
|
100
|
+
return this.packageManager;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Detects the javascript workspace settings */
|
|
107
|
+
async detectWorkspaces() {
|
|
108
|
+
// if the workspace is undefined, the detection was not run.
|
|
109
|
+
// if it is an object or null it has already run
|
|
110
|
+
if (this.workspace !== undefined) {
|
|
111
|
+
return this.workspace;
|
|
112
|
+
}
|
|
113
|
+
// workspaces depend on package manager detection so run it first
|
|
114
|
+
await this.detectPackageManager();
|
|
115
|
+
try {
|
|
116
|
+
this.workspace = await detectWorkspaces(this);
|
|
117
|
+
return this.workspace;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Detects all used build systems */
|
|
124
|
+
async detectBuildSystem() {
|
|
125
|
+
// if the workspace is undefined, the detection was not run.
|
|
126
|
+
if (this.buildSystems !== undefined) {
|
|
127
|
+
return this.buildSystems;
|
|
128
|
+
}
|
|
129
|
+
// build systems depends on workspaces detection
|
|
130
|
+
await this.detectWorkspaces();
|
|
131
|
+
try {
|
|
132
|
+
const detected = [];
|
|
133
|
+
// perform the detection in series to avoid having the same HTTP request in parallel.
|
|
134
|
+
// It's faster to perform one detection, do all the needed HTTP requests and reuse the results
|
|
135
|
+
// on consecutive runs.
|
|
136
|
+
for (const BuildSystem of buildSystems) {
|
|
137
|
+
const res = await new BuildSystem(this).detect();
|
|
138
|
+
if (res) {
|
|
139
|
+
detected.push(res.toJSON());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return detected;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** Detects all used build systems */
|
|
149
|
+
async detectFrameworks() {
|
|
150
|
+
// if the workspace is undefined, the detection was not run.
|
|
151
|
+
if (this.frameworks !== undefined) {
|
|
152
|
+
return [...this.frameworks.values()].flat();
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
// This needs to be run first
|
|
156
|
+
await this.detectBuildSystem();
|
|
157
|
+
this.frameworks = new Map();
|
|
158
|
+
if (this.workspace?.isRoot) {
|
|
159
|
+
for (const pkg of this.workspace.packages) {
|
|
160
|
+
this.frameworks.set(pkg, await this.detectFrameworksInPath(pkg));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
this.frameworks.set('', await this.detectFrameworksInPath());
|
|
165
|
+
}
|
|
166
|
+
return [...this.frameworks.values()].flat();
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async detectFrameworksInPath(path) {
|
|
173
|
+
try {
|
|
174
|
+
const detected = [];
|
|
175
|
+
// perform the detection in series to avoid having the same HTTP request in parallel.
|
|
176
|
+
// It's faster to perform one detection, do all the needed HTTP requests and reuse the results
|
|
177
|
+
// on consecutive runs.
|
|
178
|
+
for (const Frameowk of frameworks) {
|
|
179
|
+
const res = await new Frameowk(this, path).detect();
|
|
180
|
+
if (res) {
|
|
181
|
+
detected.push(res);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return detected;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async getDevServerSettings() {
|
|
191
|
+
await this.detectFrameworks();
|
|
192
|
+
const buildSystem = this.buildSystems.find((system) => system.dev);
|
|
193
|
+
if (buildSystem) {
|
|
194
|
+
console.log(buildSystem);
|
|
195
|
+
// get the framework for the default build system
|
|
196
|
+
// if (this.frameworks.size > 1) {
|
|
197
|
+
// }
|
|
198
|
+
// console.log(this.frameworks)
|
|
199
|
+
}
|
|
200
|
+
// TODO return frameworks
|
|
201
|
+
// console.log(this)
|
|
202
|
+
// return {
|
|
203
|
+
// command: '',
|
|
204
|
+
// frameworkPort: number,
|
|
205
|
+
// }
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -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 | null>;
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
try {
|
|
16
|
+
const { packages } = parse(await project.fs.readFile(workspaceFile));
|
|
17
|
+
return packages;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Get the workspace globs from the package.json file */
|
|
24
|
+
export async function detectNpmOrYarnWorkspaceGlobs(pkgJSON) {
|
|
25
|
+
if (Array.isArray(pkgJSON.workspaces)) {
|
|
26
|
+
return pkgJSON.workspaces;
|
|
27
|
+
}
|
|
28
|
+
if (typeof pkgJSON.workspaces === 'object') {
|
|
29
|
+
return pkgJSON.workspaces.packages || [];
|
|
30
|
+
}
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* If it's a javascript workspace (npm, pnpm, yarn) it will retrieve a list of all
|
|
35
|
+
* package paths and will indicate if it's the root of the workspace
|
|
36
|
+
*/
|
|
37
|
+
export async function detectWorkspaces(project) {
|
|
38
|
+
if (!project.packageManager) {
|
|
39
|
+
throw new Error('Please run the packageManager detection before calling the workspace detection!');
|
|
40
|
+
}
|
|
41
|
+
const pkgJSON = await project.getRootPackageJSON();
|
|
42
|
+
const workspaceGlobs = project.packageManager.name === "pnpm" /* PkgManager.PNPM */
|
|
43
|
+
? await detectPnpmWorkspaceGlobs(project)
|
|
44
|
+
: await detectNpmOrYarnWorkspaceGlobs(pkgJSON);
|
|
45
|
+
if (workspaceGlobs.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const packages = await getWorkspacePackages(project, workspaceGlobs);
|
|
49
|
+
const isRoot = project.baseDirectory === project.jsWorkspaceRoot;
|
|
50
|
+
const relBaseDirectory = project.fs.relative(project.jsWorkspaceRoot, project.baseDirectory);
|
|
51
|
+
// if the current base directory is not part of the detected workspace packages it's not part of this workspace
|
|
52
|
+
// and therefore return no workspace info
|
|
53
|
+
if (!isRoot && !packages.includes(relBaseDirectory)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
rootDir: project.jsWorkspaceRoot,
|
|
58
|
+
isRoot,
|
|
59
|
+
packages,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DirType } from '../file-system.js';
|
|
2
|
+
import type { Project } from '../project.js';
|
|
3
|
+
export type identifyPackageFn = (options: {
|
|
4
|
+
entry: string;
|
|
5
|
+
type: DirType;
|
|
6
|
+
directory: string;
|
|
7
|
+
}) => Promise<boolean> | boolean;
|
|
8
|
+
/** Find all packages inside a provided directory */
|
|
9
|
+
export declare function findPackages(project: Project,
|
|
10
|
+
/**
|
|
11
|
+
* The relative directory it should start checking.
|
|
12
|
+
* If a jsWorkspaceRoot is set it will join it with it otherwise it tries to resolve based on the root
|
|
13
|
+
*/
|
|
14
|
+
dir: string,
|
|
15
|
+
/** A function that identifies if a directory is a package. By default it checks if it has a package.json */
|
|
16
|
+
identifyPackage: identifyPackageFn,
|
|
17
|
+
/** The depth to look. It can be either a single star `*` for one directory depth or a `**` for deep checking */
|
|
18
|
+
depth?: string): Promise<string[]>;
|
|
19
|
+
/** Get a list of all workspace package paths (absolute paths) */
|
|
20
|
+
export declare function getWorkspacePackages(project: Project, patterns: string[]): Promise<string[]>;
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
const defaultIdentifyPackage = ({ entry }) => entry === 'package.json';
|
|
16
|
+
/** Find all packages inside a provided directory */
|
|
17
|
+
export async function findPackages(project,
|
|
18
|
+
/**
|
|
19
|
+
* The relative directory it should start checking.
|
|
20
|
+
* If a jsWorkspaceRoot is set it will join it with it otherwise it tries to resolve based on the root
|
|
21
|
+
*/
|
|
22
|
+
dir,
|
|
23
|
+
/** A function that identifies if a directory is a package. By default it checks if it has a package.json */
|
|
24
|
+
identifyPackage,
|
|
25
|
+
/** The depth to look. It can be either a single star `*` for one directory depth or a `**` for deep checking */
|
|
26
|
+
depth) {
|
|
27
|
+
const found = [];
|
|
28
|
+
let content = {};
|
|
29
|
+
const startDir = project.jsWorkspaceRoot
|
|
30
|
+
? project.fs.resolve(project.jsWorkspaceRoot, dir)
|
|
31
|
+
: project.root
|
|
32
|
+
? project.fs.resolve(project.root, dir)
|
|
33
|
+
: project.fs.resolve(dir);
|
|
34
|
+
try {
|
|
35
|
+
content = await project.fs.readDir(startDir, true);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
// noop
|
|
39
|
+
}
|
|
40
|
+
for (const [part, type] of Object.entries(content)) {
|
|
41
|
+
if (await identifyPackage({ entry: part, type, directory: startDir })) {
|
|
42
|
+
found.push(dir);
|
|
43
|
+
}
|
|
44
|
+
if (depth && type === 'directory') {
|
|
45
|
+
found.push(...(await findPackages(project, project.fs.join(dir, part), identifyPackage, depth === '**' ? depth : undefined)));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return found;
|
|
49
|
+
}
|
|
50
|
+
/** Get a list of all workspace package paths (absolute paths) */
|
|
51
|
+
export async function getWorkspacePackages(project, patterns) {
|
|
52
|
+
const results = [];
|
|
53
|
+
if (!patterns.length) {
|
|
54
|
+
return results;
|
|
55
|
+
}
|
|
56
|
+
for (const pattern of patterns) {
|
|
57
|
+
const matcher = new Minimatch(pattern);
|
|
58
|
+
// skip negated pattern for exploring as we filter at the end
|
|
59
|
+
if (matcher.negate) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const { dir, depth } = getDirFromPattern(matcher);
|
|
63
|
+
results.push(...(await findPackages(project, dir, defaultIdentifyPackage, depth)));
|
|
64
|
+
}
|
|
65
|
+
// initially add all results to the set
|
|
66
|
+
// and filter out then the negated patterns
|
|
67
|
+
const filtered = new Set();
|
|
68
|
+
for (const result of results) {
|
|
69
|
+
for (const pattern of patterns) {
|
|
70
|
+
const matcher = new Minimatch(pattern);
|
|
71
|
+
if (minimatch(result, matcher.pattern)) {
|
|
72
|
+
filtered.add(project.fs.join(result));
|
|
73
|
+
if (matcher.negate) {
|
|
74
|
+
filtered.delete(project.fs.join(result));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return [...filtered];
|
|
80
|
+
}
|