breakfast 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55fe92f6b48d4ee747f50fc3a831d0863723e6bd
4
- data.tar.gz: 9a123637c58184758187ee44848f435a027d6910
3
+ metadata.gz: f9efb82f14ced85f239814ee2c1433b33f84cda1
4
+ data.tar.gz: ee25eca42d5a7358d824f7f5b533f6ca755e63b0
5
5
  SHA512:
6
- metadata.gz: d361f652699abef3b4a145ff06370860c08552240830fb338e2fbfe399d769141de8a803c14859c91585cf15084ce92ca80c48ea2a70787a428bcf34e308ed68
7
- data.tar.gz: 901bb0ece81ea661d5871ab62b8d2228fdfc68466faf99e66dbf1ab024f48196e7792a17d0fd1bf390573476b4755776f0be997347e47fd96e790c9f861c2b6d
6
+ metadata.gz: 62cdcdf0e004938f9d672cf8dc1d700f7b2aee6416617283611767e34ae9cbf99d8396e7de82fe75cb2b94c0891c0268c42f03cd58c6ff4c76901d00e9569077
7
+ data.tar.gz: e3ed59e5fc4c426d6c342427c3e6251ff1dba14e735def521dc19c6bb747fdb0bbae596c4670b443a3c041353abb29aa40a93608ecc7ad49f5e7b832b6b10328
@@ -1,9 +1,59 @@
1
1
  # CHANGE LOG
2
2
 
3
+ ### 0.4.0 - 2016-11-14
4
+ #### Upgrading to `0.4.0` from `0.3.0`
5
+ - Update gem with `bundle update breakfast`
6
+ - Bump the `breakfast-rails` version in `package.json` to `0.4.0`
7
+ - Run `npm install`
8
+
9
+ *Note* Now by default asset fingerprinting will be on by default in production.
10
+ A copy of each with the original filename will be present as well, so any
11
+ hard-coded links to assets will still work correctly.
12
+
13
+ #### Added
14
+ - Asset Digests. Now when deploying assets will have fingerprints added to their
15
+ file names. This allows browsers to aggressively cache your assets.
16
+ - New Option: `breakfast.manifest.digest`. Defaults to false in development /
17
+ test and true everywhere else. When true, enables Rails to serve fingerprinted
18
+ assets.
19
+ - Rake Commands to trigger certain behavior:
20
+ - `breakfast:assets:build`
21
+ Manually run a compilation step.
22
+ - `breakfast:assets:build_production`
23
+ Manually trigger a production build. This will cause assets to get minified.
24
+ - `breakfast:assets:digest`
25
+ Run through your compiled assets and add a fingerprint to each one. Creates
26
+ a copy, leaving a file with the original filename and a duplicate with an
27
+ md5 fingerprint.
28
+ - `breakfast:assets:clean`
29
+ Removes any assets from the output folder that are not specified in the
30
+ manifest file (removes out of date files).
31
+ - `breakfast:assets:nuke`
32
+ Removes manifest and fingerprinted assets from the output folder.
33
+ - New Capistrano Option: `:breakfast_npm_install_command`
34
+ Defaults to just `install`. Can be overridden to redirect output to dev/null.
35
+ Example:
36
+
37
+ ```
38
+ set :breakfast_npm_install_command, "install > /dev/null 2>&1"
39
+ ```
40
+
41
+ #### Changes
42
+ - Fixed small CSS issue if box-sizing is not set border-box globally.
43
+
44
+
45
+ #### Contributors
46
+ Many many thanks to the contributors for this release!
47
+ - [@patkoperwas](https://github.com/patkoperwas)
48
+ - [@mikeastock](https://github.com/mikeastock)
49
+ - [@HParker](https://github.com/HParker)
50
+
51
+
3
52
  ## 0.3.1 - 2016-10-19
4
53
  - Better support for determining if Server is running. Using puma, passneger,
5
54
  etc. instead of the default rails server command now work.
6
55
 
56
+
7
57
  ## 0.3.0 - 2016-09-28
8
58
 
9
59
  ### Upgrading from `0.2.0`
data/README.md CHANGED
@@ -15,46 +15,48 @@ See the official docs at
15
15
 
16
16
  View updates in the [CHANGELOG](https://github.com/devlocker/breakfast/blob/master/CHANGELOG.md)
17
17
 
18
- ### Latest Patch `0.3.1`
19
- - Allows Breakfast to run when Rails is started outside of bin/rails server,
20
- i.e. bundle exec puma, passenger, thin, etc.
21
-
22
- ### Latest Release `0.3.0`
18
+ ### Latest Release `0.4.0`
23
19
  #### Added
24
- - New status bar that allows the user to switch reload strategies on the fly
25
- - Support for Haml & Slim files (without .html extension)
26
- - Reloading on ruby file changes.
27
- - Specify minimum Node & NPM versions when installing (avoid awkward and none
28
- descriptive error messages)
29
- - NPM binary path for Capistrano
20
+ - Asset Digests. Now when deploying assets will have fingerprints added to their
21
+ file names. This allows browsers to aggressively cache your assets.
22
+ - New Option: `breakfast.manifest.digest`. Defaults to false in development /
23
+ test and true everywhere else. When true, enables Rails to serve fingerprinted
24
+ assets.
25
+ - Rake Commands to trigger certain behavior:
26
+ - `breakfast:assets:build`
27
+ Manually run a compilation step.
28
+ - `breakfast:assets:build_production`
29
+ Manually trigger a production build. This will cause assets to get minified.
30
+ - `breakfast:assets:digest`
31
+ Run through your compiled assets and add a fingerprint to each one. Creates
32
+ a copy, leaving a file with the original filename and a duplicate with an
33
+ md5 fingerprint.
34
+ - `breakfast:assets:clean`
35
+ Removes any assets from the output folder that are not specified in the
36
+ manifest file (removes out of date files).
37
+ - `breakfast:assets:nuke`
38
+ Removes manifest and fingerprinted assets from the output folder.
39
+ - New Capistrano Option: `:breakfast_npm_install_command`
40
+ Defaults to just `install`. Can be overridden to redirect output to dev/null.
41
+ Example:
30
42
 
31
- #### Changes
32
- - config.breakfast.view_folders change to config.breakfast.source_code_folders.
33
- Change brought about by need to trigger reloads when Ruby source code changes.
43
+ ```
44
+ set :breakfast_npm_install_command, "install > /dev/null 2>&1"
45
+ ```
34
46
 
35
- #### Removed
36
- - config.breakfast.view_folders is no longer supported. Deprecated in favor of
37
- source_code_folders option.
47
+ #### Changes
48
+ - Fixed small CSS issue if box-sizing is not set border-box globally.
38
49
 
39
50
 
40
51
  ### Upgrading
41
- #### Upgrading to `0.3.0` from `0.2.0`
52
+ #### Upgrading to `0.4.0` from `0.3.0`
42
53
  - Update gem with `bundle update breakfast`
43
- - Bump the `breakfast-rails` version in `package.json` to `0.3.1`
54
+ - Bump the `breakfast-rails` version in `package.json` to `0.4.0`
44
55
  - Run `npm install`
45
- - If you have modified the `config.breakfast.view_folders` option you will need
46
- to replace it. The new option is `config.breakfast.source_code_folders` and it
47
- defaults to `[Rails.root.join("app")]`. If you have view or Ruby files that
48
- you would like to trigger reloads outside of the `app` folder then append
49
- those paths by adding:
50
-
51
- ```
52
- config.breakfast.source_code_folders << Rails.root.join("lib")
53
- ```
54
-
55
- To which ever environment you want `Breakfast` to run in
56
- (probably `config/environments/development.rb`).
57
56
 
57
+ *Note* Now by default asset fingerprinting will be on by default in production.
58
+ A copy of each with the original filename will be present as well, so any
59
+ hard-coded links to assets will still work correctly.
58
60
 
59
61
  ### Contributing
60
62
  Bug reports and pull requests are welcome on GitHub at
@@ -1,13 +1,17 @@
1
1
  require "breakfast/version"
2
+
3
+ require "breakfast/brunch_watcher"
4
+ require "breakfast/compilation_listener"
2
5
  require "breakfast/live_reload_channel"
6
+ require "breakfast/manifest"
3
7
  require "breakfast/status_channel"
4
8
  require "breakfast/view_helper"
5
- require "breakfast/brunch_watcher"
6
- require "breakfast/compilation_listener"
7
9
 
8
10
  module Breakfast
9
11
  STATUS_CHANNEL = "breakfast_status".freeze
10
12
  RELOAD_CHANNEL = "breakfast_live_reload".freeze
13
+ BUILD_COMMAND = "./node_modules/brunch/bin/brunch build".freeze
14
+ PRODUCTION_BUILD_COMMAND = "./node_modules/brunch/bin/brunch build --production".freeze
11
15
  end
12
16
 
13
17
  require "breakfast/railtie" if defined?(Rails)
@@ -1,6 +1,6 @@
1
- require 'capistrano/version'
1
+ require "capistrano/version"
2
2
 
3
- if defined?(Capistrano::VERSION) && Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new('3.0.0')
3
+ if defined?(Capistrano::VERSION) && Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new("3.0.0")
4
4
  load File.expand_path("../capistrano/tasks/breakfast.rake", __FILE__)
5
5
  else
6
6
  raise "Requires Capistrano V3"
@@ -3,13 +3,28 @@ namespace :breakfast do
3
3
  task :compile do
4
4
  on roles fetch(:breakfast_roles) do |host|
5
5
  within release_path do
6
- execute fetch(:breakfast_npm_path).to_sym, "install"
7
- execute "node_modules/brunch/bin/brunch", "build --production"
6
+ with rails_env: "#{fetch(:rails_env) || fetch(:stage)}" do
7
+ execute fetch(:breakfast_npm_path).to_sym, fetch(:breakfast_npm_install_command)
8
+ execute :rails, "breakfast:assets:build_production"
9
+ execute :rails, "breakfast:assets:digest"
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ desc "Clean out old assets"
16
+ task :clean do
17
+ on roles fetch(:breakfast_roles) do |host|
18
+ within release_path do
19
+ with rails_env: "#{fetch(:rails_env) || fetch(:stage)}" do
20
+ execute :rails, "breakfast:assets:clean"
21
+ end
8
22
  end
9
23
  end
10
24
  end
11
25
 
12
26
  after "deploy:updated", "breakfast:compile"
27
+ after "deploy:published", "breakfast:clean"
13
28
  end
14
29
 
15
30
 
@@ -17,5 +32,6 @@ namespace :load do
17
32
  task :defaults do
18
33
  set :breakfast_roles, -> { :web }
19
34
  set :breakfast_npm_path, "/usr/bin/npm"
35
+ set :breakfast_npm_install_command, "install"
20
36
  end
21
37
  end
@@ -3,9 +3,9 @@ module Breakfast
3
3
  ASSET_EXTENSIONS = ["css", "js"].freeze
4
4
  SOURCE_CODE_EXTENSIONS = ["rb", "html", "haml", "slim"].freeze
5
5
 
6
- def self.start(asset_output_folders:, source_code_folders:)
7
- asset_listener =
8
- ::Listen.to(*asset_output_folders) do |modified, added, removed|
6
+ def self.start(asset_output_folder:, source_code_folders:)
7
+ asset_listener =
8
+ ::Listen.to(asset_output_folder) do |modified, added, removed|
9
9
  files = modified + added + removed
10
10
 
11
11
  ASSET_EXTENSIONS.each do |extension|
@@ -15,7 +15,7 @@ module Breakfast
15
15
  end
16
16
  end
17
17
 
18
- rails_listener =
18
+ rails_listener =
19
19
  ::Listen.to(*source_code_folders) do |modified, added, removed|
20
20
  files = modified + added + removed
21
21
 
@@ -0,0 +1,115 @@
1
+ require "json"
2
+ require "digest"
3
+ require "fileutils"
4
+
5
+ module Breakfast
6
+ class Manifest
7
+ MANIFEST_REGEX = /^\.breakfast-manifest-[0-9a-f]{32}.json$/
8
+ SPROCKETS_MANIFEST_REGEX = /^\.sprockets-manifest-[0-9a-f]{32}.json$/
9
+ FINGERPRINT_REGEX = /-[0-9a-f]{32}./
10
+
11
+ attr_reader :base_dir, :manifest_path, :cache
12
+ def initialize(base_dir:)
13
+ FileUtils.mkdir_p(base_dir)
14
+
15
+ @base_dir = Pathname.new(base_dir)
16
+ @manifest_path = find_manifest_or_create
17
+ @cache = update_cache!
18
+ end
19
+
20
+ def asset(path)
21
+ cache[path]
22
+ end
23
+
24
+ # The #digest! method will run through all of the compiled assets and
25
+ # create a copy of each asset with a digest fingerprint. This fingerprint
26
+ # will change whenever the file contents change. This allows us to use HTTP
27
+ # headers to cache these assets as we will be able to reliably know when
28
+ # they change.
29
+ #
30
+ # These fingerprinted files are copies of the original. The originals are
31
+ # not removed and still available should the need arise to serve a
32
+ # non-fingerprinted asset.
33
+ #
34
+ # Example manifest:
35
+ # {
36
+ # app.js => app-76c6ee161ba431e823301567b175acda.js,
37
+ # images/logo.png => images/logo-869269cdf1773ff0dec91bafb37310ea.png,
38
+ # }
39
+ #
40
+ # Resulting File Structure:
41
+ # - /
42
+ # - app.js
43
+ # - app-76c6ee161ba431e823301567b175acda.js
44
+ # - images/
45
+ # - logo.png
46
+ # - logo-869269cdf1773ff0dec91bafb37310ea.png
47
+ def digest!
48
+ assets = asset_paths.map do |path|
49
+ digest = Digest::MD5.new
50
+ digest.update(File.read("#{base_dir}/#{path}"))
51
+
52
+ digest_path = "#{path.sub_ext('')}-#{digest.hexdigest}#{File.extname(path)}"
53
+
54
+ FileUtils.cp("#{base_dir}/#{path}", "#{base_dir}/#{digest_path}")
55
+
56
+ [path, digest_path]
57
+ end
58
+
59
+ File.open(manifest_path, "w") do |manifest|
60
+ manifest.write(assets.to_h.to_json)
61
+ end
62
+
63
+ update_cache!
64
+ end
65
+
66
+ # Remove any files not directly referenced by the manifest.
67
+ def clean!
68
+ files_to_keep = cache.keys.concat(cache.values)
69
+
70
+ if (sprockets_manifest = Dir.entries("#{base_dir}").detect { |entry| entry =~ SPROCKETS_MANIFEST_REGEX })
71
+ files_to_keep.concat(JSON.parse(File.read("#{base_dir}/#{sprockets_manifest}"))["files"].keys)
72
+ end
73
+
74
+ Dir["#{base_dir}/**/*"].each do |path|
75
+ next if File.directory?(path) || files_to_keep.include?(Pathname(path).relative_path_from(base_dir).to_s)
76
+
77
+ FileUtils.rm(path)
78
+ end
79
+ end
80
+
81
+ # Remove manifest, any fingerprinted files.
82
+ def nuke!
83
+ Dir["#{base_dir}/**/*"]
84
+ .select { |path| path =~ FINGERPRINT_REGEX }
85
+ .each { |file| FileUtils.rm(file) }
86
+
87
+ FileUtils.rm(manifest_path)
88
+ end
89
+
90
+ private
91
+
92
+ def update_cache!
93
+ @cache = JSON.parse(File.read(manifest_path))
94
+ end
95
+
96
+ # Creates a or finds a manifest file in a given directory. The manifest
97
+ # file is is prefixed with a dot ('.') and given a random string to ensure
98
+ # the file is not served or easily discoverable.
99
+ def find_manifest_or_create
100
+ if (manifest = Dir.entries("#{base_dir}").detect { |entry| entry =~ MANIFEST_REGEX })
101
+ "#{base_dir}/#{manifest}"
102
+ else
103
+ manifest = "#{base_dir}/.breakfast-manifest-#{SecureRandom.hex(16)}.json"
104
+ File.open(manifest, "w") { |manifest| manifest.write({}.to_json) }
105
+ manifest
106
+ end
107
+ end
108
+
109
+ def asset_paths
110
+ Dir["#{base_dir}/**/*"]
111
+ .reject { |path| File.directory?(path) || path =~ FINGERPRINT_REGEX }
112
+ .map { |file| Pathname(file).relative_path_from(base_dir) }
113
+ end
114
+ end
115
+ end
@@ -11,10 +11,11 @@ module Breakfast
11
11
  config.breakfast.css_reload_strategy = :hot
12
12
  config.breakfast.ruby_reload_strategy = :off
13
13
 
14
- config.breakfast.asset_output_folders = [Rails.root.join("public")]
14
+ config.breakfast.asset_output_folder = Rails.root.join("public", "assets")
15
15
  config.breakfast.source_code_folders = [Rails.root.join("app")]
16
16
  config.breakfast.environments = %w(development)
17
17
  config.breakfast.status_bar_location = :bottom
18
+ config.breakfast.digest = !(Rails.env.development? || Rails.env.test?)
18
19
  end
19
20
 
20
21
  initializer "breakfast.setup_view_helpers" do |app|
@@ -23,14 +24,22 @@ module Breakfast
23
24
  end
24
25
  end
25
26
 
27
+ rake_tasks do
28
+ load "tasks/breakfast.rake"
29
+ end
30
+
26
31
  config.after_initialize do |app|
32
+ if config.breakfast.digest
33
+ config.breakfast.manifest = Breakfast::Manifest.new(base_dir: config.breakfast.asset_output_folder)
34
+ end
35
+
27
36
  if config.breakfast.environments.include?(Rails.env) && LocalEnvironment.new.running_server?
28
37
  Thread.new do
29
38
  Breakfast::BrunchWatcher.spawn(log: Rails.logger)
30
39
  end
31
40
 
32
41
  Breakfast::CompilationListener.start(
33
- asset_output_folders: config.breakfast.asset_output_folders,
42
+ asset_output_folder: config.breakfast.asset_output_folder,
34
43
  source_code_folders: config.breakfast.source_code_folders
35
44
  )
36
45
  end
@@ -1,3 +1,3 @@
1
1
  module Breakfast
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -19,5 +19,16 @@ module Breakfast
19
19
  end
20
20
  end
21
21
  end
22
+
23
+ include ActionView::Helpers::AssetUrlHelper
24
+ include ActionView::Helpers::AssetTagHelper
25
+
26
+ def compute_asset_path(path, options = {})
27
+ if Rails.configuration.breakfast.digest && Rails.configuration.breakfast.manifest.asset(path)
28
+ path = Rails.configuration.breakfast.manifest.asset(path)
29
+ end
30
+
31
+ super(path, options)
32
+ end
22
33
  end
23
34
  end
@@ -3,9 +3,9 @@ require "rails/generators"
3
3
  module Breakfast
4
4
  module Generators
5
5
  class InstallGenerator < Rails::Generators::Base
6
- source_root File.expand_path('../templates', __FILE__)
7
- NODE_VERSION = 'v4.1.1'
8
- NPM_VERSION = '3.10.6'
6
+ source_root File.expand_path("../templates", __FILE__)
7
+ NODE_VERSION = "v4.1.1"
8
+ NPM_VERSION = "3.10.6"
9
9
 
10
10
  def install
11
11
  if node_prerequisites_installed?
@@ -0,0 +1,61 @@
1
+ require "rake"
2
+ require "breakfast"
3
+
4
+ namespace :breakfast do
5
+ namespace :assets do
6
+ desc "Build assets"
7
+ task :build => :environment do
8
+ exec(Breakfast::BUILD_COMMAND)
9
+ end
10
+
11
+ desc "Build assets for production"
12
+ task :build_production => :environment do
13
+ exec(Breakfast::PRODUCTION_BUILD_COMMAND)
14
+ end
15
+
16
+ desc "Add a digest to non-fingerprinted assets"
17
+ task :digest => :environment do
18
+ if Rails.configuration.breakfast.manifest
19
+ Rails.configuration.breakfast.manifest.digest!
20
+ else
21
+ raise Breakfast::ManifestDisabledError
22
+ end
23
+ end
24
+
25
+ desc "Remove out of date assets"
26
+ task :clean => :environment do
27
+ if Rails.configuration.breakfast.manifest
28
+ Rails.configuration.breakfast.manifest.clean!
29
+ else
30
+ raise Breakfast::ManifestDisabledError
31
+ end
32
+ end
33
+
34
+ desc "Remove manifest and fingerprinted assets"
35
+ task :nuke => :environment do
36
+ if Rails.configuration.breakfast.manifest
37
+ Rails.configuration.breakfast.manifest.nuke!
38
+ else
39
+ raise Breakfast::ManifestDisabledError
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ module Breakfast
46
+ class ManifestDisabledError < StandardError
47
+ def initialize
48
+ super(
49
+ <<~ERROR
50
+ Rails.configuration.breakfast.manifest is set to false.
51
+ Enable it by adding the following in your environment file:
52
+
53
+ config.breakfast.manifest.digest = true
54
+
55
+ *Note* by default digest is set to false in development and test enviornments.
56
+
57
+ ERROR
58
+ )
59
+ end
60
+ end
61
+ end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "breakfast-rails",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Assets for the Breakfast Gem",
5
5
  "main": "./lib/breakfast-rails.js",
6
6
  "scripts": {
@@ -211,7 +211,7 @@ class StatusBar {
211
211
  display: flex;
212
212
  flex-grow: 1;
213
213
  height: 30px;
214
- padding: 8px;
214
+ padding: 0 8px;
215
215
  }
216
216
 
217
217
  .breakfast-status-bar .breakfast-message-log-error {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: breakfast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Koperwas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-19 00:00:00.000000000 Z
11
+ date: 2016-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,6 +119,7 @@ files:
119
119
  - lib/breakfast/capistrano/tasks/breakfast.rake
120
120
  - lib/breakfast/compilation_listener.rb
121
121
  - lib/breakfast/live_reload_channel.rb
122
+ - lib/breakfast/manifest.rb
122
123
  - lib/breakfast/railtie.rb
123
124
  - lib/breakfast/status_channel.rb
124
125
  - lib/breakfast/version.rb
@@ -128,6 +129,7 @@ files:
128
129
  - lib/generators/breakfast/templates/app.scss
129
130
  - lib/generators/breakfast/templates/brunch-config.js
130
131
  - lib/generators/breakfast/templates/package.json
132
+ - lib/tasks/breakfast.rake
131
133
  - node_package/.eslintrc.json
132
134
  - node_package/.npmignore
133
135
  - node_package/package.json