├── .yo-rc.json ├── .gitattributes ├── app ├── templates │ ├── _bowerrc │ ├── demo │ │ ├── styl │ │ │ ├── main.styl │ │ │ ├── _global.styl │ │ │ └── _vars.styl │ │ ├── less │ │ │ ├── _color.less │ │ │ ├── main.less │ │ │ ├── _header.less │ │ │ └── _global.less │ │ ├── scss │ │ │ ├── style.scss │ │ │ ├── _color.scss │ │ │ ├── _header.scss │ │ │ └── _main.scss │ │ ├── js │ │ │ └── calculator.js │ │ ├── coffee │ │ │ └── app.coffee │ │ ├── ts │ │ │ ├── Sayings.ts │ │ │ └── Animal.ts │ │ └── es6 │ │ │ └── app.js │ ├── editorconfig │ ├── _bower.json │ ├── _gitignore │ ├── jshintrc │ ├── _brunch-config.js │ ├── _package.json │ ├── _Gulpfile.js │ └── _Gruntfile.js └── index.js ├── .gitignore ├── .travis.yml ├── .editorconfig ├── .jshintrc ├── package.json ├── LICENSE ├── .jscsrc ├── CHANGELOG.md └── README.md /.yo-rc.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /app/templates/_bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/Resources/libs" 3 | } 4 | -------------------------------------------------------------------------------- /app/templates/demo/styl/main.styl: -------------------------------------------------------------------------------- 1 | @require '_vars' 2 | @require '_global' 3 | -------------------------------------------------------------------------------- /app/templates/demo/less/_color.less: -------------------------------------------------------------------------------- 1 | @success: #5cb85c; 2 | @danger : #d9534f; 3 | @info: #d9edf7; -------------------------------------------------------------------------------- /app/templates/demo/scss/style.scss: -------------------------------------------------------------------------------- 1 | @import 'color'; 2 | @import 'main'; 3 | @import 'header'; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | bower_components/ 3 | *.log 4 | 5 | build/ 6 | dist/ 7 | .idea/ 8 | temp/ -------------------------------------------------------------------------------- /app/templates/demo/scss/_color.scss: -------------------------------------------------------------------------------- 1 | $primary: #5cb85c; 2 | $secondary : #d9534f; 3 | $info: #d9edf7; 4 | -------------------------------------------------------------------------------- /app/templates/demo/less/main.less: -------------------------------------------------------------------------------- 1 | @import '_color.less'; 2 | @import '_global.less'; 3 | @import '_header.less'; 4 | -------------------------------------------------------------------------------- /app/templates/demo/less/_header.less: -------------------------------------------------------------------------------- 1 | .header-less { 2 | color: @info; 3 | background-color: @success; 4 | height: 50px; 5 | } 6 | -------------------------------------------------------------------------------- /app/templates/demo/scss/_header.scss: -------------------------------------------------------------------------------- 1 | .footer-sass { 2 | background-color: $primary; 3 | color: $info; 4 | height: 300px; 5 | } 6 | -------------------------------------------------------------------------------- /app/templates/demo/scss/_main.scss: -------------------------------------------------------------------------------- 1 | .primary-sass { 2 | color: $primary; 3 | } 4 | 5 | .secondary-sass { 6 | color: $secondary; 7 | } 8 | -------------------------------------------------------------------------------- /app/templates/demo/less/_global.less: -------------------------------------------------------------------------------- 1 | .success-less { 2 | background-color: @info; 3 | color: @success; 4 | } 5 | 6 | .danger-less { 7 | background-color: @info; 8 | color: @danger; 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_install: 5 | - currentfolder=${PWD##*/} 6 | - if [ "$currentfolder" != 'generator-jolistarter' ]; then cd .. && eval "mv $currentfolder generator-jolistarter" && cd generator-jolistarter; fi 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /app/templates/demo/styl/_global.styl: -------------------------------------------------------------------------------- 1 | .body-styl 2 | background-color $main-bg-color 3 | color $success-color 4 | 5 | .primary-styl 6 | padding: 20px 7 | background-color $failure-color 8 | color $success-color 9 | font-size 19px 10 | -------------------------------------------------------------------------------- /app/templates/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /app/templates/demo/js/calculator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Calculator = { 4 | add: function add(a, b) { 5 | return console.log(a + b); 6 | }, 7 | substract: function substract(a, b) { 8 | return console.log(a - b); 9 | } 10 | }; 11 | 12 | module.exports = Calculator; -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": false, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "eqnull": true, 8 | "immed": true, 9 | "latedef": false, 10 | "newcap": true, 11 | "noarg": true, 12 | "undef": true, 13 | "strict": true, 14 | "quotmark": "single", 15 | "scripturl": true 16 | } 17 | -------------------------------------------------------------------------------- /app/templates/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.1.0", 4 | "authors": [ 5 | "Laurent Brunet " 6 | ], 7 | "license": "MIT", 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components", 12 | "test", 13 | "tests" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /app/templates/demo/styl/_vars.styl: -------------------------------------------------------------------------------- 1 | // GENERIC 2 | $main-bg-color = #fff 3 | $main-txt-color = #555 4 | 5 | // Meaningful colors 6 | $unknown-color = #495b71 7 | $success-color = #2ac256 8 | $warning-color = #d1be65 9 | $failure-color = #de1500 10 | -------------------------------------------------------------------------------- /app/templates/_gitignore: -------------------------------------------------------------------------------- 1 | ._* 2 | .DS_Store 3 | .vagrant 4 | 5 | # Symfony 6 | /web/bundles/ 7 | /app/bootstrap.php.cache 8 | /app/cache/* 9 | /app/config/parameters.yml 10 | /app/logs/* 11 | /build/ 12 | /vendor/ 13 | /bin/ 14 | /composer.phar 15 | 16 | # Yeoman 17 | node_modules 18 | .tmp 19 | .sass-cache 20 | web/libs 21 | web/dist 22 | web/css 23 | app/dist 24 | -------------------------------------------------------------------------------- /app/templates/jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "strict": true 17 | } 18 | -------------------------------------------------------------------------------- /app/templates/demo/coffee/app.coffee: -------------------------------------------------------------------------------- 1 | # Assignment: 2 | number = 42 3 | opposite = true 4 | 5 | # Conditions: 6 | number = -42 if opposite 7 | 8 | # Functions: 9 | square = (x) -> x * x 10 | 11 | # Arrays: 12 | list = [1, 2, 3, 4, 5] 13 | 14 | # Objects: 15 | math = 16 | root: Math.sqrt 17 | square: square 18 | cube: (x) -> x * square x 19 | 20 | # Splats: 21 | race = (winner, runners...) -> 22 | print winner, runners 23 | 24 | # Existence: 25 | alert "I knew it!" if elvis? 26 | 27 | # Array comprehensions: 28 | cubes = (math.cube num for num in list) -------------------------------------------------------------------------------- /app/templates/demo/ts/Sayings.ts: -------------------------------------------------------------------------------- 1 | module Sayings { 2 | export class Greeter { 3 | greeting: string; 4 | constructor(message: string) { 5 | this.greeting = message; 6 | } 7 | greet() { 8 | return "Hello, " + this.greeting; 9 | } 10 | } 11 | } 12 | var greeter = new Sayings.Greeter("world"); 13 | 14 | var button = document.createElement('button'); 15 | button.textContent = "Say Hello"; 16 | button.onclick = function() { 17 | alert(greeter.greet()); 18 | }; 19 | 20 | document.body.appendChild(button); 21 | -------------------------------------------------------------------------------- /app/templates/demo/es6/app.js: -------------------------------------------------------------------------------- 1 | class Polygon { 2 | constructor(height, width) { //class constructor 3 | this.name = 'Polygon'; 4 | this.height = height; 5 | this.width = width; 6 | } 7 | 8 | sayName() { //class method 9 | console.log('Hi, I am a', this.name + '.'); 10 | } 11 | } 12 | 13 | class Square extends Polygon { 14 | constructor(length) { 15 | super(length, length); //call the parent method with super 16 | this.name = 'Square'; 17 | } 18 | 19 | get area() { //calculated attribute getter 20 | return this.height * this.width; 21 | } 22 | } 23 | 24 | let s = new Square(5); 25 | 26 | s.sayName(); 27 | console.log(s.area); 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-joli-symfony", 3 | "version": "1.1.0", 4 | "description": "Scaffolds a standard Symfony2 application with Yeoman", 5 | "license": "MIT", 6 | "main": "app/index.js", 7 | "repository": "jolicode/generator-joli-symfony", 8 | "author": { 9 | "name": "Laurent Brunet", 10 | "email": "", 11 | "url": "https://github.com/lbrunet" 12 | }, 13 | "engines": { 14 | "node": ">=0.10.0" 15 | }, 16 | "files": [ 17 | "app" 18 | ], 19 | "keywords": [ 20 | "yeoman-generator" 21 | ], 22 | "dependencies": { 23 | "chalk": "^0.5.0", 24 | "fs-extra": "^0.22.1", 25 | "js-yaml": "^3.2.3", 26 | "rimraf": "^2.4.2", 27 | "yeoman-generator": "^0.18.0", 28 | "yosay": "^0.3.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/templates/demo/ts/Animal.ts: -------------------------------------------------------------------------------- 1 | class Animal { 2 | constructor(public name: string) { } 3 | move(meters: number) { 4 | alert(this.name + " moved " + meters + "m."); 5 | } 6 | } 7 | 8 | class Snake extends Animal { 9 | constructor(name: string) { super(name); } 10 | move() { 11 | alert("Slithering..."); 12 | super.move(5); 13 | } 14 | } 15 | 16 | class Horse extends Animal { 17 | constructor(name: string) { super(name); } 18 | move() { 19 | alert("Galloping..."); 20 | super.move(45); 21 | } 22 | } 23 | 24 | var sam = new Snake("Sammy the Python"); 25 | var tom: Animal = new Horse("Tommy the Palomino"); 26 | 27 | sam.move(); 28 | tom.move(34); 29 | tom.move(50); 30 | tom.move(700); 31 | tom.move(7); 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Laurent Brunet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /app/templates/_brunch-config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.config = { 4 | paths: { 5 | 'public': 'web', 6 | 'watched': ['app/Resources'] 7 | }, 8 | files: { 9 | javascripts: { 10 | joinTo: { 11 | 'js/app.js': /^app/, 12 | 'js/vendor.js': /^(?!app)/, 13 | } 14 | }, 15 | stylesheets: { 16 | joinTo: 'css/style.css' 17 | } 18 | }, 19 | conventions: { 20 | ignored: [ 21 | /\/_/, // File beginning by "_" like _settings.scss 22 | // Brunch does include all Bower components by default, we blacklist unneeded ones. 23 | //'bower_components/foundation/' 24 | ], 25 | assets: /^app\/Resources\/assets/ 26 | }, 27 | plugins: { 28 | <% if (babelBrunch) { %> 29 | babel: { 30 | pattern: /\.(js|jsx)$/ 31 | },<% } %><% if (sassBrunch) { %> 32 | sass: { 33 | allowCache: true 34 | },<% } %><% if (uglifyJsBrunch) { %> 35 | uglify: { 36 | mangle: true, 37 | compress: { 38 | global_defs: { 39 | DEBUG: false 40 | } 41 | } 42 | },<% } %><% if (typescriptBrunch) { %> 43 | Typescript: { 44 | tscArgs: '--module commonjs' 45 | },<% } %> 46 | cleancss: { 47 | keepSpecialComments: 0, 48 | removeEmpty: true 49 | } 50 | } 51 | }; -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"], 3 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], 4 | "requireSpacesInFunctionExpression": { 5 | "beforeOpeningCurlyBrace": true 6 | }, 7 | "disallowMultipleVarDecl": true, 8 | "disallowSpacesInsideArrayBrackets": true, 9 | "disallowSpacesInsideParentheses": true, 10 | "disallowSpaceAfterObjectKeys": true, 11 | "disallowQuotedKeysInObjects": true, 12 | "requireSpaceBeforeBinaryOperators": ["?", "+", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 13 | "disallowSpaceAfterBinaryOperators": ["!"], 14 | "requireSpaceAfterBinaryOperators": ["?", ",", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 15 | "disallowSpaceBeforeBinaryOperators": [","], 16 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 17 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 18 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 19 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 20 | "disallowImplicitTypeConversion": ["numeric", "binary", "string"], 21 | "disallowKeywords": ["with", "eval"], 22 | "disallowMultipleLineBreaks": true, 23 | "disallowKeywordsOnNewLine": ["else"], 24 | "requireLineFeedAtFileEnd": true, 25 | "excludeFiles": ["node_modules/**"], 26 | "validateIndentation": 2 27 | } 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## 1.0.0 - 2015-08-06 6 | 7 | ### Changed 8 | - Bootstrap's installation improved 9 | - Assetic's deletion improved 10 | - Brand new method to fetch Symfony's versions 11 | - Now detects if `composer` and `bower`are already installed on the system 12 | - `Gruntfile.js` and `Gulpfile.js` updated 13 | - `bower.json` updated 14 | - Npm modules updated 15 | 16 | ### Removed 17 | - Module `grunt-sass` removed 18 | - Module `load-grunt-tasks` removed 19 | - Module `gulp-load-plugins` removed 20 | - Bundle `DoctrineMongoDBBundle` removed 21 | - File `.bowerrc` removed - All files installed with bower will be stored in the default `bower_component` directory. 22 | 23 | 24 | ### Added 25 | 26 | Grunt 27 | - Module `grunt-less` added 28 | - Module `grunt-babel` added 29 | - Module `grunt-contrib-watch` added 30 | 31 | Gulp 32 | - Module `gulp-less` added 33 | - Module `gulp-babel` added 34 | - Module `gulp-typescript` added 35 | - Module `gulp-coffee` added 36 | - Module `gulp-watch` added 37 | 38 | Brunch 39 | - Configuration file `brunch-config.js` added 40 | - Choice `Brunch` added in the tools list 41 | - Module `less-brunch` added 42 | - Module `sass-brunch` added 43 | - Module `stylus-brunch` added 44 | - Module `coffee-brunch` added 45 | - Module `typescript-brunch` added 46 | - Module `uglify-js-brunch` added 47 | - Module `babel-brunch` added 48 | 49 | NPM 50 | - Module `fs-extra` added 51 | 52 | - Demo added 53 | - files `scss` 54 | - files `less` 55 | - files `stylus` 56 | - files `Typescript` 57 | - files `Coffee` 58 | - files `Js (export)` 59 | - files `Js (Class ES6)` 60 | -------------------------------------------------------------------------------- /app/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.0.1", 4 | "author": "Laurent Brunet ", 5 | "private": true, 6 | "repository": { 7 | "type": "git", 8 | "url": "" 9 | }<% if (toolsExtension === 'grunt') { %>, 10 | "dependencies": { 11 | <% if (gruntcompass || gruntLess || gruntBabel) { %>"grunt-contrib-watch": "^0.6.1",<% } %> 12 | <% if (gruntcoffee) { %>"grunt-contrib-coffee": "^0.13.0",<% } %> 13 | <% if (gruntcoffee || gruntTypescript || gruntBabel) { %>"grunt-contrib-uglify": "^0.9.1",<% } %> 14 | <% if (gruntcoffee || gruntTypescript || gruntBabel) { %>"grunt-contrib-concat": "^0.5.1",<% } %> 15 | <% if (gruntTypescript) { %>"grunt-typescript": "^0.6.2",<% } %> 16 | <% if (gruntcompass) { %>"grunt-contrib-compass": "^1.0.3",<% } %> 17 | <% if (gruntLess) { %>"grunt-contrib-less": "^1.0.1",<% } %> 18 | <% if (gruntBabel) { %>"grunt-babel": "^5.0.1",<% } %> 19 | "grunt-cli": "^0.1.13", 20 | "grunt": "^0.4.5" 21 | }<% } %><% if (toolsExtension === 'gulp') { %>, 22 | "dependencies": { 23 | <% if (gulpRubySass) { %>"gulp-ruby-sass": "^1.0.5",<% } %> 24 | <% if (gulpRubySass || gulpConcat) { %>"gulp-sourcemaps": "^1.5.2",<% } %> 25 | <% if (gulpRubySass || gulpConcat) { %>"gulp-rename": "^1.2.2",<% } %> 26 | <% if (gulpRubySass) { %>"gulp-watch": "^4.2.4",<% } %> 27 | <% if (gulpRubySass || gulpLess) { %>"gulp-minify-css": "^1.1.6",<% } %> 28 | <% if (gulpConcat || gulpBabel || gulpCoffee || gulpTypescript) { %>"gulp-concat": "^2.6.0",<% } %> 29 | <% if (gulpConcat || gulpBabel || gulpCoffee || gulpTypescript) { %>"gulp-uglify": "^1.2.0",<% } %> 30 | <% if (gulpLess) { %>"gulp-less": "^3.0.3",<% } %> 31 | <% if (gulpBabel) { %>"gulp-babel": "^5.1.0",<% } %> 32 | <% if (gulpCoffee) { %>"gulp-coffee": "^2.3.1",<% } %> 33 | <% if (gulpTypescript) { %>"gulp-typescript": "^2.7.8",<% } %> 34 | "gulp-util": "^3.0.6", 35 | "gulp": "^3.9.0" 36 | }<% } %><% if (toolsExtension === 'brunch') { %>, 37 | "dependencies": { 38 | <% if (lessBrunch) { %>"less-brunch": "^1.8.1",<% } %> 39 | <% if (sassBrunch) { %>"sass-brunch": "^1.8.10",<% } %> 40 | <% if (stylusBrunch) { %>"stylus-brunch": "^1.8.1",<% } %> 41 | <% if (coffeeScriptBrunch) { %>"coffee-script-brunch": "^1.8.2",<% } %> 42 | <% if (typescriptBrunch) { %>"typescript-brunch": "^0.8.1",<% } %> 43 | <% if (uglifyJsBrunch) { %>"uglify-js-brunch": "^1.7.8",<% } %> 44 | <% if (babelBrunch) { %>"babel-brunch": "^5.1.2",<% } %> 45 | "javascript-brunch": "^1.7.1", 46 | "clean-css-brunch": "^1.7.2", 47 | "brunch": "^1.8.3" 48 | }<% } %> 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JoliSymfony - Symfony2 2 | ===================== 3 | [![NPM Version](https://img.shields.io/npm/v/generator-joli-symfony.svg?style=flat-square)](https://www.npmjs.com/package/generator-joli-symfony) 4 | [![Download Month](https://img.shields.io/npm/dm/generator-joli-symfony.svg?style=flat-square)](https://www.npmjs.com/package/generator-joli-symfony) 5 | 6 | # /!\ This project is no longer maintained, use at your own risks 7 | 8 | generator-joli-symfony is a [Yeoman Generator](http://yeoman.io/generators/) to scaffold Symfony2 projects with sensible defaults, common bundles and frontend tools. 9 | 10 | It will create a new Symfony project, remove Assetic and replace it with either Gulp, Grunt or Brunch. 11 | 12 | ### Demo 13 | 14 | ![](http://i.imgur.com/qPMgBMv.gif) 15 | 16 | ## Dependencies 17 | 18 | Mandatory dependencies : 19 | 20 | - [npm](http://nodejs.org/) 21 | - [yo](http://yeoman.io/) 22 | - [gulp](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md#getting-started) 23 | - [grunt](http://gruntjs.com/getting-started) 24 | - [brunch](http://brunch.io/) 25 | 26 | Optional dependencies : 27 | 28 | - [gem](https://www.ruby-lang.org/en/downloads/) 29 | - [compass](http://compass-style.org/install/) 30 | 31 | 32 | ## What you can choose 33 | 34 | * Symfony 2 Standard Edition: 35 | * The list of versions of symfony is available [here](https://symfony.com/versions.json) 36 | * Grunt: 37 | * [grunt-compass](https://github.com/gruntjs/grunt-contrib-compass) 38 | * [grunt-less](https://github.com/gruntjs/grunt-contrib-less) 39 | * [grunt-babel](https://github.com/babel/grunt-babel) 40 | * [grunt-coffee](https://github.com/gruntjs/grunt-contrib-coffee) 41 | * [grunt-typescript](https://github.com/k-maru/grunt-typescript) 42 | * Gulp: 43 | * [gulp-ruby-sass](https://github.com/sindresorhus/gulp-ruby-sass) 44 | * gulp-copy 45 | * gulp-javascript 46 | * [gulp-less](https://github.com/plus3network/gulp-less) 47 | * [gulp-babel](https://github.com/babel/gulp-babel) 48 | * [gulp-typescript](https://github.com/ivogabe/gulp-typescript) 49 | * [gulp-coffee](https://github.com/wearefractal/gulp-coffee) 50 | * Brunch: 51 | * [less-brunch](https://github.com/brunch/less-brunch) 52 | * [sass-brunch](https://github.com/brunch/sass-brunch) 53 | * [stylus-brunch](https://github.com/brunch/stylus-brunch) 54 | * [coffee-script-brunch](https://github.com/brunch/coffee-script-brunch) 55 | * [typescript-brunch](https://github.com/joshheyse/typescript-brunch) 56 | * [uglify-js-brunch](https://github.com/brunch/uglify-js-brunch) 57 | * [babel-brunch](https://github.com/babel/babel-brunch) 58 | * Bootstrap-sass-official 59 | 60 | ## Default workflow 61 | 62 | * Installs Symfony 63 | * Removes Assetic for versions lower than 2.8 64 | * Only if using grunt-less or grunt-babel or grunt-compass: **(grunt-contrib-watch)** 65 | * Only if using grunt-typescript or grunt-coffee or grunt-babel : **(grunt-uglify)** 66 | * Only if using gulp-ruby-sass **(gulp-watch)** 67 | * Only if using gulp-ruby-sass or gulp-javascript **(gulp-rename, gulp-sourcemaps)** 68 | * Only if using gulp-ruby-sass or gulp-less **(gulp-minify-css)** 69 | * Only if using gulp-javascript or gulp-coffee or gulp-typescript or gulp-babel **(gulp-uglify, gulp-concat)** 70 | * Starts the automatic execution of `bower` and `npm` after scaffolding has finished. 71 | 72 | ## Assets location 73 | 74 | Assets are stored in the **app/Resources/** folder : 75 | 76 | * app/Resources/scss 77 | * app/Resources/fonts 78 | * app/Resources/... 79 | 80 | ## Getting Started 81 | 82 | - Install: `npm install -g yo` 83 | - Install: `npm install -g generator-joli-symfony` 84 | - Run: `yo joli-symfony --force` 85 | 86 | ## Contribute 87 | 88 | `generator-joli-symfony` is fork-friendly : you can maintain a custom version, in which you `npm install && npm link` so that you can still use it with `yo joli-symfony`, or with the name of your choice. 89 | -------------------------------------------------------------------------------- /app/templates/_Gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | <% if (gulpRubySass) { %>var sass = require('gulp-ruby-sass');<% } %> 3 | <% if (gulpRubySass || gulpLess) { %> 4 | var sourcemaps = require('gulp-sourcemaps'); 5 | var minifyCss = require('gulp-minify-css'); 6 | var watch = require('gulp-watch');<% } %> 7 | <% if (gulpRubySass || gulpConcat || gulpLess) { %> 8 | var rename = require('gulp-rename');<% } %> 9 | <% if (gulpConcat || gulpBabel || gulpCoffee || gulpTypescript) { %> 10 | var concat = require('gulp-concat'); 11 | var uglify = require('gulp-uglify');<% } %> 12 | <% if (gulpTypescript) { %>var ts = require('gulp-typescript');<% } %> 13 | <% if (gulpCoffee) { %>var coffee = require('gulp-coffee');<% } %> 14 | <% if (gulpLess) { %>var less = require('gulp-less');<% } %> 15 | <% if (gulpBabel) { %>var babel = require('gulp-babel');<% } %> 16 | var gutil = require('gulp-util'); 17 | 18 | var path = { 19 | app: 'app/Resources', 20 | bower_components: './bower_components' 21 | }; 22 | 23 | <% if (gulpCopy) { %> 24 | gulp.task('copy', function() { 25 | gulp.src(path.app + '/assets/fonts/*.{ttf,woff,eof,svg,eot}') 26 | .pipe(gulp.dest('web/fonts/')); 27 | });<% } %> 28 | 29 | <% if (gulpRubySass) { %> 30 | /** 31 | * gulp-ruby-sass 32 | * @see https://www.npmjs.com/package/gulp-ruby-sass 33 | * 34 | * Compile Sass to CSS using Compass. 35 | */ 36 | gulp.task('sass', function() { 37 | 38 | return sass(path.app + '/scss', { compass: true, style: 'compressed', sourcemap: true }) 39 | .on('error', function (err) { 40 | console.error('Error!', err.message); 41 | }) 42 | .pipe(minifyCss({keepSpecialComments:0})) 43 | .pipe(sourcemaps.write()) 44 | .pipe(rename({suffix: '.min'})) 45 | .pipe(gulp.dest('web/css/')); 46 | });<% } %> 47 | 48 | <% if (gulpConcat) { %> 49 | /** 50 | * gulp-concat && gulp-uglify 51 | * @see https://www.npmjs.com/package/gulp-concat 52 | * @see https://www.npmjs.com/package/gulp-uglify 53 | * 54 | * Compile and minify js vendor (bower_components). 55 | */ 56 | gulp.task('vendor', function() { 57 | gulp.src([ 58 | './bower_components/jquery/dist/jquery.js', 59 | './bower_components/bootstrap/assets/javascripts/bootstrap.js' 60 | ]) 61 | .pipe(concat('vendor.js')) 62 | .pipe(uglify({mangle: true})) 63 | .pipe(rename({suffix: '.min'})) 64 | .pipe(gulp.dest('web/js/')); 65 | }); 66 | 67 | /** 68 | * gulp-concat && gulp-uglify 69 | * @see https://www.npmjs.com/package/gulp-concat 70 | * @see https://www.npmjs.com/package/gulp-uglify 71 | * 72 | * Compile and minify js App (app/Resources/js). 73 | */ 74 | gulp.task('app', function() { 75 | return gulp.src(path.app + '/js/**/*.js') 76 | .pipe(sourcemaps.init()) 77 | .pipe(concat('app.js')) 78 | .pipe(uglify({mangle: true}).on('error', gutil.log)) 79 | .pipe(rename({suffix: '.min'})) 80 | .pipe(sourcemaps.write()) 81 | .pipe(gulp.dest('web/js/')); 82 | });<% } %> 83 | 84 | <% if (gulpLess) { %> 85 | /** 86 | * gulp-less 87 | * @see https://www.npmjs.com/package/gulp-less 88 | * 89 | * Compile Less to CSS. 90 | */ 91 | gulp.task('less', function() { 92 | gulp.src(path.app + '/less/main.less') 93 | .pipe(sourcemaps.init()) 94 | .pipe(less()) 95 | .pipe(minifyCss({keepSpecialComments:0})) 96 | .pipe(sourcemaps.write()) 97 | .pipe(rename({suffix: '.min'})) 98 | .pipe(gulp.dest('web/css/')); 99 | });<% } %> 100 | 101 | <% if (gulpCoffee) { %> 102 | /** 103 | * gulp-coffee 104 | * @see https://www.npmjs.com/package/gulp-coffee 105 | * 106 | * Compile CoffeeScript files to Javascript. 107 | */ 108 | gulp.task('coffee', function() { 109 | gulp.src(path.app + '/js/*.coffee') 110 | .pipe(sourcemaps.init()) 111 | .pipe(coffee({ bare: true })).on('error', gutil.log) 112 | .pipe(concat('coffee.js')) 113 | .pipe(uglify({mangle: true}).on('error', gutil.log)) 114 | .pipe(rename({suffix: '.min'})) 115 | .pipe(sourcemaps.write()) 116 | .pipe(gulp.dest('web/js/')); 117 | });<% } %> 118 | 119 | <% if (gulpTypescript) { %> 120 | /** 121 | * gulp-typescript 122 | * @see https://www.npmjs.com/package/gulp-typescript 123 | * 124 | * Compile Typescript files to Javascript. 125 | */ 126 | gulp.task('ts', function() { 127 | var tsResult = gulp.src(path.app + '/js/*.ts') 128 | .pipe(sourcemaps.init()) 129 | .pipe(ts({ 130 | sortOutput: true, 131 | target: 'ES6', // 'ES3' (default), 'ES5' or 'ES6'. 132 | module: 'commonjs' //'commonjs' or 'amd'. 133 | })); 134 | 135 | return tsResult.js 136 | .pipe(concat('typescript.js')) 137 | .pipe(uglify({mangle: true}).on('error', gutil.log)) 138 | .pipe(rename({suffix: '.min'})) 139 | .pipe(sourcemaps.write()) 140 | .pipe(gulp.dest('web/js/')); 141 | });<% } %> 142 | 143 | <% if (gulpBabel) { %> 144 | /** 145 | * gulp-babel 146 | * @see https://www.npmjs.com/package/gulp-babel 147 | * 148 | * Turn ES6 code into vanilla ES5 with no runtime required 149 | */ 150 | gulp.task('babel', function () { 151 | return gulp.src(path.app + '/js/**/*.js') 152 | .pipe(sourcemaps.init()) 153 | .pipe(babel()) 154 | .pipe(concat('babel.js')) 155 | .pipe(uglify({mangle: true}).on('error', gutil.log)) 156 | .pipe(rename({suffix: '.min'})) 157 | .pipe(sourcemaps.write('.')) 158 | .pipe(gulp.dest('web/js/')); 159 | });<% } %> 160 | 161 | gulp.task('default', [ 162 | <% if (gulpCopy) { %>'copy',<% } %> 163 | <% if (gulpConcat) { %>'vendor',<% } %> 164 | <% if (gulpConcat) { %>'app',<% } %> 165 | <% if (gulpBabel) { %>'babel',<% } %> 166 | <% if (gulpCoffee) { %>'coffee',<% } %> 167 | <% if (gulpTypescript) { %>'ts',<% } %> 168 | <% if (gulpLess) { %>'less',<% } %> 169 | <% if (gulpRubySass) { %>'sass'<% } %> 170 | ]); 171 | -------------------------------------------------------------------------------- /app/templates/_Gruntfile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function (grunt) { 4 | <% if (gruntcompass) { %> 5 | grunt.loadNpmTasks('grunt-contrib-compass');<% } %> 6 | <% if (gruntLess || gruntcompass || gruntBabel) { %> 7 | grunt.loadNpmTasks('grunt-contrib-watch');<% } %> 8 | <% if (gruntTypescript || gruntcoffee || gruntBabel) { %> 9 | grunt.loadNpmTasks('grunt-contrib-concat'); 10 | grunt.loadNpmTasks('grunt-contrib-uglify');<% } %> 11 | <% if (gruntTypescript) { %> 12 | grunt.loadNpmTasks('grunt-typescript');<% } %> 13 | <% if (gruntcoffee) { %> 14 | grunt.loadNpmTasks('grunt-contrib-coffee');<% } %> 15 | <% if (gruntLess) { %> 16 | grunt.loadNpmTasks('grunt-contrib-less');<% } %> 17 | <% if (gruntLess || gruntcompass || gruntcoffee || gruntBabel) { %> 18 | grunt.loadNpmTasks('grunt-contrib-watch');<% } %> 19 | <% if (gruntBabel) { %> 20 | grunt.loadNpmTasks('grunt-babel');<% } %> 21 | 22 | var path = { 23 | app: 'app/Resources', 24 | assets: 'app/Resources/assets', 25 | build: 'build', 26 | bower_components: './bower_components' 27 | }; 28 | 29 | var libSources = [ 30 | //path.bower_components + '/react/react.js', 31 | ]; 32 | 33 | var sources = [ 34 | path.build + '/js/*.js' 35 | ]; 36 | 37 | grunt.initConfig({ 38 | <% if (gruntcompass) { %> 39 | /** 40 | * grunt-contrib-compass 41 | * @see https://github.com/gruntjs/grunt-contrib-compass 42 | * 43 | * Compile Sass to CSS using Compass. 44 | */ 45 | compass: { 46 | sass: { 47 | options: { 48 | sourcemap: true, 49 | sassDir: path.app + '/scss', 50 | cssDir: 'web/css', 51 | //importPath: path.bower_components, // Uncomment this line if the folder is present bower_components 52 | imagesDir: 'images', 53 | imagesPath: path.assets, 54 | generatedImagesDir: 'web/images', 55 | outputStyle: 'compressed', 56 | noLineComments: true 57 | } 58 | } 59 | },<% } %> 60 | <% if (gruntTypescript) { %> 61 | /** 62 | * grunt-typescript 63 | * @see https://www.npmjs.com/package/grunt-typescript 64 | * 65 | * Run predefined tasks whenever watched file patterns are added, changed or deleted. 66 | */ 67 | typescript: { 68 | base: { 69 | src: [path.app + '/js/**/*.ts'], 70 | dest: 'build/js/app.js', 71 | options: { 72 | module: 'commonjs', //amd or commonjs 73 | target: 'es5', //or es3 74 | sourceMap: true, 75 | declaration: true 76 | //watch: true //Detect all target files root. eg: 'path/to/typescript/files/' 77 | } 78 | } 79 | },<% } %> 80 | <% if (gruntcoffee) { %> 81 | /** 82 | * grunt-coffee 83 | * @see https://www.npmjs.com/package/grunt-coffee 84 | * 85 | * JavaScripts your Coffee 86 | */ 87 | coffee: { 88 | compileBare: { 89 | options: { 90 | sourceMap: true, 91 | bare: true, 92 | join: true 93 | }, 94 | files: { 95 | 'build/js/app.js': [ 96 | path.app + '/js/app.coffee' 97 | ] 98 | } 99 | } 100 | },<% } %> 101 | <% if (gruntcoffee || gruntTypescript || gruntBabel) { %> 102 | /** 103 | * grunt-contrib-uglify 104 | * @see https://github.com/gruntjs/grunt-contrib-uglify 105 | * 106 | */ 107 | uglify: { 108 | options: { 109 | mangle: false, 110 | sourceMap : true, 111 | sourceMapIncludeSources : true 112 | }, 113 | all: { 114 | files: { 115 | 'web/js/vendor.min.js': ['build/js/vendor.js'], 116 | 'web/js/app.min.js': ['build/js/app.js'], 117 | } 118 | } 119 | }, 120 | 121 | concat: { 122 | options: { 123 | sourceMap: true 124 | }, 125 | dist: { 126 | files: [{ 127 | src: libSources, 128 | dest: path.build + '/js/vendor.js' 129 | }, { 130 | src: sources, 131 | dest: path.build + '/js/app.js' 132 | }] 133 | } 134 | },<% } %> 135 | <% if (gruntLess) { %> 136 | /** 137 | * grunt-contrib-less 138 | * @see https://github.com/gruntjs/grunt-contrib-less 139 | * 140 | * Compile Less to CSS. 141 | */ 142 | less: { 143 | development: { 144 | options: { 145 | compress: true, 146 | yuicompress: true, 147 | optimization: 2, 148 | sourceMap: true 149 | }, 150 | files: { 151 | 'web/css/less.min.css': path.app + '/less/main.less' 152 | } 153 | } 154 | },<% } %> 155 | <% if (gruntBabel) { %> 156 | /** 157 | * grunt-babel 158 | * @see https://github.com/gruntjs/grunt-babel 159 | * 160 | * Turn ES6 code into vanilla ES5 with no runtime required 161 | */ 162 | babel: { 163 | options: { 164 | sourceMap: true 165 | }, 166 | dist: { 167 | files: [{ 168 | cwd: path.app + '/js', 169 | src: '*.js', 170 | dest: 'build/js', 171 | expand: true 172 | }] 173 | } 174 | },<% } %> 175 | <% if (gruntLess || gruntcompass || gruntBabel) { %> 176 | /** 177 | * grunt-watch 178 | * @see https://github.com/gruntjs/grunt-watch 179 | * 180 | */ 181 | watch: {<% if (gruntcompass) { %> 182 | scss: { 183 | files: [path.app + '/scss/**/*.scss'], 184 | tasks: ['css'] 185 | },<% } %><% if (gruntBabel) { %> 186 | js: { 187 | files: [path.app + '/js/**/*.js'], 188 | tasks: ['js'] 189 | },<% } %><% if (gruntLess) { %> 190 | less: { 191 | files: [path.app + '/less/**/*.less'], 192 | tasks: ['less'] 193 | }<% } %> 194 | }<% } %> 195 | }); 196 | 197 | /**************************************************************** 198 | * Grunt Task Definitions 199 | ****************************************************************/ 200 | grunt.registerTask('default', [<% if (gruntcoffee || gruntTypescript || gruntBabel) { %>'js',<% } %> <% if (gruntcompass || gruntLess) { %>'css'<% } %>]); 201 | <% if (gruntcoffee || gruntTypescript || gruntBabel) { %>grunt.registerTask('js', [<% if (gruntBabel) { %>'babel',<% } %> <% if (gruntTypescript) { %>'typescript',<% } %><% if (gruntcoffee) { %>'coffee',<% } %> 'concat', 'uglify']);<% } %> 202 | grunt.registerTask('css', [<% if (gruntcompass) { %>'compass',<% } %><% if (gruntLess) { %>'less',<% } %>]); 203 | }; 204 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var yeoman = require('yeoman-generator'); 4 | var chalk = require('chalk'); 5 | var path = require('path'); 6 | var yaml = require('js-yaml'); 7 | var fs = require('fs-extra'); 8 | var rmdir = require('rimraf'); 9 | var child_process = require('child_process'); 10 | var request = require('request'); 11 | var _ = require('lodash'); 12 | var Download = require('download'); 13 | 14 | module.exports = yeoman.generators.Base.extend({ 15 | initializing: function () { 16 | this.pkg = require('../package.json'); 17 | var Jolicode = '\n ' + chalk.yellow('##') + ' ## ## ## ####### ## ' + chalk.yellow('##') + ' ' + chalk.yellow('##') + ' \n ' + chalk.yellow('##') + ' ## ## ## ## ## ' + chalk.yellow('##') + ' ' + chalk.yellow('##') + ' \n ' + chalk.yellow('##') + ' ## ###### ## ## ## ###### ####### ###### ' + chalk.yellow('##') + ' ' + chalk.yellow('##') + ' \n ' + chalk.yellow('##') + ' ## ## ## ## ## ## ## ## ## ## ######## ' + chalk.yellow('##') + ' ' + chalk.yellow('##') + ' \n ' + chalk.yellow('##') + ' ## ### ## ## ## ## ## ## ## ## ## ## ## ' + chalk.yellow('##') + ' ' + chalk.yellow('##') + ' \n ' + chalk.yellow('##') + ' ##### ###### ## ## ####### ###### ####### ###### ' + chalk.yellow('##') + ' ' + chalk.yellow('##'); 18 | var JolicodeDesc = '\n\n A Yeoman generator for the Symfony2 framework\n\n Created by ' + chalk.yellow('@JoliCode ') + ' & ' + chalk.blue('@lbrunet_com') + '\n ' + chalk.cyan('http://jolicode.com/') + '\n'; 19 | this.log(Jolicode); 20 | this.log(JolicodeDesc); 21 | }, 22 | 23 | askSymfonyStandard: function () { 24 | var done = this.async(); 25 | 26 | this.SymfonyStandardDistribution = { 27 | host: 'https://symfony.com/download?v=Symfony_Standard_Vendors_', 28 | commit: 'lts', 29 | ext: 'zip' 30 | }; 31 | 32 | var prompts = [{ 33 | type: 'confirm', 34 | name: 'symfonyStandard', 35 | message: 'Would you like to use the Symfony "Standard Edition" distribution ' + this.SymfonyStandardDistribution.commit, 36 | default: true 37 | }]; 38 | 39 | this.prompt(prompts, function (answers) { 40 | if (answers.symfonyStandard) { 41 | this.symfonyDistribution = this.SymfonyStandardDistribution; 42 | } else { 43 | this.symfonyDistribution = null; 44 | } 45 | done(); 46 | }.bind(this)); 47 | }, 48 | 49 | getTagSymfony: function () { 50 | var done = this.async(); 51 | var invalidEntries = 0; 52 | 53 | function filterByTag(obj) { 54 | if ('installable' === obj || 'non_installable' === obj) { 55 | invalidEntries++; 56 | return false; 57 | } else { 58 | return true; 59 | } 60 | } 61 | 62 | request('https://symfony.com/versions.json', function (error, response, body) { 63 | if (!error && response.statusCode === 200) { 64 | this.parsed = JSON.parse(body); 65 | var filtered = Object.keys(this.parsed); 66 | this.versionSf2 = filtered.filter(filterByTag); 67 | done(); 68 | } else { 69 | console.log(chalk.red('A problem occurred'), error); 70 | } 71 | }.bind(this)); 72 | }, 73 | 74 | askSymfonyCustom: function () { 75 | if (this.symfonyDistribution === null) { 76 | var done = this.async(); 77 | console.log('Please provide GitHub details of the Symfony distribution you would like to use.'); 78 | 79 | var prompts = [{ 80 | type: 'list', 81 | name: 'symfonyCommit', 82 | message: 'Commit (commit/branch/tag)', 83 | default: 'lts', 84 | choices: this.versionSf2 85 | }]; 86 | 87 | this.prompt(prompts, function (answers) { 88 | this.symfonyDistribution = { 89 | host: 'https://symfony.com/download?v=Symfony_Standard_Vendors_', 90 | commit: answers.symfonyCommit, 91 | ext: 'zip' 92 | }; 93 | 94 | done(); 95 | }.bind(this)); 96 | } 97 | }, 98 | 99 | askToolsExtension: function () { 100 | var done = this.async(); 101 | var prompts = [{ 102 | type: 'list', 103 | name: 'toolsExtension', 104 | message: 'Which tools would you like to use?', 105 | default: 'gulp', 106 | choices: ['grunt', 'gulp', 'brunch'] 107 | }]; 108 | this.prompt(prompts, function (answers) { 109 | this.toolsExtension = answers.toolsExtension; 110 | done(); 111 | }.bind(this)); 112 | }, 113 | 114 | askGruntCustom: function () { 115 | if (this.toolsExtension === 'grunt') { 116 | var done = this.async(); 117 | 118 | var prompts = [{ 119 | type: 'checkbox', 120 | name: 'gruntCustom', 121 | message: 'Customize Gruntfile', 122 | choices: [ 123 | { 124 | name: 'grunt-compass', 125 | value: 'gruntCompass', 126 | checked: true 127 | }, 128 | { 129 | name: 'grunt-less', 130 | value: 'gruntLess', 131 | checked: false 132 | }, 133 | { 134 | name: 'grunt-babel', 135 | value: 'gruntBabel', 136 | checked: true 137 | }, 138 | { 139 | name: 'grunt-coffee', 140 | value: 'gruntCoffee', 141 | checked: false 142 | }, 143 | { 144 | name: 'grunt-typescript', 145 | value: 'gruntTypescript', 146 | checked: true 147 | } 148 | ] 149 | }]; 150 | 151 | this.prompt(prompts, function (answers) { 152 | function hasFeature(feat) { 153 | return answers.gruntCustom.indexOf(feat) !== -1; 154 | } 155 | 156 | this.gruntcompass = hasFeature('gruntCompass'); 157 | this.gruntcoffee = hasFeature('gruntCoffee'); 158 | this.gruntTypescript = hasFeature('gruntTypescript'); 159 | this.gruntLess = hasFeature('gruntLess'); 160 | this.gruntBabel = hasFeature('gruntBabel'); 161 | 162 | done(); 163 | }.bind(this)); 164 | } 165 | }, 166 | 167 | askGulpCustom: function () { 168 | if (this.toolsExtension === 'gulp') { 169 | var done = this.async(); 170 | 171 | var prompts = [{ 172 | type: 'checkbox', 173 | name: 'gulpCustom', 174 | message: 'Customize Gulpfile', 175 | choices: [ 176 | { 177 | name: 'gulp-ruby-sass', 178 | value: 'gulpRubySass', 179 | checked: true 180 | }, 181 | { 182 | name: 'gulp-copy', 183 | value: 'gulpCopy', 184 | checked: false 185 | }, 186 | { 187 | name: 'gulp-javascript', 188 | value: 'gulpConcat', 189 | checked: false 190 | }, 191 | { 192 | name: 'gulp-less', 193 | value: 'gulpLess', 194 | checked: false 195 | }, 196 | { 197 | name: 'gulp-babel', 198 | value: 'gulpBabel', 199 | checked: true 200 | }, 201 | { 202 | name: 'gulp-typescript', 203 | value: 'gulpTypescript', 204 | checked: false 205 | }, 206 | { 207 | name: 'gulp-coffee', 208 | value: 'gulpCoffee', 209 | checked: false 210 | } 211 | ] 212 | }]; 213 | 214 | this.prompt(prompts, function (answers) { 215 | function hasFeature(feat) { 216 | return answers.gulpCustom.indexOf(feat) !== -1; 217 | } 218 | 219 | this.gulpRubySass = hasFeature('gulpRubySass'); 220 | this.gulpCopy = hasFeature('gulpCopy'); 221 | this.gulpConcat = hasFeature('gulpConcat'); 222 | this.gulpLess = hasFeature('gulpLess'); 223 | this.gulpBabel = hasFeature('gulpBabel'); 224 | this.gulpTypescript = hasFeature('gulpTypescript'); 225 | this.gulpCoffee = hasFeature('gulpCoffee'); 226 | 227 | done(); 228 | }.bind(this)); 229 | } 230 | }, 231 | 232 | askBrunchCustom: function () { 233 | if (this.toolsExtension === 'brunch') { 234 | var done = this.async(); 235 | 236 | var prompts = [{ 237 | type: 'checkbox', 238 | name: 'brunchCustom', 239 | message: 'Customize Brunch', 240 | choices: [ 241 | { 242 | name: 'less-brunch', 243 | value: 'lessBrunch', 244 | checked: false 245 | }, 246 | { 247 | name: 'sass-brunch', 248 | value: 'sassBrunch', 249 | checked: true 250 | }, 251 | { 252 | name: 'stylus-brunch', 253 | value: 'stylusBrunch', 254 | checked: false 255 | }, 256 | { 257 | name: 'coffee-script-brunch', 258 | value: 'coffeeScriptBrunch', 259 | checked: false 260 | }, 261 | { 262 | name: 'typescript-brunch', 263 | value: 'typescriptBrunch', 264 | checked: false 265 | }, 266 | { 267 | name: 'uglify-js-brunch', 268 | value: 'uglifyJsBrunch', 269 | checked: true 270 | }, 271 | { 272 | name: 'babel-brunch', 273 | value: 'babelBrunch', 274 | checked: true 275 | } 276 | ] 277 | }]; 278 | 279 | this.prompt(prompts, function (answers) { 280 | function hasFeature(feat) { 281 | return answers.brunchCustom.indexOf(feat) !== -1; 282 | } 283 | 284 | this.lessBrunch = hasFeature('lessBrunch'); 285 | this.sassBrunch = hasFeature('sassBrunch'); 286 | this.stylusBrunch = hasFeature('stylusBrunch'); 287 | this.coffeeScriptBrunch = hasFeature('coffeeScriptBrunch'); 288 | this.typescriptBrunch = hasFeature('typescriptBrunch'); 289 | this.uglifyJsBrunch = hasFeature('uglifyJsBrunch'); 290 | this.babelBrunch = hasFeature('babelBrunch'); 291 | 292 | done(); 293 | }.bind(this)); 294 | } 295 | }, 296 | 297 | askBootStrapSass: function () { 298 | var done = this.async(); 299 | 300 | var prompts = [{ 301 | type: 'confirm', 302 | name: 'bootStrapSass', 303 | message: 'Would you like to use "BootStrap Sass"?', 304 | default: true 305 | }]; 306 | 307 | this.prompt(prompts, function (answers) { 308 | this.bootStrapSass = answers.bootStrapSass; 309 | done(); 310 | }.bind(this)); 311 | }, 312 | 313 | _unzip: function (archive, destination, opts, cb) { 314 | if (_.isFunction(opts) && !cb) { 315 | cb = opts; 316 | opts = { extract: true }; 317 | } 318 | 319 | opts = _.assign({ extract: true }, opts); 320 | 321 | var log = this.log.write() 322 | .info('... Fetching %s ...', archive) 323 | .info(chalk.yellow('This might take a few moments')); 324 | 325 | var download = new Download(opts) 326 | .get(archive) 327 | .dest(destination) 328 | .use(function (res) { 329 | res.on('data', function () {}); 330 | }); 331 | 332 | download.run(function (err) { 333 | if (err) { 334 | return cb (err); 335 | } 336 | 337 | log.write().ok('Done in ' + destination).write(); 338 | cb(); 339 | }); 340 | }, 341 | 342 | symfonyBase: function () { 343 | var done = this.async(); 344 | var symfonyCommit = this.parsed[this.symfonyDistribution.commit]; 345 | 346 | var appPath = this.destinationRoot(); 347 | var repo = this.symfonyDistribution.host + symfonyCommit + '.' + this.symfonyDistribution.ext; 348 | 349 | this._unzip(repo, appPath, function (err, remote) { 350 | if (err) { 351 | console.log(err); 352 | return; 353 | } else { 354 | console.log(' 👍 ' + chalk.green(' Download success ! ')); 355 | done(); 356 | } 357 | }); 358 | }, 359 | 360 | moveSymfonyBase: function () { 361 | var done = this.async(); 362 | var directory = this.destinationRoot() + '/Symfony'; 363 | this.directory(directory, '.'); 364 | fs.move('./Symfony/', '.', function (err) { 365 | done(); 366 | }); 367 | }, 368 | 369 | symfonyWithAsseticInstalled: function () { 370 | var symfonyVersionAssetic = ['2.3', '2.6', '2.7']; 371 | var checkVersion = symfonyVersionAssetic.indexOf(this.symfonyDistribution.commit); 372 | this.symfonyWithAssetic = (checkVersion !== -1) ? true : false ; 373 | }, 374 | 375 | installComposer: function () { 376 | if (this.symfonyWithAssetic) { 377 | var done = this.async(); 378 | this.pathComposer = 'php ./composer.phar'; 379 | child_process.exec('php -r "readfile(\'https://getcomposer.org/installer\');" | php', function (error, stdout, stderr) { 380 | console.log(chalk.green('Installing composer locally.')); 381 | console.log('See ' + chalk.yellow('http://getcomposer.org') + ' for more details on composer.'); 382 | console.log(''); 383 | done(); 384 | }); 385 | } 386 | }, 387 | 388 | checkBower: function () { 389 | this.globalBower = false; 390 | 391 | if (this.bootStrapSass) { 392 | var done = this.async(); 393 | 394 | child_process.execFile('bower', ['-v'], function (error, stdout, stderr) { 395 | if (error !== null) { 396 | var prompts = [{ 397 | type: 'confirm', 398 | name: 'checkBower', 399 | message: chalk.red('WARNING: No global bower installation found. We will install it locally if you decide to continue. Continue ?'), 400 | default: true 401 | }]; 402 | this.prompt(prompts, function (answers) { 403 | if (answers.checkBower) { 404 | child_process.exec('npm install -g bower', function (error, stdout, stderr) { 405 | if (error !== null) { 406 | console.log('exec error: ' + error); 407 | } else { 408 | console.log(chalk.green('Installing bower locally.')); 409 | console.log('See ' + chalk.yellow('http://bower.io/') + ' for more details on bower.'); 410 | console.log(''); 411 | this.globalBower = true; 412 | done(); 413 | } 414 | }.bind(this)); 415 | } else { 416 | console.log(chalk.red('Bower did not installed locally!')); 417 | done(); 418 | } 419 | }.bind(this)); 420 | } else { 421 | this.globalBower = true; 422 | done(); 423 | } 424 | }.bind(this)); 425 | } 426 | }, 427 | 428 | writing: { 429 | removeSymfonyBase: function () { 430 | var done = this.async(); 431 | var directory = this.destinationRoot() + '/Symfony'; 432 | rmdir(directory, function (error) { 433 | if (null === error) { 434 | done(); 435 | } 436 | }); 437 | }, 438 | 439 | app: function () { 440 | if (this.toolsExtension === 'grunt') { 441 | this.template('_Gruntfile.js', 'Gruntfile.js'); 442 | } 443 | if (this.toolsExtension === 'gulp') { 444 | this.template('_Gulpfile.js', 'Gulpfile.js'); 445 | } 446 | if (this.toolsExtension === 'brunch') { 447 | this.template('_brunch-config.js', 'brunch-config.js'); 448 | } 449 | if (this.gruntcompass || this.gulpRubySass || this.sassBrunch) { 450 | this.directory('./demo/scss', 'app/Resources/scss'); 451 | } 452 | if (this.gruntLess || this.gulpLess || this.lessBrunch) { 453 | this.directory('./demo/less', 'app/Resources/less'); 454 | } 455 | if (this.stylusBrunch) { 456 | this.directory('./demo/styl', 'app/Resources/styl'); 457 | } 458 | if (this.gruntcoffee || this.gulpCoffee || this.coffeeScriptBrunch) { 459 | this.directory('./demo/coffee', 'app/Resources/js'); 460 | } 461 | if (this.gruntBabel || this.gulpBabel || this.babelBrunch) { 462 | this.directory('./demo/es6', 'app/Resources/js'); 463 | } 464 | if (this.uglifyJsBrunch || this.gulpConcat) { 465 | this.directory('./demo/js', 'app/Resources/js'); 466 | } 467 | if (this.gruntTypescript || this.gulpTypescript || this.typescriptBrunch) { 468 | this.directory('./demo/ts', 'app/Resources/js'); 469 | } 470 | this.fs.copy( 471 | this.templatePath('_gitignore'), 472 | this.destinationPath('.gitignore') 473 | ); 474 | this.template('_bower.json', 'bower.json'); 475 | this.template('_package.json', 'package.json'); 476 | }, 477 | 478 | projectfiles: function () { 479 | this.fs.copy( 480 | this.templatePath('editorconfig'), 481 | this.destinationPath('.editorconfig') 482 | ); 483 | this.fs.copy( 484 | this.templatePath('jshintrc'), 485 | this.destinationPath('.jshintrc') 486 | ); 487 | } 488 | }, 489 | 490 | install: { 491 | installComponents: function () { 492 | this.installDependencies({ 493 | bower: this.globalBower, 494 | npm: true, 495 | skipInstall: false 496 | }); 497 | } 498 | }, 499 | 500 | end: { 501 | addBootStrapSass: function () { 502 | if (this.bootStrapSass && this.globalBower) { 503 | child_process.exec('bower install bootstrap-sass-official --save', function (error, stdout, stderr) { 504 | if (error !== null) { 505 | console.log('exec error: ' + error); 506 | } else { 507 | console.log(chalk.green('[bootstrap-sass-official] installed!')); 508 | } 509 | }); 510 | } 511 | }, 512 | 513 | cleanConfig: function () { 514 | if (this.symfonyWithAssetic) { 515 | var confDev = yaml.safeLoad(fs.readFileSync('app/config/config_dev.yml')); 516 | delete confDev.assetic; 517 | var newConfDev = yaml.dump(confDev, {indent: 4}); 518 | fs.writeFileSync('app/config/config_dev.yml', newConfDev); 519 | 520 | var conf = yaml.safeLoad(fs.readFileSync('app/config/config.yml')); 521 | delete conf.assetic; 522 | var newConf = yaml.dump(conf, {indent: 4}); 523 | fs.writeFileSync('app/config/config.yml', newConf); 524 | } 525 | }, 526 | 527 | updateAppKernel: function () { 528 | if (this.symfonyWithAssetic) { 529 | var appKernelPath = 'app/AppKernel.php'; 530 | var appKernelContents = this.readFileAsString(appKernelPath); 531 | 532 | var newAppKernelContents = appKernelContents.replace('new Symfony\\Bundle\\AsseticBundle\\AsseticBundle(),', ''); 533 | fs.writeFileSync(appKernelPath, newAppKernelContents); 534 | } 535 | }, 536 | 537 | cleanComposer: function () { 538 | if (this.symfonyWithAssetic) { 539 | var removeAssetic = this.pathComposer + ' remove ' + 'symfony/assetic-bundle'; 540 | 541 | child_process.exec(removeAssetic, function (error, stdout, stderr) { 542 | if (error !== null) { 543 | console.log('exec error: ' + error); 544 | } else { 545 | console.log(chalk.green('[symfony/assetic-bundle] deleted!')); 546 | } 547 | }); 548 | } 549 | }, 550 | } 551 | }); 552 | --------------------------------------------------------------------------------