publisher.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // Dependecies.
  2. const prompt = require('prompt');
  3. const shelljs = require('shelljs');
  4. const fs = require('fs-extra');
  5. const path = require('path');
  6. // This can be changed when we have a new major release.
  7. const minimumDependency = '>=3.4.0-alpha';
  8. // CMD Arguments Management.
  9. let doNotBuild = false;
  10. let doNotPublish = false;
  11. // Pathe management.
  12. process.env.PATH += (path.delimiter + path.join(__dirname, 'node_modules', '.bin'));
  13. // Global Variables.
  14. const config = require("./config/config.json");
  15. const basePath = config.basePath;
  16. const packages = config.packages;
  17. /**
  18. * Remove a directory.
  19. */
  20. const rmDir = function (dirPath) {
  21. try { var files = fs.readdirSync(dirPath); }
  22. catch (e) { return; }
  23. if (files.length > 0)
  24. for (var i = 0; i < files.length; i++) {
  25. var filePath = dirPath + '/' + files[i];
  26. if (fs.statSync(filePath).isFile())
  27. fs.unlinkSync(filePath);
  28. else
  29. rmDir(filePath);
  30. }
  31. fs.rmdirSync(dirPath);
  32. };
  33. /**
  34. * Get Files from folder.
  35. */
  36. const getFiles = function(dir, files_) {
  37. files_ = files_ || [];
  38. var files = fs.readdirSync(dir);
  39. for (var i in files) {
  40. var name = dir + '/' + files[i];
  41. if (fs.statSync(name).isDirectory()) {
  42. getFiles(name, files_);
  43. } else {
  44. files_.push(name);
  45. }
  46. }
  47. return files_;
  48. }
  49. /**
  50. * Update the version in the engine class for Babylon
  51. */
  52. function updateEngineVersion(newVersion) {
  53. console.log("Updating version in babylon.engine.ts to: " + newVersion);
  54. let engineContent = fs.readFileSync("../../src/Engine/babylon.engine.ts").toString();
  55. let replaced = engineContent.replace(/(public static get Version\(\): string {\s*return ")(.*)(";\s*})/g, "$1" + newVersion + "$3");
  56. fs.writeFileSync("../../src/Engine/babylon.engine.ts", replaced);
  57. }
  58. /**
  59. * Get the version from the engine class for Babylon
  60. */
  61. function getEngineVersion() {
  62. console.log("Get version from babylon.engine.ts");
  63. const engineContent = fs.readFileSync("../../src/Engine/babylon.engine.ts").toString();
  64. const versionRegex = new RegExp(`public static get Version\\(\\): string {[\\s\\S]*return "([\\s\\S]*?)";[\\s\\S]*}`, "gm");
  65. const match = versionRegex.exec(engineContent);
  66. if (match && match.length) {
  67. const version = match[1];
  68. console.log("Version found: " + version);
  69. return version;
  70. }
  71. console.log("Version not found in engine.ts");
  72. process.exit(1);
  73. }
  74. /**
  75. * Publish a package to npm.
  76. */
  77. function publish(version, packageName, basePath) {
  78. console.log('Publishing ' + packageName + " from " + basePath);
  79. let tag = "";
  80. // check for alpha or beta
  81. if (version.indexOf('alpha') !== -1 || version.indexOf('beta') !== -1) {
  82. tag = '--tag preview';
  83. }
  84. //publish the respected package
  85. if (doNotPublish) {
  86. console.log("If publishing enabled: " + 'npm publish \"' + basePath + "\"" + ' ' + tag);
  87. }
  88. else {
  89. console.log("Executing: " + 'npm publish \"' + basePath + "\"" + ' ' + tag);
  90. shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tag);
  91. }
  92. }
  93. /**
  94. * Build the folder with Gulp.
  95. */
  96. function buildBabylonJSAndDependencies() {
  97. // run gulp typescript-all
  98. console.log("Running gulp compilation");
  99. let exec = shelljs.exec("gulp typescript-all --gulpfile ../Gulp/gulpfile.js");
  100. if (exec.code) {
  101. console.log("Error during compilation, aborting");
  102. process.exit(1);
  103. }
  104. }
  105. /**
  106. * Process Legacy Packages.
  107. */
  108. function processLegacyPackages(version) {
  109. packages.forEach((package) => {
  110. if (package.name === "core") {
  111. processCore(package, version);
  112. }
  113. else {
  114. if (package.required) {
  115. package.required.forEach(file => {
  116. fs.copySync(basePath + file, basePath + package.path + '/' + path.basename(file));
  117. });
  118. }
  119. let packageJson = require(basePath + package.path + 'package.json');
  120. packageJson.version = version;
  121. if (packageJson.dependencies) {
  122. Object.keys(packageJson.dependencies).forEach(key => {
  123. if (key.indexOf("babylonjs") !== -1) {
  124. packageJson.dependencies[key] = version;
  125. }
  126. });
  127. }
  128. if (packageJson.peerDependencies) packageJson.peerDependencies.babylonjs = minimumDependency;
  129. fs.writeFileSync(basePath + package.path + 'package.json', JSON.stringify(packageJson, null, 4));
  130. publish(version, package.name, basePath + package.path);
  131. }
  132. });
  133. }
  134. /**
  135. * Process ES6 Packages.
  136. */
  137. function processEs6Packages(version) {
  138. let es6Packages = config.es6;
  139. es6Packages.forEach(package => {
  140. let projectPath = package.path;
  141. let buildPath = path.normalize(basePath + projectPath + package.buildPath);
  142. if (package.required) {
  143. package.required.forEach(file => {
  144. fs.copySync(file, basePath + '/' + path.basename(file));
  145. });
  146. }
  147. console.log("Cleanup " + buildPath);
  148. rmDir(buildPath);
  149. console.log("Executing " + 'tsc -t es6 -m esNext -p ' + projectPath);
  150. let tscCompile = shelljs.exec('tsc -t es6 -m esNext -p ' + projectPath);
  151. if (tscCompile.code !== 0) {
  152. throw new Error("Tsc compilation failed");
  153. }
  154. let packageJson = require("./config" + '/template.package.json');
  155. let files = getFiles(buildPath).map(f => f.replace(buildPath + "/", "")).filter(f => f.indexOf("assets/") === -1);
  156. packageJson.files = files;
  157. packageJson.version = version;
  158. Object.keys(package.payload).forEach(key => {
  159. packageJson[key] = package.payload[key]
  160. });
  161. ["dependencies", "peerDependencies", "devDependencies"].forEach(key => {
  162. if (package.payload[key]) {
  163. packageJson[key] = {};
  164. Object.keys(package.payload[key]).forEach(packageName => {
  165. if (package.payload[key][packageName] === true) {
  166. packageJson[key][packageName] = version;
  167. } else {
  168. packageJson[key][packageName] = package.payload[key][packageName];
  169. }
  170. });
  171. }
  172. });
  173. fs.writeFileSync(buildPath + '/package.json', JSON.stringify(packageJson, null, 4));
  174. publish(version, package.name, buildPath);
  175. });
  176. }
  177. /**
  178. * Special treatment for core.
  179. */
  180. function processCore(package, version) {
  181. let packageJson = require(package.path + 'package.json');
  182. // make a temporary directory
  183. fs.ensureDirSync(basePath + 'package/');
  184. let files = [
  185. {
  186. path: basePath + "babylon.d.ts",
  187. objectName: "babylon.d.ts"
  188. },
  189. {
  190. path: basePath + "babylon.js",
  191. objectName: "babylon.js"
  192. },
  193. {
  194. path: basePath + "babylon.max.js",
  195. objectName: "babylon.max.js"
  196. },
  197. {
  198. path: basePath + "babylon.worker.js",
  199. objectName: "babylon.worker.js"
  200. },
  201. {
  202. path: basePath + "Oimo.js",
  203. objectName: "Oimo.js"
  204. },
  205. {
  206. path: basePath + package.path + "readme.md",
  207. objectName: "readme.md"
  208. }
  209. ];
  210. //copy them to the package path
  211. files.forEach(file => {
  212. fs.copySync(file.path, basePath + 'package/' + file.objectName);
  213. });
  214. // update package.json
  215. packageJson.version = version;
  216. console.log("Generating file list");
  217. let packageFiles = ["package.json"];
  218. files.forEach(file => {
  219. if (!file.isDir) {
  220. packageFiles.push(file.objectName);
  221. } else {
  222. //todo is it better to read the content and add it? leave it like that ATM
  223. packageFiles.push(file.objectName + "/index.js", file.objectName + "/index.d.ts", file.objectName + "/es6.js")
  224. }
  225. });
  226. console.log("Updating package.json");
  227. packageJson.files = packageFiles;
  228. packageJson.main = "babylon.js";
  229. packageJson.typings = "babylon.d.ts";
  230. fs.writeFileSync(basePath + 'package/' + 'package.json', JSON.stringify(packageJson, null, 4));
  231. publish(version, package.name, basePath + 'package/');
  232. // remove package directory
  233. fs.removeSync(basePath + 'package/');
  234. // now update the main package.json
  235. packageJson.files = packageJson.files.map(file => {
  236. if (file !== 'package.json' && file !== 'readme.md') {
  237. return 'dist/preview release/' + file;
  238. } else {
  239. return file;
  240. }
  241. });
  242. packageJson.main = "dist/preview release/babylon.js";
  243. packageJson.typings = "dist/preview release/babylon.d.ts";
  244. fs.writeFileSync(package.path + 'package.json', JSON.stringify(packageJson, null, 4));
  245. }
  246. const createVersion = function(version) {
  247. // Prevent to build for test Cases.
  248. if (!doNotBuild) {
  249. buildBabylonJSAndDependencies();
  250. }
  251. // Create the packages and publish if needed.
  252. processLegacyPackages(version);
  253. processEs6Packages(version);
  254. }
  255. /**
  256. * Main function driving the publication.
  257. */
  258. module.exports = function(noBuild, noPublish, askVersion) {
  259. doNotBuild = noBuild;
  260. doNotPublish = noPublish;
  261. if (askVersion) {
  262. prompt.start();
  263. prompt.get(['version'], function (err, result) {
  264. const version = result.version;
  265. // Update the engine version if needed.
  266. if (!version || !version.length) {
  267. console.log("New version required.");
  268. Process.exit(1);
  269. return;
  270. }
  271. updateEngineVersion(version);
  272. createVersion(version);
  273. // Invite user to tag with the new version.
  274. if (newVersion) {
  275. console.log("Done, please tag git with " + version);
  276. }
  277. });
  278. }
  279. else {
  280. const version = getEngineVersion();
  281. createVersion(version);
  282. }
  283. };