From 90515fbb98c3b35ff744c28c609ecec29d0c2ccc Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sat, 27 Jul 2013 21:04:16 +0600 Subject: [PATCH 1/7] A bit of refactoring Twelve lines of code less and only two more --- lib/bower-rails/dsl.rb | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index 75e3e0b..9f64638 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -1,16 +1,10 @@ -require "json" +require 'json' require 'fileutils' module BowerRails class Dsl - - def self.config=(conf) - @config = conf - end - - def self.config - @config - end + cattr_accessor :config + attr_reader :dependencies def self.evalute(file) inst = new @@ -26,7 +20,7 @@ def initialize end def eval_file(file) - contents = File.open(file,"r").read + contents = File.open(file, "r").read instance_eval(contents, file.to_s, 1) end @@ -34,10 +28,6 @@ def directories @dependencies.keys end - def dependencies - @dependencies - end - def group(*args, &blk) @groups.concat [args] yield From a9c7a690e229ff324aa9b22c40ea3eed5dda4703 Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sat, 27 Jul 2013 22:04:27 +0600 Subject: [PATCH 2/7] A bunch of fixes and modifications added: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vendor dir is set as a default as it was described in #16 - @assets_path is now just '/assets' by default as Bower doesn’t just handle JavaScript libraries: it will manage any packages, even if that means HTML, CSS, or images. - added missing :name option for BowerRails::Dsl#dependencies_to_json method as it is needed for Bower 1.0.0 - added BowerRails::Dsl#write_dotbowerrc to use .bowerrc as a native tool for managing assets' directory - fix for BowerRails::Dsl#js method: Before it was like: @groups = ["lib"] if @groups.empty? @groups.each do |g| g_options = Hash === g.last ? g.pop : {} assets_path = g_options[:assets_path] || @assets_path g_norm = normalize_location_path(g.first,assets_path) @dependencies[g_norm] ||= {} @dependencies[g_norm][name] = version end But you call Array#last and Array#first for the instance of String as g is a String in @groups.each block Now it is like: @groups = [["vendor", {}]] if @groups.empty? --- lib/bower-rails/dsl.rb | 28 +++++++++++++++++++++------- lib/tasks/bower.rake | 1 + 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index 9f64638..ba12003 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -16,7 +16,7 @@ def initialize @dependencies = {} @groups = [] @root_path = BowerRails::Dsl.config[:root_path] || File.expand_path("./") - @assets_path = BowerRails::Dsl.config[:assets_path] || "/assets/javascripts" + @assets_path = BowerRails::Dsl.config[:assets_path] || "/assets" end def eval_file(file) @@ -39,7 +39,7 @@ def js(name, *args) options = Hash === args.last ? args.pop : {} version = args.first || "latest" - @groups = ["lib"] if @groups.empty? + @groups = [["vendor", {}]] if @groups.empty? @groups.each do |g| g_options = Hash === g.last ? g.pop : {} @@ -58,18 +58,32 @@ def to_json(location) def write_bower_json @dependencies.each do |dir,data| FileUtils.mkdir_p dir unless File.directory? dir - File.open(File.join(dir,"bower.json"),"w") do |f| + File.open(File.join(dir,"bower.json"), "w") do |f| f.write(dependencies_to_json(data)) end end end + def write_dotbowerrc + @groups = [["vendor", {}]] if @groups.empty? + + @groups.each do |g| + g_options = Hash === g.last ? g.pop : {} + assets_path = g_options[:assets_path] || @assets_path + + File.open(File.join(g.first, assets_path, ".bowerrc"), "w") do |f| + f.write(JSON.pretty_generate({:directory => "bower_components"})) + end + end + end + private def dependencies_to_json(data) - JSON.pretty_generate({ - :dependencies => data - }) + JSON.pretty_generate({ + :name => "dsl-generated dependencies", + :dependencies => data + }) end def assets_path(assets_path) @@ -77,7 +91,7 @@ def assets_path(assets_path) end def normalize_location_path(loc,assets_path) - File.join(@root_path,loc.to_s,assets_path) + File.join(@root_path, loc.to_s, assets_path) end end diff --git a/lib/tasks/bower.rake b/lib/tasks/bower.rake index 755d464..409517f 100644 --- a/lib/tasks/bower.rake +++ b/lib/tasks/bower.rake @@ -52,6 +52,7 @@ def dsl_perform_command remove_components = true if remove_components dsl.write_bower_json + dsl.write_dotbowerrc puts "bower.js files generated" end From 8679b3d46e5adb7168af6a0bc516801b0b375120 Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sun, 28 Jul 2013 20:32:19 +0600 Subject: [PATCH 3/7] Fixed mess with groups and Railties now add assets paths dynamically, according to user's custom assets_path --- lib/bower-rails/dsl.rb | 49 +++++++++++++++++++++----------------- lib/bower-rails/railtie.rb | 9 +++++-- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index ba12003..79a03d4 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -7,21 +7,20 @@ class Dsl attr_reader :dependencies def self.evalute(file) - inst = new - inst.eval_file(file) - inst + instance = new + instance.eval_file(file) + instance end def initialize @dependencies = {} @groups = [] @root_path = BowerRails::Dsl.config[:root_path] || File.expand_path("./") - @assets_path = BowerRails::Dsl.config[:assets_path] || "/assets" + @assets_path = BowerRails::Dsl.config[:assets_path] || "assets" end def eval_file(file) - contents = File.open(file, "r").read - instance_eval(contents, file.to_s, 1) + instance_eval(File.open(file, "rb") { |f| f.read }, file.to_s) end def directories @@ -29,23 +28,22 @@ def directories end def group(*args, &blk) - @groups.concat [args] + custom_assets_path = args[1][:assets_path] + raise ArgumentError, "Assets should be stored in /assets directory, try :assets_path => 'assets/#{custom_assets_path}' instead" if custom_assets_path.match(/assets/).nil? + new_group = [args[0], args[1]] + @groups << new_group yield - ensure - args.each { @groups.pop } end def js(name, *args) - options = Hash === args.last ? args.pop : {} version = args.first || "latest" - - @groups = [["vendor", {}]] if @groups.empty? + @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.each do |g| - g_options = Hash === g.last ? g.pop : {} - assets_path = g_options[:assets_path] || @assets_path + group_options = g.last + assets_path = group_options[:assets_path] - g_norm = normalize_location_path(g.first,assets_path) + g_norm = normalize_location_path(g.first.to_s, assets_path) @dependencies[g_norm] ||= {} @dependencies[g_norm][name] = version end @@ -65,18 +63,24 @@ def write_bower_json end def write_dotbowerrc - @groups = [["vendor", {}]] if @groups.empty? - - @groups.each do |g| - g_options = Hash === g.last ? g.pop : {} - assets_path = g_options[:assets_path] || @assets_path + @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? + @groups.map do |g| + group_options = g.last + assets_path = group_options[:assets_path] - File.open(File.join(g.first, assets_path, ".bowerrc"), "w") do |f| + File.open(File.join(g.first.to_s, assets_path, ".bowerrc"), "w") do |f| f.write(JSON.pretty_generate({:directory => "bower_components"})) end end end + def final_assets_path + @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? + @groups.map do |g| + [g.first.to_s, g.last[:assets_path]] + end + end + private def dependencies_to_json(data) @@ -87,10 +91,11 @@ def dependencies_to_json(data) end def assets_path(assets_path) + raise ArgumentError, "Assets should be stored in /assets directory, try assets_path 'assets/#{assets_path}' instead" if assets_path.match(/assets/).nil? @assets_path = assets_path end - def normalize_location_path(loc,assets_path) + def normalize_location_path(loc, assets_path) File.join(@root_path, loc.to_s, assets_path) end diff --git a/lib/bower-rails/railtie.rb b/lib/bower-rails/railtie.rb index aba2a6b..e772c18 100644 --- a/lib/bower-rails/railtie.rb +++ b/lib/bower-rails/railtie.rb @@ -1,12 +1,17 @@ require 'bower-rails' +require 'bower-rails/dsl' require 'rails' + module BowerRails class Railtie < Rails::Railtie railtie_name :bower + BowerRails::Dsl.config = {:root_path => Rails.root} + dsl = BowerRails::Dsl.evalute(File.join("Jsfile")) + config.after_initialize do |app| - ["lib", "vendor"].each do |dir| - app.config.assets.paths << Rails.root.join(dir, 'assets', 'bower_components') + dsl.final_assets_path.map do |assets_root, assets_path| + app.config.assets.paths << Rails.root.join(assets_root, assets_path, "bower_components") end end From c5870e38c2cc763ce497ff4c983d5816dac257b0 Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sun, 28 Jul 2013 20:41:49 +0600 Subject: [PATCH 4/7] Readme updated --- README.md | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 93c6ce9..932f7cb 100644 --- a/README.md +++ b/README.md @@ -59,26 +59,47 @@ The bower.json file is two seperate bower [component.js](https://github.com/twit ##Ruby DSL configuration -The Ruby DSL configuration is a Jsfile with DSL syntax similar to Bundler - +The Ruby DSL configuration is a Jsfile with DSL syntax similar to Bundler. **Example Jsfile** +By default assets are put to `./vendor/assets/bower_components` directory: + +``` ruby + +# Puts to ./vendor/assets/bower_components +js "backbone" +js "moment" +``` + +But the default value can be overridden by `assets_path` method: + +``` ruby +assets_path "assets/my_javascripts" + +# Puts to ./vendor/assets/my_javascripts/bower_components +js "backbone" +js "moment" +``` + +And finally, the `assets_path` method can be overridden by an option in a `group` call: + ``` ruby assets_path "assets/javascript" -# Puts files under ./vendor/assets/js +# Puts files under ./vendor/assets/js/bower_components group :vendor, :assets_path => "assets/js" do js "jquery" # Assummes it's latests js "backbone", "1.2" end -# Puts files under ./lib/assets/javascript +# Puts files under ./lib/assets/javascript/bower_components group :lib do js "jquery" js "backbone", "1.2" end ``` +NOTE: All the assets should be stored in `/assets` subdirectory so putting it under `./vendor/js` directory is unavailable **Available commands with a Jsfile** From 062405925b71a82c5617504d12dc9e3f815e88bb Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sun, 28 Jul 2013 21:07:41 +0600 Subject: [PATCH 5/7] Setting default assets_path if it is not specified by user --- lib/bower-rails/dsl.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index 79a03d4..82540da 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -28,8 +28,10 @@ def directories end def group(*args, &blk) - custom_assets_path = args[1][:assets_path] - raise ArgumentError, "Assets should be stored in /assets directory, try :assets_path => 'assets/#{custom_assets_path}' instead" if custom_assets_path.match(/assets/).nil? + if args[1] + custom_assets_path = args[1][:assets_path] + raise ArgumentError, "Assets should be stored in /assets directory, try :assets_path => 'assets/#{custom_assets_path}' instead" if custom_assets_path.match(/assets/).nil? + end new_group = [args[0], args[1]] @groups << new_group yield @@ -40,8 +42,8 @@ def js(name, *args) @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.each do |g| - group_options = g.last - assets_path = group_options[:assets_path] + group_options = Hash === g.last ? g.pop : {} + assets_path = group_options[:assets_path] || @assets_path g_norm = normalize_location_path(g.first.to_s, assets_path) @dependencies[g_norm] ||= {} @@ -65,8 +67,8 @@ def write_bower_json def write_dotbowerrc @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.map do |g| - group_options = g.last - assets_path = group_options[:assets_path] + group_options = Hash === g.last ? g.pop : {} + assets_path = group_options[:assets_path] || @assets_path File.open(File.join(g.first.to_s, assets_path, ".bowerrc"), "w") do |f| f.write(JSON.pretty_generate({:directory => "bower_components"})) @@ -77,7 +79,9 @@ def write_dotbowerrc def final_assets_path @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.map do |g| - [g.first.to_s, g.last[:assets_path]] + group_options = Hash === g.last ? g.pop : {} + assets_path = group_options[:assets_path] || @assets_path + [g.first.to_s, assets_path] end end From 2305665d0f3da7c83037ade5774b417e746f48aa Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Sun, 28 Jul 2013 21:19:17 +0600 Subject: [PATCH 6/7] DRYing BowerRails::Dsl --- lib/bower-rails/dsl.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index 82540da..19156b8 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -31,8 +31,11 @@ def group(*args, &blk) if args[1] custom_assets_path = args[1][:assets_path] raise ArgumentError, "Assets should be stored in /assets directory, try :assets_path => 'assets/#{custom_assets_path}' instead" if custom_assets_path.match(/assets/).nil? + new_group = [args[0], args[1]] + else + new_group = [args[0]] end - new_group = [args[0], args[1]] + @groups << new_group yield end @@ -42,10 +45,7 @@ def js(name, *args) @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.each do |g| - group_options = Hash === g.last ? g.pop : {} - assets_path = group_options[:assets_path] || @assets_path - - g_norm = normalize_location_path(g.first.to_s, assets_path) + g_norm = normalize_location_path(g.first.to_s, group_assets_path(g)) @dependencies[g_norm] ||= {} @dependencies[g_norm][name] = version end @@ -67,10 +67,7 @@ def write_bower_json def write_dotbowerrc @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.map do |g| - group_options = Hash === g.last ? g.pop : {} - assets_path = group_options[:assets_path] || @assets_path - - File.open(File.join(g.first.to_s, assets_path, ".bowerrc"), "w") do |f| + File.open(File.join(g.first.to_s, group_assets_path(g), ".bowerrc"), "w") do |f| f.write(JSON.pretty_generate({:directory => "bower_components"})) end end @@ -79,11 +76,14 @@ def write_dotbowerrc def final_assets_path @groups = [[:vendor, { assets_path: @assets_path }]] if @groups.empty? @groups.map do |g| - group_options = Hash === g.last ? g.pop : {} - assets_path = group_options[:assets_path] || @assets_path - [g.first.to_s, assets_path] + [g.first.to_s, group_assets_path(g)] end - end + end + + def group_assets_path group + group_options = Hash === group.last ? group.pop : {} + group_options[:assets_path] || @assets_path + end private From 3966a3a34eb394fdc3a14a4df0a491224f36a62c Mon Sep 17 00:00:00 2001 From: Sergey Kishenin Date: Mon, 29 Jul 2013 14:02:29 +0600 Subject: [PATCH 7/7] Additional fixes - using .bowerrc for managing bower directories with plain bower.json - using before_initialize instead of after_initialize at bower-rails/railties.rb - group.last instead of group.pop --- lib/bower-rails/dsl.rb | 4 ++-- lib/bower-rails/railtie.rb | 18 +++++++++++++----- lib/tasks/bower.rake | 12 +++++++++--- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/bower-rails/dsl.rb b/lib/bower-rails/dsl.rb index 19156b8..de7602b 100644 --- a/lib/bower-rails/dsl.rb +++ b/lib/bower-rails/dsl.rb @@ -81,8 +81,8 @@ def final_assets_path end def group_assets_path group - group_options = Hash === group.last ? group.pop : {} - group_options[:assets_path] || @assets_path + group_options = Hash === group.last ? group.last : {:assets_path => @assets_path} + group_options[:assets_path] end private diff --git a/lib/bower-rails/railtie.rb b/lib/bower-rails/railtie.rb index e772c18..015db51 100644 --- a/lib/bower-rails/railtie.rb +++ b/lib/bower-rails/railtie.rb @@ -6,12 +6,20 @@ module BowerRails class Railtie < Rails::Railtie railtie_name :bower - BowerRails::Dsl.config = {:root_path => Rails.root} - dsl = BowerRails::Dsl.evalute(File.join("Jsfile")) + if File.exist?(File.join("Jsfile")) + BowerRails::Dsl.config = {:root_path => Rails.root} + dsl = BowerRails::Dsl.evalute(File.join("Jsfile")) - config.after_initialize do |app| - dsl.final_assets_path.map do |assets_root, assets_path| - app.config.assets.paths << Rails.root.join(assets_root, assets_path, "bower_components") + config.before_initialize do |app| + dsl.final_assets_path.map do |assets_root, assets_path| + app.config.assets.paths << Rails.root.join(assets_root, assets_path, "bower_components") + end + end + else + config.before_initialize do |app| + ["lib", "vendor"].each do |dir| + app.config.assets.paths << Rails.root.join(dir, 'assets', 'bower_components') + end end end diff --git a/lib/tasks/bower.rake b/lib/tasks/bower.rake index 409517f..6ef3f83 100644 --- a/lib/tasks/bower.rake +++ b/lib/tasks/bower.rake @@ -84,17 +84,23 @@ def perform_command remove_components = true FileUtils.rm_rf("bower_components") if remove_components #create bower json - File.open("bower.json","w") do |f| + File.open("bower.json", "w") do |f| f.write(data.to_json) end + #create .bowerrc + File.open(".bowerrc", "w") do |f| + f.write(JSON.pretty_generate({:directory => "bower_components"})) + end + #run command yield #remove bower file FileUtils.rm("bower.json") - end if data - + #remove .bowerrc + FileUtils.rm(".bowerrc") + end if data && !data["dependencies"].empty? end end