middleman-extensionless-helper 1.0.0 → 1.0.1
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ba853edbd0fd4464a9c545c66c61e33325b250d
|
4
|
+
data.tar.gz: b8a8633b275746293eb925cd1eae23e652928a95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e8e2d11cd0dd77b4c640655e1aaca6bae2596be1372c81af3af5ce23ae5b3b444969b768b88d31c56260801824b0fd9d02abc3227ed31b61cbdd6d1f0a39173
|
7
|
+
data.tar.gz: e7cbd584a8c269c9c4c7930ba517314ddbedf6d759a97378ecd85d551d97a52b55b7be47e73d8bf26498ec37eb1927a0a521c4e7cc861a41fe10b5fdea878ea0
|
data/CHANGELOG.md
ADDED
@@ -1,169 +1,170 @@
|
|
1
1
|
module Middleman
|
2
|
-
|
3
|
-
|
2
|
+
module ExtensionLessHelper
|
3
|
+
class Extension < ::Middleman::Extension
|
4
|
+
option :target, [], 'Target files/paths from the source directory'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
EXTENSION_MAP = {
|
7
|
+
'.erb' => '.html'
|
8
|
+
}
|
8
9
|
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def initialize(app, options_hash={}, &block)
|
12
|
+
super
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
require 'digest/sha2'
|
15
|
+
require 'fileutils'
|
16
|
+
require 'ostruct'
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
@target = create_target(options.target)
|
19
|
+
end
|
19
20
|
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
#
|
23
|
+
# Hooks
|
24
|
+
#
|
24
25
|
|
25
|
-
|
26
|
+
public
|
26
27
|
|
27
|
-
|
28
|
+
def after_configuration
|
29
|
+
|
30
|
+
# Avoid applying a layout to target files.
|
31
|
+
# #page requires a URL having a absolute path from the root that is not the source directory
|
32
|
+
# but the web site. Besides, because it's the URL, a file name in it must be the same as MM
|
33
|
+
# names in a build process. Hence the URL looks like "/foo.html"(the original file is "foo").
|
34
|
+
@target.each do |target|
|
35
|
+
app.page File.join('', target.build), :layout => false
|
36
|
+
end
|
28
37
|
|
29
|
-
# Avoid applying a layout to target files.
|
30
|
-
# #page requires a URL having a absolute path from the root that is not the source directory
|
31
|
-
# but the web site. Besides, because of it's the URL, a file name in it must be the same as MM
|
32
|
-
# names in a build process. Hence the URL looks like "/foo.html"(the original file is "foo").
|
33
|
-
@target.each do |target|
|
34
|
-
app.page File.join('', target.build), :layout => false
|
35
38
|
end
|
36
39
|
|
37
|
-
|
40
|
+
def before_build(builder)
|
38
41
|
|
39
|
-
|
42
|
+
# Rename target files in the build directory for avoiding a "create" message by MM.
|
43
|
+
# e.g. build/foo -> build/foo.html
|
44
|
+
# Because target files are renamed by this extension in a previous build process, MM cannot
|
45
|
+
# find them and assumes that they are newly created and displays a "create" message.
|
46
|
+
# So, restore a name of target files to one which MM names in a build process.
|
47
|
+
@target.each do |target|
|
48
|
+
rename_build_file(target.expect, target.build)
|
49
|
+
end
|
40
50
|
|
41
|
-
|
42
|
-
|
43
|
-
# Because target files are renamed by this extension in a previous build process, MM cannot
|
44
|
-
# find them and assumes that they are newly created and displays a "create" message.
|
45
|
-
# So, restore a name of target files to one which MM names in a build process.
|
46
|
-
@target.each do |target|
|
47
|
-
rename_build_file(target.expect, target.build)
|
48
|
-
end
|
51
|
+
# SHOULD do after above the process, because a build path in a target object is referred.
|
52
|
+
inject_target_state
|
49
53
|
|
50
|
-
|
51
|
-
inject_target_state
|
54
|
+
end
|
52
55
|
|
53
|
-
|
56
|
+
def after_build(builder)
|
54
57
|
|
55
|
-
|
58
|
+
# Rename target files in the build directory as we expect.
|
59
|
+
# e.g. build/foo.html -> build/foo
|
60
|
+
@target.each do |target|
|
61
|
+
rename_build_file(target.build, target.expect)
|
56
62
|
|
57
|
-
|
58
|
-
|
59
|
-
@target.each do |target|
|
60
|
-
rename_build_file(target.build, target.expect)
|
63
|
+
# SHOULD do after above the process, because a build path in a target object is referred.
|
64
|
+
present_status(builder, target)
|
61
65
|
|
62
|
-
|
63
|
-
present_status(builder, target)
|
66
|
+
end
|
64
67
|
|
65
68
|
end
|
66
69
|
|
67
|
-
end
|
68
70
|
|
71
|
+
#
|
72
|
+
# Internals
|
73
|
+
#
|
69
74
|
|
70
|
-
|
71
|
-
# Internals
|
72
|
-
#
|
75
|
+
private
|
73
76
|
|
74
|
-
|
77
|
+
def convert_source_path(source)
|
78
|
+
# This isn't a smart way, but shouldn't use #split|Regexp because there're some "edge" cases.
|
75
79
|
|
76
|
-
|
77
|
-
# This isn't a smart way, but shouldn't use #split|Regexp because there are some "edge" cases.
|
80
|
+
template_exts = EXTENSION_MAP.keys
|
78
81
|
|
79
|
-
|
82
|
+
first_ext = File.extname(source).downcase
|
83
|
+
return {} unless template_exts.include?(first_ext)
|
80
84
|
|
81
|
-
|
82
|
-
|
85
|
+
expected_path = source.sub(/#{Regexp.quote(first_ext)}$/i, '')
|
86
|
+
return {} if File.extname(expected_path) != ''
|
83
87
|
|
84
|
-
|
85
|
-
|
88
|
+
base_name = File.basename expected_path
|
89
|
+
return {} if base_name.start_with?('.') && !base_name.match(/^\.ht(?:access|passwd)$/)
|
86
90
|
|
87
|
-
|
88
|
-
|
91
|
+
build_ext = EXTENSION_MAP[first_ext]
|
92
|
+
{build: (expected_path + build_ext), expect: expected_path}
|
93
|
+
end
|
89
94
|
|
90
|
-
|
91
|
-
{build: (expected_path + build_ext), expect: expected_path}
|
92
|
-
end
|
95
|
+
def create_target(target)
|
93
96
|
|
94
|
-
|
97
|
+
# SHOULD NOT check an existence of file in here, because files in a source directory are
|
98
|
+
# changed, created and removed until starting a build process.
|
99
|
+
[target].flatten.inject([]) do |stack, path|
|
100
|
+
paths = convert_source_path(path)
|
101
|
+
(stack << OpenStruct.new(paths.merge(original: path))) if !paths.empty?
|
102
|
+
stack
|
103
|
+
end
|
95
104
|
|
96
|
-
# SHOULD NOT check an existence of file in here, because files in a source directory are
|
97
|
-
# changed, created and removed until starting a build process.
|
98
|
-
[target].flatten.inject([]) do |stack, path|
|
99
|
-
paths = convert_source_path(path)
|
100
|
-
(stack << OpenStruct.new(paths.merge(original: path))) if !paths.empty?
|
101
|
-
stack
|
102
105
|
end
|
103
106
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
Digest::SHA256.file(path).hexdigest
|
108
|
-
end
|
107
|
+
def digest_of(path)
|
108
|
+
Digest::SHA256.file(path).hexdigest
|
109
|
+
end
|
109
110
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
111
|
+
def inject_target_state
|
112
|
+
state_skel = {created: false, removed: false, active: true, digest: ''}
|
113
|
+
|
114
|
+
@target.each do |target|
|
115
|
+
path_in_source = path_of target.original, :source
|
116
|
+
path_in_build = path_of target.build, :build
|
117
|
+
in_source = File.file? path_in_source
|
118
|
+
in_build = File.file? path_in_build
|
119
|
+
state = OpenStruct.new state_skel.dup
|
120
|
+
|
121
|
+
case true
|
122
|
+
when in_source && in_build then # no-op # File is updated or identical.
|
123
|
+
when in_source && !in_build then state.created = true # File is created.
|
124
|
+
when !in_source && in_build then state.removed = true # File is removed.
|
125
|
+
else state.active = false # No file.
|
126
|
+
end
|
127
|
+
|
128
|
+
state.digest = digest_of(path_in_build) if in_build
|
129
|
+
target.state = state
|
125
130
|
end
|
126
|
-
|
127
|
-
state.digest = digest_of(path_in_build) if in_build
|
128
|
-
target.state = state
|
129
131
|
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def path_of(path_crumb, type, absolute = true)
|
133
132
|
|
134
|
-
|
135
|
-
# value of :build_dir|:source can be updated anytime.
|
136
|
-
id = type.to_sym == :build ? :build_dir : :source
|
137
|
-
path = File.join(app.config[id], path_crumb)
|
138
|
-
absolute ? File.expand_path(path) : path
|
139
|
-
end
|
133
|
+
def path_of(path_crumb, type, absolute = true)
|
140
134
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
when target.state.created
|
148
|
-
['rename', "#{message} (create)", :green]
|
149
|
-
when target.state.removed
|
150
|
-
['remove', "#{build_path.call target.expect}", :red]
|
151
|
-
when target.state.active
|
152
|
-
digest_of(path_of(target.expect, :build)) == target.state.digest \
|
153
|
-
? ['rename', "#{message} (identical)", :blue] \
|
154
|
-
: ['rename', "#{message} (update)", :yellow]
|
155
|
-
else
|
156
|
-
['no-target', path_of(target.original, :source, false), :magenta]
|
157
|
-
end
|
135
|
+
# SHOULD get path to the build|source directory at any time of need, because the
|
136
|
+
# configuration value of :build_dir|:source can be updated anytime.
|
137
|
+
id = type.to_sym == :build ? :build_dir : :source
|
138
|
+
path = File.join(app.config[id], path_crumb)
|
139
|
+
absolute ? File.expand_path(path) : path
|
140
|
+
end
|
158
141
|
|
159
|
-
builder
|
160
|
-
|
142
|
+
def present_status(builder, target)
|
143
|
+
build_path = ->(path){ path_of path, :build, false }
|
144
|
+
message = "#{build_path.call target.build} => #{build_path.call target.expect}"
|
145
|
+
|
146
|
+
status, message, color = \
|
147
|
+
case true
|
148
|
+
when target.state.created
|
149
|
+
['rename', "#{message} (create)", :green]
|
150
|
+
when target.state.removed
|
151
|
+
['remove', "#{build_path.call target.expect}", :red]
|
152
|
+
when target.state.active
|
153
|
+
digest_of(path_of(target.expect, :build)) == target.state.digest \
|
154
|
+
? ['rename', "#{message} (identical)", :blue] \
|
155
|
+
: ['rename', "#{message} (update)", :yellow]
|
156
|
+
else
|
157
|
+
['no-target', path_of(target.original, :source, false), :magenta]
|
158
|
+
end
|
159
|
+
|
160
|
+
builder.say_status "EH:#{status}", message, color
|
161
|
+
end
|
161
162
|
|
162
|
-
|
163
|
-
|
164
|
-
|
163
|
+
def rename_build_file(from, to)
|
164
|
+
src, dest = [path_of(from, :build), path_of(to, :build)]
|
165
|
+
FileUtils.mv(src, dest) if File.file?(src) && !File.exist?(dest)
|
166
|
+
end
|
165
167
|
end
|
166
|
-
|
167
168
|
end
|
168
169
|
end
|
169
170
|
|
@@ -1,23 +1,25 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$:.unshift(lib) unless $:.include?(lib)
|
4
|
+
require 'middleman-extensionless-helper/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name
|
7
|
-
s.version
|
8
|
-
s.platform
|
9
|
-
s.authors
|
10
|
-
s.email
|
11
|
-
s.homepage
|
12
|
-
s.summary
|
13
|
-
s.description
|
14
|
-
s.
|
7
|
+
s.name = 'middleman-extensionless-helper'
|
8
|
+
s.version = Middleman::ExtensionlessHelper::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['AT-AT']
|
11
|
+
s.email = ['dec.alpha21264@gmail.com']
|
12
|
+
s.homepage = 'https://github.com/AT-AT/middleman-extensionless-helper'
|
13
|
+
s.summary = %q{A Middleman extension to remove an automatically added content extension}
|
14
|
+
s.description = %q{A Middleman extension to remove an automatically added content extension}
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.files = `git ls-files -z`.split("\0")
|
15
17
|
s.test_files = `git ls-files -- {test,spec,features,fixtures}/*`.split("\n")
|
16
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
-
s.require_paths = [
|
19
|
+
s.require_paths = ['lib']
|
18
20
|
|
19
21
|
# The version of middleman-core your extension depends on
|
20
|
-
s.add_runtime_dependency(
|
22
|
+
s.add_runtime_dependency('middleman-core', ['~> 3.4.1'])
|
21
23
|
|
22
24
|
# Additional dependencies
|
23
25
|
# None.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-extensionless-helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AT-AT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: middleman-core
|
@@ -32,6 +32,7 @@ extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- ".gitignore"
|
35
|
+
- CHANGELOG.md
|
35
36
|
- Gemfile
|
36
37
|
- LICENSE.md
|
37
38
|
- README.md
|
@@ -86,7 +87,8 @@ files:
|
|
86
87
|
- lib/middleman_extension.rb
|
87
88
|
- middleman-extensionless-helper.gemspec
|
88
89
|
homepage: https://github.com/AT-AT/middleman-extensionless-helper
|
89
|
-
licenses:
|
90
|
+
licenses:
|
91
|
+
- MIT
|
90
92
|
metadata: {}
|
91
93
|
post_install_message:
|
92
94
|
rdoc_options: []
|