index.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. "use strict";
  2. const path = require("path");
  3. const pMap = require("p-map");
  4. const slash = require("slash");
  5. const { Command } = require("@lerna/command");
  6. const { PackageGraph } = require("@lerna/package-graph");
  7. const { symlinkDependencies } = require("@lerna/symlink-dependencies");
  8. module.exports = factory;
  9. function factory(argv) {
  10. return new LinkCommand(argv);
  11. }
  12. class LinkCommand extends Command {
  13. get requiresGit() {
  14. return false;
  15. }
  16. initialize() {
  17. this.allPackages = this.packageGraph.rawPackageList;
  18. if (this.options.contents) {
  19. // globally override directory to link
  20. for (const pkg of this.allPackages) {
  21. pkg.contents = this.options.contents;
  22. }
  23. }
  24. this.targetGraph = this.options.forceLocal
  25. ? new PackageGraph(this.allPackages, "allDependencies", "forceLocal")
  26. : this.packageGraph;
  27. }
  28. execute() {
  29. if (this.options._.pop() === "convert") {
  30. return this.convertLinksToFileSpecs();
  31. }
  32. return symlinkDependencies(this.allPackages, this.targetGraph, this.logger.newItem("link dependencies"));
  33. }
  34. convertLinksToFileSpecs() {
  35. const rootPkg = this.project.manifest;
  36. const rootDependencies = {};
  37. const hoisted = {};
  38. const changed = new Set();
  39. const savePrefix = "file:";
  40. for (const targetNode of this.targetGraph.values()) {
  41. const resolved = { name: targetNode.name, type: "directory" };
  42. // install root file: specifiers to avoid bootstrap
  43. rootDependencies[targetNode.name] = targetNode.pkg.resolved.saveSpec;
  44. for (const depNode of targetNode.localDependents.values()) {
  45. const depVersion = slash(path.relative(depNode.pkg.location, targetNode.pkg.location));
  46. // console.log("\n%s\n %j: %j", depNode.name, name, `${savePrefix}${depVersion}`);
  47. depNode.pkg.updateLocalDependency(resolved, depVersion, savePrefix);
  48. changed.add(depNode);
  49. }
  50. if (targetNode.pkg.devDependencies) {
  51. // hoist _all_ devDependencies to the root
  52. Object.assign(hoisted, targetNode.pkg.devDependencies);
  53. targetNode.pkg.set("devDependencies", {});
  54. changed.add(targetNode);
  55. }
  56. }
  57. // mutate project manifest, completely overwriting existing dependencies
  58. rootPkg.set("dependencies", rootDependencies);
  59. rootPkg.set("devDependencies", Object.assign(rootPkg.get("devDependencies") || {}, hoisted));
  60. return pMap(changed, (node) => node.pkg.serialize()).then(() => rootPkg.serialize());
  61. }
  62. }
  63. module.exports.LinkCommand = LinkCommand;