index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. "use strict";
  2. const fs = require("fs-extra");
  3. const path = require("path");
  4. const pMap = require("p-map");
  5. const writeJsonFile = require("write-json-file");
  6. const { Command } = require("@lerna/command");
  7. const childProcess = require("@lerna/child-process");
  8. module.exports = factory;
  9. function factory(argv) {
  10. return new InitCommand(argv);
  11. }
  12. class InitCommand extends Command {
  13. get requiresGit() {
  14. return false;
  15. }
  16. runValidations() {
  17. this.logger.verbose(this.name, "skipping validations");
  18. }
  19. runPreparations() {
  20. this.logger.verbose(this.name, "skipping preparations");
  21. }
  22. initialize() {
  23. this.exact = this.options.exact;
  24. this.lernaVersion = this.options.lernaVersion;
  25. if (!this.gitInitialized()) {
  26. this.logger.info("", "Initializing Git repository");
  27. return childProcess.exec("git", ["init"], this.execOpts);
  28. }
  29. }
  30. execute() {
  31. let chain = Promise.resolve();
  32. chain = chain.then(() => this.ensurePackageJSON());
  33. chain = chain.then(() => this.ensureLernaConfig());
  34. chain = chain.then(() => this.ensurePackagesDir());
  35. return chain.then(() => {
  36. this.logger.success("", "Initialized Lerna files");
  37. });
  38. }
  39. ensurePackageJSON() {
  40. let chain = Promise.resolve();
  41. if (!this.project.manifest) {
  42. this.logger.info("", "Creating package.json");
  43. // initialize with default indentation so write-pkg doesn't screw it up with tabs
  44. chain = chain.then(() =>
  45. writeJsonFile(
  46. path.join(this.project.rootPath, "package.json"),
  47. {
  48. name: "root",
  49. private: true,
  50. },
  51. { indent: 2 }
  52. )
  53. );
  54. } else {
  55. this.logger.info("", "Updating package.json");
  56. }
  57. chain = chain.then(() => {
  58. const rootPkg = this.project.manifest;
  59. let targetDependencies;
  60. if (rootPkg.dependencies && rootPkg.dependencies.lerna) {
  61. // lerna is a dependency in the current project
  62. targetDependencies = rootPkg.dependencies;
  63. } else {
  64. // lerna is a devDependency or no dependency, yet
  65. if (!rootPkg.devDependencies) {
  66. // mutate raw JSON object
  67. rootPkg.set("devDependencies", {});
  68. }
  69. targetDependencies = rootPkg.devDependencies;
  70. }
  71. targetDependencies.lerna = this.exact ? this.lernaVersion : `^${this.lernaVersion}`;
  72. return rootPkg.serialize();
  73. });
  74. return chain;
  75. }
  76. ensureLernaConfig() {
  77. // config already defaulted to empty object in Project constructor
  78. const { config, version: projectVersion } = this.project;
  79. let version;
  80. if (this.options.independent) {
  81. version = "independent";
  82. } else if (projectVersion) {
  83. version = projectVersion;
  84. } else {
  85. version = "0.0.0";
  86. }
  87. if (!projectVersion) {
  88. this.logger.info("", "Creating lerna.json");
  89. } else {
  90. this.logger.info("", "Updating lerna.json");
  91. }
  92. delete config.lerna; // no longer relevant
  93. if (this.exact) {
  94. // ensure --exact is preserved for future init commands
  95. const commandConfig = config.command || (config.command = {});
  96. const initConfig = commandConfig.init || (commandConfig.init = {});
  97. initConfig.exact = true;
  98. }
  99. Object.assign(config, {
  100. packages: this.project.packageConfigs,
  101. version,
  102. });
  103. return this.project.serializeConfig();
  104. }
  105. ensurePackagesDir() {
  106. this.logger.info("", "Creating packages directory");
  107. return pMap(this.project.packageParentDirs, (dir) => fs.mkdirp(dir));
  108. }
  109. }
  110. module.exports.InitCommand = InitCommand;