middleman-diff 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +6 -0
- data/Gemfile +18 -0
- data/LICENSE.md +20 -0
- data/README.md +64 -0
- data/Rakefile +27 -0
- data/cucumber.yml +2 -0
- data/features/diff.feature +38 -0
- data/features/extension.feature +11 -0
- data/features/hooks.feature +34 -0
- data/features/keep.feature +47 -0
- data/features/step_definitions/diff_steps.rb +18 -0
- data/features/step_definitions/filesystem_steps.rb +25 -0
- data/features/step_definitions/output_steps.rb +7 -0
- data/features/storage.feature +25 -0
- data/features/support/env.rb +4 -0
- data/fixtures/inactive/.gitkeep +0 -0
- data/fixtures/typical-modified/build/index.html +10 -0
- data/fixtures/typical-modified/build/javascripts/main.js +4 -0
- data/fixtures/typical-modified/build/stylesheets/main.css +2 -0
- data/fixtures/typical-modified/config.rb +16 -0
- data/fixtures/typical-modified/source/index.html.haml +1 -0
- data/fixtures/typical-modified/source/javascripts/main.js.coffee +1 -0
- data/fixtures/typical-modified/source/layouts/layout.haml +7 -0
- data/fixtures/typical-modified/source/stylesheets/main.css.sass +2 -0
- data/fixtures/typical/build/index.html +10 -0
- data/fixtures/typical/build/javascripts/main.js +4 -0
- data/fixtures/typical/build/stylesheets/main.css +2 -0
- data/fixtures/typical/config.rb +16 -0
- data/fixtures/typical/source/index.html.haml +1 -0
- data/fixtures/typical/source/javascripts/main.js.coffee +1 -0
- data/fixtures/typical/source/layouts/layout.haml +7 -0
- data/fixtures/typical/source/stylesheets/main.css.sass +2 -0
- data/lib/middleman-diff.rb +4 -0
- data/lib/middleman-diff/cli.rb +71 -0
- data/lib/middleman-diff/extension.rb +43 -0
- data/lib/middleman-diff/preview.rb +116 -0
- data/lib/middleman_extension.rb +1 -0
- data/middleman-diff.gemspec +19 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61d953d17238b483e2833b03800c49920a23c2fd
|
4
|
+
data.tar.gz: 0981c88714d42bd0ecfda876ad22ddee10929253
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3573b71ed9f1b1e64b4319f96d64c637320a7bf4f53b84b4feb308349fd00601f980c522f806a23e1676f2bb96542c0941609e5b1c036f7ae76458f28c2e23d
|
7
|
+
data.tar.gz: c9072661426000a2b3e15205cca45db482dd3ecc08a46fb245ad592790fa32beff14529f0297d9fc6ff72bd72412ca3b576a2ae4842c01552635dde2afed98f9
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rake', group: [:development, :test]
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'rdoc'
|
9
|
+
gem 'yard'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'aruba'
|
14
|
+
gem 'cucumber'
|
15
|
+
gem 'fivemat'
|
16
|
+
gem 'middleman'
|
17
|
+
gem 'rspec'
|
18
|
+
end
|
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Andrew Kvalheim
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
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, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# middleman-diff
|
2
|
+
|
3
|
+
[![Gem Version][gem-version-badge]][gem-version]
|
4
|
+
[![Build Status][build-status-badge]][build-status]
|
5
|
+
|
6
|
+
Preview what's changed in your [Middleman][middleman] build.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add the extension to your `Gemfile`,
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'middleman-diff'
|
14
|
+
```
|
15
|
+
|
16
|
+
run `bundle install`, and activate it in `config.rb`:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
activate :diff
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Preview what's changed since the last build, and optionally use it as the
|
25
|
+
current build:
|
26
|
+
|
27
|
+
```console
|
28
|
+
$ middleman diff
|
29
|
+
create tmp/preview/index.html
|
30
|
+
{build => tmp/preview}/index.html | 2 +-
|
31
|
+
1 file changed, 1 insertion(+), 1 deletion(-)
|
32
|
+
|
33
|
+
diff --git a/build/index.html b/tmp/preview/index.html
|
34
|
+
index 68c37b9..218e4ff 100644
|
35
|
+
--- a/build/index.html
|
36
|
+
+++ b/tmp/preview/index.html
|
37
|
+
@@ -5,6 +5,6 @@
|
38
|
+
</head>
|
39
|
+
<body>
|
40
|
+
<h1>Hello there!</h1>
|
41
|
+
- <p>This site is kind of alright.</p>
|
42
|
+
+ <p>This site is awesome.</p>
|
43
|
+
</body>
|
44
|
+
</html>
|
45
|
+
Would you like to apply these changes to the build? [y/N] y
|
46
|
+
Build has been updated.
|
47
|
+
```
|
48
|
+
|
49
|
+
## Configuration
|
50
|
+
|
51
|
+
The following configuration options are available:
|
52
|
+
|
53
|
+
Name | Default | Description
|
54
|
+
------------- | --------- | ---------------------------------------------------
|
55
|
+
`build_hooks` | `true` | Whether to run build hooks when previewing the build
|
56
|
+
`keep` | `:prompt` | Whether to `:always`, `:never`, or `:prompt` to keep the preview as the build
|
57
|
+
`temp_dir` | `'tmp'` | Directory in which to build when previewing
|
58
|
+
|
59
|
+
|
60
|
+
[build-status]: https://travis-ci.org/AndrewKvalheim/middleman-diff
|
61
|
+
[build-status-badge]: https://travis-ci.org/AndrewKvalheim/middleman-diff.png?branch=master
|
62
|
+
[gem-version]: https://badge.fury.io/rb/middleman-diff
|
63
|
+
[gem-version-badge]: https://badge.fury.io/rb/middleman-diff.png
|
64
|
+
[middleman]: http://middlemanapp.com/
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
# Gem helpers
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
# Feature tests
|
8
|
+
begin
|
9
|
+
require 'cucumber'
|
10
|
+
require 'cucumber/rake/task'
|
11
|
+
|
12
|
+
Cucumber::Rake::Task.new(:features) do |cucumber|
|
13
|
+
cucumber.cucumber_opts = '--profile ci' if ENV['CI'] == 'true'
|
14
|
+
end
|
15
|
+
rescue
|
16
|
+
desc 'Cucumber is not available.'
|
17
|
+
task :features do
|
18
|
+
abort 'Cucumber is not available.'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# All tests
|
23
|
+
desc 'Run all tests.'
|
24
|
+
task test: %w(features)
|
25
|
+
|
26
|
+
# Default
|
27
|
+
task default: :test
|
data/cucumber.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
Feature: Diff
|
2
|
+
|
3
|
+
Scenario: There is no last build.
|
4
|
+
Given a fixture app "typical" without "build"
|
5
|
+
When I attempt to diff
|
6
|
+
Then it should fail with "There's no existing build to compare against."
|
7
|
+
|
8
|
+
Scenario: No changes have been made since the last build.
|
9
|
+
Given a fixture app "typical"
|
10
|
+
When I diff
|
11
|
+
Then the output should not match /^[+-]/
|
12
|
+
|
13
|
+
Scenario: A file has been created since the last build.
|
14
|
+
Given a fixture app "typical"
|
15
|
+
And a file named "source/created.html.haml" with:
|
16
|
+
"""
|
17
|
+
This is the created document.
|
18
|
+
"""
|
19
|
+
When I diff
|
20
|
+
Then the output should match /^\+\s+This is the created document/
|
21
|
+
And the output should not match /^-\s+/
|
22
|
+
|
23
|
+
Scenario: A file has been modified since the last build.
|
24
|
+
Given a fixture app "typical"
|
25
|
+
And a file named "source/index.html.haml" with:
|
26
|
+
"""
|
27
|
+
This is the modified document.
|
28
|
+
"""
|
29
|
+
When I diff
|
30
|
+
Then the output should match /^-\s+This is the original document/
|
31
|
+
And the output should match /^\+\s+This is the modified document/
|
32
|
+
|
33
|
+
Scenario: A file has been deleted since the last build.
|
34
|
+
Given a fixture app "typical"
|
35
|
+
And I remove the file "source/index.html.haml"
|
36
|
+
When I diff
|
37
|
+
Then the output should match /^-\s+This is the original document/
|
38
|
+
And the output should not match /^\+\s+/
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Extension
|
2
|
+
|
3
|
+
Scenario: Activation is required.
|
4
|
+
Given a fixture app "inactive"
|
5
|
+
When I attempt to diff
|
6
|
+
Then it should fail with "You must activate this extension."
|
7
|
+
|
8
|
+
Scenario: The build command is unaffected.
|
9
|
+
Given a fixture app "typical"
|
10
|
+
When I successfully run `middleman build`
|
11
|
+
Then a directory named "build" should exist
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature: Hooks
|
2
|
+
|
3
|
+
Scenario: Build hooks are not modified.
|
4
|
+
Given a fixture app "typical"
|
5
|
+
When I successfully run `middleman build`
|
6
|
+
Then the output should contain "The before_build hook has been run."
|
7
|
+
And the output should contain "The after_build hook has been run."
|
8
|
+
|
9
|
+
Scenario: Build hooks are run.
|
10
|
+
Given a fixture app "typical"
|
11
|
+
When I diff
|
12
|
+
Then the output should contain "The before_build hook has been run."
|
13
|
+
And the output should contain "The after_build hook has been run."
|
14
|
+
|
15
|
+
Scenario: Build hooks have been disabled.
|
16
|
+
Given a fixture app "typical"
|
17
|
+
And the text "activate :diff" in the file "config.rb" is replaced with:
|
18
|
+
"""
|
19
|
+
activate :diff, build_hooks: false
|
20
|
+
"""
|
21
|
+
When I diff and type "n"
|
22
|
+
Then the output should not match /The \w+_build hook has been run./
|
23
|
+
|
24
|
+
Scenario: Files from a build hook are previewed.
|
25
|
+
Given a fixture app "typical"
|
26
|
+
And I append to "config.rb" with "activate :gzip"
|
27
|
+
When I diff
|
28
|
+
Then a file named "build/index.html.gz" should not exist
|
29
|
+
|
30
|
+
Scenario: Files from a build hook are kept.
|
31
|
+
Given a fixture app "typical"
|
32
|
+
And I append to "config.rb" with "activate :gzip"
|
33
|
+
When I diff and type "y"
|
34
|
+
Then a file named "build/index.html.gz" should exist
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Feature: Keep
|
2
|
+
|
3
|
+
Scenario: A prompt is displayed.
|
4
|
+
Given a fixture app "typical-modified"
|
5
|
+
When I diff
|
6
|
+
Then the output should contain:
|
7
|
+
"""
|
8
|
+
Would you like to apply these changes to the build? [y/N]
|
9
|
+
"""
|
10
|
+
|
11
|
+
Scenario: Changes are discarded by default.
|
12
|
+
Given a fixture app "typical-modified"
|
13
|
+
When I diff
|
14
|
+
Then the output should contain "Preview has been discarded."
|
15
|
+
And the file "build/index.html" should contain "original document"
|
16
|
+
|
17
|
+
Scenario: Changes are discarded.
|
18
|
+
Given a fixture app "typical-modified"
|
19
|
+
When I diff and type "n"
|
20
|
+
Then it should pass with "Preview has been discarded."
|
21
|
+
And the file "build/index.html" should contain "original document"
|
22
|
+
|
23
|
+
Scenario: Changes are kept.
|
24
|
+
Given a fixture app "typical-modified"
|
25
|
+
When I diff and type "y"
|
26
|
+
Then it should pass with "Build has been updated."
|
27
|
+
And the file "build/index.html" should contain "modified document"
|
28
|
+
|
29
|
+
Scenario: Changes are always discarded.
|
30
|
+
Given a fixture app "typical-modified"
|
31
|
+
And the text "activate :diff" in the file "config.rb" is replaced with:
|
32
|
+
"""
|
33
|
+
activate :diff, keep: :never
|
34
|
+
"""
|
35
|
+
When I diff noninteractively
|
36
|
+
Then the output should contain "Preview has been discarded."
|
37
|
+
And the file "build/index.html" should contain "original document"
|
38
|
+
|
39
|
+
Scenario: Changes are always kept.
|
40
|
+
Given a fixture app "typical-modified"
|
41
|
+
And the text "activate :diff" in the file "config.rb" is replaced with:
|
42
|
+
"""
|
43
|
+
activate :diff, keep: :always
|
44
|
+
"""
|
45
|
+
When I diff noninteractively
|
46
|
+
Then the output should contain "Build has been updated."
|
47
|
+
And the file "build/index.html" should contain "modified document"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
When(/^I attempt to diff$/) do
|
2
|
+
step 'I run `middleman diff`'
|
3
|
+
end
|
4
|
+
|
5
|
+
When(/^I diff noninteractively$/) do
|
6
|
+
step 'I attempt to diff'
|
7
|
+
step 'the exit status should be 0'
|
8
|
+
end
|
9
|
+
|
10
|
+
When(/^I diff$/) do
|
11
|
+
step 'I diff and type ""'
|
12
|
+
end
|
13
|
+
|
14
|
+
When(/^I diff and type "(.*?)"$/) do |text|
|
15
|
+
step 'I run `middleman diff` interactively'
|
16
|
+
step "I type \"#{ text }\""
|
17
|
+
step 'the exit status should be 0'
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
Then(/^a directory named "(.*?)" should be empty$/) do |path|
|
5
|
+
in_current_dir do
|
6
|
+
Pathname.new(path).children.empty?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Given(/^a fixture app "(.*?)" without "(.*?)"$/) do |name, path|
|
11
|
+
step "a fixture app \"#{ name }\""
|
12
|
+
in_current_dir do
|
13
|
+
FileUtils.rmtree path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Given(/^the text "(.*?)" in the file "(.*?)" is replaced with:$/) do |text, path, replacement|
|
18
|
+
in_current_dir do
|
19
|
+
content = open(path) { |file| file.read }
|
20
|
+
|
21
|
+
open(path, 'w') do |file|
|
22
|
+
file.write content.gsub(text, replacement)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: Storage
|
2
|
+
|
3
|
+
Scenario: The temporary directory is created if necessary.
|
4
|
+
Given a fixture app "typical"
|
5
|
+
When I diff
|
6
|
+
Then a directory named "tmp" should exist
|
7
|
+
|
8
|
+
Scenario: The preview directory is cleaned when unused.
|
9
|
+
Given a fixture app "typical" without "build"
|
10
|
+
When I attempt to diff
|
11
|
+
Then a directory named "tmp" should be empty
|
12
|
+
|
13
|
+
Scenario: The preview directory is cleaned.
|
14
|
+
Given a fixture app "typical"
|
15
|
+
When I diff
|
16
|
+
Then a directory named "tmp" should be empty
|
17
|
+
|
18
|
+
Scenario: A non-default temporary directory is configured and created.
|
19
|
+
Given a fixture app "typical"
|
20
|
+
And the text "activate :diff" in the file "config.rb" is replaced with:
|
21
|
+
"""
|
22
|
+
activate :diff, temp_dir: 'some/other/location'
|
23
|
+
"""
|
24
|
+
When I diff
|
25
|
+
Then a directory named "some/other/location" should exist
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
activate :diff
|
2
|
+
|
3
|
+
before_build do
|
4
|
+
puts 'The before_build hook has been run.'
|
5
|
+
end
|
6
|
+
|
7
|
+
after_build do
|
8
|
+
puts 'The after_build hook has been run.'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Workaround for middleman/middleman#706
|
12
|
+
configure :build do
|
13
|
+
compass_config do |config|
|
14
|
+
config.sass_options = { line_comments: false }
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is the modified document.
|
@@ -0,0 +1 @@
|
|
1
|
+
document.write 'This is the original script.'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
activate :diff
|
2
|
+
|
3
|
+
before_build do
|
4
|
+
puts 'The before_build hook has been run.'
|
5
|
+
end
|
6
|
+
|
7
|
+
after_build do
|
8
|
+
puts 'The after_build hook has been run.'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Workaround for middleman/middleman#706
|
12
|
+
configure :build do
|
13
|
+
compass_config do |config|
|
14
|
+
config.sass_options = { line_comments: false }
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is the original document.
|
@@ -0,0 +1 @@
|
|
1
|
+
document.write 'This is the original script.'
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'middleman-core/cli'
|
2
|
+
|
3
|
+
module Middleman
|
4
|
+
module Cli
|
5
|
+
# Extension to the Middleman CLI
|
6
|
+
class Diff < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
namespace :diff
|
10
|
+
|
11
|
+
# Whether to exit with status 1 when a failure happens
|
12
|
+
#
|
13
|
+
# @return [Boolean]
|
14
|
+
def self.exit_on_failure?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
# Interactively diff a preview with the build, optionally replacing the
|
19
|
+
# existing build with it.
|
20
|
+
#
|
21
|
+
# @return [void]
|
22
|
+
desc 'diff', "Preview what's changed in the build."
|
23
|
+
def diff
|
24
|
+
extension.with_preview do |preview|
|
25
|
+
preview.show_diff
|
26
|
+
|
27
|
+
if keep?
|
28
|
+
preview.replace_build
|
29
|
+
say 'Build has been updated.'
|
30
|
+
else
|
31
|
+
say 'Preview has been discarded.'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Middleman application instance
|
39
|
+
#
|
40
|
+
# @return [Middleman::Application]
|
41
|
+
def app
|
42
|
+
@_app ||= ::Middleman::Application.server.inst
|
43
|
+
end
|
44
|
+
|
45
|
+
# Activated extension instance
|
46
|
+
#
|
47
|
+
# @return [Middleman::Extensions::Diff]
|
48
|
+
def extension
|
49
|
+
@_extension ||= begin
|
50
|
+
extension = app.extensions.find { |e| e.first == :diff }.try(:last)
|
51
|
+
|
52
|
+
fail Thor::Error, 'You must activate this extension.' unless extension
|
53
|
+
|
54
|
+
extension
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Whether to replace the existing build with the preview
|
59
|
+
#
|
60
|
+
# @return [Boolean]
|
61
|
+
def keep?
|
62
|
+
case extension.options.keep
|
63
|
+
when :always then true
|
64
|
+
when :never then false
|
65
|
+
when :prompt
|
66
|
+
yes?('Would you like to apply these changes to the build? [y/N]')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'middleman-core'
|
2
|
+
|
3
|
+
module Middleman
|
4
|
+
module Diff
|
5
|
+
# Middleman extension
|
6
|
+
class Extension < ::Middleman::Extension
|
7
|
+
option :build_hooks, true,
|
8
|
+
'Whether to run build hooks when previewing the build'
|
9
|
+
option :keep, :prompt,
|
10
|
+
'Whether to :always, :never, or :prompt to keep the preview'
|
11
|
+
option :temp_dir, 'tmp',
|
12
|
+
'Path in which to build when previewing'
|
13
|
+
|
14
|
+
# Runs when the extension is activated
|
15
|
+
#
|
16
|
+
# @param app [Middleman::Application] Middleman application instance
|
17
|
+
# @param options_hash [Hash] options
|
18
|
+
# @param block [Block] configuration block
|
19
|
+
# @return [void]
|
20
|
+
def initialize(app, **options_hash, &block)
|
21
|
+
# Build options from options_hash
|
22
|
+
super
|
23
|
+
|
24
|
+
require 'middleman-diff/preview'
|
25
|
+
require 'pathname'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Yield a preview of the build.
|
29
|
+
#
|
30
|
+
# @yield [Middleman::Diff::Preview]
|
31
|
+
# @yieldreturn [void]
|
32
|
+
# @return [void]
|
33
|
+
def with_preview
|
34
|
+
preview = Preview.new(app, build_hooks: options.build_hooks,
|
35
|
+
temp_dir: options.temp_dir)
|
36
|
+
|
37
|
+
yield preview
|
38
|
+
|
39
|
+
preview.dispose
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
require 'rack/test' # Required by Middleman::Cli::Build
|
4
|
+
require 'tmpdir'
|
5
|
+
|
6
|
+
module Middleman
|
7
|
+
module Diff
|
8
|
+
# Preview of the build
|
9
|
+
class Preview
|
10
|
+
# Generate a preview of the build.
|
11
|
+
#
|
12
|
+
# @param app [Middleman::Appliation] Middleman application instance
|
13
|
+
# @param build_hooks [Boolean]
|
14
|
+
# @param temp_dir [String] path to temporary directory
|
15
|
+
# @return [void]
|
16
|
+
def initialize(app, build_hooks: true, temp_dir: 'tmp')
|
17
|
+
@app = app
|
18
|
+
@build_hooks = build_hooks
|
19
|
+
@temp_dir = Pathname.new(temp_dir)
|
20
|
+
|
21
|
+
build_preview
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clean up any temporary files from the preview.
|
25
|
+
#
|
26
|
+
# @return [void]
|
27
|
+
def dispose
|
28
|
+
preview_dir.rmtree if preview_dir.exist?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Replace the existing build with the preview.
|
32
|
+
#
|
33
|
+
# @return [void]
|
34
|
+
def replace_build
|
35
|
+
build_dir.rmtree
|
36
|
+
FileUtils.move preview_dir, build_dir
|
37
|
+
end
|
38
|
+
|
39
|
+
# Output a diff of the existing build and preview.
|
40
|
+
#
|
41
|
+
# @return [void]
|
42
|
+
def show_diff
|
43
|
+
prefix = %w(git diff --no-index --patch-with-stat --)
|
44
|
+
system(*(prefix + [build_dir.to_s, preview_dir.to_s]))
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Instance of the CLI used for building
|
50
|
+
#
|
51
|
+
# @return [thor_with_preview_dir]
|
52
|
+
def build_cli
|
53
|
+
@_build_cli ||= build_cli_with_preview_dir.new
|
54
|
+
end
|
55
|
+
|
56
|
+
# A modified Middleman::Cli::Build that builds to the preview directory
|
57
|
+
#
|
58
|
+
# @return [Class]
|
59
|
+
def build_cli_with_preview_dir
|
60
|
+
current_preview_dir = preview_dir
|
61
|
+
|
62
|
+
Class.new(::Middleman::Cli::Build).tap do |klass|
|
63
|
+
klass.define_singleton_method(:shared_instance) do
|
64
|
+
@_shared_instance ||= ::Middleman::Application.server.inst do
|
65
|
+
set :build_dir, current_preview_dir
|
66
|
+
config[:environment] = :build
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Build into the preview directory.
|
73
|
+
#
|
74
|
+
# @return [void]
|
75
|
+
def build_preview
|
76
|
+
trigger_build_hook :before_build
|
77
|
+
build_cli.action Middleman::Cli::BuildAction.new(build_cli, {})
|
78
|
+
trigger_build_hook :after_build
|
79
|
+
end
|
80
|
+
|
81
|
+
# Directory of the existing build
|
82
|
+
#
|
83
|
+
# @return [Pathname]
|
84
|
+
def build_dir
|
85
|
+
@_build_dir ||= begin
|
86
|
+
dir = Pathname.new(@app.build_dir)
|
87
|
+
|
88
|
+
unless dir.exist?
|
89
|
+
fail Thor::Error, "There's no existing build to compare against."
|
90
|
+
end
|
91
|
+
|
92
|
+
dir
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Directory in which to build the preview
|
97
|
+
#
|
98
|
+
# @return [Pathname]
|
99
|
+
def preview_dir
|
100
|
+
@_preview_dir ||= begin
|
101
|
+
Pathname.new(Dir.mktmpdir('preview_', @temp_dir.tap(&:mkpath)))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Run a build hook.
|
106
|
+
#
|
107
|
+
# @param name [Symbol]
|
108
|
+
# @return [void]
|
109
|
+
def trigger_build_hook(name)
|
110
|
+
return unless @build_hooks
|
111
|
+
|
112
|
+
build_cli.class.shared_instance.run_hook name, build_cli
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'middleman-diff'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'middleman-diff'
|
5
|
+
gem.version = '0.0.1'
|
6
|
+
gem.platform = Gem::Platform::RUBY
|
7
|
+
gem.required_ruby_version = '~> 2.1'
|
8
|
+
gem.license = 'MIT'
|
9
|
+
gem.authors = ['Andrew Kvalheim']
|
10
|
+
gem.email = ['Andrew@Kvalhe.im']
|
11
|
+
gem.homepage = 'https://github.com/AndrewKvalheim/middleman-diff'
|
12
|
+
gem.summary = "Preview what's changed in your Middleman build."
|
13
|
+
|
14
|
+
gem.files = `git ls-files -z`.split("\0")
|
15
|
+
gem.test_files = gem.files.grep(/^(features|fixtures)\//)
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'middleman-core', '~> 3.3'
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: middleman-diff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Kvalheim
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: middleman-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.3'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- Andrew@Kvalhe.im
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".gitignore"
|
35
|
+
- ".travis.yml"
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE.md
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- cucumber.yml
|
41
|
+
- features/diff.feature
|
42
|
+
- features/extension.feature
|
43
|
+
- features/hooks.feature
|
44
|
+
- features/keep.feature
|
45
|
+
- features/step_definitions/diff_steps.rb
|
46
|
+
- features/step_definitions/filesystem_steps.rb
|
47
|
+
- features/step_definitions/output_steps.rb
|
48
|
+
- features/storage.feature
|
49
|
+
- features/support/env.rb
|
50
|
+
- fixtures/inactive/.gitkeep
|
51
|
+
- fixtures/typical-modified/build/index.html
|
52
|
+
- fixtures/typical-modified/build/javascripts/main.js
|
53
|
+
- fixtures/typical-modified/build/stylesheets/main.css
|
54
|
+
- fixtures/typical-modified/config.rb
|
55
|
+
- fixtures/typical-modified/source/index.html.haml
|
56
|
+
- fixtures/typical-modified/source/javascripts/main.js.coffee
|
57
|
+
- fixtures/typical-modified/source/layouts/layout.haml
|
58
|
+
- fixtures/typical-modified/source/stylesheets/main.css.sass
|
59
|
+
- fixtures/typical/build/index.html
|
60
|
+
- fixtures/typical/build/javascripts/main.js
|
61
|
+
- fixtures/typical/build/stylesheets/main.css
|
62
|
+
- fixtures/typical/config.rb
|
63
|
+
- fixtures/typical/source/index.html.haml
|
64
|
+
- fixtures/typical/source/javascripts/main.js.coffee
|
65
|
+
- fixtures/typical/source/layouts/layout.haml
|
66
|
+
- fixtures/typical/source/stylesheets/main.css.sass
|
67
|
+
- lib/middleman-diff.rb
|
68
|
+
- lib/middleman-diff/cli.rb
|
69
|
+
- lib/middleman-diff/extension.rb
|
70
|
+
- lib/middleman-diff/preview.rb
|
71
|
+
- lib/middleman_extension.rb
|
72
|
+
- middleman-diff.gemspec
|
73
|
+
homepage: https://github.com/AndrewKvalheim/middleman-diff
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '2.1'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.2.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Preview what's changed in your Middleman build.
|
97
|
+
test_files:
|
98
|
+
- features/diff.feature
|
99
|
+
- features/extension.feature
|
100
|
+
- features/hooks.feature
|
101
|
+
- features/keep.feature
|
102
|
+
- features/step_definitions/diff_steps.rb
|
103
|
+
- features/step_definitions/filesystem_steps.rb
|
104
|
+
- features/step_definitions/output_steps.rb
|
105
|
+
- features/storage.feature
|
106
|
+
- features/support/env.rb
|
107
|
+
- fixtures/inactive/.gitkeep
|
108
|
+
- fixtures/typical-modified/build/index.html
|
109
|
+
- fixtures/typical-modified/build/javascripts/main.js
|
110
|
+
- fixtures/typical-modified/build/stylesheets/main.css
|
111
|
+
- fixtures/typical-modified/config.rb
|
112
|
+
- fixtures/typical-modified/source/index.html.haml
|
113
|
+
- fixtures/typical-modified/source/javascripts/main.js.coffee
|
114
|
+
- fixtures/typical-modified/source/layouts/layout.haml
|
115
|
+
- fixtures/typical-modified/source/stylesheets/main.css.sass
|
116
|
+
- fixtures/typical/build/index.html
|
117
|
+
- fixtures/typical/build/javascripts/main.js
|
118
|
+
- fixtures/typical/build/stylesheets/main.css
|
119
|
+
- fixtures/typical/config.rb
|
120
|
+
- fixtures/typical/source/index.html.haml
|
121
|
+
- fixtures/typical/source/javascripts/main.js.coffee
|
122
|
+
- fixtures/typical/source/layouts/layout.haml
|
123
|
+
- fixtures/typical/source/stylesheets/main.css.sass
|
124
|
+
has_rdoc:
|