@vnejs/monorepo 0.0.4 → 0.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vnejs/monorepo",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Monorepo tooling for @vnejs",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -0,0 +1,64 @@
1
+ const resolveGraph = require("../workspace/resolve-graph");
2
+ const findRoot = require("../workspace/find-root");
3
+ const { run } = require("../publish/utils");
4
+
5
+ const runLayerTurbo = (layer, root, { script, force }) => {
6
+ const filters = layer.map((pkg) => `--filter=${pkg.name}`).join(" ");
7
+ const forceFlag = force ? " --force" : "";
8
+
9
+ run(`npx turbo run ${script} ${filters}${forceFlag}`, root);
10
+ };
11
+
12
+ module.exports = (options = {}) => {
13
+ const script = options.script ?? "build";
14
+ const root = findRoot(options.cwd ?? process.cwd());
15
+ const dryRun = Boolean(options.dryRun);
16
+ const sequential = Boolean(options.sequential);
17
+
18
+ const { order, layers } = resolveGraph({
19
+ cwd: options.cwd ?? root,
20
+ script,
21
+ onlyVersion: options.onlyVersion,
22
+ name: options.name,
23
+ includeDependencies: Boolean(options.name || options.onlyVersion),
24
+ });
25
+
26
+ if (!order.length) {
27
+ console.error(`No workspace packages matched filters with script "${script}".`);
28
+ process.exit(1);
29
+ }
30
+
31
+ console.log(`\n=== Build: ${order.length} packages, ${layers.length} layers ===`);
32
+ console.log(`Script: ${script}`);
33
+ console.log(`Root: ${root}`);
34
+ console.log(`Mode: ${sequential ? "sequential" : "layers (turbo)"}\n`);
35
+
36
+ const runPackage = (pkg, label) => {
37
+ console.log(`\n==> ${label} ${pkg.name} (${pkg.dir})`);
38
+
39
+ if (dryRun) return;
40
+
41
+ run(`npm run ${script}`, pkg.absDir);
42
+ };
43
+
44
+ if (sequential) {
45
+ order.forEach((pkg, index) => runPackage(pkg, `[${index + 1}/${order.length}]`));
46
+ } else {
47
+ for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) {
48
+ const layer = layers[layerIndex];
49
+ console.log(`\n=== Layer ${layerIndex + 1}/${layers.length} (${layer.length} packages) ===`);
50
+
51
+ if (dryRun) {
52
+ console.log(` turbo run ${script} ${layer.map((pkg) => `--filter=${pkg.name}`).join(" ")}`);
53
+ layer.forEach((pkg, index) => {
54
+ console.log(` ==> [${layerIndex + 1}/${layers.length}:${index + 1}/${layer.length}] ${pkg.name} (${pkg.dir})`);
55
+ });
56
+ continue;
57
+ }
58
+
59
+ runLayerTurbo(layer, root, { script, force: options.force });
60
+ }
61
+ }
62
+
63
+ if (dryRun) console.log("\nDry run complete.");
64
+ };
@@ -0,0 +1,24 @@
1
+ const findRoot = require("../workspace/find-root");
2
+ const { run } = require("../publish/utils");
3
+
4
+ module.exports = (options = {}) => {
5
+ const root = findRoot(options.cwd ?? process.cwd());
6
+
7
+ console.log(`Monorepo root: ${root}\n`);
8
+
9
+ console.log("==> Removing node_modules...");
10
+ run("rm -rf node_modules", root);
11
+ run('find . -name node_modules -type d -prune -exec rm -rf {} +', root);
12
+
13
+ console.log("==> Removing Turbo cache...");
14
+ run("rm -rf .turbo", root);
15
+ run('find . -name .turbo -type d -prune -exec rm -rf {} +', root);
16
+
17
+ console.log("==> Removing dist folders...");
18
+ run('find . -name dist -type d -prune -exec rm -rf {} +', root);
19
+
20
+ console.log("==> Removing package-lock files...");
21
+ run('find . -name package-lock.json -type f -delete', root);
22
+
23
+ console.log("\n==> Clear complete.");
24
+ };
package/src/cli.js CHANGED
@@ -9,6 +9,8 @@ const runChangedAction = require("./run-changed");
9
9
  const graphAction = require("./graph");
10
10
  const syncDepsAction = require("./sync-deps");
11
11
  const bumpAction = require("./bump");
12
+ const buildAction = require("./build");
13
+ const clearAction = require("./clear");
12
14
 
13
15
  const program = new Command();
14
16
 
@@ -78,6 +80,17 @@ program
78
80
  }),
79
81
  );
80
82
 
83
+ program
84
+ .command("build")
85
+ .description("Build workspace packages in dependency order (turbo per layer)")
86
+ .option("--script <script>", "npm script to run in each package", "build")
87
+ .option("--only-version <pattern>", "filter by version prefix, e.g. 0.0.x")
88
+ .option("--name <pattern>", "filter by package name substring (includes dependency closure)")
89
+ .option("--sequential", "build one package at a time in flat graph order", false)
90
+ .option("--force", "pass --force to turbo (bypass cache)", false)
91
+ .option("--dry-run", "show build plan without running", false)
92
+ .action((options) => buildAction(options));
93
+
81
94
  program
82
95
  .command("changed-packages")
83
96
  .description("List workspace packages changed in git")
@@ -101,4 +114,9 @@ program
101
114
  .option("--dry-run", "list packages without running the script", false)
102
115
  .action(runChangedAction);
103
116
 
117
+ program
118
+ .command("clear")
119
+ .description("Clean node_modules, caches, dist, and lockfiles")
120
+ .action(clearAction);
121
+
104
122
  program.parse();
package/src/index.js CHANGED
@@ -6,6 +6,8 @@ module.exports = {
6
6
  graph: require("./graph"),
7
7
  syncDeps: require("./sync-deps"),
8
8
  bump: require("./bump"),
9
+ build: require("./build"),
10
+ clear: require("./clear"),
9
11
  resolveGraph: require("./workspace/resolve-graph"),
10
12
  listWorkspacePackages: require("./workspace/list-packages"),
11
13
  toTildeMinor: require("./workspace/to-tilde-minor"),
@@ -25,6 +25,24 @@ const buildDependencyGraph = (packages) => {
25
25
  return { graph, byName };
26
26
  };
27
27
 
28
+ const expandDependencyClosure = (packageNames, graph, byName) => {
29
+ const expanded = new Set(packageNames);
30
+ const queue = [...packageNames];
31
+
32
+ while (queue.length) {
33
+ const name = queue.shift();
34
+
35
+ for (const dep of graph.get(name) ?? []) {
36
+ if (!byName.has(dep) || expanded.has(dep)) continue;
37
+
38
+ expanded.add(dep);
39
+ queue.push(dep);
40
+ }
41
+ }
42
+
43
+ return [...expanded];
44
+ };
45
+
28
46
  const restrictGraph = (graph, packageNames) => {
29
47
  const names = new Set(packageNames);
30
48
  const restricted = new Map();
@@ -42,5 +60,6 @@ const restrictGraph = (graph, packageNames) => {
42
60
  module.exports = {
43
61
  DEPENDENCY_FIELDS,
44
62
  buildDependencyGraph,
63
+ expandDependencyClosure,
45
64
  restrictGraph,
46
65
  };
@@ -18,9 +18,13 @@ const expandWorkspacePattern = (root, pattern) => {
18
18
  if (part === "**") {
19
19
  if (!existsSync(dir)) return;
20
20
 
21
+ walk(dir, idx + 1);
22
+
21
23
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
22
24
  if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== "dist") {
23
- walk(path.join(dir, entry.name), idx + 1);
25
+ const subdir = path.join(dir, entry.name);
26
+ walk(subdir, idx + 1);
27
+ walk(subdir, idx);
24
28
  }
25
29
  }
26
30
 
@@ -1,26 +1,28 @@
1
1
  const listWorkspacePackages = require("./list-packages");
2
2
  const filterPackages = require("./filter-packages");
3
- const { buildDependencyGraph, restrictGraph } = require("./build-graph");
3
+ const { buildDependencyGraph, expandDependencyClosure, restrictGraph } = require("./build-graph");
4
4
  const { topoSort, topoSortLayers } = require("./topo-sort");
5
5
 
6
6
  module.exports = (options = {}) => {
7
7
  const { root, packages } = listWorkspacePackages({ cwd: options.cwd });
8
- const selected = filterPackages(packages, options);
8
+ let selected = filterPackages(packages, options);
9
9
 
10
10
  if (!selected.length) {
11
11
  return { root, selected: [], order: [], layers: [], byName: new Map() };
12
12
  }
13
13
 
14
14
  const byName = new Map(packages.map((pkg) => [pkg.name, pkg]));
15
- const restricted = restrictGraph(
16
- buildDependencyGraph(packages).graph,
17
- selected.map((pkg) => pkg.name),
18
- );
19
- const layerNames = topoSortLayers(
20
- restricted,
21
- selected.map((pkg) => pkg.name),
22
- );
23
- const order = topoSort(restricted, selected.map((pkg) => pkg.name)).map((name) => byName.get(name));
15
+ const { graph } = buildDependencyGraph(packages);
16
+ let packageNames = selected.map((pkg) => pkg.name);
17
+
18
+ if (options.includeDependencies && packageNames.length) {
19
+ packageNames = expandDependencyClosure(packageNames, graph, byName);
20
+ selected = packageNames.map((name) => byName.get(name)).filter(Boolean);
21
+ }
22
+
23
+ const restricted = restrictGraph(graph, packageNames);
24
+ const layerNames = topoSortLayers(restricted, packageNames);
25
+ const order = topoSort(restricted, packageNames).map((name) => byName.get(name));
24
26
  const layers = layerNames.map((layer) => layer.map((name) => byName.get(name)));
25
27
 
26
28
  return { root, selected, order, layers, byName };