middleman-extensionless-helper 1.0.0 → 1.0.1
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:
|
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: []
|