├── .gitignore ├── Gruntfile.js ├── README.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .ftpauth 3 | /laravel -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var handlebars = require('handlebars'); 2 | var _ = require('lodash'); 3 | var semver = require('semver'); 4 | var fs = require('fs'); 5 | var moment = require('moment'); 6 | 7 | moment.locale('zh-cn'); 8 | 9 | /*global module:false*/ 10 | module.exports = function(grunt) { 11 | 12 | var DOWNLOAD_PREFIX = 'http://down.golaravel.com/'; 13 | var laravel_tags; 14 | var lumen_tags; 15 | 16 | // Project configuration. 17 | grunt.initConfig({ 18 | // Metadata. 19 | pkg: grunt.file.readJSON('package.json'), 20 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 21 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 22 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 23 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 24 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', 25 | // Task configuration. 26 | exec: { 27 | composer_selfupdate: { 28 | cmd: 'composer selfupdate', 29 | stdout: false, 30 | stderr: false 31 | }, 32 | clone_laravel: { 33 | cmd: 'git clone https://github.com/laravel/laravel --depth=1 --no-single-branch -q', 34 | stdout: false, 35 | stderr: false 36 | }, 37 | list_laravel_tags: { 38 | cmd: 'git tag --list', 39 | cwd: './laravel', 40 | callback: function(err, stdout, stderr) { 41 | if(stderr.length > 0) { 42 | grunt.fail.fatal('git tag failed!'); 43 | } 44 | 45 | var tags = stdout.toString().trim().split('\n').filter(function(tag){ 46 | if(/^v3/.test(tag)) { 47 | return false; 48 | } 49 | 50 | return true; 51 | }); 52 | 53 | tags = _.chain(tags).groupBy(function(ver){ 54 | return [semver.major(ver), semver.minor(ver)].join('.'); 55 | }).map(function(group){ 56 | return _.reduce(group, function(result, ver){ 57 | if(semver.gt(result, ver)) return result; 58 | 59 | return ver; 60 | }); 61 | }).value(); 62 | 63 | tags.push('master'); 64 | 65 | console.log(tags); 66 | 67 | laravel_tags = tags; 68 | }, 69 | stdout: false, 70 | stderr: false 71 | }, 72 | export_laravel_versions: { 73 | cmd: function() { 74 | var template = '{{#tags}}git archive --format=tar --prefix=laravel-{{this}}/ {{this}} | tar xf - && {{/tags}}'; 75 | var cmd; 76 | var tags = laravel_tags; 77 | 78 | template = handlebars.compile(template); 79 | cmd = template({tags: tags}).replace(/&&\s*$/g, ''); 80 | 81 | console.log(cmd); 82 | return cmd; 83 | }, 84 | cwd: 'laravel', 85 | stdout: false, 86 | stderr: false 87 | }, 88 | laravel_composer_install: { 89 | cmd: function(){ 90 | var cwd = process.cwd(); 91 | var template = '{{#tags}}(cd {{../cwd}}/laravel/laravel-{{this}} && cp .env.example .env >/dev/null 2>&1 || true &&' + 92 | 'composer install && php artisan key:generate >/dev/null 2>&1 || true) && {{/tags}}'; 93 | var cmd; 94 | var tags = laravel_tags; 95 | 96 | template = handlebars.compile(template); 97 | cmd = template({tags: tags, cwd: cwd}).replace(/&&\s*$/g, ''); 98 | 99 | console.log(cmd); 100 | return cmd; 101 | }, 102 | cwd: 'laravel', 103 | stdout: false, 104 | stderr: false 105 | }, 106 | 107 | 108 | clone_lumen: { 109 | cmd: 'git clone https://github.com/laravel/lumen --depth=1 --no-single-branch -q', 110 | stdout: false, 111 | stderr: false 112 | }, 113 | list_lumen_tags: { 114 | cmd: 'git tag --list', 115 | cwd: './lumen', 116 | callback: function(err, stdout, stderr) { 117 | if(stderr.length > 0) { 118 | grunt.fail.fatal('git tag failed!'); 119 | } 120 | 121 | var tags = stdout.toString().trim().split('\n').filter(function(tag){ 122 | return true; 123 | }); 124 | 125 | tags = _.chain(tags).groupBy(function(ver){ 126 | return [semver.major(ver), semver.minor(ver)].join('.'); 127 | }).map(function(group){ 128 | return _.reduce(group, function(result, ver){ 129 | if(semver.gt(result, ver)) return result; 130 | 131 | return ver; 132 | }); 133 | }).value(); 134 | 135 | tags.push('master'); 136 | 137 | console.log(tags); 138 | 139 | lumen_tags = tags; 140 | }, 141 | stdout: false, 142 | stderr: false 143 | }, 144 | export_lumen_versions: { 145 | cmd: function() { 146 | var template = '{{#tags}}git archive --format=tar --prefix=lumen-{{this}}/ {{this}} | tar xf - && {{/tags}}'; 147 | var cmd; 148 | var tags = lumen_tags; 149 | 150 | template = handlebars.compile(template); 151 | cmd = template({tags: tags}).replace(/&&\s*$/g, ''); 152 | 153 | console.log(cmd); 154 | return cmd; 155 | }, 156 | cwd: 'lumen', 157 | stdout: false, 158 | stderr: false 159 | }, 160 | lumen_composer_install: { 161 | cmd: function(){ 162 | var cwd = process.cwd(); 163 | var template = '{{#tags}}(cd {{../cwd}}/lumen/lumen-{{this}} && cp .env.example .env >/dev/null 2>&1 || true && ' + 164 | 'composer install) && {{/tags}}'; 165 | var cmd; 166 | var tags = lumen_tags; 167 | 168 | template = handlebars.compile(template); 169 | cmd = template({tags: tags, cwd: cwd}).replace(/&&\s*$/g, ''); 170 | 171 | console.log(cmd); 172 | return cmd;post-create-project-cmd 173 | }, 174 | cwd: 'lumen', 175 | stdout: false, 176 | stderr: false 177 | }, 178 | 179 | zip_lumen: { 180 | cmd: function(){ 181 | var cwd = process.cwd(); 182 | var template = '{{#tags}}(echo {{this}} && zip -q -r lumen-{{this}}.zip lumen-{{this}}) && {{/tags}}'; 183 | var cmd; 184 | var tags = lumen_tags; 185 | 186 | template = handlebars.compile(template); 187 | cmd = template({tags: tags, cwd: cwd}).replace(/&&\s*$/g, ''); 188 | 189 | console.log(cmd); 190 | return cmd; 191 | }, 192 | cwd: 'lumen', 193 | stdout: false, 194 | stderr: false 195 | }, 196 | zip_laravel: { 197 | cmd: function(){ 198 | var cwd = process.cwd(); 199 | var template = '{{#tags}}(echo {{this}} && zip -q -r laravel-{{this}}.zip laravel-{{this}}) && {{/tags}}'; 200 | var cmd; 201 | var tags = laravel_tags; 202 | 203 | template = handlebars.compile(template); 204 | cmd = template({tags: tags, cwd: cwd}).replace(/&&\s*$/g, ''); 205 | 206 | console.log(cmd); 207 | return cmd; 208 | }, 209 | cwd: 'laravel', 210 | stdout: false, 211 | stderr: false 212 | } 213 | }, 214 | clean: ['laravel', 'lumen'], 215 | zip_directories: { 216 | versions: { 217 | files: [{ 218 | filter: 'isDirectory', 219 | expand: true, 220 | cwd: './laravel', 221 | src: ['laravel-*'], 222 | dest: './laravel' 223 | }, 224 | { 225 | filter: 'isDirectory', 226 | expand: true, 227 | cwd: './lumen', 228 | src: ['lumen-*'], 229 | dest: './lumen' 230 | } 231 | ] 232 | } 233 | }, 234 | ftp_push: { 235 | upyun: { 236 | options: { 237 | host: 'v0.ftp.upyun.com', 238 | authKey: 'upyun', 239 | dest: '/' 240 | }, 241 | files: [{ 242 | expand: true, 243 | cwd: 'laravel', 244 | src: ['*.zip', 'laravel-*.json'] 245 | }, 246 | { 247 | expand: true, 248 | cwd: 'lumen', 249 | src: ['*.zip'] 250 | } 251 | ] 252 | } 253 | 254 | }, 255 | replace: { 256 | dist: { 257 | options: { 258 | patterns: [ 259 | { 260 | match: //ig, 261 | replacement: '' 262 | }, 263 | //v4 264 | { 265 | match: /@import url\(\/\/fonts.googleapis.com\/css\?family=.*\);/ig, 266 | replacement: '' 267 | }, 268 | 269 | //v5 270 | { 271 | match: //ig, 272 | replacement: '' 273 | }, 274 | { 275 | match: /' 277 | }, 278 | { 279 | match: /' 281 | }, 282 | { 283 | match: /\/\/cdnjs.cloudflare.com\/ajax\/libs/ig, 284 | replacement: 'http://cdn.bootcss.com' 285 | }, 286 | { 287 | match: /twitter-bootstrap/ig, 288 | replacement: 'bootstrap' 289 | } 290 | ] 291 | }, 292 | files: [ 293 | {expand: true, cwd: 'laravel', src: ['laravel-*/resources/views/**/*.blade.php'], dest: 'laravel'}, 294 | {expand: true, cwd: 'laravel', src: ['laravel-*/app/views/**/*.php'], dest: 'laravel'} 295 | ] 296 | } 297 | } 298 | }); 299 | 300 | // These plugins provide necessary tasks. 301 | grunt.loadNpmTasks('grunt-contrib-clean'); 302 | grunt.loadNpmTasks('grunt-contrib-copy'); 303 | grunt.loadNpmTasks('grunt-zip-directories'); 304 | grunt.loadNpmTasks('grunt-exec'); 305 | grunt.loadNpmTasks('grunt-ftp-push-fullpath'); 306 | grunt.loadNpmTasks('grunt-replace'); 307 | 308 | // Default task. 309 | grunt.registerTask('default', [ 310 | 'clean', 311 | 'exec:composer_selfupdate', 312 | 'exec:clone_laravel', 313 | 'exec:list_laravel_tags', 314 | 'exec:export_laravel_versions', 315 | 316 | 'exec:clone_lumen', 317 | 'exec:list_lumen_tags', 318 | 'exec:export_lumen_versions', 319 | 320 | 'replace', 321 | 'exec:laravel_composer_install', 322 | 'exec:lumen_composer_install', 323 | 324 | 'exec:zip_laravel', 325 | 'exec:zip_lumen', 326 | 'version_list', 327 | 'ftp_push' 328 | ]); 329 | 330 | grunt.registerTask('test', ['exec:git_tag_list', 'version-list']); 331 | 332 | grunt.registerTask('version_list', 'save all laravel & lumen zips\' url to a json file', function(){ 333 | var laravels; 334 | var lumens; 335 | var now = moment().format('LLL'); 336 | 337 | laravels = _.map(laravel_tags, function(tag){ 338 | var states = fs.statSync('laravel/laravel-' + tag + '.zip'); 339 | 340 | return { 341 | version: tag, 342 | download_url: DOWNLOAD_PREFIX + 'laravel/laravel-' + tag + '.zip', 343 | size: states.size 344 | }; 345 | }).reverse(); 346 | 347 | lumens = _.map(lumen_tags, function(tag){ 348 | var states = fs.statSync('lumen/lumen-' + tag + '.zip'); 349 | 350 | return { 351 | version: tag, 352 | download_url: DOWNLOAD_PREFIX + 'lumen/lumen-' + tag + '.zip', 353 | size: states.size 354 | }; 355 | }).reverse(); 356 | 357 | grunt.file.write('laravel/laravel-versions.json', 'listLaravelVersions(' + JSON.stringify({time: now, laravels: laravels, lumens: lumens}) + ');'); 358 | }); 359 | 360 | }; 361 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OS: Ubuntu 14.0.x 2 | 3 | 1. install Node.js & npm 4 | 2. install grunt-cli 5 | 3. install git 6 | 4. install php5-cli, php5-mcrypt 7 | 5. run `php5enmod mcrypt` 8 | 6. install Composer 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel-versions", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "Gruntfile.js", 6 | "devDependencies": { 7 | "grunt": "^0.4.5", 8 | "grunt-contrib-clean": "^0.6.0", 9 | "grunt-contrib-copy": "^0.8.0", 10 | "grunt-exec": "^0.4.6", 11 | "grunt-ftp-push-fullpath": "^0.2.4", 12 | "grunt-replace": "^0.9.2", 13 | "grunt-zip-directories": "^0.1.3", 14 | "handlebars": "^3.0.3", 15 | "lodash": "^3.9.3", 16 | "moment": "^2.10.3", 17 | "semver": "^4.3.6" 18 | }, 19 | "scripts": { 20 | "test": "echo \"Error: no test specified\" && exit 1" 21 | }, 22 | "author": "WangSai", 23 | "license": "MIT" 24 | } 25 | --------------------------------------------------------------------------------