1 | 'use strict';
|
2 |
|
3 | var path = require('path');
|
4 | var getPackages = require('@manypkg/get-packages');
|
5 | var index = require('./index-09611511.cjs.js');
|
6 | var errors = require('@backstage/errors');
|
7 | var child_process = require('child_process');
|
8 | var util = require('util');
|
9 |
|
10 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
11 |
|
12 | var path__default = _interopDefaultLegacy(path);
|
13 |
|
14 | const execFile = util.promisify(child_process.execFile);
|
15 | async function runGit(...args) {
|
16 | var _a, _b;
|
17 | try {
|
18 | const { stdout } = await execFile("git", args, {
|
19 | shell: true,
|
20 | cwd: index.paths.targetRoot
|
21 | });
|
22 | return stdout.trim().split(/\r\n|\r|\n/);
|
23 | } catch (error) {
|
24 | errors.assertError(error);
|
25 | if (error.stderr || typeof error.code === "number") {
|
26 | const stderr = (_a = error.stderr) == null ? void 0 : _a.toString("utf8");
|
27 | const msg = (_b = stderr == null ? void 0 : stderr.trim()) != null ? _b : `with exit code ${error.code}`;
|
28 | throw new Error(`git ${args[0]} failed, ${msg}`);
|
29 | }
|
30 | throw new errors.ForwardedError("Unknown execution error", error);
|
31 | }
|
32 | }
|
33 | async function listChangedFiles(ref) {
|
34 | if (!ref) {
|
35 | throw new Error("ref is required");
|
36 | }
|
37 | let diffRef = ref;
|
38 | try {
|
39 | const [base] = await runGit("merge-base", "HEAD", ref);
|
40 | diffRef = base;
|
41 | } catch {
|
42 | }
|
43 | const tracked = await runGit("diff", "--name-only", diffRef);
|
44 | const untracked = await runGit("ls-files", "--others", "--exclude-standard");
|
45 | return Array.from( new Set([...tracked, ...untracked]));
|
46 | }
|
47 |
|
48 | class PackageGraph extends Map {
|
49 | static async listTargetPackages() {
|
50 | const { packages } = await getPackages.getPackages(index.paths.targetDir);
|
51 | return packages;
|
52 | }
|
53 | static fromPackages(packages) {
|
54 | const graph = new PackageGraph();
|
55 | for (const pkg of packages) {
|
56 | const name = pkg.packageJson.name;
|
57 | const existingPkg = graph.get(name);
|
58 | if (existingPkg) {
|
59 | throw new Error(`Duplicate package name '${name}' at ${pkg.dir} and ${existingPkg.dir}`);
|
60 | }
|
61 | graph.set(name, {
|
62 | name,
|
63 | dir: pkg.dir,
|
64 | packageJson: pkg.packageJson,
|
65 | allLocalDependencies: new Map(),
|
66 | publishedLocalDependencies: new Map(),
|
67 | localDependencies: new Map(),
|
68 | localDevDependencies: new Map(),
|
69 | localOptionalDependencies: new Map(),
|
70 | allLocalDependents: new Map(),
|
71 | publishedLocalDependents: new Map(),
|
72 | localDependents: new Map(),
|
73 | localDevDependents: new Map(),
|
74 | localOptionalDependents: new Map()
|
75 | });
|
76 | }
|
77 | for (const node of graph.values()) {
|
78 | for (const depName of Object.keys(node.packageJson.dependencies || {})) {
|
79 | const depPkg = graph.get(depName);
|
80 | if (depPkg) {
|
81 | node.allLocalDependencies.set(depName, depPkg);
|
82 | node.publishedLocalDependencies.set(depName, depPkg);
|
83 | node.localDependencies.set(depName, depPkg);
|
84 | depPkg.allLocalDependents.set(node.name, node);
|
85 | depPkg.publishedLocalDependents.set(node.name, node);
|
86 | depPkg.localDependents.set(node.name, node);
|
87 | }
|
88 | }
|
89 | for (const depName of Object.keys(node.packageJson.devDependencies || {})) {
|
90 | const depPkg = graph.get(depName);
|
91 | if (depPkg) {
|
92 | node.allLocalDependencies.set(depName, depPkg);
|
93 | node.localDevDependencies.set(depName, depPkg);
|
94 | depPkg.allLocalDependents.set(node.name, node);
|
95 | depPkg.localDevDependents.set(node.name, node);
|
96 | }
|
97 | }
|
98 | for (const depName of Object.keys(node.packageJson.optionalDependencies || {})) {
|
99 | const depPkg = graph.get(depName);
|
100 | if (depPkg) {
|
101 | node.allLocalDependencies.set(depName, depPkg);
|
102 | node.publishedLocalDependencies.set(depName, depPkg);
|
103 | node.localOptionalDependencies.set(depName, depPkg);
|
104 | depPkg.allLocalDependents.set(node.name, node);
|
105 | depPkg.publishedLocalDependents.set(node.name, node);
|
106 | depPkg.localOptionalDependents.set(node.name, node);
|
107 | }
|
108 | }
|
109 | }
|
110 | return graph;
|
111 | }
|
112 | collectPackageNames(startingPackageNames, collectFn) {
|
113 | const targets = new Set();
|
114 | const searchNames = startingPackageNames.slice();
|
115 | while (searchNames.length) {
|
116 | const name = searchNames.pop();
|
117 | if (targets.has(name)) {
|
118 | continue;
|
119 | }
|
120 | const node = this.get(name);
|
121 | if (!node) {
|
122 | throw new Error(`Package '${name}' not found`);
|
123 | }
|
124 | targets.add(name);
|
125 | const collected = collectFn(node);
|
126 | if (collected) {
|
127 | searchNames.push(...collected);
|
128 | }
|
129 | }
|
130 | return targets;
|
131 | }
|
132 | async listChangedPackages(options) {
|
133 | var _a, _b;
|
134 | const changedFiles = await listChangedFiles(options.ref);
|
135 | const dirMap = new Map(Array.from(this.values()).map((pkg) => [
|
136 | path__default["default"].relative(index.paths.targetRoot, pkg.dir).split(path__default["default"].sep).join(path__default["default"].posix.sep) + path__default["default"].posix.sep,
|
137 | pkg
|
138 | ]));
|
139 | const packageDirs = Array.from(dirMap.keys());
|
140 | const result = new Array();
|
141 | let searchIndex = 0;
|
142 | changedFiles.sort();
|
143 | packageDirs.sort();
|
144 | for (const packageDir of packageDirs) {
|
145 | while (searchIndex < changedFiles.length && changedFiles[searchIndex] < packageDir) {
|
146 | searchIndex += 1;
|
147 | }
|
148 | if ((_a = changedFiles[searchIndex]) == null ? void 0 : _a.startsWith(packageDir)) {
|
149 | searchIndex += 1;
|
150 | result.push(dirMap.get(packageDir));
|
151 | while ((_b = changedFiles[searchIndex]) == null ? void 0 : _b.startsWith(packageDir)) {
|
152 | searchIndex += 1;
|
153 | }
|
154 | }
|
155 | }
|
156 | return result;
|
157 | }
|
158 | }
|
159 |
|
160 | exports.PackageGraph = PackageGraph;
|
161 |
|