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.

390 lines
12 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 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
  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. }
  78. ;
  79. // duck-type if there is a project installed
  80. if( fs.existsSync(updatePaths.definition) ) {
  81. // perform update if new version
  82. if(currentConfig.version !== release.version) {
  83. console.log('Updating Semantic UI from ' + currentConfig.version + ' to ' + release.version);
  84. console.info('Updating ui definitions...');
  85. wrench.copyDirSyncRecursive(source.definitions, updatePaths.definition, settings.wrench.update);
  86. console.info('Updating default theme...');
  87. wrench.copyDirSyncRecursive(source.themes, updatePaths.theme, settings.wrench.update);
  88. console.info('Updating tasks...');
  89. wrench.copyDirSyncRecursive(source.tasks, updatePaths.tasks, settings.wrench.update);
  90. console.info('Updating gulpfile.js');
  91. gulp.src(source.userGulpFile)
  92. .pipe(plumber())
  93. .pipe(gulp.dest(updateFolder))
  94. ;
  95. // copy theme import
  96. console.info('Updating theme import file');
  97. gulp.src(source.themeImport)
  98. .pipe(plumber())
  99. .pipe(gulp.dest(updatePaths.themeImport))
  100. ;
  101. console.info('Adding new site theme files...');
  102. wrench.copyDirSyncRecursive(source.site, updatePaths.site, settings.wrench.site);
  103. console.info('Updating version...');
  104. // update version number in semantic.json
  105. gulp.src(updatePaths.config)
  106. .pipe(plumber())
  107. .pipe(rename(settings.rename.json)) // preserve file extension
  108. .pipe(jsonEditor({
  109. version: release.version
  110. }))
  111. .pipe(gulp.dest(manager.root))
  112. ;
  113. console.info('Update complete! Run "\033[92mgulp build\033[0m" to rebuild dist/ files.');
  114. return;
  115. }
  116. else {
  117. console.log('Current version of Semantic UI already installed');
  118. return;
  119. }
  120. }
  121. else {
  122. console.error('Cannot locate files to update at path: ', updatePaths.definition);
  123. console.log('Running installer');
  124. }
  125. }
  126. /*--------------
  127. Determine Root
  128. ---------------*/
  129. // PM that supports Build Tools (NPM Only Now)
  130. if(manager.name == 'NPM') {
  131. rootQuestions[0].message = rootQuestions[0].message
  132. .replace('{packageMessage}', 'We detected you are using \033[92m' + manager.name + '\033[0m. Nice! ')
  133. .replace('{root}', manager.root)
  134. ;
  135. // set default path to detected PM root
  136. rootQuestions[0].default = manager.root;
  137. rootQuestions[1].default = manager.root;
  138. // insert PM questions after "Install Type" question
  139. Array.prototype.splice.apply(questions.setup, [2, 0].concat(rootQuestions));
  140. // omit cleanup questions for managed install
  141. questions.cleanup = [];
  142. }
  143. /*--------------
  144. Set-up
  145. ---------------*/
  146. return gulp
  147. .src('gulpfile.js')
  148. .pipe(prompt.prompt(questions.setup, function(answers) {
  149. /*--------------
  150. Exit Conditions
  151. ---------------*/
  152. // if config exists and user specifies not to proceed
  153. if(answers.overwrite !== undefined && answers.overwrite == 'no') {
  154. return;
  155. }
  156. console.clear();
  157. console.log('Installing');
  158. console.log('------------------------------');
  159. /*--------------
  160. Paths
  161. ---------------*/
  162. var
  163. installPaths = {
  164. config : files.config,
  165. configFolder : folders.config,
  166. site : answers.site || folders.site,
  167. themeConfig : files.themeConfig,
  168. themeConfigFolder : folders.themeConfig
  169. },
  170. installFolder = false
  171. ;
  172. /*--------------
  173. PM Install
  174. ---------------*/
  175. // Check if PM install
  176. if(answers.useRoot || answers.customRoot) {
  177. // Set root to custom root path if set
  178. if(answers.customRoot) {
  179. if(answers.customRoot === '') {
  180. console.log('Unable to proceed, invalid project root');
  181. return;
  182. }
  183. manager.root = answers.customRoot;
  184. }
  185. // special install paths only for PM install
  186. installPaths = extend(false, {}, installPaths, {
  187. definition : folders.definitions,
  188. lessImport : folders.lessImport,
  189. tasks : folders.tasks,
  190. theme : folders.themes,
  191. themeImport : folders.themeImport
  192. });
  193. // add project root to semantic root
  194. installFolder = path.join(manager.root, answers.semanticRoot);
  195. // add install folder to all output paths
  196. for(var destination in installPaths) {
  197. if( installPaths.hasOwnProperty(destination) ) {
  198. // config goes in project root, rest in install folder
  199. installPaths[destination] = (destination == 'config' || destination == 'configFolder')
  200. ? path.normalize( path.join(manager.root, installPaths[destination]) )
  201. : path.normalize( path.join(installFolder, installPaths[destination]) )
  202. ;
  203. }
  204. }
  205. // create project folders
  206. try {
  207. mkdirp.sync(installFolder);
  208. mkdirp.sync(installPaths.definition);
  209. mkdirp.sync(installPaths.theme);
  210. mkdirp.sync(installPaths.tasks);
  211. }
  212. catch(error) {
  213. console.error('NPM does not have permissions to create folders at your specified path. Adjust your folders permissions and run "npm install" again');
  214. }
  215. console.log('Installing to \033[92m' + answers.semanticRoot + '\033[0m');
  216. console.info('Copying UI definitions');
  217. wrench.copyDirSyncRecursive(source.definitions, installPaths.definition, settings.wrench.install);
  218. wrench.copyDirSyncRecursive(source.themes, installPaths.theme, settings.wrench.install);
  219. console.info('Copying gulp tasks');
  220. wrench.copyDirSyncRecursive(source.tasks, installPaths.tasks, settings.wrench.install);
  221. // copy theme import
  222. console.info('Adding theme files');
  223. gulp.src(source.themeImport)
  224. .pipe(plumber())
  225. .pipe(gulp.dest(installPaths.themeImport))
  226. ;
  227. gulp.src(source.lessImport)
  228. .pipe(plumber())
  229. .pipe(gulp.dest(installPaths.lessImport))
  230. ;
  231. // create gulp file
  232. console.info('Creating gulpfile.js');
  233. gulp.src(source.userGulpFile)
  234. .pipe(plumber())
  235. .pipe(gulp.dest(installFolder))
  236. ;
  237. }
  238. /*--------------
  239. Site Theme
  240. ---------------*/
  241. // Copy _site templates folder to destination
  242. if( fs.existsSync(installPaths.site) ) {
  243. console.info('Site folder exists, merging files (no overwrite)', installPaths.site);
  244. }
  245. else {
  246. console.info('Creating site theme folder', installPaths.site);
  247. }
  248. wrench.copyDirSyncRecursive(source.site, installPaths.site, settings.wrench.site);
  249. /*--------------
  250. Theme Config
  251. ---------------*/
  252. var
  253. // determine path to site theme folder from theme config
  254. // force CSS path variable to use forward slashes for paths
  255. pathToSite = path.relative(path.resolve(installPaths.themeConfigFolder), path.resolve(installPaths.site)).replace(/\\/g,'/'),
  256. siteVariable = "@siteFolder : '" + pathToSite + "/';"
  257. ;
  258. // rewrite site variable in theme.less
  259. console.info('Adjusting @siteFolder to: ', pathToSite + '/');
  260. if(fs.existsSync(installPaths.themeConfig)) {
  261. console.info('Modifying src/theme.config (LESS config)', installPaths.themeConfig);
  262. gulp.src(installPaths.themeConfig)
  263. .pipe(plumber())
  264. .pipe(replace(regExp.siteVariable, siteVariable))
  265. .pipe(gulp.dest(installPaths.themeConfigFolder))
  266. ;
  267. }
  268. else {
  269. console.info('Creating src/theme.config (LESS config)', installPaths.themeConfig);
  270. gulp.src(source.themeConfig)
  271. .pipe(plumber())
  272. .pipe(rename({ extname : '' }))
  273. .pipe(replace(regExp.siteVariable, siteVariable))
  274. .pipe(gulp.dest(installPaths.themeConfigFolder))
  275. ;
  276. }
  277. /*--------------
  278. Semantic.json
  279. ---------------*/
  280. var
  281. jsonConfig = install.createJSON(answers)
  282. ;
  283. // adjust variables in theme.less
  284. if( fs.existsSync(files.config) ) {
  285. console.info('Extending config file (semantic.json)', installPaths.config);
  286. gulp.src(installPaths.config)
  287. .pipe(plumber())
  288. .pipe(rename(settings.rename.json)) // preserve file extension
  289. .pipe(jsonEditor(jsonConfig))
  290. .pipe(gulp.dest(installPaths.configFolder))
  291. ;
  292. }
  293. else {
  294. console.info('Creating config file (semantic.json)', installPaths.config);
  295. gulp.src(source.config)
  296. .pipe(plumber())
  297. .pipe(rename({ extname : '' })) // remove .template from ext
  298. .pipe(jsonEditor(jsonConfig))
  299. .pipe(gulp.dest(installPaths.configFolder))
  300. ;
  301. }
  302. // Completion Message
  303. if(installFolder) {
  304. console.log('Install complete! Navigate to \033[92m' + answers.semanticRoot + '\033[0m and run "\033[92mgulp build\033[0m" to build');
  305. }
  306. else {
  307. console.log('');
  308. console.log('');
  309. }
  310. }))
  311. .pipe(prompt.prompt(questions.cleanup, function(answers) {
  312. if(answers.cleanup == 'yes') {
  313. del(install.setupFiles);
  314. }
  315. if(answers.build == 'yes') {
  316. gulp.start('build');
  317. }
  318. }))
  319. ;
  320. };