You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
12 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. /*******************************
  2. Install Task
  3. *******************************/
  4. /*
  5. Install tasks
  6. For more notes
  7. * Runs automatically after npm update (hooks)
  8. * (NPM) Install - Will ask for where to put semantic (outside pm folder)
  9. * (NPM) Upgrade - Will look for semantic install, copy over files and update if new version
  10. * Standard installer runs asking for paths to site files etc
  11. */
  12. var
  13. gulp = require('gulp'),
  14. // node dependencies
  15. console = require('better-console'),
  16. extend = require('extend'),
  17. fs = require('fs'),
  18. mkdirp = require('mkdirp'),
  19. path = require('path'),
  20. // gulp dependencies
  21. chmod = require('gulp-chmod'),
  22. del = require('del'),
  23. jsonEditor = require('gulp-json-editor'),
  24. plumber = require('gulp-plumber'),
  25. prompt = require('gulp-prompt'),
  26. rename = require('gulp-rename'),
  27. replace = require('gulp-replace'),
  28. requireDotFile = require('require-dot-file'),
  29. wrench = require('wrench'),
  30. // install config
  31. install = require('./config/project/install'),
  32. // user config
  33. config = require('./config/user'),
  34. // release config (name/title/etc)
  35. release = require('./config/project/release'),
  36. // shorthand
  37. questions = install.questions,
  38. files = install.files,
  39. folders = install.folders,
  40. regExp = install.regExp,
  41. settings = install.settings,
  42. source = install.source
  43. ;
  44. // Export install task
  45. module.exports = function () {
  46. var
  47. currentConfig = requireDotFile('semantic.json'),
  48. manager = install.getPackageManager(),
  49. rootQuestions = questions.root
  50. ;
  51. console.clear();
  52. /* Test NPM install
  53. manager = {
  54. name : 'NPM',
  55. root : path.normalize(__dirname + '/../')
  56. };
  57. */
  58. /*--------------
  59. PM Config
  60. ---------------*/
  61. /* Don't do end user config if SUI is a sub-module */
  62. if( install.isSubModule() ) {
  63. console.info('SUI is a sub-module, skipping end-user install');
  64. return;
  65. }
  66. // run update scripts if semantic.json exists
  67. if(currentConfig && manager.name === 'NPM') {
  68. var
  69. updateFolder = path.join(manager.root, currentConfig.base),
  70. updatePaths = {
  71. config : path.join(manager.root, files.config),
  72. tasks : path.join(updateFolder, folders.tasks),
  73. themeImport : path.join(updateFolder, folders.themeImport),
  74. definition : path.join(currentConfig.paths.source.definitions),
  75. site : path.join(currentConfig.paths.source.site),
  76. theme : path.join(currentConfig.paths.source.themes),
  77. defaultTheme : path.join(currentConfig.paths.source.themes, folders.defaultTheme)
  78. }
  79. ;
  80. // duck-type if there is a project installed
  81. if( fs.existsSync(updatePaths.definition) ) {
  82. // perform update if new version
  83. if(currentConfig.version !== release.version) {
  84. console.log('Updating Semantic UI from ' + currentConfig.version + ' to ' + release.version);
  85. console.info('Updating ui definitions...');
  86. wrench.copyDirSyncRecursive(source.definitions, updatePaths.definition, settings.wrench.overwrite);
  87. console.info('Updating default theme...');
  88. wrench.copyDirSyncRecursive(source.themes, updatePaths.theme, settings.wrench.merge);
  89. wrench.copyDirSyncRecursive(source.defaultTheme, updatePaths.defaultTheme, settings.wrench.overwrite);
  90. console.info('Updating tasks...');
  91. wrench.copyDirSyncRecursive(source.tasks, updatePaths.tasks, settings.wrench.overwrite);
  92. console.info('Updating gulpfile.js');
  93. gulp.src(source.userGulpFile)
  94. .pipe(plumber())
  95. .pipe(gulp.dest(updateFolder))
  96. ;
  97. // copy theme import
  98. console.info('Updating theme import file');
  99. gulp.src(source.themeImport)
  100. .pipe(plumber())
  101. .pipe(gulp.dest(updatePaths.themeImport))
  102. ;
  103. console.info('Adding new site theme files...');
  104. wrench.copyDirSyncRecursive(source.site, updatePaths.site, settings.wrench.merge);
  105. console.info('Updating version...');
  106. // update version number in semantic.json
  107. gulp.src(updatePaths.config)
  108. .pipe(plumber())
  109. .pipe(rename(settings.rename.json)) // preserve file extension
  110. .pipe(jsonEditor({
  111. version: release.version
  112. }))
  113. .pipe(gulp.dest(manager.root))
  114. ;
  115. console.info('Update complete! Run "\033[92mgulp build\033[0m" to rebuild dist/ files.');
  116. return;
  117. }
  118. else {
  119. console.log('Current version of Semantic UI already installed');
  120. return;
  121. }
  122. }
  123. else {
  124. console.error('Cannot locate files to update at path: ', updatePaths.definition);
  125. console.log('Running installer');
  126. }
  127. }
  128. /*--------------
  129. Determine Root
  130. ---------------*/
  131. // PM that supports Build Tools (NPM Only Now)
  132. if(manager.name == 'NPM') {
  133. rootQuestions[0].message = rootQuestions[0].message
  134. .replace('{packageMessage}', 'We detected you are using \033[92m' + manager.name + '\033[0m. Nice! ')
  135. .replace('{root}', manager.root)
  136. ;
  137. // set default path to detected PM root
  138. rootQuestions[0].default = manager.root;
  139. rootQuestions[1].default = manager.root;
  140. // insert PM questions after "Install Type" question
  141. Array.prototype.splice.apply(questions.setup, [2, 0].concat(rootQuestions));
  142. // omit cleanup questions for managed install
  143. questions.cleanup = [];
  144. }
  145. /*--------------
  146. Set-up
  147. ---------------*/
  148. return gulp
  149. .src('gulpfile.js')
  150. .pipe(prompt.prompt(questions.setup, function(answers) {
  151. /*--------------
  152. Exit Conditions
  153. ---------------*/
  154. // if config exists and user specifies not to proceed
  155. if(answers.overwrite !== undefined && answers.overwrite == 'no') {
  156. return;
  157. }
  158. console.clear();
  159. console.log('Installing');
  160. console.log('------------------------------');
  161. /*--------------
  162. Paths
  163. ---------------*/
  164. var
  165. installPaths = {
  166. config : files.config,
  167. configFolder : folders.config,
  168. site : answers.site || folders.site,
  169. themeConfig : files.themeConfig,
  170. themeConfigFolder : folders.themeConfig
  171. },
  172. installFolder = false
  173. ;
  174. /*--------------
  175. PM Install
  176. ---------------*/
  177. // Check if PM install
  178. if(answers.useRoot || answers.customRoot) {
  179. // Set root to custom root path if set
  180. if(answers.customRoot) {
  181. if(answers.customRoot === '') {
  182. console.log('Unable to proceed, invalid project root');
  183. return;
  184. }
  185. manager.root = answers.customRoot;
  186. }
  187. // special install paths only for PM install
  188. installPaths = extend(false, {}, installPaths, {
  189. definition : folders.definitions,
  190. lessImport : folders.lessImport,
  191. tasks : folders.tasks,
  192. theme : folders.themes,
  193. defaultTheme : path.join(folders.themes, folders.defaultTheme),
  194. themeImport : folders.themeImport
  195. });
  196. // add project root to semantic root
  197. installFolder = path.join(manager.root, answers.semanticRoot);
  198. // add install folder to all output paths
  199. for(var destination in installPaths) {
  200. if( installPaths.hasOwnProperty(destination) ) {
  201. // config goes in project root, rest in install folder
  202. installPaths[destination] = (destination == 'config' || destination == 'configFolder')
  203. ? path.normalize( path.join(manager.root, installPaths[destination]) )
  204. : path.normalize( path.join(installFolder, installPaths[destination]) )
  205. ;
  206. }
  207. }
  208. // create project folders
  209. try {
  210. mkdirp.sync(installFolder);
  211. mkdirp.sync(installPaths.definition);
  212. mkdirp.sync(installPaths.theme);
  213. mkdirp.sync(installPaths.tasks);
  214. }
  215. catch(error) {
  216. console.error('NPM does not have permissions to create folders at your specified path. Adjust your folders permissions and run "npm install" again');
  217. }
  218. console.log('Installing to \033[92m' + answers.semanticRoot + '\033[0m');
  219. console.info('Copying UI definitions');
  220. wrench.copyDirSyncRecursive(source.definitions, installPaths.definition, settings.wrench.overwrite);
  221. console.info('Copying UI themes');
  222. wrench.copyDirSyncRecursive(source.themes, installPaths.theme, settings.wrench.merge);
  223. wrench.copyDirSyncRecursive(source.defaultTheme, installPaths.defaultTheme, settings.wrench.overwrite);
  224. console.info('Copying gulp tasks');
  225. wrench.copyDirSyncRecursive(source.tasks, installPaths.tasks, settings.wrench.overwrite);
  226. // copy theme import
  227. console.info('Adding theme files');
  228. gulp.src(source.themeImport)
  229. .pipe(plumber())
  230. .pipe(gulp.dest(installPaths.themeImport))
  231. ;
  232. gulp.src(source.lessImport)
  233. .pipe(plumber())
  234. .pipe(gulp.dest(installPaths.lessImport))
  235. ;
  236. // create gulp file
  237. console.info('Creating gulpfile.js');
  238. gulp.src(source.userGulpFile)
  239. .pipe(plumber())
  240. .pipe(gulp.dest(installFolder))
  241. ;
  242. }
  243. /*--------------
  244. Site Theme
  245. ---------------*/
  246. // Copy _site templates folder to destination
  247. if( fs.existsSync(installPaths.site) ) {
  248. console.info('Site folder exists, merging files (no overwrite)', installPaths.site);
  249. }
  250. else {
  251. console.info('Creating site theme folder', installPaths.site);
  252. }
  253. wrench.copyDirSyncRecursive(source.site, installPaths.site, settings.wrench.merge);
  254. /*--------------
  255. Theme Config
  256. ---------------*/
  257. var
  258. // determine path to site theme folder from theme config
  259. // force CSS path variable to use forward slashes for paths
  260. pathToSite = path.relative(path.resolve(installPaths.themeConfigFolder), path.resolve(installPaths.site)).replace(/\\/g,'/'),
  261. siteVariable = "@siteFolder : '" + pathToSite + "/';"
  262. ;
  263. // rewrite site variable in theme.less
  264. console.info('Adjusting @siteFolder to: ', pathToSite + '/');
  265. if(fs.existsSync(installPaths.themeConfig)) {
  266. console.info('Modifying src/theme.config (LESS config)', installPaths.themeConfig);
  267. gulp.src(installPaths.themeConfig)
  268. .pipe(plumber())
  269. .pipe(replace(regExp.siteVariable, siteVariable))
  270. .pipe(gulp.dest(installPaths.themeConfigFolder))
  271. ;
  272. }
  273. else {
  274. console.info('Creating src/theme.config (LESS config)', installPaths.themeConfig);
  275. gulp.src(source.themeConfig)
  276. .pipe(plumber())
  277. .pipe(rename({ extname : '' }))
  278. .pipe(replace(regExp.siteVariable, siteVariable))
  279. .pipe(gulp.dest(installPaths.themeConfigFolder))
  280. ;
  281. }
  282. /*--------------
  283. Semantic.json
  284. ---------------*/
  285. var
  286. jsonConfig = install.createJSON(answers)
  287. ;
  288. // adjust variables in theme.less
  289. if( fs.existsSync(files.config) ) {
  290. console.info('Extending config file (semantic.json)', installPaths.config);
  291. gulp.src(installPaths.config)
  292. .pipe(plumber())
  293. .pipe(rename(settings.rename.json)) // preserve file extension
  294. .pipe(jsonEditor(jsonConfig))
  295. .pipe(gulp.dest(installPaths.configFolder))
  296. ;
  297. }
  298. else {
  299. console.info('Creating config file (semantic.json)', installPaths.config);
  300. gulp.src(source.config)
  301. .pipe(plumber())
  302. .pipe(rename({ extname : '' })) // remove .template from ext
  303. .pipe(jsonEditor(jsonConfig))
  304. .pipe(gulp.dest(installPaths.configFolder))
  305. ;
  306. }
  307. // Completion Message
  308. if(installFolder) {
  309. console.log('Install complete! Navigate to \033[92m' + answers.semanticRoot + '\033[0m and run "\033[92mgulp build\033[0m" to build');
  310. }
  311. else {
  312. console.log('');
  313. console.log('');
  314. }
  315. }))
  316. .pipe(prompt.prompt(questions.cleanup, function(answers) {
  317. if(answers.cleanup == 'yes') {
  318. del(install.setupFiles);
  319. }
  320. if(answers.build == 'yes') {
  321. gulp.start('build');
  322. }
  323. }))
  324. ;
  325. };