Guard is My Best Friend
Guardfile 語法說明
guard
:<plugin> : 使用 plugingroup
:<group name> …end
: 定義一個 task 分類區塊%w[]
: Ruby 宣告 Array 的方式, 用空白區分:key => value
: 宣告 Hashes 的 key/value%r{}
: Regexen 正規表達式, 可到 rubular 測試
Group
example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
group :tb2 do guard :concat, :type => 'css', :files = > %w[boostrap bootstrap-responsive], :input_dir => 'app/assets/css, :output => 'public/css/bootstrap.css end group :zf4 do guard :concat, :type => 'css', :files = > %w[normalize foundation4], :input_dir => 'app/assets/css, :output => 'public/css/foundation.css end |
Plugins
CoffeeScript
編譯 CoffeeScript
- input :
.coffee
路徑 - output :
.javascript
輸出路徑
example:
1 2 3 |
guard :coffeescript, :input => "app/assets/coffee", :output => "public/js" |
Concat
合併檔案
- type : 檔案類型 (副檔名), ex:
css
,js
… - files : 哪些檔案要被合併, 用 Array 的方式定義
- input_dir : 來源路徑
- output : 合併後的檔案 (去除
.副檔名
)
example:
1 2 3 4 5 |
guard :concat, :type => "css", :files => %w[bootstrap-responsive bootstrap button], :input_dir => "public/css", :output => "public/css/styles.min" |
1 2 3 4 5 6 7 8 9 10 |
# This will concatenate the javascript files a.js and b.js in public/js to all.js guard :concat, type: "js", files: %w(b a), input_dir: "public/js", output: "public/js/all" # analog css example guard :concat, type: "css", files: %w(c d), input_dir: "public/css", output: "public/css/all" # js example with * guard :concat, type: "js", files: %w(vendor/* b a), input_dir: "public/js", output: "public/js/all" # will concatenate all files in the vendor dir, then b then a (watch out of dependencies) |
Livereload
- Blocks/Closures
- watch : 偵測什麼的檔案變化, 可以用
%r
正規表達式
example:
1 2 3 4 5 6 7 8 |
# .+ 任意字元 # (?<!) zero-width negative look-behind assertion. # (?<!\.min\.(css|html|js|blade\.php)$) # 不包含 .min 文字但以 css 或 html 或 js 或 blade.php 結尾 guard 'livereload' do watch(%r{.+(?<!\.min)\.(css|html|js|blade\.php)$}) end |
可用參數:
1 2 3 4 5 |
:host => '127.3.3.1' # default '0.0.0.0' :port => '12345' # default '35729' :apply_css_live => false # default true :override_url => false # default false :grace_period => 0.5 # default 0 (seconds) |
example:
1 2 3 |
guard 'livereload', :host => '127.3.3.1', :port => '12345' do watch(%r{.+(?<!\.min)\.(css|html|js|blade\.php)$}) end |
Minify
example:
1 2 3 4 5 6 |
min_js = 'public/js/bootstrap.min.js' watch 'public/js/bootstrap.js' do |m| js = File.read(m[0]) File.open(min_js, 'w') { |file| file.write(JSMin.minify(js)) } puts min_js + " has minify." end |
1 2 3 4 5 6 7 8 |
watch('public/css/styles.min.css') do |m| css = File.read(m[0]) File.open(m[0], 'w') { |file| file.write(CSSMin.minify(css)) } end watch('public/js/scripts.min.js') do |m| js = File.read(m[0]) File.open(m[0], 'w') { |file| file.write(JSMin.minify(js)) } end |
PHP Unit Testing
1 2 3 4 5 6 |
# # PHP Unit Testing # guard :shell, :all_on_start => false do watch(%r{^app/tests/.+Test\.php$}) { `phpunit` } end |
參考完整 Guardfile 範例
Laravel-Guard Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
guard :coffeescript, :input => "app/assets/coffee", :output => "public/js" guard :concat, :type => "css", :files => %w[bootstrap-responsive bootstrap button], :input_dir => "public/css", :output => "public/css/styles.min" guard :concat, :type => "js", :files => %w[bootstrap], :input_dir => "public/js", :output => "public/js/scripts.min" # Refresh the browser on save guard 'livereload' do watch(%r{.+(?<!\.min)\.(css|html|js|blade\.php)$}) end guard :phpunit, :all_on_start => false, :tests_path => 'app/tests/', :cli => '--colors -c phpunit.xml' do # Run any test in app/tests upon save. watch(%r{^.+Test\.php$}) # When a view file is updated, run tests. # Tip: you probably only want to run your integration tests. watch(%r{app/views/.+\.php}) { Dir.glob('app/tests/**/*.php') } # When a file is edited, try to run its associated test. # Save app/models/User.php, and it will run app/tests/models/UserTest.php watch(%r{^app/(.+)/(.+)\.php$}) { |m| "app/tests/#{m[1]}/#{m[2]}Test.php"} end module ::Guard class Refresher < Guard def run_all # refresh end def run_on_additions(paths) refresh end def run_on_removals(paths) refresh end def refresh `php artisan guard:refresh` end end end require 'cssmin' require 'jsmin' guard :refresher do watch(%r[public/js/.+]) watch(%r[public/css/.+]) watch(%r{app/config/packages/way/guard-laravel/guard.php}) do |m| `php artisan guard:refresh` end watch('public/css/styles.min.css') do |m| css = File.read(m[0]) File.open(m[0], 'w') { |file| file.write(CSSMin.minify(css)) } end watch('public/js/scripts.min.js') do |m| js = File.read(m[0]) File.open(m[0], 'w') { |file| file.write(JSMin.minify(js)) } end end guard :sass, :input => 'app/assets/sass', :output => 'public/css' |
My Laravel Example :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
require 'cssmin' require 'jsmin' group :tb2 do all_js = 'bootstrap.all' all_css = 'bootstrap.all' min_js = 'public/js/bootstrap.min.js' min_css = 'public/css/bootstrap.min.css' # Compile CoffeeScript guard :coffeescript, :input => "app/assets/coffee", :output => "app/assets/js" # Compile SASS guard :sass, :input => 'app/assets/sass', :output => 'app/assets/css' # Concat CSS guard :concat, :type => "css", :files => %w[bootstrap bootstrap-responsive button], :input_dir => "app/assets/css", :output => "public/css/" + all_css # Concat JS guard :concat, :type => "js", :files => %w[jquery.1.9.1 bootstrap jqBootstrapValidation], :input_dir => "app/assets/js", :output => "public/js/" + all_js # # Minify JS # watch 'public/js/'+ all_js +'.js' do |m| js = File.read(m[0]) File.open(min_js, 'w') { |file| file.write(JSMin.minify(js)) } puts min_js + " has minify." end # # Minify CSS # watch 'public/css/'+ all_css +'.css' do |m| css = File.read(m[0]) File.open(min_css, 'w') { |file| file.write(CSSMin.minify(css)) } puts min_css + " has minify." end end # # Live Reload # guard 'livereload' do watch(%r{.+(?<!\.min)\.(css|html|js|blade\.php)$}) end # # PHP Unit Testing # guard :phpunit, :all_on_start => false, :tests_path => 'app/tests/', :cli => '--colors -c phpunit.xml' do # Run any test in app/tests upon save. watch(%r{^.+Test\.php$}) # When a view file is updated, run tests. # Tip: you probably only want to run your integration tests. watch(%r{app/views/.+\.php}) { Dir.glob('app/tests/**/*.php') } # When a file is edited, try to run its associated test. # Save app/models/User.php, and it will run app/tests/models/UserTest.php watch(%r{^app/(.+)/(.+)\.php$}) { |m| "app/tests/#{m[1]}/#{m[2]}Test.php"} end |