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.

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