Commit ae570ca7 authored by Philipp Nowinski's avatar Philipp Nowinski
Browse files

[FEATURE] extract toolchain from website-base and add install script

parent cab284f0
# http://editorconfig.org
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
charset = utf-8
# Get rid of whitespace to avoid diffs with a bunch of EOL changes
trim_trailing_whitespace = true
# Unix-style newlines with a newline ending every file
[*]
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true
# CSS-Files
[*.css]
indent_style = tab
indent_size = 4
# HTML-Files
[*.html]
indent_style = tab
indent_size = 4
# TMPL-Files
[*.tmpl]
indent_style = tab
indent_size = 4
# LESS-Files
[*.less]
indent_style = tab
indent_size = 4
# JS-Files
[*.js]
indent_style = tab
indent_size = 4
# JSON-Files
[*.json]
indent_style = tab
indent_size = 4
# PHP-Files
[*.php]
indent_style = tab
indent_size = 4
# ReST-Files
[*.rst]
indent_style = space
indent_size = 3
# MD-Files
[*.md]
trim_trailing_whitespace = false
indent_style = space
indent_size = 4
# package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
# TypoScript
[*.ts]
indent_style = tab
indent_size = 4
# XLF-Files
[*.xlf]
indent_style = tab
indent_size = 4
# SQL-Files
[*.sql]
indent_style = tab
indent_size = 2
node_modules/
coverage
.idea
*.iml
node_modules
......@@ -58,5 +58,6 @@
"validthis": false,
"worker": false,
"wsh": false,
"yui": false
"yui": false,
"predef": ["-console"]
}
language: node_js
node_js:
- '0.10'
before_install:
- currentfolder=${PWD##*/}
- if [ "$currentfolder" != 'generator-sgalinski' ]; then cd .. && eval "mv $currentfolder generator-sgalinski" && cd generator-sgalinski; fi
{}
\ No newline at end of file
[![sgalinski Internet Services](http://www.sgalinski.de/_Resources/Static/Packages/SGalinski.SgalinskiDe/Images/logo.png "sgalinski Internet Services")](http://www.sgalinski.de/)
# generator-gulp-sgalinski
> [Yeoman](http://yeoman.io) generator
> **Note: major changes with version 3.0.0**
> If you have used previous versions of this generator, there are some things to notice:
> The asset-paths.json files are no longer needed. The generator now follows a convention over configuration approach
> and assumes, that your extensions follow the same directory structure. Also, the standalone mode has been removed.
> The whole purpose of this generator is now to scaffold a frontend build process for TYPO3 projects with Extbase Extensions.
## Installation
* [Install Node](docs/INSTALL-NODE.md)
To use the sgalinski-generator you need to have node and npm installed. Furthermore, you should have
yeoman, gulp and bower installed globally. To do so, simply run
```bash
npm install -g yo
npm install -g gulp
```
Finally, to install the generator, run
```bash
npm install -g generator-gulp-sgalinski
```
## Usage
To run the generator, navigate to the directory you want to create your project in and run
```bash
yo gulp-sgalinski
```
## Updating
If you want to update the Toolchain for an existing project, simply run the generator again inside your projects root.
The generator will ask you before overwriting existing files. Keep an eye on the release notes to see if there are
any breaking changes.
Starting with v3.2.1, the generator will add an entry to the package.json that will provide you with the version number
of the generator your projects setup has been generated with.
### Further documentation
* [Sprite engine](docs/SPRITE-ENGINE.md)
* [Inline SVG](docs/INLINE-SVG.md)
#### TYPO3 projects
The purpose of this generator is to scaffold a frontend build process for TYPO3 projects with Extbase Extensions. This
assumes, that your code is organized in extension folders under typo3conf/ext and that all extensions follow the same
directory structure. The generator will ask you for the paths to the asset files relative to the extensions folder.
##### Running a specific task
If you just want to run a specific task for a specific extension, run
```bash
gulp [taskname] --ext [extensionname]
```
E.g. if you want to run the CSS task for an extension called 'acme_base', run
```bash
gulp css --ext acme_base
```
You must specify the extension name here, to tell gulp which SASS files you want to compile.
##### Watching the whole project
By running
```bash
gulp
```
you will get a development environment with BrowserSync and some watchers that will automatically trigger tasks when you change sourcefiles. If you are not familliar with [BrowserSync](http://www.browsersync.io/), you should definitely check it out.
BrowserSync will basically start up a server and provide you with a URL which points to your project. BrowserSync will be set up with a proxy that tunnels request to your development URL. You can change this URL inside gulp/browser-sync.js. BrowserSync will also disable the TYPO3 cache and the ([scriptmerger extension](http://typo3.org/extensions/repository/view/scriptmerger)) for every request, by setting query string parameters. Apart from the livereload functionallity, BrowserSync offers some other cool features like syncing Mouse- and Keyboardevents. Since version 2.0.0, there is also a UI with a lot more to discover. You should read about this on the BrowserSync website.
Once the default tasks started and BrowserSync is ready to serve your files, all changes you make to you CSS and JavaScript files will automatically injected into the browser, without reloading the site. Gulp will automatically figure out the extension you made changes to and pass the information to the corresponding task.
#### Available gulp tasks
* default
* [command: 'gulp']
* The default task will be triggered by just calling 'gulp' without a specific task name. It will start BrowserSync and watchers for your CSS and JavaScript.
* css
* [command: 'gulp css']
* The css task will compile your sass files to css and run a bunch of additional processes on them.
* It will run the included sprite-engine ([learn how to use it](docs/SPRITE-ENGINE.md)).
* It will resolve css-width and css-height functions ([learn how to use them](https://www.npmjs.com/package/gulp-css-image-dimensions)).
* It will autoprefix your css.
* It will resolve css @import-statements to avoid additional requests.
* It will generate sourcempas for your css files.
* It will log the filesize of the generated css to the console. You can specify a limit to get warnings if this limit is exceeded.
* It will minify your css.
* javascript
* [command: 'gulp javascript']
* The javascript task runs jshint on your JS files. It also runs
[browserify](http://browserify.org/) on them and uglify the result.
* images
* [command: 'gulp images']
* The images task will optimize (lossless) all images inside you images directory. This is not part of the watch
task, so you have to start it manually.
* [command: 'gulp images-fileadmin']
* Runs the image optimization on all images inside fileadmin and uploads. You might want to run this task on a regular
basis to compress user uploaded content.
* browser-sync
* [command: 'gulp browser-sync']
* BrowserSync starts a webserver with built-in code sync and action sync. Refer to
[the BrowserSync website](http://www.browsersync.io/) to learn more about it. BrowserSync will also add query string
parameters to every request that disable the TYPO3 cache and the ([scriptmerger extension](http://typo3.org/extensions/repository/view/scriptmerger)).
#### config files
The gulp-sgalinski generator will generate the following config files:
* .editorconfig
* [Editorconfig](http://editorconfig.org/) is a great common way to synchronize editor settings across projects and
IDEs/Editors. You can simply remove it, if you don't want to use it.
* .jshintrc
* This is where you can define all rules JsHint will apply to your code. If you delete this file, JsHint will use
the standard settings. This file should also work for instances of JsHint that are built into your Editor.
* .scss-lint.yml
* A configuration file for SCSS-Linters.
* gulp/config.json
* This is where the paths to your asset files, relative to the extension folder are defined, as well as the list
of extension names you want gulp to watch for changes.
* package.json [mandatory]
* The package.json file is the manifest for every node.js module. Since gulp is written in node, you will need this
file. This is where all used node modules (e.g. every gulp task is a node module) are defined as dependencies. They
will get installed from the NPM registry when you run 'npm install' inside your project root (the generator will run
'npm install' and 'bower install' automatically for you as its last step).
#### What to check in?
There are different opinions on which files should be under version control. We recommend to put the following files
on your ignorelist (.gitignore, .svnignore, etc.):
* node_modules
* This folder can be quite heavy and its contents can differ depending on you Operating System. The recommended way
is to check in the package.json and run 'npm install' on every new checkout.
## Changelog
* 2015-07-21   v3.2.1   Update README; add toolchain version number to package.json
* 2015-07-21   v3.2.0   update to sprity; performance optim.; plugin updates; new config files
* 2015-06-04   v3.1.0   add inline-svg plugin
* 2015-05-21   v3.0.0   Remove standalone mode; get rid of asset-path.json; add check-filesize-plugin
* 2015-02-22   v2.1.0   add cache and scriptmerger deactivation via query string params
* 2015-02-15   v2.0.0   get rid of compass + update browsersync + add global watcher
* 2015-01-19   v1.1.0   major changes to the scaffolded gulp tasks + massive README
* 2015-01-13   v1.0.0   add livereload as browsersync alternative [first stable version]
* 2015-01-12   v0.1.0   release
## License
MIT
'use strict';
var yeoman = require('yeoman-generator'),
chalk = require('chalk'),
yosay = require('yosay'),
path = require('path'),
_ = require('underscore'),
_s = require('underscore.string');
module.exports = yeoman.generators.Base.extend((function() {
var Generator = {},
answers = {},
resourcePathsSuggestions = {
cssPath: path.join('Resources', 'Public', 'StyleSheets'),
sassPath: path.join('Resources', 'Public', 'Sass'),
imagesPath: path.join('Resources', 'Public', 'Images'),
javascriptPath: path.join('Resources', 'Public', 'Scripts'),
spritePath: 'Sprites',
svgPath: 'Svg'
};
Generator.initializing = function() {
Generator.pkg = require('../package.json');
};
Generator.prompting = {
basicPrompts: function() {
var done = this.async();
// Greet the user
this.log(yosay(
'Welcome to the dandy ' + chalk.red('Sgalinski') + ' generator!'
));
this.log(chalk.bold.yellow('I will help you to setup a frontend build process for ' +
'your TYPO3 project with Extbase Extensions.\n\n'));
this.prompt([
{
type: 'input',
name: 'projectName',
message: 'Please enter the name of your project',
default: process.cwd().split(path.sep).pop()
}
], function(_answers) {
answers = _.extend(answers, _answers);
done();
});
},
pathPrompts: function() {
var done = this.async(),
questions;
// define questions
questions = [
{
type: 'input',
name: 'cssPath',
message: 'Please specify the path to the compiled css files',
default: resourcePathsSuggestions.cssPath
},
{
type: 'input',
name: 'sassPath',
message: 'Please specify the path to the sass source files',
default: resourcePathsSuggestions.sassPath
},
{
type: 'input',
name: 'javascriptPath',
message: 'Please specify the path to the javascript files',
default: resourcePathsSuggestions.javascriptPath
},
{
type: 'input',
name: 'imagesPath',
message: 'Please specify the path to the images',
default: resourcePathsSuggestions.imagesPath
},
{
type: 'input',
name: 'spritePath',
message: 'Please specify the path to the sprite images (relative to images)',
default: resourcePathsSuggestions.spritePath
},
{
type: 'input',
name: 'svgPath',
message: 'Please specify the path to the svg files (relative to images)',
default: resourcePathsSuggestions.svgPath
},
{
type: 'input',
name: 'extensions',
message: 'Please enter the names of the extensions you want gulp to watch for changes, ' +
'separated by commas (project_base, ext_one, ext_two).',
default: ''
}
];
// ask questions
this.prompt(questions, function(_answers) {
var extensionArray = _answers.extensions.split(',');
_answers.extensions = '';
for (var ext in extensionArray) {
if (extensionArray.hasOwnProperty(ext)) {
if (_answers.extensions !== '') {
_answers.extensions += ',\n\t\t';
}
_answers.extensions += '"' + _s.trim(extensionArray[ext]) + '"';
}
}
answers = _.extend(answers, _answers);
done();
});
},
cssPrompts: function() {
var done = this.async();
this.prompt([
{
type: 'input',
name: 'filesizeLimitCss',
message: 'Specify a maximum size (in Bytes) for CSS files. Leave blank if you don\'t want to ' +
'specify a limit',
default: ''
},
{
type: 'input',
name: 'filesizeLimitGzippedCss',
message: 'Specify a maximum size (in Bytes) for CSS files after gzip compression. Leave blank if you don\'t want to ' +
'specify a limit',
default: ''
}
], function(_answers) {
answers = _.extend(answers, _answers);
done();
});
},
javascriptPrompts: function() {
var done = this.async();
this.prompt([
{
type: 'input',
name: 'filesizeLimitJs',
message: 'Specify a maximum size (in Bytes) for JavaScript files. Leave blank if you don\'t want to ' +
'specify a limit',
default: ''
},
{
type: 'input',
name: 'filesizeLimitGzippedJs',
message: 'Specify a maximum size (in Bytes) for JavaScript files after gzip compression. Leave blank if you don\'t want to ' +
'specify a limit',
default: ''
}
], function(_answers) {
answers = _.extend(answers, _answers);
done();
});
},
configPrompts: function() {
var done = this.async();
this.prompt([
{
type: 'input',
name: 'autoprefixerBrowserSelection',
message: 'Please provide the configuration strings for autoprefixer',
default: '\'last 1 version\', \'> 1%\', \'ie 8\''
}
], function(_answers) {
answers = _.extend(answers, _answers);
done();
});
},
browserSyncPrompts: function() {
var done = this.async();
this.prompt({
type: 'input',
name: 'devUrl',
message: 'Please specify the URL where your TYPO3 site will be reachable during development',
default: answers.projectName + '.dev'
}, function(_answers) {
answers = _.extend(answers, _answers);
done();
});
}
};
Generator.writeGeneralConfigs = function() {
this.fs.copy(
this.templatePath('_editorconfig'),
this.destinationPath('.editorconfig')
);
this.fs.copy(
this.templatePath('_jshintrc'),
this.destinationPath('.jshintrc')
);
this.fs.copy(
this.templatePath('_scss-lint.yml'),
this.destinationPath('.scss-lint.yml')
);
};
Generator.writeGulp = function() {
this.fs.copyTpl(
this.templatePath('_gulpfile.js'),
this.destinationPath('gulpfile.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/settings.js'),
this.destinationPath('gulp/settings.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/css.js'),
this.destinationPath('gulp/css.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/browser-sync.js'),
this.destinationPath('gulp/browser-sync.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/images.js'),
this.destinationPath('gulp/images.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/javascript.js'),
this.destinationPath('gulp/javascript.js'),
answers
);
this.fs.copyTpl(
this.templatePath('gulp/config.json'),
this.destinationPath('gulp/config.json'),
answers
);
this.fs.copy(
this.templatePath('gulp/sprite-scss-template.mustache'),
this.destinationPath('gulp/sprite-scss-template.mustache'),
answers
);
this.fs.copy(
this.templatePath('gulp/inline-svg-template.mustache'),
this.destinationPath('gulp/inline-svg-template.mustache'),
answers
);
};
Generator.writeDependencyManagement = function() {
this.fs.copyTpl(
this.templatePath('_package.json'),
this.destinationPath('package.json'),
answers
);
};
Generator.install = function() {
this.installDependencies({
skipInstall: this.options['skip-install']
});
};
return Generator;
})());
# http://editorconfig.org
root = true
[*]
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
'use strict';
var gulp = require('gulp'),
settings = require('./gulp/settings'),
path = require('path'),
gutil = require('gulp-util'),
chalk = require('chalk'),
config = require('./gulp/config.json');
require('require-dir')('./gulp');
function getExtensionName(changedFile, task) {
var extension = changedFile.path.split('/' + task)[0].split('typo3conf/ext/')[1];
gutil.log(chalk.green('Change in "') + chalk.magenta(path.relative('.', changedFile.path)) + chalk.green('"'));
return extension;
}
function setExtensionName(file) {
settings.setExtension(getExtensionName(file, config.directories.javascript));
}
gulp.task('watch', function() {
var sassWatchers = [];
for (var i = config.extensions.length; i--;) {
sassWatchers.push('typo3conf/ext/' + config.extensions[i] + '/' + config.directories.sass + '/**/*.scss');
}
sassWatchers.push('!**/_sprite.scss');
gulp.watch(sassWatchers, ['css']).on('change', function(file) {
settings.setExtension(getExtensionName(file, config.directories.sass));
}
);
for (i = config.extensions.length; i--;) {
gulp.watch(
['typo3conf/ext/' + config.extensions[i] + '/' + config.directories.javascript + '/**/*.js'],
['javascript']).on('change', setExtensionName);
}
});
gulp.task('default', function() {
gulp.start('browser-sync', 'watch');
});
{
"asi": false,
"bitwise": true,
"boss": false,
"browser": true,
"camelcase": true,
"couch": false,
"curly": true,
"debug": false,
"devel": false,
"dojo": false,
"eqeqeq": true,
"eqnull": false,
"es5": false,
"esnext": false,
"evil": false,
"expr": false,
"forin": true,
"funcscope": false,
"globals": {},
"globalstrict": false,
"immed": true,
"indent": 4,
"iterator": false,
"jquery": false,
"lastsemic": false,
"latedef": true,
"laxbreak": false,
"laxcomma": false,