html_mockup 0.4.0 → 0.5.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.
- data/bin/mockup +0 -0
- data/lib/html_mockup/cli.rb +38 -85
- data/lib/html_mockup/extractor.rb +100 -0
- data/lib/html_mockup/mockupfile.rb +63 -0
- data/lib/html_mockup/project.rb +54 -0
- data/lib/html_mockup/rack/html_mockup.rb +8 -6
- data/lib/html_mockup/rack/sleep.rb +21 -0
- data/lib/html_mockup/release/finalizers/dir.rb +24 -0
- data/lib/html_mockup/release/finalizers/zip.rb +4 -0
- data/lib/html_mockup/release/finalizers.rb +11 -0
- data/lib/html_mockup/release/injector.rb +98 -0
- data/lib/html_mockup/release/processors/requirejs.rb +54 -0
- data/lib/html_mockup/release/processors/sass.rb +38 -0
- data/lib/html_mockup/release/processors/yuicompressor.rb +53 -0
- data/lib/html_mockup/release/processors.rb +11 -0
- data/lib/html_mockup/release/scm/git.rb +101 -0
- data/lib/html_mockup/release/scm.rb +32 -0
- data/lib/html_mockup/release.rb +312 -0
- data/lib/html_mockup/server.rb +30 -10
- metadata +36 -8
@@ -0,0 +1,53 @@
|
|
1
|
+
# Use the ruby-yui-compressor gem.
|
2
|
+
require 'yui/compressor'
|
3
|
+
|
4
|
+
module HtmlMockup::Release::Processors
|
5
|
+
class Yuicompressor < Base
|
6
|
+
|
7
|
+
# Compresses all JS and CSS files, it will keep all lines before
|
8
|
+
#
|
9
|
+
# /* -------------------------------------------------------------------------------- */
|
10
|
+
#
|
11
|
+
# (80 dashes)
|
12
|
+
#
|
13
|
+
# @options options [Array] match Files to match, default to ["**/*.{css,js}"]
|
14
|
+
# @options options [Regexp] :delimiter An array of header delimiters. Defaults to the one above. The delimiter will be removed from the output.
|
15
|
+
# @options options [Array[Regexp]] :skip An array of file regular expressions to specifiy which files to skip. Defaults to [/javascripts\/vendor\/.\*.js\Z/, /_doc\/.*/]
|
16
|
+
def call(release, options={})
|
17
|
+
options = {
|
18
|
+
:match => ["**/*.{css,js}"],
|
19
|
+
:skip => [/javascripts\/vendor\/.*\.js\Z/, /_doc\/.*/],
|
20
|
+
:delimiter => Regexp.escape("/* -------------------------------------------------------------------------------- */")
|
21
|
+
}.update(options)
|
22
|
+
|
23
|
+
compressor_options = {:line_break => 80}
|
24
|
+
css_compressor = YUI::CssCompressor.new(compressor_options)
|
25
|
+
js_compressor = YUI::JavaScriptCompressor.new(compressor_options)
|
26
|
+
|
27
|
+
# Add version numbers and minify the files
|
28
|
+
release.get_files(options[:match], options[:skip]).each do |f|
|
29
|
+
type = f[/\.(.+)$/,1]
|
30
|
+
|
31
|
+
data = File.read(f);
|
32
|
+
File.open(f,"w") do |fh|
|
33
|
+
|
34
|
+
# Extract header and store for later use
|
35
|
+
header = data[/\A(.+?)\n#{options[:delimiter]}\s*\n/m,1]
|
36
|
+
minified = [header]
|
37
|
+
|
38
|
+
# Actual minification
|
39
|
+
release.log self, "Minifying #{f}"
|
40
|
+
case type
|
41
|
+
when "css"
|
42
|
+
minified << css_compressor.compress(data)
|
43
|
+
when "js"
|
44
|
+
minified << js_compressor.compress(data)
|
45
|
+
end
|
46
|
+
|
47
|
+
fh.write minified.join("\n")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module HtmlMockup::Release::Processors
|
2
|
+
class Base
|
3
|
+
def call(release, options = {})
|
4
|
+
raise ArgumentError, "Implement in subclass"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require File.dirname(__FILE__) + "/finalizers/zip"
|
10
|
+
require File.dirname(__FILE__) + "/finalizers/dir"
|
11
|
+
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module HtmlMockup::Release::Scm
|
4
|
+
class Git < Base
|
5
|
+
|
6
|
+
# @option config [String] :ref Ref to use for current tag
|
7
|
+
# @option config [String, Pathname] :path Path to working dir
|
8
|
+
def initialize(config={})
|
9
|
+
super(config)
|
10
|
+
@config[:ref] ||= "HEAD"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Version is either:
|
14
|
+
# - the tagged version number (first "v" will be stripped) or
|
15
|
+
# - the return value of "git describe --tags HEAD"
|
16
|
+
# - the short SHA1 if there hasn't been a previous tag
|
17
|
+
def version
|
18
|
+
get_scm_data if @_version.nil?
|
19
|
+
@_version
|
20
|
+
end
|
21
|
+
|
22
|
+
# Date will be Time.now if it can't be determined from GIT repository
|
23
|
+
def date
|
24
|
+
get_scm_data if @_date.nil?
|
25
|
+
@_date
|
26
|
+
end
|
27
|
+
|
28
|
+
def previous
|
29
|
+
self.class.new(@config.dup.update(:ref => get_previous_tag_name))
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def get_previous_tag_name
|
35
|
+
# Get list of SHA1 that have a ref
|
36
|
+
begin
|
37
|
+
sha1s = `git --git-dir=#{git_dir} log --pretty='%H' --simplify-by-decoration`.split("\n")
|
38
|
+
tags = []
|
39
|
+
while tags.size < 2 && sha1s.any?
|
40
|
+
sha1 = sha1s.shift
|
41
|
+
tag = `git --git-dir=#{git_dir} describe --tags --exact-match #{sha1} 2>/dev/null`.strip
|
42
|
+
tags << tag if !tag.empty?
|
43
|
+
end
|
44
|
+
tags.last
|
45
|
+
rescue
|
46
|
+
raise "Could not get previous tag"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def git_dir
|
51
|
+
@git_dir ||= find_git_dir(@config[:path])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Some hackery to determine if we're on a tagged version or not
|
55
|
+
def get_scm_data(ref = @config[:ref])
|
56
|
+
@_version = ""
|
57
|
+
@_date = Time.now
|
58
|
+
begin
|
59
|
+
if File.exist?(git_dir)
|
60
|
+
@_version = `git --git-dir=#{git_dir} describe --tags #{ref} 2>&1`
|
61
|
+
|
62
|
+
if $?.to_i > 0
|
63
|
+
# HEAD is not a tagged verison, get the short SHA1 instead
|
64
|
+
@_version = `git --git-dir=#{git_dir} show #{ref} --format=format:"%h" --quiet 2>&1`
|
65
|
+
else
|
66
|
+
# HEAD is a tagged version, if version is prefixed with "v" it will be stripped off
|
67
|
+
@_version.gsub!(/^v/,"")
|
68
|
+
end
|
69
|
+
@_version.strip!
|
70
|
+
|
71
|
+
# Get the date in epoch time
|
72
|
+
date = `git --git-dir=#{git_dir} show #{ref} --format=format:"%ct" --quiet 2>&1`
|
73
|
+
if date =~ /\d+/
|
74
|
+
@_date = Time.at(date.to_i)
|
75
|
+
else
|
76
|
+
@_date = Time.now
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
rescue RuntimeError => e
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# Find the git dir
|
86
|
+
def find_git_dir(path)
|
87
|
+
path = Pathname.new(path).realpath
|
88
|
+
while path.parent != path && !(path + ".git").directory?
|
89
|
+
path = path.parent
|
90
|
+
end
|
91
|
+
|
92
|
+
path = path + ".git"
|
93
|
+
|
94
|
+
raise "Could not find suitable .git dir in #{path}" if !path.directory?
|
95
|
+
|
96
|
+
path
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module HtmlMockup::Release::Scm
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize(config={})
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the release version string from the SCM
|
11
|
+
#
|
12
|
+
# @return String The current version string
|
13
|
+
def version
|
14
|
+
raise "Implement in subclass"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the release version date from the SCM
|
18
|
+
def date
|
19
|
+
raise "Implement in subclass"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a Release::Scm object with the previous version's data
|
23
|
+
#
|
24
|
+
# @return HtmlMockup::Release::Scm The previous version
|
25
|
+
def previous
|
26
|
+
raise "Implement in subclass"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require File.dirname(__FILE__) + "/scm/git"
|
@@ -0,0 +1,312 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/cli"
|
2
|
+
|
3
|
+
module HtmlMockup
|
4
|
+
class Release
|
5
|
+
|
6
|
+
attr_reader :config, :project
|
7
|
+
|
8
|
+
attr_reader :finalizers, :injections, :stack, :cleanups
|
9
|
+
|
10
|
+
def self.default_stack
|
11
|
+
[]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.default_finalizers
|
15
|
+
[[:dir, {}]]
|
16
|
+
end
|
17
|
+
|
18
|
+
# @option config [Symbol] :scm The SCM to use (default = :git)
|
19
|
+
# @option config [String, Pathname] :target_path The path/directory to put the release into
|
20
|
+
# @option config [String, Pathname]:build_path Temporary path used to build the release
|
21
|
+
# @option config [Boolean] :cleanup_build Wether or not to remove the build_path after we're done (default = true)
|
22
|
+
def initialize(project, config = {})
|
23
|
+
defaults = {
|
24
|
+
:scm => :git,
|
25
|
+
:source_path => Pathname.new(Dir.pwd) + "html",
|
26
|
+
:target_path => Pathname.new(Dir.pwd) + "releases",
|
27
|
+
:build_path => Pathname.new(Dir.pwd) + "build",
|
28
|
+
:cleanup_build => true
|
29
|
+
}
|
30
|
+
|
31
|
+
@config = {}.update(defaults).update(config)
|
32
|
+
@project = project
|
33
|
+
@finalizers = []
|
34
|
+
@injections = []
|
35
|
+
@stack = []
|
36
|
+
@cleanups = []
|
37
|
+
end
|
38
|
+
|
39
|
+
# Accessor for target_path
|
40
|
+
# The target_path is the path where the finalizers will put the release
|
41
|
+
#
|
42
|
+
# @return Pathname the target_path
|
43
|
+
def target_path
|
44
|
+
Pathname.new(self.config[:target_path])
|
45
|
+
end
|
46
|
+
|
47
|
+
# Accessor for build_path
|
48
|
+
# The build_path is a temporary directory where the release will be built
|
49
|
+
#
|
50
|
+
# @return Pathname the build_path
|
51
|
+
def build_path
|
52
|
+
Pathname.new(self.config[:build_path])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Accessor for source_path
|
56
|
+
# The source path is the root of the mockup
|
57
|
+
#
|
58
|
+
# @return Pathanem the source_path
|
59
|
+
def source_path
|
60
|
+
Pathname.new(self.config[:source_path])
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get the current SCM object
|
64
|
+
def scm(force = false)
|
65
|
+
return @_scm if @_scm && !force
|
66
|
+
|
67
|
+
case self.config[:scm]
|
68
|
+
when :git
|
69
|
+
@_scm = Release::Scm::Git.new(:path => self.source_path)
|
70
|
+
else
|
71
|
+
raise "Unknown SCM #{options[:scm].inspect}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Inject variables into files with an optional filter
|
76
|
+
#
|
77
|
+
# @examples
|
78
|
+
# release.inject({"VERSION" => release.version, "DATE" => release.date}, :into => %w{_doc/toc.html})
|
79
|
+
# release.inject({"CHANGELOG" => {:file => "", :filter => BlueCloth}}, :into => %w{_doc/changelog.html})
|
80
|
+
def inject(variables, options)
|
81
|
+
@injections << [variables, options]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Use a certain pre-processor
|
85
|
+
#
|
86
|
+
# @examples
|
87
|
+
# release.use :sprockets, sprockets_config
|
88
|
+
def use(processor, options = {})
|
89
|
+
@stack << [processor, options]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Write out the whole release into a directory, zip file or anything you can imagine
|
93
|
+
# #finalize can be called multiple times, it just will run all of them.
|
94
|
+
#
|
95
|
+
# The default finalizer is :dir
|
96
|
+
#
|
97
|
+
# @param [Symbol, Proc] Finalizer to use
|
98
|
+
#
|
99
|
+
# @examples
|
100
|
+
# release.finalize :zip
|
101
|
+
def finalize(finalizer, options = {})
|
102
|
+
@finalizers << [finalizer, options]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Files to clean up in the build directory just before finalization happens
|
106
|
+
#
|
107
|
+
# @param [String] Pattern to glob within build directory
|
108
|
+
#
|
109
|
+
# @examples
|
110
|
+
# release.cleanup "**/.DS_Store"
|
111
|
+
def cleanup(pattern)
|
112
|
+
@cleanups << pattern
|
113
|
+
end
|
114
|
+
|
115
|
+
# Generates a banner if a block is given, or returns the currently set banner.
|
116
|
+
# It automatically takes care of adding comment marks around the banner.
|
117
|
+
#
|
118
|
+
# The default banner looks like this:
|
119
|
+
#
|
120
|
+
# =======================
|
121
|
+
# = Version : v1.0.0 =
|
122
|
+
# = Date : 2012-06-20 =
|
123
|
+
# =======================
|
124
|
+
#
|
125
|
+
#
|
126
|
+
# @option options [:css,:js,:html,false] :comment Wether or not to comment the output and in what style. (default=js)
|
127
|
+
def banner(options = {}, &block)
|
128
|
+
options = {
|
129
|
+
:comment => :js
|
130
|
+
}.update(options)
|
131
|
+
|
132
|
+
if block_given?
|
133
|
+
@_banner = yield.to_s
|
134
|
+
elsif !@_banner
|
135
|
+
banner = []
|
136
|
+
banner << "Version : #{self.scm.version}"
|
137
|
+
banner << "Date : #{self.scm.date.strftime("%Y-%m-%d")}"
|
138
|
+
|
139
|
+
size = banner.inject(0){|mem,b| b.size > mem ? b.size : mem }
|
140
|
+
banner.map!{|b| "= #{b.ljust(size)} =" }
|
141
|
+
div = "=" * banner.first.size
|
142
|
+
banner.unshift(div)
|
143
|
+
banner << div
|
144
|
+
@_banner = banner.join("\n")
|
145
|
+
end
|
146
|
+
|
147
|
+
if options[:comment]
|
148
|
+
self.comment(@_banner, :style => options[:comment])
|
149
|
+
else
|
150
|
+
@_banner
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Actually perform the release
|
155
|
+
def run!
|
156
|
+
# Validate paths
|
157
|
+
validate_paths!
|
158
|
+
|
159
|
+
# Extract valid mockup
|
160
|
+
extract!
|
161
|
+
|
162
|
+
# Run stack
|
163
|
+
run_stack!
|
164
|
+
|
165
|
+
# Run injections
|
166
|
+
run_injections!
|
167
|
+
|
168
|
+
# Run cleanups
|
169
|
+
run_cleanups!
|
170
|
+
|
171
|
+
# Run finalizers
|
172
|
+
run_finalizers!
|
173
|
+
|
174
|
+
# Cleanup
|
175
|
+
cleanup! if self.config[:cleanup_build]
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
def log(part, msg)
|
180
|
+
puts part.class.to_s + " : " + msg.to_s
|
181
|
+
end
|
182
|
+
|
183
|
+
# @param [Array] globs an array of file path globs that will be globbed against the build_path
|
184
|
+
# @param [Array] excludes an array of regexps that will be excluded from the result
|
185
|
+
def get_files(globs, excludes = [])
|
186
|
+
files = globs.map{|g| Dir.glob(self.build_path + g) }.flatten
|
187
|
+
if excludes.any?
|
188
|
+
files.reject{|c| excludes.detect{|e| e.match(c) } }
|
189
|
+
else
|
190
|
+
files
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
protected
|
195
|
+
|
196
|
+
# ==============
|
197
|
+
# = The runway =
|
198
|
+
# ==============
|
199
|
+
|
200
|
+
def validate_paths!
|
201
|
+
# Make sure the build_path is empty
|
202
|
+
raise ArgumentError, "Build path \"#{self.build_path}\" is not empty" if self.build_path.exist?
|
203
|
+
|
204
|
+
# Make sure the target_path exists
|
205
|
+
raise ArgumentError, "Target path \"#{self.target_path}\" does not exist" if !self.target_path.exist?
|
206
|
+
end
|
207
|
+
|
208
|
+
def extract!
|
209
|
+
extractor = Extractor.new(self.project, self.build_path)
|
210
|
+
extractor.run!
|
211
|
+
end
|
212
|
+
|
213
|
+
def run_stack!
|
214
|
+
@stack = self.class.default_stack.dup if @stack.empty?
|
215
|
+
@stack.each do |processor, options|
|
216
|
+
get_callable(processor, HtmlMockup::Release::Processors).call(self, options)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def run_injections!
|
221
|
+
@injections.each do |injection|
|
222
|
+
Injector.new(injection[0], injection[1]).call(self)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def run_finalizers!
|
227
|
+
@finalizers = self.class.default_finalizers.dup if @finalizers.empty?
|
228
|
+
@finalizers.each do |finalizer, options|
|
229
|
+
get_callable(finalizer, HtmlMockup::Release::Finalizers).call(self, options)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def run_cleanups!
|
234
|
+
# We switch to the build path and append the globbed files for safety, so even if you manage to sneak in a
|
235
|
+
# pattern like "/**/*" it won't do you any good as it will be reappended to the path
|
236
|
+
Dir.chdir(self.build_path.to_s) do
|
237
|
+
@cleanups.each do |pattern|
|
238
|
+
Dir.glob(pattern).each do |file|
|
239
|
+
path = File.join(self.build_path.to_s, file)
|
240
|
+
log(self, "Cleaning up \"#{path}\" in build")
|
241
|
+
rm(path)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def cleanup!
|
248
|
+
log(self, "Cleaning up build path #{self.build_path}")
|
249
|
+
rm_rf(self.build_path)
|
250
|
+
end
|
251
|
+
|
252
|
+
# Makes callable into a object that responds to call.
|
253
|
+
#
|
254
|
+
# @param [#call, Symbol, Class] callable If callable already responds to #call will just return callable, a Symbol will be searched for in the scope parameter, a class will be instantiated (and checked if it will respond to #call)
|
255
|
+
# @param [Module] scope The scope in which to search callable in if it's a Symbol
|
256
|
+
def get_callable(callable, scope)
|
257
|
+
return callable if callable.respond_to?(:call)
|
258
|
+
|
259
|
+
if callable.kind_of?(Symbol)
|
260
|
+
# TODO camelcase callable
|
261
|
+
callable = callable.to_s.capitalize.to_sym
|
262
|
+
if scope.constants.include?(callable)
|
263
|
+
c = scope.const_get(callable)
|
264
|
+
callable = c if c.is_a?(Class)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
if callable.kind_of?(Class)
|
269
|
+
callable = callable.new
|
270
|
+
end
|
271
|
+
|
272
|
+
if callable.respond_to?(:call)
|
273
|
+
callable
|
274
|
+
else
|
275
|
+
raise ArgumentError, "Could not resolve #{callable.inspect}. Callable must be an object that responds to #call or a symbol that resolve to such an object or a class with a #call instance method."
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
# @param [String] string The string to comment
|
281
|
+
#
|
282
|
+
# @option options [:html, :css, :js] :style The comment style to use (default=:js, which is the same as :css)
|
283
|
+
# @option options [Boolean] :per_line Comment per line or make one block? (default=true)
|
284
|
+
def comment(string, options = {})
|
285
|
+
options = {
|
286
|
+
:style => :css,
|
287
|
+
:per_line => true
|
288
|
+
}.update(options)
|
289
|
+
|
290
|
+
commenters = {
|
291
|
+
:html => Proc.new{|s| "<!-- #{s} -->" },
|
292
|
+
:css => Proc.new{|s| "/* #{s} */" },
|
293
|
+
:js => Proc.new{|s| "/* #{s} */" }
|
294
|
+
}
|
295
|
+
|
296
|
+
commenter = commenters[options[:style]] || commenters[:js]
|
297
|
+
|
298
|
+
if options[:per_line]
|
299
|
+
string = string.split(/\r?\n/)
|
300
|
+
string.map{|s| commenter.call(s) }.join("\n")
|
301
|
+
else
|
302
|
+
commenter.call(s)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
require File.dirname(__FILE__) + "/extractor"
|
309
|
+
require File.dirname(__FILE__) + "/release/scm"
|
310
|
+
require File.dirname(__FILE__) + "/release/injector"
|
311
|
+
require File.dirname(__FILE__) + "/release/finalizers"
|
312
|
+
require File.dirname(__FILE__) + "/release/processors"
|
data/lib/html_mockup/server.rb
CHANGED
@@ -6,17 +6,28 @@ require File.dirname(__FILE__) + "/rack/html_validator"
|
|
6
6
|
|
7
7
|
module HtmlMockup
|
8
8
|
class Server
|
9
|
-
attr_accessor :options,:server_options, :root, :partial_path
|
10
9
|
|
11
|
-
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
attr_accessor :html_path, :partial_path
|
13
|
+
|
14
|
+
attr_accessor :port, :handler
|
15
|
+
|
16
|
+
def initialize(html_path, partial_path, options={})
|
12
17
|
@stack = ::Rack::Builder.new
|
13
18
|
|
14
19
|
@middleware = []
|
15
|
-
@
|
20
|
+
@html_path = html_path
|
16
21
|
@partial_path = partial_path
|
17
|
-
@options
|
22
|
+
@options = {
|
23
|
+
:handler => nil, # Autodetect
|
24
|
+
:port => 9000
|
25
|
+
}.update(options)
|
26
|
+
|
27
|
+
@port = @options[:port]
|
28
|
+
@handler = @options[:handler]
|
18
29
|
end
|
19
|
-
|
30
|
+
|
20
31
|
# Use the specified Rack middleware
|
21
32
|
def use(middleware, *args, &block)
|
22
33
|
@middleware << [middleware, args, block]
|
@@ -25,7 +36,7 @@ module HtmlMockup
|
|
25
36
|
def handler
|
26
37
|
if self.options[:handler]
|
27
38
|
begin
|
28
|
-
@handler = ::Rack::Handler.get(self.
|
39
|
+
@handler = ::Rack::Handler.get(self.handler)
|
29
40
|
rescue LoadError
|
30
41
|
rescue NameError
|
31
42
|
end
|
@@ -35,9 +46,9 @@ module HtmlMockup
|
|
35
46
|
end
|
36
47
|
@handler ||= detect_rack_handler
|
37
48
|
end
|
38
|
-
|
39
|
-
def run
|
40
|
-
self.handler.run self.application,
|
49
|
+
|
50
|
+
def run!
|
51
|
+
self.handler.run self.application, self.server_options do |server|
|
41
52
|
trap(:INT) do
|
42
53
|
## Use thins' hard #stop! if available, otherwise just #stop
|
43
54
|
server.respond_to?(:stop!) ? server.stop! : server.stop
|
@@ -45,6 +56,7 @@ module HtmlMockup
|
|
45
56
|
end
|
46
57
|
end
|
47
58
|
end
|
59
|
+
alias :run :run!
|
48
60
|
|
49
61
|
def application
|
50
62
|
return @app if @app
|
@@ -56,7 +68,7 @@ module HtmlMockup
|
|
56
68
|
@middleware.each { |c,a,b| @stack.use(c, *a, &b) }
|
57
69
|
|
58
70
|
@stack.use Rack::HtmlValidator if self.options["validate"]
|
59
|
-
@stack.run Rack::HtmlMockup.new(self.
|
71
|
+
@stack.run Rack::HtmlMockup.new(self.html_path, self.partial_path)
|
60
72
|
|
61
73
|
@app = @stack.to_app
|
62
74
|
end
|
@@ -64,6 +76,14 @@ module HtmlMockup
|
|
64
76
|
|
65
77
|
protected
|
66
78
|
|
79
|
+
# Generate server options for handler
|
80
|
+
def server_options
|
81
|
+
{
|
82
|
+
:Port => self.port
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
|
67
87
|
# Sinatra's detect_rack_handler
|
68
88
|
def detect_rack_handler
|
69
89
|
servers = %w[mongrel thin webrick]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: html_mockup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,27 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.16.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.16.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rack
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,7 +37,12 @@ dependencies:
|
|
32
37
|
version: 1.0.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.0.0
|
36
46
|
description:
|
37
47
|
email: flurin@digitpaint.nl
|
38
48
|
executables:
|
@@ -48,8 +58,23 @@ files:
|
|
48
58
|
- examples/partials/test.part.rhtml
|
49
59
|
- examples/script/server
|
50
60
|
- lib/html_mockup/cli.rb
|
61
|
+
- lib/html_mockup/extractor.rb
|
62
|
+
- lib/html_mockup/mockupfile.rb
|
63
|
+
- lib/html_mockup/project.rb
|
51
64
|
- lib/html_mockup/rack/html_mockup.rb
|
52
65
|
- lib/html_mockup/rack/html_validator.rb
|
66
|
+
- lib/html_mockup/rack/sleep.rb
|
67
|
+
- lib/html_mockup/release.rb
|
68
|
+
- lib/html_mockup/release/finalizers.rb
|
69
|
+
- lib/html_mockup/release/finalizers/dir.rb
|
70
|
+
- lib/html_mockup/release/finalizers/zip.rb
|
71
|
+
- lib/html_mockup/release/injector.rb
|
72
|
+
- lib/html_mockup/release/processors.rb
|
73
|
+
- lib/html_mockup/release/processors/requirejs.rb
|
74
|
+
- lib/html_mockup/release/processors/sass.rb
|
75
|
+
- lib/html_mockup/release/processors/yuicompressor.rb
|
76
|
+
- lib/html_mockup/release/scm.rb
|
77
|
+
- lib/html_mockup/release/scm/git.rb
|
53
78
|
- lib/html_mockup/server.rb
|
54
79
|
- lib/html_mockup/template.rb
|
55
80
|
- lib/html_mockup/w3c_validator.rb
|
@@ -66,6 +91,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
91
|
- - ! '>='
|
67
92
|
- !ruby/object:Gem::Version
|
68
93
|
version: '0'
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
hash: -1984595046850543499
|
69
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
98
|
none: false
|
71
99
|
requirements:
|
@@ -74,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
102
|
version: '0'
|
75
103
|
requirements: []
|
76
104
|
rubyforge_project:
|
77
|
-
rubygems_version: 1.8.
|
105
|
+
rubygems_version: 1.8.24
|
78
106
|
signing_key:
|
79
107
|
specification_version: 3
|
80
108
|
summary: HTML Mockup is a set of tools to create self-containing HTML mockups.
|