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.

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