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

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 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. };