bower-rails 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e093ead1cb89b8a18574ac632f4eb317f92778d
4
- data.tar.gz: df6f32947bcf3d5d6b85d9ddd07a63085c336d92
3
+ metadata.gz: 31f963c6de9dbf11d82b7332fac43fb6567b7f37
4
+ data.tar.gz: 1d92e3757ebdec02f959734146467fb785f1c622
5
5
  SHA512:
6
- metadata.gz: 88354fff0c91e7a6f62b355d5ef8a5cd8b55a6cd5ab6b3f0b5f783fba045be31140042608f7c1f16c31ade792c432a7d98b429326ebaa72752d75d0c52be7f6a
7
- data.tar.gz: c1f2d63f353362eac6ff534d1cbc3220ee301177ba49d6c27f944c0330890cc4d35830ef543344491762d0af3e8097c523ed9245f825755cdca696ae6dc89a19
6
+ metadata.gz: 035db30cbf3f159541e4bc6a17ae603345d8a49a2333b709fe47a43fb08a6668c2e9d80c2ed966cc9c25d3f764de822c30067a07717abbb2fc4bd9d5c74d8eb5
7
+ data.tar.gz: a89cf62910a31b30317028c0b291958f317ee542d728500018389a1076574360a0bfa0b427a5c71e447f042f1d30db2559049609497b51699a7c99b24f095575
data/README.md CHANGED
@@ -1,11 +1,17 @@
1
1
  bower-rails
2
2
  ===========
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/bower-rails.png)](http://badge.fury.io/rb/bower-rails)
5
- [![Code Climate](https://codeclimate.com/github/42dev/bower-rails.png)](https://codeclimate.com/github/42dev/bower-rails)
6
- [![Dependency Status](https://gemnasium.com/SergeyKishenin/bower-rails.png)](https://gemnasium.com/SergeyKishenin/bower-rails)
7
- [![Build Status](https://travis-ci.org/42dev/bower-rails.png?branch=master)](https://travis-ci.org/42dev/bower-rails)
8
- [![Coverage Status](https://coveralls.io/repos/42dev/bower-rails/badge.png)](https://coveralls.io/r/42dev/bower-rails)
4
+ [![Gem Version](http://img.shields.io/gem/v/bower-rails.svg)][gem]
5
+ [![Code Climate](http://img.shields.io/codeclimate/github/42dev/bower-rails.svg)][codeclimate]
6
+ [![Dependency Status](http://img.shields.io/gemnasium/SergeyKishenin/bower-rails.svg)][gemnasium]
7
+ [![Build Status](http://img.shields.io/travis/mbj/concord/master.svg)][travis]
8
+ [![Coverage Status](https://coveralls.io/repos/42dev/bower-rails/badge.png)][coveralls]
9
+
10
+ [gem]: https://rubygems.org/gems/bower-rails
11
+ [travis]: https://travis-ci.org/mbj/concord
12
+ [gemnasium]: https://gemnasium.com/SergeyKishenin/bower-rails
13
+ [codeclimate]: https://codeclimate.com/github/42dev/bower-rails
14
+ [coveralls]: https://coveralls.io/r/42dev/bower-rails
9
15
 
10
16
  Bower support for Rails projects. Dependency file is bower.json in Rails root dir or Bowerfile if you use DSL.
11
17
  Check out [changelog][] for the latest changes and releases.
@@ -22,7 +28,7 @@ Check out [changelog][] for the latest changes and releases.
22
28
  in Gemfile
23
29
 
24
30
  ``` Ruby
25
- gem "bower-rails", "~> 0.7.3"
31
+ gem "bower-rails", "~> 0.8.0"
26
32
  ```
27
33
 
28
34
  ##JSON configuration
@@ -84,7 +90,7 @@ asset "secret_logic", "1.0.0", git: "git@github.com:initech/secret_logic"
84
90
  # get from a github repo
85
91
  asset "secret_logic", "1.0.0", github: "initech/secret_logic"
86
92
 
87
- # get a specific revision from a git endpoint
93
+ # get a specific revision from a git endpoint
88
94
  asset "secret_logic", github: "initech/secret_logic", ref: '0adff'
89
95
  ```
90
96
 
@@ -98,7 +104,7 @@ asset "backbone"
98
104
  asset "moment"
99
105
  ```
100
106
 
101
- And finally, the `assets_path` method can be overridden by an option in a `group` call:
107
+ The `assets_path` method can be overridden by an option in a `group` call:
102
108
 
103
109
  ``` ruby
104
110
  assets_path "assets/javascript"
@@ -118,16 +124,56 @@ end
118
124
  NOTE: Available groups are `:lib` and `:vendor`. Others are not allowed according to the Rails convention.
119
125
  NOTE: All the assets should be stored in `/assets` subdirectory so putting it under `./vendor/js` directory is unavailable
120
126
 
127
+ And finally, you can specify the assets to be in the devDependencies block:
128
+
129
+ ``` ruby
130
+ asset "backbone", "1.1.1"
131
+
132
+ # Adds jasmine-sinon and jasmine-matchers to devDependencies
133
+ dependency :dev_dependencies do
134
+ asset "jasmine-sinon" # Defaults to 'latest'
135
+ asset "jasmine-matchers" # Defaults to 'latest'
136
+ end
137
+
138
+ # Explicit dependency group notation ( not neccessary )
139
+ dependency_group :dependencies do
140
+ asset "emberjs" # Defaults to 'latest'
141
+ end
142
+ ```
143
+ results in the following bower.json file:
144
+
145
+ ```
146
+ {
147
+ "name": "dsl-generated dependencies",
148
+ "dependencies": {
149
+ "backbone": "1.1.1"
150
+ "angular": "1.2.18",
151
+ },
152
+ "devDependencies": {
153
+ "jasmine-sinon": "latest",
154
+ "jasmine-matchers": "latest"
155
+ }
156
+ }
157
+ ```
158
+ NOTE: Available dependency groups are `:dependencies` (default) and `:dev_dependencies`. Others are not allowed according to the Rails convention.
159
+
121
160
  ##Configuration
122
161
 
123
162
  Change options in your `config/initializers/bower_rails.rb`:
124
163
 
125
164
  ``` ruby
126
165
  BowerRails.configure do |bower_rails|
127
- # By default options are false
128
- bower_rails.install_before_precompile = true # invokes rake bower:install before precompilation
129
- bower_rails.resolve_before_precompile = true # invokes rake bower:resolve before precompilation
130
- bower_rails.clean_before_precompile = true # invokes rake bower:clean before precompilation
166
+ # Tell bower-rails what path should be considered as root. Defaults to Dir.pwd
167
+ bower_rails.root_path = Dir.pwd
168
+
169
+ # Invokes rake bower:install before precompilation. Defaults to false
170
+ bower_rails.install_before_precompile = true
171
+
172
+ # Invokes rake bower:resolve before precompilation. Defaults to false
173
+ bower_rails.resolve_before_precompile = true
174
+
175
+ # Invokes rake bower:clean before precompilation. Defaults to false
176
+ bower_rails.clean_before_precompile = true
131
177
  end
132
178
  ```
133
179
 
@@ -148,8 +194,9 @@ By default this line is added while running the generator.
148
194
 
149
195
  Once you are done with `bower.json` or `Bowerfile` you can run
150
196
 
151
- * `rake bower:install` to install js components
152
- * `rake bower:update` to update js components
197
+ * `rake bower:install` to install packages
198
+ * `rake bower:install:deployment` to install packages from bower.json
199
+ * `rake bower:update` to update packages
153
200
  * `rake bower:update:prune` to update components and uninstall extraneous packages
154
201
  * `rake bower:list` to list all packages
155
202
  * `rake bower:clean` to remove all files not listed as [main files](#bower-main-files) (if specified)
data/lib/bower-rails.rb CHANGED
@@ -5,6 +5,9 @@ module BowerRails
5
5
  extend self
6
6
 
7
7
  class << self
8
+ # The root path of the project
9
+ attr_accessor :root_path
10
+
8
11
  # An array of tasks to enhance `rake assets:precompile`
9
12
  attr_reader :tasks
10
13
 
@@ -35,10 +38,10 @@ module BowerRails
35
38
  end
36
39
  end
37
40
 
38
- # By default tasks are empty
39
- @tasks = []
40
41
 
41
42
  # Set default values for options
43
+ @root_path = Dir.pwd
44
+ @tasks = []
42
45
  @install_before_precompile = false
43
46
  @resolve_before_precompile = false
44
47
  @clean_before_precompile = false
@@ -4,15 +4,19 @@ require 'fileutils'
4
4
  module BowerRails
5
5
  class Dsl
6
6
 
7
- def self.evalute(filename)
8
- new.tap { |dsl| dsl.eval_file(File.join(dsl.root_path, filename)) }
7
+ DEFAULT_DEPENDENCY_GROUP = :dependencies
8
+
9
+ def self.evalute(root_path, filename)
10
+ new.tap { |dsl| dsl.eval_file(File.join(root_path, filename)) }
9
11
  end
10
12
 
11
13
  attr_reader :dependencies, :root_path
12
14
 
13
- def initialize
15
+ def initialize(root_path)
16
+ @dependency_groups = []
17
+ @root_path = root_path
18
+ @bower_dependencies_list = []
14
19
  @dependencies = {}
15
- @root_path ||= Dir.pwd
16
20
  @assets_path ||= "assets"
17
21
  end
18
22
 
@@ -34,6 +38,16 @@ module BowerRails
34
38
  yield if block_given?
35
39
  end
36
40
 
41
+ def dependency_group(name, options = {}, &block)
42
+
43
+ assert_dependency_group_name name
44
+ add_dependency_group name
45
+
46
+ yield if block_given?
47
+
48
+ remove_dependency_group!
49
+ end
50
+
37
51
  def asset(name, *args)
38
52
  group = @current_group || default_group
39
53
  options = Hash === args.last ? args.pop.dup : {}
@@ -53,7 +67,8 @@ module BowerRails
53
67
 
54
68
  normalized_group_path = normalize_location_path(group.first, group_assets_path(group))
55
69
  @dependencies[normalized_group_path] ||= {}
56
- @dependencies[normalized_group_path][name] = version
70
+ @dependencies[normalized_group_path][current_dependency_group_normalized] ||= {}
71
+ @dependencies[normalized_group_path][current_dependency_group_normalized][name] = version
57
72
  end
58
73
 
59
74
  def write_bower_json
@@ -66,7 +81,7 @@ module BowerRails
66
81
  end
67
82
 
68
83
  def generate_dotbowerrc
69
- contents = JSON.parse(File.read(File.join(@root_path, '.bowerrc'))) rescue {}
84
+ contents = JSON.parse(File.read(File.join(root_path, '.bowerrc'))) rescue {}
70
85
  contents["directory"] = "bower_components"
71
86
  JSON.pretty_generate(contents)
72
87
  end
@@ -83,7 +98,7 @@ module BowerRails
83
98
  def final_assets_path
84
99
  groups.map do |group|
85
100
  [group.first.to_s, group_assets_path(group)]
86
- end
101
+ end.uniq
87
102
  end
88
103
 
89
104
  def group_assets_path group
@@ -92,6 +107,39 @@ module BowerRails
92
107
 
93
108
  private
94
109
 
110
+ # Returns name for the current dependency from the stack
111
+ #
112
+ def current_dependency_group
113
+ @dependency_groups.last || DEFAULT_DEPENDENCY_GROUP.to_sym
114
+ end
115
+
116
+ # Returns normalized current dependency group name
117
+ #
118
+ def current_dependency_group_normalized
119
+ normalize_dependency_group_name current_dependency_group
120
+ end
121
+
122
+ # Implementing ActiveSupport::Inflector camelize(:lower)
123
+ #
124
+ def normalize_dependency_group_name(name)
125
+ segments = name.to_s.dup.downcase.split(/_/)
126
+ [segments.shift, *segments.map{ |word| word.capitalize }].join('').to_sym
127
+ end
128
+
129
+ # Stores the dependency group name in the stack
130
+ #
131
+ def add_dependency_group(dependency_group)
132
+ @dependency_groups.push dependency_group.to_sym
133
+
134
+ dependency_group
135
+ end
136
+
137
+ # Removes the dependency group name in the stack
138
+ #
139
+ def remove_dependency_group!
140
+ @dependency_groups.pop
141
+ end
142
+
95
143
  def add_group(*group)
96
144
  @groups = (groups << group) and return group
97
145
  end
@@ -104,11 +152,18 @@ module BowerRails
104
152
  [:vendor, { :assets_path => @assets_path }]
105
153
  end
106
154
 
155
+ # Attempts to parse data from @dependencies to JSON
156
+ #
107
157
  def dependencies_to_json(data)
108
158
  JSON.pretty_generate({
109
- :name => "dsl-generated dependencies",
110
- :dependencies => data
111
- })
159
+ :name => "dsl-generated dependencies"
160
+ }.merge(data))
161
+ end
162
+
163
+ def assert_dependency_group_name(name)
164
+ unless [:dependencies, :devDependencies].include?(normalize_dependency_group_name(name))
165
+ raise ArgumentError, "Dependency group should be either dependencies or dev_dependencies, provided: #{name}"
166
+ end
112
167
  end
113
168
 
114
169
  def assets_path(assets_path)
@@ -127,7 +182,7 @@ module BowerRails
127
182
  end
128
183
 
129
184
  def normalize_location_path(loc, assets_path)
130
- File.join(@root_path, loc.to_s, assets_path)
185
+ File.join(root_path, loc.to_s, assets_path)
131
186
  end
132
187
  end
133
188
  end
@@ -0,0 +1,195 @@
1
+ require 'json'
2
+ require 'pp'
3
+ require 'find'
4
+
5
+ module BowerRails
6
+ class Performer
7
+ include FileUtils
8
+
9
+ def self.perform(*args, &block)
10
+ new.perform(*args, &block)
11
+ end
12
+
13
+ def root_path
14
+ BowerRails.root_path
15
+ end
16
+
17
+ def perform(remove_components = true, &block)
18
+ entries = Dir.entries(root_path)
19
+
20
+ npm_path = File.join(root_path, 'node_modules', '.bin')
21
+ bower = find_command('bower', [npm_path])
22
+
23
+ if bower.nil?
24
+ $stderr.puts ["Bower not found! You can install Bower using Node and npm:",
25
+ "$ npm install bower -g",
26
+ "For more info see http://bower.io/"].join("\n")
27
+ return
28
+ end
29
+
30
+ if entries.include?('Bowerfile')
31
+ dsl_perform_command remove_components do
32
+ instance_exec(bower, &block) if block_given?
33
+ end
34
+ elsif entries.include?('bower.json')
35
+ perform_command remove_components do
36
+ instance_exec(bower, &block) if block_given?
37
+ end
38
+ else
39
+ raise LoadError, "No Bowerfile or bower.json file found. Make sure you have it at the root of your project"
40
+ end
41
+ end
42
+
43
+ def dsl
44
+ @dsl ||= BowerRails::Dsl.evalute(root_path, "Bowerfile")
45
+ end
46
+
47
+ def dsl_perform_command(remove_components = true, &block)
48
+ if remove_components
49
+ dsl.write_bower_json
50
+ dsl.write_dotbowerrc
51
+ puts "bower.js files generated"
52
+ end
53
+
54
+ if block_given?
55
+ dsl.directories.each do |dir|
56
+ Dir.chdir(dir) do
57
+ yield
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ #run the passed bower block in appropriate folders
64
+ def perform_command(remove_components = true, &block)
65
+ # Load in bower json file
66
+ txt = File.read(File.join(root_path, "bower.json"))
67
+ json = JSON.parse(txt)
68
+
69
+
70
+ # Load and merge root .bowerrc
71
+ dot_bowerrc = JSON.parse(File.read(File.join(root_path, '.bowerrc'))) rescue {}
72
+ dot_bowerrc["directory"] = "bower_components"
73
+
74
+ if json.except('lib', 'vendor').empty?
75
+ folders = json.keys
76
+ else
77
+ raise "Assuming a standard bower package but cannot find the required 'name' key" unless !!json['name']
78
+ folders = ['vendor']
79
+ end
80
+
81
+ folders.each do |dir|
82
+ data = json[dir]
83
+
84
+ # Assume using standard bower.json if folder name is not found
85
+ data = json if data.nil?
86
+
87
+ # Check folder existence and create?
88
+ dir = File.join(root_path, dir, "assets")
89
+ FileUtils.mkdir_p dir unless File.directory? dir
90
+ # Go in to dir to act
91
+ Dir.chdir(dir) do
92
+
93
+ # Remove old components
94
+ FileUtils.rm_rf("bower_components") if remove_components
95
+
96
+ # Create bower.json
97
+ File.open("bower.json", "w") do |f|
98
+ f.write(data.to_json)
99
+ end
100
+
101
+ # Create .bowerrc
102
+ File.open(".bowerrc", "w") do |f|
103
+ f.write(JSON.pretty_generate(dot_bowerrc))
104
+ end
105
+
106
+ # Run command
107
+ yield if block_given?
108
+
109
+ # Remove bower.json
110
+ FileUtils.rm("bower.json")
111
+
112
+ # Remove .bowerrc
113
+ FileUtils.rm(".bowerrc")
114
+ end if data && !data["dependencies"].empty?
115
+ end
116
+ end
117
+
118
+ def resolve_asset_paths
119
+ # Resolve relative paths in CSS
120
+ Dir['bower_components/**/*.css'].each do |filename|
121
+ contents = File.read(filename) if FileTest.file?(filename)
122
+ # http://www.w3.org/TR/CSS2/syndata.html#uri
123
+ url_regex = /url\(\s*['"]?(?![a-z]+:)([^'"\)]*)['"]?\s*\)/
124
+
125
+ # Resolve paths in CSS file if it contains a url
126
+ if contents =~ url_regex
127
+ directory_path = Pathname.new(File.dirname(filename))
128
+ .relative_path_from(Pathname.new('bower_components'))
129
+
130
+ # Replace relative paths in URLs with Rails asset_path helper
131
+ new_contents = contents.gsub(url_regex) do |match|
132
+ relative_path = $1
133
+ image_path = directory_path.join(relative_path).cleanpath
134
+ puts "#{match} => #{image_path}"
135
+
136
+ "url(<%= asset_path '#{image_path}' %>)"
137
+ end
138
+
139
+ # Replace CSS with ERB CSS file with resolved asset paths
140
+ FileUtils.rm(filename)
141
+ File.write(filename + '.erb', new_contents)
142
+ end
143
+ end
144
+ end
145
+
146
+ def remove_extra_files
147
+ puts "\nAttempting to remove all but main files as specified by bower\n"
148
+
149
+ Dir['bower_components/*'].each do |component_dir|
150
+ if File.exists?(File.join(component_dir, 'bower.json'))
151
+ bower_file = File.read(File.join(component_dir, 'bower.json'))
152
+ elsif File.exists?(File.join(component_dir, '.bower.json'))
153
+ bower_file = File.read(File.join(component_dir, '.bower.json'))
154
+ else
155
+ next
156
+ end
157
+
158
+ # Parse bower.json
159
+ bower_json = JSON.parse(bower_file)
160
+ main_files = bower_json['main']
161
+ next unless main_files
162
+
163
+ # Handle singular or multiple files
164
+ main_files = [main_files] unless main_files.is_a?(Array)
165
+
166
+ # Remove "./" relative path from main file strings
167
+ main_files.map! { |file| File.join(component_dir, file.gsub(/^\.\//, '')) }
168
+
169
+ # Delete all files that are not in main
170
+ Find.find(component_dir).reverse_each do |file_or_dir|
171
+ next if main_files.include?(file_or_dir)
172
+ if File.directory?(file_or_dir)
173
+ Dir.rmdir(file_or_dir) if (Dir.entries(file_or_dir) - %w[ . .. ]).empty?
174
+ else
175
+ FileUtils.rm(file_or_dir)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
182
+ def find_command(cmd, paths = [])
183
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
184
+ paths += ENV['PATH'].split(File::PATH_SEPARATOR)
185
+ paths.each do |path|
186
+ exts.each do |ext|
187
+ exe = File.join(path, "#{cmd}#{ext}")
188
+ return exe if (File.executable?(exe) && File.file?(exe))
189
+ end
190
+ end
191
+ nil
192
+ end
193
+
194
+ end
195
+ end
@@ -9,8 +9,7 @@ module BowerRails
9
9
 
10
10
  if File.exist?(@@bowerfile)
11
11
  config.before_initialize do |app|
12
- @dsl = BowerRails::Dsl.evalute(@@bowerfile)
13
-
12
+ @dsl = BowerRails::Dsl.evalute(BowerRails.root_path, @@bowerfile)
14
13
  @dsl.final_assets_path.map do |assets_root, assets_path|
15
14
  app.config.assets.paths << Rails.root.join(assets_root, assets_path, "bower_components")
16
15
  end
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module BowerRails
3
- VERSION = "0.7.3"
3
+ VERSION = "0.8.0"
4
4
  end
@@ -1,10 +1,13 @@
1
1
  BowerRails.configure do |bower_rails|
2
- # Invoke `rake bower:install` automatically before the `rake assets:precompile` task.
2
+ # Tell bower-rails what path should be considered as root. Defaults to Dir.pwd
3
+ # bower_rails.root_path = Dir.pwd
4
+
5
+ # Invokes rake bower:install before precompilation. Defaults to false
3
6
  # bower_rails.install_before_precompile = true
4
7
 
5
- # Invoke `rake bower:resolve` automatically before the `rake assets:precompile` task.
8
+ # Invokes rake bower:resolve before precompilation. Defaults to false
6
9
  # bower_rails.resolve_before_precompile = true
7
10
 
8
- # Invoke `rake bower:clean` automatically before the `rake assets:precompile` task.
9
- # bower_rails.clean_before_precompile = true
10
- end
11
+ # Invokes rake bower:clean before precompilation. Defaults to false
12
+ # bower_rails.clean_before_precompile = true
13
+ end
data/lib/tasks/bower.rake CHANGED
@@ -1,29 +1,50 @@
1
- require 'json'
2
- require 'pp'
3
- require 'find'
1
+ require 'bower-rails/performer'
4
2
 
5
3
  include BeforeHook
6
4
 
7
5
  namespace :bower do
8
6
  desc "Install components from bower"
9
7
  task :install, :options do |_, args|
10
- args.with_defaults(:options => '')
11
- perform do |bower|
12
- sh "#{bower} install #{args[:options]}"
8
+ if ENV['RAILS_ENV'] && ENV['RAILS_ENV'] == 'development'
9
+ Rake::Task["bower:install:development"].invoke(args[:options])
10
+ else
11
+ Rake::Task["bower:install:production"].invoke(args[:options])
12
+ end
13
+ end
14
+
15
+ namespace :install do
16
+ desc "Install components from bower using previously generated bower.json"
17
+ task :deployment, :options do |_, args|
18
+ args.with_defaults(:options => '')
19
+ BowerRails::Performer.perform false do |bower|
20
+ sh "#{bower} install #{args[:options]}"
21
+ end
22
+ end
23
+
24
+ desc "Install both dependencies and devDependencies from bower"
25
+ task :development, :options do |_, args|
26
+ args.with_defaults(:options => '')
27
+ perform{ |bower| sh "#{bower} install #{args[:options]}" }
28
+ end
29
+
30
+ desc "Install only dependencies, excluding devDependencies from bower"
31
+ task :production, :options do |_, args|
32
+ args.with_defaults(:options => '')
33
+ perform{ |bower| sh "#{bower} install -p #{args[:options]}" }
13
34
  end
14
35
  end
15
36
 
16
37
  desc "Update bower components"
17
38
  task :update, :options do |_, args|
18
39
  args.with_defaults(:options => '')
19
- perform do |bower|
40
+ BowerRails::Performer.perform do |bower|
20
41
  sh "#{bower} update #{args[:options]}"
21
42
  end
22
43
  end
23
44
 
24
45
  desc "List bower components"
25
46
  task :list do
26
- perform false do |bower|
47
+ BowerRails::Performer.perform false do |bower|
27
48
  sh "#{bower} list"
28
49
  end
29
50
  end
@@ -32,7 +53,7 @@ namespace :bower do
32
53
  desc "Update existing components and uninstalls extraneous components"
33
54
  task :prune, :options do |_, args|
34
55
  args.with_defaults(:options => '')
35
- perform do |bower|
56
+ BowerRails::Performer.perform do |bower|
36
57
  sh "#{bower} update #{args[:options]} && #{bower} prune #{args[:options]}"
37
58
  end
38
59
  end
@@ -40,14 +61,14 @@ namespace :bower do
40
61
 
41
62
  desc "Resolve assets paths in bower components"
42
63
  task :resolve do
43
- perform false do
64
+ BowerRails::Performer.perform false do
44
65
  resolve_asset_paths
45
66
  end
46
67
  end
47
68
 
48
69
  desc "Attempt to keep only files listed in 'main' of each component's bower.json"
49
70
  task :clean do
50
- perform false do
71
+ BowerRails::Performer.perform false do
51
72
  remove_extra_files
52
73
  end
53
74
  end
@@ -57,186 +78,4 @@ before 'assets:precompile' do
57
78
  BowerRails.tasks.map do |task|
58
79
  Rake::Task[task].invoke
59
80
  end
60
- end
61
-
62
- def perform remove_components = true, &block
63
- entries = Dir.entries(get_bower_root_path)
64
-
65
- npm_path = File.join(get_bower_root_path, 'node_modules', '.bin')
66
- bower = find_command('bower', [npm_path])
67
-
68
- if bower.nil?
69
- $stderr.puts <<EOS
70
- Bower not found! You can install Bower using Node and npm:
71
- $ npm install bower -g
72
- For more info see http://bower.io/
73
- EOS
74
- return
75
- end
76
-
77
- if entries.include?('Bowerfile')
78
- dsl_perform_command remove_components do
79
- yield bower if block_given?
80
- end
81
- elsif entries.include?('bower.json')
82
- perform_command remove_components do
83
- yield bower if block_given?
84
- end
85
- else
86
- raise LoadError, "No Bowerfile or bower.json file found. Make sure you have it at the root of your project"
87
- end
88
- end
89
-
90
- def get_bower_root_path
91
- Dir.pwd
92
- end
93
-
94
- def dsl_perform_command remove_components = true, &block
95
- dsl = BowerRails::Dsl.evalute("Bowerfile")
96
-
97
- if remove_components
98
- dsl.write_bower_json
99
- dsl.write_dotbowerrc
100
- puts "bower.js files generated"
101
- end
102
-
103
- if block_given?
104
- dsl.directories.each do |dir|
105
- Dir.chdir(dir) do
106
- yield
107
- end
108
- end
109
- end
110
- end
111
-
112
- #run the passed bower block in appropriate folders
113
- def perform_command remove_components = true, &block
114
- bower_root = get_bower_root_path
115
- #load in bower json file
116
- txt = File.read(File.join(bower_root, "bower.json"))
117
- json = JSON.parse(txt)
118
-
119
-
120
- #load and merge root .bowerrc
121
- dot_bowerrc = JSON.parse(File.read(File.join(bower_root, '.bowerrc'))) rescue {}
122
- dot_bowerrc["directory"] = "bower_components"
123
-
124
- if json.except('lib', 'vendor').empty?
125
- folders = json.keys
126
- else
127
- raise "Assuming a standard bower package but cannot find the required 'name' key" unless !!json['name']
128
- folders = ['vendor']
129
- end
130
-
131
- folders.each do |dir|
132
- data = json[dir]
133
-
134
- # assume using standard bower.json if folder name is not found
135
- data = json if data.nil?
136
-
137
- #check folder existence and create?
138
- dir = File.join(bower_root, dir, "assets")
139
- FileUtils.mkdir_p dir unless File.directory? dir
140
- #go in to dir to act
141
- Dir.chdir(dir) do
142
-
143
- #remove old components
144
- FileUtils.rm_rf("bower_components") if remove_components
145
-
146
- #create bower json
147
- File.open("bower.json", "w") do |f|
148
- f.write(data.to_json)
149
- end
150
-
151
- #create .bowerrc
152
- File.open(".bowerrc", "w") do |f|
153
- f.write(JSON.pretty_generate(dot_bowerrc))
154
- end
155
-
156
- #run command
157
- yield if block_given?
158
-
159
- #remove bower file
160
- FileUtils.rm("bower.json")
161
-
162
- #remove .bowerrc
163
- FileUtils.rm(".bowerrc")
164
- end if data && !data["dependencies"].empty?
165
- end
166
- end
167
-
168
- def resolve_asset_paths
169
- # Resolve relative paths in CSS
170
- Dir['bower_components/**/*.css'].each do |filename|
171
- contents = File.read(filename) if FileTest.file?(filename)
172
- # http://www.w3.org/TR/CSS2/syndata.html#uri
173
- url_regex = /url\(\s*['"]?(?![a-z]+:)([^'"\)]*)['"]?\s*\)/
174
-
175
- # Resolve paths in CSS file if it contains a url
176
- if contents =~ url_regex
177
- directory_path = Pathname.new(File.dirname(filename))
178
- .relative_path_from(Pathname.new('bower_components'))
179
-
180
- # Replace relative paths in URLs with Rails asset_path helper
181
- new_contents = contents.gsub(url_regex) do |match|
182
- relative_path = $1
183
- image_path = directory_path.join(relative_path).cleanpath
184
- puts "#{match} => #{image_path}"
185
-
186
- "url(<%= asset_path '#{image_path}' %>)"
187
- end
188
-
189
- # Replace CSS with ERB CSS file with resolved asset paths
190
- FileUtils.rm(filename)
191
- File.write(filename + '.erb', new_contents)
192
- end
193
- end
194
- end
195
-
196
- def remove_extra_files
197
- puts "\nAttempting to remove all but main files as specified by bower\n"
198
-
199
- Dir['bower_components/*'].each do |component_dir|
200
- if File.exists?(File.join(component_dir, 'bower.json'))
201
- bower_file = File.read(File.join(component_dir, 'bower.json'))
202
- elsif File.exists?(File.join(component_dir, '.bower.json'))
203
- bower_file = File.read(File.join(component_dir, '.bower.json'))
204
- else
205
- next
206
- end
207
-
208
- # parse bower.json
209
- bower_json = JSON.parse(bower_file)
210
- main_files = bower_json['main']
211
- next unless main_files
212
-
213
- # handle singular or multiple files
214
- main_files = [main_files] unless main_files.is_a?(Array)
215
-
216
- # Remove "./" relative path from main file strings
217
- main_files.map! { |file| File.join(component_dir, file.gsub(/^\.\//, '')) }
218
-
219
- # delete all files that are not in main
220
- Find.find(component_dir).reverse_each do |file_or_dir|
221
- next if main_files.include?(file_or_dir)
222
- if File.directory?(file_or_dir)
223
- Dir.rmdir(file_or_dir) if (Dir.entries(file_or_dir) - %w[ . .. ]).empty?
224
- else
225
- FileUtils.rm(file_or_dir)
226
- end
227
- end
228
- end
229
- end
230
-
231
- # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
232
- def find_command(cmd, paths = [])
233
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
234
- paths += ENV['PATH'].split(File::PATH_SEPARATOR)
235
- paths.each do |path|
236
- exts.each do |ext|
237
- exe = File.join(path, "#{cmd}#{ext}")
238
- return exe if (File.executable?(exe) && File.file?(exe))
239
- end
240
- end
241
- nil
242
- end
81
+ end
@@ -8,9 +8,13 @@ module BeforeHook
8
8
 
9
9
  desc old_task.full_comment
10
10
  task task_name => old_task.prerequisites do
11
- new_task.call
11
+ begin
12
+ new_task.call
13
+ rescue LoadError
14
+ #empty
15
+ end
12
16
  old_task.invoke
13
17
  end
14
18
  end
15
19
  end
16
- end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bower-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Harrison
@@ -62,6 +62,7 @@ files:
62
62
  - README.md
63
63
  - lib/bower-rails.rb
64
64
  - lib/bower-rails/dsl.rb
65
+ - lib/bower-rails/performer.rb
65
66
  - lib/bower-rails/railtie.rb
66
67
  - lib/bower-rails/version.rb
67
68
  - lib/generators/bower_rails/initialize/initialize_generator.rb