gulp-rails 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +4 -0
  4. data/CODE_OF_CONDUCT.md +13 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +92 -0
  8. data/Rakefile +10 -0
  9. data/exe/gulp-rails +4 -0
  10. data/gulp-rails.gemspec +20 -0
  11. data/lib/gulp-rails.rb +10 -0
  12. data/lib/gulp-rails/cli.rb +27 -0
  13. data/lib/gulp-rails/generator.rb +71 -0
  14. data/lib/gulp-rails/settings.rb +28 -0
  15. data/lib/gulp-rails/version.rb +3 -0
  16. data/templates/Gulpfile.js +2 -0
  17. data/templates/asset_rev_helper.rb +33 -0
  18. data/templates/frontend/images/.keep +0 -0
  19. data/templates/frontend/scripts/application.js +6 -0
  20. data/templates/frontend/styles/application.scss +8 -0
  21. data/templates/gulp/tasks/clean.js +7 -0
  22. data/templates/gulp/tasks/images.js +13 -0
  23. data/templates/gulp/tasks/lint.js +11 -0
  24. data/templates/gulp/tasks/revision.js +22 -0
  25. data/templates/gulp/tasks/scripts.js +55 -0
  26. data/templates/gulp/tasks/sourcemaps.js +20 -0
  27. data/templates/gulp/tasks/styles.js +22 -0
  28. data/templates/gulp/tasks/templates.js +12 -0
  29. data/templates/gulp/utils/onerror.js +6 -0
  30. data/templates/gulp_config.js.erb +62 -0
  31. data/templates/gulp_default_task.js.erb +20 -0
  32. data/templates/gulp_spec_task.js +66 -0
  33. data/templates/gulp_test_task.js +65 -0
  34. data/templates/gulp_watch_task.js.erb +19 -0
  35. data/templates/jshintrc.json +3 -0
  36. data/templates/package.json.erb +50 -0
  37. data/templates/spec/javascript/spec_runner.html +30 -0
  38. data/templates/test/sample_test.js +3 -0
  39. data/templates/test/test_helper.js +1 -0
  40. data/templates/test/test_runner.html +17 -0
  41. data/templates/testem.json.erb +5 -0
  42. metadata +127 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97c33290a26f1b022e82b986d72cf02887e8ed7b
4
+ data.tar.gz: c85fd3e6cd4ede136c16682413730d9074d77500
5
+ SHA512:
6
+ metadata.gz: 6ed45132ac81f18557fd5d9643781ccb4f55e53cee9fafe49844a969038e854f0b373c9491b4dd6cd8347f96fe5cba4c89449c80c3de55f2d3479c62294d4c27
7
+ data.tar.gz: 1c896a4d78efe8cae4ffa760504fe454daf3fcc3b33c0c32a0f03accb58bc4e52ec57fd5aa3694b295cc6abda8cf9502b568dc6891e76b80a8f8b6dcbd94ff32
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.5
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gulp-rails.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Nando Vieira
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ # gulp-rails
2
+
3
+ Want to use Gulp on your Rails application? Here's some sample configuration.
4
+
5
+ It includes:
6
+
7
+ - JavaScript transpiling with Babel.js (with Browserify for ES6 module support)
8
+ - Stylesheet generation using Sass
9
+ - Assets with cache bursting for production
10
+ - Template compilation using Handlebars
11
+ - ES6 linting with JSHint
12
+ - Tests using QUnit and Phantom.js
13
+ - Tests using testem
14
+
15
+ All tasks are available at `./gulp/tasks/*`.
16
+
17
+ ## Installation
18
+
19
+ Install the gem:
20
+
21
+ $ gem install gulp-rails
22
+
23
+ ## Usage
24
+
25
+ Then from your project's root directory:
26
+
27
+ $ gulp-rails install # default to qunit
28
+ $ gulp-rails install -t qunit
29
+ $ gulp-rails install -t jasmine
30
+ $ gulp-rails install /some/other/path
31
+
32
+ ### Running Gulp
33
+
34
+ You can start the `watch` script for development:
35
+
36
+ ```
37
+ $ npm run-script watch
38
+ ```
39
+
40
+ When you're ready to deploy, run the `build` script. This will generate the minified version with cache burst.
41
+
42
+ ```
43
+ $ npm run-script build
44
+ ```
45
+
46
+ ### Tests
47
+
48
+ Browserify requires you load each and every file in order to create the module structure. This is handled by the `(tests|specs)-manifest` task, which will create a file at `./tmp/(tests|specs)-loader.js`.
49
+
50
+ Then we compile this file using our JavaScript pipeline; the generated file will be available at `./tmp/(tests|specs).js`. This file is loaded by the test runner.
51
+
52
+ To see sourcemaps when running tests, you must start a local server. You can execute something like:
53
+
54
+ - `python -m SimpleHTTPServer`
55
+ - `php -S localhost:8000`
56
+ - `ruby -run -e httpd . -p 8000`
57
+
58
+ The you can visit <http://localhost:8000/test/javascript/test_runner.html> (QUnit) or <http://localhost:8000/spec/javascript/spec_runner.html> (Jasmine).
59
+
60
+ If you want to use [testem](https://github.com/airportyh/testem), just run `npm run-script testem`.
61
+
62
+ ### Bundle files
63
+
64
+ You can have as many bundles as you need; just create root files at `app/frontend/styles/` and `app/frontend/scripts`. By default, this setup comes with `app/frontend/styles/application.scss` and `app/frontend/scripts/application.js`.
65
+
66
+ ### Rails helpers
67
+
68
+ For asset cache bursting to work, you'll have to copy the helper methods available at `app/helpers/application_helper.rb`.
69
+
70
+ This file will replace the `path_to_asset` method, which is used by all methods that require an asset path. I'm using the `gulp-rev` package creating the manifest, instead of using the one created by asset pipeline.
71
+
72
+ Talking about asset pipeline... you don't have to disable it, and I honestly don't encourage you to do so because you may have engines that need this feature.
73
+
74
+ ### Source Maps
75
+
76
+ You don't want to expose your sourcemaps in production, but you may want to allow having this for an exception tracking service like [Rollbar](http://rollbar.com). We generate a name like `sm-<uuid>`, but you can change the `sourcemapsOutput` option at `./gulp/config.js` to whatever you want.
77
+
78
+ ## Development
79
+
80
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec gulp-rails` to use the gem in this directory, ignoring other installed copies of this gem.
81
+
82
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
83
+
84
+ ## Contributing
85
+
86
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fnando/gulp-rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
87
+
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
92
+
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gulp-rails'
4
+ GulpRails::CLI.start
@@ -0,0 +1,20 @@
1
+ require './lib/gulp-rails/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'gulp-rails'
5
+ spec.version = GulpRails::VERSION
6
+ spec.authors = ['Nando Vieira']
7
+ spec.email = ['fnando.vieira@gmail.com']
8
+ spec.summary = 'Set up Rails with Gulp for asset pipeline.'
9
+ spec.description = spec.summary
10
+ spec.homepage = 'https://github.com/fnando/gulp-rails'
11
+ spec.license = 'MIT'
12
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
13
+ spec.bindir = 'exe'
14
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
15
+ spec.require_paths = ['lib']
16
+
17
+ spec.add_development_dependency 'thor'
18
+ spec.add_development_dependency 'bundler', '~> 1.10'
19
+ spec.add_development_dependency 'rake', '~> 10.0'
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'securerandom'
2
+ require 'thor'
3
+ require 'thor/group'
4
+
5
+ module GulpRails
6
+ require 'gulp-rails/version'
7
+ require 'gulp-rails/cli'
8
+ require 'gulp-rails/generator'
9
+ require 'gulp-rails/settings'
10
+ end
@@ -0,0 +1,27 @@
1
+ module GulpRails
2
+ class CLI < Thor
3
+ map %w[-v --version] => :version
4
+
5
+ desc 'install PATH', 'Install Gulp files'
6
+ option 'test_framework', required: true, default: 'qunit', aliases: '-t'
7
+ def install(path = Dir.pwd)
8
+ validate_test_framework!
9
+
10
+ generator = Generator.new
11
+ generator.destination_root = File.expand_path(path)
12
+ generator.options = options
13
+ generator.settings = Settings.new(options)
14
+ generator.invoke_all
15
+ end
16
+
17
+ desc 'version', 'Display version'
18
+ def version
19
+ say VERSION
20
+ end
21
+
22
+ private
23
+ def validate_test_framework!
24
+ raise Error.new, 'invalid test framework. Can be qunit or jasmine' unless %w[qunit jasmine].include?(options['test_framework'])
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,71 @@
1
+ module GulpRails
2
+ class Generator < Thor::Group
3
+ attr_accessor :settings
4
+
5
+ include Thor::Actions
6
+ desc 'Prepare Rails project with Gulp'
7
+
8
+ def self.source_root
9
+ File.expand_path('../../../templates', __FILE__)
10
+ end
11
+
12
+ def create_testem_config_file
13
+ template 'testem.json.erb', 'testem.json'
14
+ end
15
+
16
+ def create_jshintrc
17
+ copy_file 'jshintrc.json', '.jshintrc'
18
+ end
19
+
20
+ def copy_gulpfile
21
+ copy_file 'Gulpfile.js', 'Gulpfile.js'
22
+ end
23
+
24
+ def copy_package
25
+ template 'package.json.erb', 'package.json'
26
+ end
27
+
28
+ def copy_helper
29
+ copy_file 'asset_rev_helper.rb', 'app/helpers/asset_rev_helper.rb'
30
+ end
31
+
32
+ def copy_frontend_directory
33
+ directory 'frontend', 'app/frontend', recursive: true
34
+ end
35
+
36
+ def copy_test_directory
37
+ directory settings.test_dirname, "#{settings.test_dirname}/javascript", recursive: true
38
+ end
39
+
40
+ def copy_gulp_tasks
41
+ directory 'gulp', 'gulp', recursive: true
42
+ copy_file "gulp_#{settings.test_dirname}_task.js", "gulp/tasks/#{settings.test_dirname}.js"
43
+ template 'gulp_watch_task.js.erb', 'gulp/tasks/watch.js'
44
+ template 'gulp_default_task.js.erb', 'gulp/tasks/default.js'
45
+ template 'gulp_config.js.erb', 'gulp/config.js'
46
+ other_test_task_file = (Settings::TEST_DIRNAME.values - [settings.test_dirname]).first
47
+ remove_file File.join('gulp/tasks', "#{other_test_task_file}.js")
48
+ end
49
+
50
+ def append_to_gitignore
51
+ append_to_file '.gitignore' do
52
+ %w[
53
+ /node_modules
54
+ /app/frontend/scripts/templates
55
+ /public/images
56
+ /public/javascripts
57
+ /public/stylesheets
58
+ /public/rev-manifest.json
59
+ /public/sm-*
60
+ ].join("\n")
61
+ end
62
+ end
63
+
64
+ def install_npm_packages
65
+ in_root do
66
+ run 'npm install --save-dev'
67
+ run 'npm prune'
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ module GulpRails
2
+ class Settings
3
+ attr_reader :test_framework
4
+
5
+ TEST_DIRNAME = {
6
+ 'qunit' => 'test',
7
+ 'jasmine' => 'spec'
8
+ }
9
+
10
+ def initialize(options = {})
11
+ options.each do |key, value|
12
+ instance_variable_set "@#{key}", value
13
+ end
14
+ end
15
+
16
+ def qunit?
17
+ test_framework == 'qunit'
18
+ end
19
+
20
+ def test_dirname
21
+ TEST_DIRNAME[test_framework]
22
+ end
23
+
24
+ def testem_page
25
+ File.join(test_dirname, 'javascript', "#{test_dirname}_runner.html")
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module GulpRails
2
+ VERSION = '0.1.2'
3
+ end
@@ -0,0 +1,2 @@
1
+ var requireDir = require('require-dir');
2
+ requireDir('./gulp/tasks', {recurse: true});
@@ -0,0 +1,33 @@
1
+ module AssetRevHelper
2
+ REV_MANIFEST_FILE = 'public/rev-manifest.json'.freeze
3
+
4
+ def rev_manifest_file
5
+ Rails.root.join(REV_MANIFEST_FILE)
6
+ end
7
+
8
+ def rev_manifest?
9
+ rev_manifest_file.exist?
10
+ end
11
+
12
+ def rev_manifest
13
+ @rev_manifest ||= JSON.load(rev_manifest_file.read)
14
+ end
15
+
16
+ def path_to_asset(source, options = {})
17
+ path = super(source, options)
18
+ asset_host = Rails.configuration.action_controller.asset_host.to_s
19
+
20
+ # No rev manifest? Just return path.
21
+ return File.join(asset_host, path) unless rev_manifest?
22
+
23
+ # Remove asset_host from source, so we
24
+ # can search for file on manifest.
25
+ path = path.gsub(asset_host, '')
26
+
27
+ # Try to find file on manifest; use path otherwise.
28
+ path = rev_manifest[path[1..-1]] || path
29
+
30
+ # Return the final url.
31
+ File.join(asset_host, path)
32
+ end
33
+ end
File without changes
@@ -0,0 +1,6 @@
1
+ // Use this file as your manifest file.
2
+ // More about ES6 and Babel.js at the following links:
3
+ //
4
+ // - https://leanpub.com/exploring-es6/read
5
+ // - https://babeljs.io/
6
+ //
@@ -0,0 +1,8 @@
1
+ // Use this file as your manifest file.
2
+ // More about Sass at http://sass-lang.org
3
+ //
4
+ // @import './application/core/variables';
5
+ // @import './application/core/**/*';
6
+ // @import './application/helpers/**/*';
7
+ // @import './application/modules/**/*';
8
+ // @import './application/pages/**/*';
@@ -0,0 +1,7 @@
1
+ var gulp = require('gulp');
2
+ var del = require('del');
3
+ var config = require('../config');
4
+
5
+ gulp.task('clean', function(done) {
6
+ del(config.paths.clean, done);
7
+ });
@@ -0,0 +1,13 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var del = require('del');
4
+
5
+ gulp.task('images-clean', function(done) {
6
+ del(config.paths.imagesOutput, done);
7
+ });
8
+
9
+ gulp.task('images', ['images-clean'], function() {
10
+ gulp
11
+ .src(config.paths.images)
12
+ .pipe(gulp.dest(config.paths.imagesOutput))
13
+ });
@@ -0,0 +1,11 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var jshint = require('gulp-jshint');
4
+ var gutil = require('gulp-util');
5
+
6
+ gulp.task('lint', function() {
7
+ gulp.src(config.paths.scriptsMainFiles)
8
+ .pipe(jshint())
9
+ .pipe(jshint.reporter('jshint-stylish'))
10
+ .pipe(config.production ? jshint.reporter('fail') : gutil.noop());
11
+ });
@@ -0,0 +1,22 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var rev = require('gulp-rev');
4
+ var replace = require('gulp-rev-replace');
5
+ var path = require('path');
6
+
7
+ gulp.task('revision', ['revision-generate'], function(){
8
+ var manifest = gulp.src(config.paths.revisionManifest);
9
+
10
+ return gulp.src(config.paths.revisionReplace)
11
+ .pipe(replace({manifest: manifest}))
12
+ .pipe(gulp.dest(config.paths.public));
13
+ });
14
+
15
+ gulp.task('revision-generate', function(done) {
16
+ gulp.src([config.paths.revision])
17
+ .pipe(rev())
18
+ .pipe(gulp.dest(config.paths.public))
19
+ .pipe(rev.manifest())
20
+ .pipe(gulp.dest(config.paths.public))
21
+ .on('end', done);
22
+ });
@@ -0,0 +1,55 @@
1
+ // Compile JavaScript files.
2
+ // All .js files living at app/frontend/scripts/*.js will be exported
3
+ // as a separated bundle file. This way you can have different script
4
+ // files for different sections, like the marketing website and the application.
5
+
6
+ var gulp = require('gulp');
7
+ var config = require('../config');
8
+ var buffer = require('vinyl-buffer');
9
+ var browserify = require('browserify');
10
+ var del = require('del');
11
+ var uglify = require('gulp-uglify');
12
+ var source = require('vinyl-source-stream');
13
+ var sourcemaps = require('gulp-sourcemaps');
14
+ var babelify = require('babelify');
15
+ var onerror = require('../utils/onerror');
16
+ var gutil = require('gulp-util');
17
+ var es = require('event-stream');
18
+ var glob = require('glob');
19
+ var normalize = /app\/frontend\/scripts\//;
20
+ var path = require('path');
21
+
22
+ function bundle(entry) {
23
+ return browserify({
24
+ entries: entry,
25
+ paths: [config.paths.scriptsBaseDir, config.paths.nodeModules],
26
+ debug: true
27
+ })
28
+ .transform(babelify.configure({
29
+ sourceMapRelative: process.cwd(),
30
+ optional: ['es7.asyncFunctions', 'runtime']
31
+ }))
32
+ .bundle().on('error', onerror)
33
+ .pipe(source(path.basename(entry)))
34
+ .pipe(buffer())
35
+ .pipe(sourcemaps.init({loadMaps: true}))
36
+ .pipe(config.production ? uglify() : gutil.noop()).on('error', onerror)
37
+ .pipe(sourcemaps.write('.', {sourceMappingURLPrefix: config.paths.sourcemapsPrefix}))
38
+ .pipe(gulp.dest(config.paths.scriptOutput));
39
+ }
40
+
41
+ gulp.task('scripts-clean', function(done) {
42
+ del(config.paths.scriptsClean, done);
43
+ });
44
+
45
+ gulp.task('scripts', ['scripts-clean'], function(done) {
46
+ glob(config.paths.scriptsMainFiles, function(err, files) {
47
+ if (err) { done(err); }
48
+
49
+ var tasks = files.map(function(file) {
50
+ return bundle(file);
51
+ });
52
+
53
+ es.merge(tasks).on('end', done);
54
+ });
55
+ });
@@ -0,0 +1,20 @@
1
+ // Move source maps somewhere else. This is done only for production build.
2
+ var gulp = require('gulp');
3
+ var config = require('../config');
4
+ var glob = require('glob');
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+
8
+ gulp.task('sourcemaps', function(done) {
9
+ fs.mkdirSync(config.paths.sourcemapsOutput, '0755');
10
+
11
+ glob(config.paths.sourcemaps, function(err, files) {
12
+ if (err) { done(err); }
13
+
14
+ files.forEach(function(file) {
15
+ fs.renameSync(file, path.join(config.paths.sourcemapsOutput, path.basename(file)));
16
+ })
17
+
18
+ done();
19
+ });
20
+ });
@@ -0,0 +1,22 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var globbing = require('gulp-css-globbing');
4
+ var sass = require('gulp-sass');
5
+ var autoprefixer = require('gulp-autoprefixer');
6
+ var sourcemaps = require('gulp-sourcemaps');
7
+ var del = require('del');
8
+
9
+ gulp.task('styles-clean', function(done) {
10
+ del(config.paths.stylesClean, done);
11
+ });
12
+
13
+ gulp.task('styles', ['styles-clean'], function() {
14
+ gulp
15
+ .src(config.paths.styles)
16
+ .pipe(sourcemaps.init())
17
+ .pipe(globbing({extensions: ['.scss']}))
18
+ .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
19
+ .pipe(autoprefixer())
20
+ .pipe(sourcemaps.write('.'))
21
+ .pipe(gulp.dest(config.paths.stylesOutput))
22
+ });
@@ -0,0 +1,12 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var handlebars = require('gulp-handlebars');
4
+ var defineModule = require('gulp-define-module');
5
+
6
+ gulp.task('templates', function() {
7
+ gulp
8
+ .src(config.paths.templates)
9
+ .pipe(handlebars())
10
+ .pipe(defineModule('commonjs'))
11
+ .pipe(gulp.dest(config.paths.templatesOutput));
12
+ });
@@ -0,0 +1,6 @@
1
+ var gutil = require('gulp-util');
2
+
3
+ module.exports = function onerror(error) {
4
+ gutil.log(gutil.colors.red('\nERROR:', error.message));
5
+ this.emit('end');
6
+ };
@@ -0,0 +1,62 @@
1
+ module.exports = {
2
+ production: process.env.NODE_ENV === 'production',
3
+
4
+ paths: {
5
+ images: 'app/frontend/images/**/*',
6
+ imagesOutput: 'public/images/',
7
+ nodeModules: './node_modules',
8
+ public: 'public/',
9
+
10
+ clean: [
11
+ 'public/**/*',
12
+ '!public/robots.txt',
13
+ '!public/*.ico',
14
+ '!public/*.html', // rails error pages
15
+ '!public/*.png', // apple icons
16
+ 'tmp/tests.js',
17
+ 'tmp/tests.js.map',
18
+ 'tmp/tests-loader.js'
19
+ ],
20
+
21
+ scriptOutput: 'public/javascripts',
22
+ scripts: 'app/frontend/scripts/**/*.js',
23
+ scriptsClean: 'public/**/.{js,map}',
24
+ scriptsBaseDir: 'app/frontend/scripts',
25
+ scriptsMainFiles: 'app/frontend/scripts/*.js',
26
+
27
+ styles: 'app/frontend/styles/**/*.scss',
28
+ stylesOutput: 'public/stylesheets/',
29
+ stylesClean: 'public/**/.{css,scss,map}',
30
+
31
+ templates: 'app/frontend/templates/**/*.hbs',
32
+ templatesOutput: 'app/frontend/scripts/classmate/templates/',
33
+
34
+ <% if settings.qunit? %>
35
+ test: ['test/javascript/**/*.js', 'test/javascript/**/*.html'],
36
+ testFiles: './test/javascript/**/*{test,spec}.js',
37
+ testHelper: './test/javascript/test_helper.js',
38
+ testsLoader: './tmp/tests-loader.js',
39
+ testRunner: './test/javascript/test_runner.html',
40
+ testsBaseDir: 'test/javascript',
41
+ testsOutput: 'tests.js',
42
+ testsOutputDir: './tmp/',
43
+ <% else %>
44
+ spec: ['spec/javascript/**/*.js', 'spec/javascript/**/*.html'],
45
+ specFiles: './spec/javascript/**/*{test,spec}.js',
46
+ specLoader: './tmp/specs-loader.js',
47
+ specHelper: './spec/javascript/spec_helper.js',
48
+ specRunner: './spec/javascript/spec_runner.html',
49
+ specsBaseDir: 'spec/javascript',
50
+ specsOutput: 'specs.js',
51
+ specsOutputDir: './tmp/',
52
+ <% end %>
53
+
54
+ sourcemaps: './public/**/*.{css,js}.map',
55
+ sourcemapsOutput: './public/sm-<%= SecureRandom.uuid %>/',
56
+ sourcemapsPrefix: '/javascripts/',
57
+
58
+ revision: 'public/**/*.{jpg,svg,gif,png,css,js}',
59
+ revisionManifest: './public/rev-manifest.json',
60
+ revisionReplace: './public/**/*.{css,html,js}'
61
+ }
62
+ };
@@ -0,0 +1,20 @@
1
+ var gulp = require('gulp');
2
+ var sequence = require('run-sequence');
3
+
4
+ gulp.task('default-dev', function(done) {
5
+ sequence(
6
+ 'clean',
7
+ ['images', 'templates', 'scripts', 'styles', '<%= settings.test_dirname %>'],
8
+ done
9
+ );
10
+ });
11
+
12
+ gulp.task('default', function(done) {
13
+ sequence(
14
+ 'clean',
15
+ ['images', 'templates', 'scripts', 'styles', '<%= settings.test_dirname %>'],
16
+ 'sourcemaps',
17
+ 'revision',
18
+ done
19
+ );
20
+ });
@@ -0,0 +1,66 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var browserify = require('browserify');
4
+ var babelify = require('babelify');
5
+ var buffer = require('vinyl-buffer');
6
+ var source = require('vinyl-source-stream');
7
+ var onerror = require('../utils/onerror');
8
+ var del = require('del');
9
+ var jasmine = require('gulp-jasmine-phantom');
10
+ var glob = require('glob');
11
+ var sourcemaps = require('gulp-sourcemaps');
12
+ var path = require('path');
13
+ var fs = require('fs');
14
+ var sequence = require('run-sequence');
15
+ var gutil = require('gulp-util');
16
+
17
+ gulp.task('spec-manifest', function(done) {
18
+ glob(config.paths.specFiles, function(err, files) {
19
+ if (err) { done(err); }
20
+
21
+ var contents = 'require("' + path.resolve(config.paths.specHelper) + '");';
22
+
23
+ contents += files.map(function(file) {
24
+ return 'require("' + path.resolve(file) + '")';
25
+ }).join(';');
26
+
27
+ fs.writeFile(config.paths.specLoader, contents, done);
28
+ });
29
+ });
30
+
31
+ gulp.task('spec-scripts', function(done) {
32
+ browserify({
33
+ entries: config.paths.specLoader,
34
+ paths: [config.paths.scriptsBaseDir, config.paths.specBaseDir, config.paths.nodeModules],
35
+ debug: true,
36
+ })
37
+ .transform(babelify.configure({
38
+ sourceMapRelative: process.cwd(),
39
+ optional: ['es7.asyncFunctions', 'runtime']
40
+ }))
41
+ .bundle().on('error', onerror)
42
+ .pipe(source(config.paths.specsOutput))
43
+ .pipe(buffer())
44
+ .pipe(sourcemaps.init({loadMaps: true}))
45
+ .pipe(sourcemaps.write('.', {sourceMappingURLPrefix: config.paths.sourcemapsPrefix}))
46
+ .pipe(gulp.dest(config.paths.specsOutputDir))
47
+ .on('end', done);
48
+ });
49
+
50
+ gulp.task('spec-run', function() {
51
+ gulp.src('tmp/specs.js')
52
+ .pipe(jasmine({
53
+ integration: true,
54
+ specHtml: config.paths.specRunner,
55
+ abortOnFail: config.production
56
+ }));
57
+ });
58
+
59
+ gulp.task('spec', function(done) {
60
+ sequence(
61
+ ['spec-manifest', 'lint'],
62
+ 'spec-scripts',
63
+ 'spec-run',
64
+ done
65
+ );
66
+ });
@@ -0,0 +1,65 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var browserify = require('browserify');
4
+ var babelify = require('babelify');
5
+ var buffer = require('vinyl-buffer');
6
+ var source = require('vinyl-source-stream');
7
+ var onerror = require('../utils/onerror');
8
+ var del = require('del');
9
+ var qunit = require('node-qunit-phantomjs');
10
+ var glob = require('glob');
11
+ var sourcemaps = require('gulp-sourcemaps');
12
+ var path = require('path');
13
+ var fs = require('fs');
14
+ var sequence = require('run-sequence');
15
+ var gutil = require('gulp-util');
16
+
17
+ gulp.task('test-manifest', function(done) {
18
+ glob(config.paths.testFiles, function(err, files) {
19
+ if (err) { done(err); }
20
+
21
+ var contents = 'require("' + path.resolve(config.paths.testHelper) + '");';
22
+
23
+ contents += files.map(function(file) {
24
+ return 'require("' + path.resolve(file) + '")';
25
+ }).join(';');
26
+
27
+ fs.writeFile(config.paths.testsLoader, contents, done);
28
+ });
29
+ });
30
+
31
+ gulp.task('test-scripts', function(done) {
32
+ browserify({
33
+ entries: config.paths.testsLoader,
34
+ paths: [config.paths.scriptsBaseDir, config.paths.testsBaseDir, config.paths.nodeModules],
35
+ debug: true,
36
+ })
37
+ .transform(babelify.configure({
38
+ sourceMapRelative: process.cwd(),
39
+ optional: ['es7.asyncFunctions', 'runtime']
40
+ }))
41
+ .bundle().on('error', onerror)
42
+ .pipe(source(config.paths.testsOutput))
43
+ .pipe(buffer())
44
+ .pipe(sourcemaps.init({loadMaps: true}))
45
+ .pipe(sourcemaps.write('.', {sourceMappingURLPrefix: config.paths.sourcemapsPrefix}))
46
+ .pipe(gulp.dest(config.paths.testsOutputDir))
47
+ .on('end', done);
48
+ });
49
+
50
+ gulp.task('test-run', function() {
51
+ qunit(config.paths.testRunner, {}, function(exitcode) {
52
+ if (config.production && exitcode !== 0) {
53
+ process.exit(1);
54
+ }
55
+ });
56
+ });
57
+
58
+ gulp.task('test', function(done) {
59
+ sequence(
60
+ ['test-manifest', 'lint'],
61
+ 'test-scripts',
62
+ 'test-run',
63
+ done
64
+ );
65
+ });
@@ -0,0 +1,19 @@
1
+ var gulp = require('gulp');
2
+ var config = require('../config');
3
+ var watch = require('gulp-watch');
4
+
5
+ var mapping = [
6
+ {path: 'images' , tasks: ['images']},
7
+ {path: 'scripts' , tasks: ['scripts', 'lint', '<%= settings.test_dirname %>']},
8
+ {path: '<%= settings.test_dirname %>' , tasks: ['<%= settings.test_dirname %>', 'lint']},
9
+ {path: 'styles' , tasks: ['styles']},
10
+ {path: 'templates' , tasks: ['templates']},
11
+ ];
12
+
13
+ gulp.task('watch', ['default-dev'], function(done) {
14
+ mapping.forEach(function(map) {
15
+ watch(config.paths[map.path], function() {
16
+ gulp.start(map.tasks, done);
17
+ });
18
+ });
19
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "esnext": true
3
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "gulp-rails",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "devDependencies": {
6
+ "babel-runtime": "*",
7
+ "babelify": "*",
8
+ "browserify": "*",
9
+ "del": "*",
10
+ "es5-shim": "*",
11
+ "event-stream": "*",
12
+ "glob": "*",
13
+ "gulp": "*",
14
+ "gulp-autoprefixer": "*",
15
+ "gulp-css-globbing": "*",
16
+ "gulp-define-module": "*",
17
+ "gulp-handlebars": "*",
18
+ "gulp-jshint": "*",
19
+ "gulp-rev": "*",
20
+ "gulp-rev-replace": "*",
21
+ "gulp-sass": "*",
22
+ "gulp-sourcemaps": "*",
23
+ "gulp-uglify": "*",
24
+ "gulp-util": "*",
25
+ "gulp-watch": "*",
26
+ "handlebars": "*",
27
+ "jquery": "*",
28
+ "jshint-stylish": "*",
29
+ <% if settings.qunit? %>
30
+ "node-qunit-phantomjs": "*",
31
+ "qunitjs": "*",
32
+ "sinon": "*",
33
+ <% else %>
34
+ "gulp-jasmine-phantom": "*",
35
+ <% end %>
36
+ "require-dir": "*",
37
+ "run-sequence": "*",
38
+ "testem": "*",
39
+ "vinyl-buffer": "*",
40
+ "vinyl-source-stream": "*"
41
+ },
42
+ "scripts": {
43
+ "task": "./node_modules/gulp/bin/gulp.js",
44
+ "build": "NODE_ENV=production ./node_modules/gulp/bin/gulp.js",
45
+ "clean": "./node_modules/gulp/bin/gulp.js clean",
46
+ "watch": "./node_modules/gulp/bin/gulp.js watch",
47
+ "<%= settings.test_dirname %>": "./node_modules/gulp/bin/gulp.js <%= settings.test_dirname %>",
48
+ "testem": "./node_modules/testem/testem.js"
49
+ }
50
+ }
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Specs</title>
6
+ <link rel="stylesheet" href="../../node_modules/gulp-jasmine-phantom/vendor/jasmine-2.3/jasmine.css">
7
+ <script src="../../node_modules/es5-shim/es5-shim.js"></script>
8
+ <script src="../../node_modules/gulp-jasmine-phantom/vendor/jasmine-2.3/jasmine.js"></script>
9
+ <script src="../../node_modules/gulp-jasmine-phantom/vendor/jasmine-2.3/jasmine-html.js"></script>
10
+ <script src="../../node_modules/gulp-jasmine-phantom/vendor/jasmine-2.3/console.js"></script>
11
+ <script src="../../node_modules/gulp-jasmine-phantom/vendor/jasmine-2.3/boot.js"></script>
12
+ <script>
13
+ var consoleReporter = new jasmineRequire.ConsoleReporter()({
14
+ showColors: true,
15
+ timer: new jasmine.Timer,
16
+ print: function() {
17
+ console.log.apply(console, arguments)
18
+ }
19
+ });
20
+
21
+ if (navigator.userAgent.match(/phantomjs/i)) {
22
+ jasmine.getEnv().addReporter(consoleReporter);
23
+ }
24
+ </script>
25
+ <script src="/testem.js"></script>
26
+ </head>
27
+ <body>
28
+ <script src="../../tmp/specs.js"></script>
29
+ </body>
30
+ </html>
@@ -0,0 +1,3 @@
1
+ test('truth', function() {
2
+ ok(true);
3
+ });
@@ -0,0 +1 @@
1
+ // Add your test helpers here
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Todo: Tests</title>
6
+ <link rel="stylesheet" href="../../node_modules/qunitjs/qunit/qunit.css">
7
+ <script src="../../node_modules/es5-shim/es5-shim.js"></script>
8
+ <script src="../../node_modules/sinon/pkg/sinon.js"></script>
9
+ <script src="../../node_modules/qunitjs/qunit/qunit.js"></script>
10
+ <script src="/testem.js"></script>
11
+ </head>
12
+ <body>
13
+ <div id="qunit"></div>
14
+ <div id="qunit-fixture"></div>
15
+ <script src="../../tmp/tests.js"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,5 @@
1
+ {
2
+ "test_page": "<%= settings.testem_page %>",
3
+ "launch_in_dev": ["PhantomJS"],
4
+ "src_files": ["tmp/**/*.js"]
5
+ }
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gulp-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Nando Vieira
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-07-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description: Set up Rails with Gulp for asset pipeline.
56
+ email:
57
+ - fnando.vieira@gmail.com
58
+ executables:
59
+ - gulp-rails
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - CODE_OF_CONDUCT.md
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - exe/gulp-rails
71
+ - gulp-rails.gemspec
72
+ - lib/gulp-rails.rb
73
+ - lib/gulp-rails/cli.rb
74
+ - lib/gulp-rails/generator.rb
75
+ - lib/gulp-rails/settings.rb
76
+ - lib/gulp-rails/version.rb
77
+ - templates/Gulpfile.js
78
+ - templates/asset_rev_helper.rb
79
+ - templates/frontend/images/.keep
80
+ - templates/frontend/scripts/application.js
81
+ - templates/frontend/styles/application.scss
82
+ - templates/gulp/tasks/clean.js
83
+ - templates/gulp/tasks/images.js
84
+ - templates/gulp/tasks/lint.js
85
+ - templates/gulp/tasks/revision.js
86
+ - templates/gulp/tasks/scripts.js
87
+ - templates/gulp/tasks/sourcemaps.js
88
+ - templates/gulp/tasks/styles.js
89
+ - templates/gulp/tasks/templates.js
90
+ - templates/gulp/utils/onerror.js
91
+ - templates/gulp_config.js.erb
92
+ - templates/gulp_default_task.js.erb
93
+ - templates/gulp_spec_task.js
94
+ - templates/gulp_test_task.js
95
+ - templates/gulp_watch_task.js.erb
96
+ - templates/jshintrc.json
97
+ - templates/package.json.erb
98
+ - templates/spec/javascript/spec_runner.html
99
+ - templates/test/sample_test.js
100
+ - templates/test/test_helper.js
101
+ - templates/test/test_runner.html
102
+ - templates/testem.json.erb
103
+ homepage: https://github.com/fnando/gulp-rails
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.6
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Set up Rails with Gulp for asset pipeline.
127
+ test_files: []