utils.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import path = require('path');
  2. import glob = require('glob');
  3. import fs = require('fs-extra');
  4. import childProcess = require('child_process');
  5. import sortPackageJson = require('sort-package-json');
  6. import coreutils = require('@phosphor/coreutils');
  7. /**
  8. * Get all of the lerna package paths.
  9. */
  10. export function getLernaPaths(basePath = '.'): string[] {
  11. basePath = path.resolve(basePath);
  12. let baseConfig = require(path.join(basePath, 'package.json'));
  13. let paths: string[] = [];
  14. for (let config of baseConfig.workspaces) {
  15. paths = paths.concat(glob.sync(path.join(basePath, config)));
  16. }
  17. return paths.filter(pkgPath => {
  18. return fs.existsSync(path.join(pkgPath, 'package.json'));
  19. });
  20. }
  21. /**
  22. * Get all of the core package paths.
  23. */
  24. export function getCorePaths(): string[] {
  25. let spec = path.resolve(path.join('.', 'packages', '*'));
  26. return glob.sync(spec);
  27. }
  28. /**
  29. * Write a package.json if necessary.
  30. *
  31. * @param data - The package data.
  32. *
  33. * @oaram pkgJsonPath - The path to the package.json file.
  34. *
  35. * @returns Whether the file has changed.
  36. */
  37. export function writePackageData(pkgJsonPath: string, data: any): boolean {
  38. let text = JSON.stringify(sortPackageJson(data), null, 2) + '\n';
  39. let orig = fs
  40. .readFileSync(pkgJsonPath, 'utf8')
  41. .split('\r\n')
  42. .join('\n');
  43. if (text !== orig) {
  44. fs.writeFileSync(pkgJsonPath, text, 'utf8');
  45. return true;
  46. }
  47. return false;
  48. }
  49. /**
  50. * Read a json file.
  51. */
  52. export function readJSONFile(filePath: string): any {
  53. return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  54. }
  55. /**
  56. * Write a json file.
  57. */
  58. export function writeJSONFile(filePath: string, data: any): boolean {
  59. function sortObjByKey(value: any): any {
  60. // https://stackoverflow.com/a/35810961
  61. return typeof value === 'object'
  62. ? Array.isArray(value)
  63. ? value.map(sortObjByKey)
  64. : Object.keys(value)
  65. .sort()
  66. .reduce((o: any, key) => {
  67. const v = value[key];
  68. o[key] = sortObjByKey(v);
  69. return o;
  70. }, {})
  71. : value;
  72. }
  73. let text = JSON.stringify(data, sortObjByKey(data), 2) + '\n';
  74. let orig = {};
  75. try {
  76. orig = readJSONFile(filePath);
  77. } catch (e) {
  78. // no-op
  79. }
  80. if (!coreutils.JSONExt.deepEqual(data, orig)) {
  81. fs.writeFileSync(filePath, text, 'utf8');
  82. return true;
  83. }
  84. return false;
  85. }
  86. /**
  87. * Run a command with terminal output.
  88. *
  89. * @param cmd - The command to run.
  90. */
  91. export function run(
  92. cmd: string,
  93. options: childProcess.ExecSyncOptions = {},
  94. quiet?: boolean
  95. ): string {
  96. options = options || {};
  97. options['stdio'] = options.stdio || 'inherit';
  98. if (!quiet) {
  99. console.log('>', cmd);
  100. }
  101. const value = childProcess.execSync(cmd, options);
  102. if (value === null) {
  103. return '';
  104. }
  105. return value
  106. .toString()
  107. .replace(/(\r\n|\n)$/, '')
  108. .trim();
  109. }