Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More isolated refactor. Lets you add middlewares to the preview serve…

…r. Loads extras from extras/
  • Loading branch information...
commit f63c94a8d2b79c8044da4dd0e490702d192fa778 1 parent b1baaf7
@juliocesar authored
Showing with 109 additions and 88 deletions.
  1. +109 −88 Rakefile
View
197 Rakefile
@@ -1,7 +1,7 @@
# encoding: UTF-8
# ὅπλα / Hopla - My weapons of choice
-# ===========================
+# ===================================
#
# A dev suite that lets you use templates (for gems you have installed)
# along with SASS/compass and CoffeeScript.
@@ -10,21 +10,20 @@
#
# $ rake hopla
#
-# And you're all set! Make sure you're running ruby 1.9
+# And you're all set! Make sure you're running ruby 1.9.
# Dependencies
-Gems = %w(rack colorize compass sprockets nokogiri)
-Dependencies = Gems + %w(pathname logger fileutils)
+gems = %w(rack colorize compass sprockets nokogiri)
+dependencies = gems + %w(pathname logger fileutils ostruct)
begin
- Dependencies.map { |lib| require lib }
+ dependencies.map { |lib| require lib }
rescue LoadError
STDERR.puts %Q(
- Hopla says:
Error loading one or more required gems. Ensure you have the required
gems by running.
- $ gem install #{Gems.join ' '}
+ $ gem install #{gems.join ' '}
Or add them to your Gemfile and run `bundle install`. Additionally, you
may want to run:
@@ -36,41 +35,37 @@ rescue LoadError
end
# ---
-# String / File.join hack to cut some characters
+# String / File.join hack to cut some characters.
class String
def /(to) File.join(self, to); end
end
-# Paths we'll be referring to throughout
-Root = File.dirname __FILE__
-Public = 'public'
-Assets = 'assets'
-Scripts = Assets/'javascripts'
-Styles = Assets/'stylesheets'
-Templates = Assets/'templates'
+# The main module containing our code and instances.
+Hopla = OpenStruct.new
-# Our pretty logger. A.k.a. the definition of going the extra mile.
-class HoplaLogger < Logger
+# A few paths we'll be referring to throughout the app.
+Hopla.Root = File.dirname __FILE__
+Hopla.Public = 'public'
+Hopla.Assets = 'assets'
+Hopla.Scripts = Hopla.Assets/'javascripts'
+Hopla.Styles = Hopla.Assets/'stylesheets'
+Hopla.Templates = Hopla.Assets/'templates'
+Hopla.Extras = Hopla.Root/'extras'
+
+# Our pretty logger. A.K.A. the definition of going the extra mile.
+class HoplaLogger < ::Logger
def format_message severity, timestamp, program, message
" #{"————⥲".yellow} %s" % message + "\n"
end
end
+Hopla.logger = HoplaLogger.new STDOUT
+Hopla.logger.level = ::Logger::INFO
-# Steal everything going to stdout and ensure it conforms with
-# our aesthetic standards
-def $stdout.puts *args
- $logger.info *args
-end
-
-$logger = HoplaLogger.new STDOUT
-$logger.level = Logger::INFO
-# ---
-
-# The styles and scripts compiler
-Compiler = Sprockets::Environment.new Pathname(Root) do |env|
-
+# The styles and scripts compiler, which is just an instance of
+# Sprockets::Environment.
+Hopla.compiler = Sprockets::Environment.new Pathname(Hopla.Root) do |env|
# Log to the standard output
- env.logger = $logger
+ env.logger = Hopla.logger
# Add all compass paths to it
Compass.sass_engine_options[:load_paths].each do |path|
@@ -78,9 +73,9 @@ Compiler = Sprockets::Environment.new Pathname(Root) do |env|
end
# Append the root path, so refs like javascripts/xyz also work
- env.prepend_path Scripts
- env.prepend_path Styles
- env.prepend_path Assets
+ env.prepend_path Hopla.Scripts
+ env.prepend_path Hopla.Styles
+ env.prepend_path Hopla.Assets
# Needed since Sprockets 2.5
env.context_class.class_eval do
@@ -89,59 +84,81 @@ Compiler = Sprockets::Environment.new Pathname(Root) do |env|
end
# ---
-# The preview server
-server = Rack::Builder.app do
- FileServer = Rack::File.new Public
-
- # Tiny middleware for serving an index.html file for "directory"
- # paths. E.g.: serves '/coco/index.html' if you request '/coco/'.
- # It'll serve a compiled template for a request path should a static
- # HTML file not exist.
- Template = lambda { |env|
- env['PATH_INFO'] = '/' if ENV['FORCE_INDEX']
- noext = env['PATH_INFO'].sub /\.\w+$/, ''
- path = noext[-1] == "/" ? noext/'index' : noext
- static = Dir["#{Public/path}.html"][0]
- template = Dir["#{Templates/path}.*"][0]
- if static
- [200, {'Content-Type' => 'text/html'}, File.open(static)]
- elsif template
- [200, {'Content-Type' => 'text/html'}, [Tilt.new(template).render]]
- else
- [404, {'Content-Type' => 'text/plain'}, ["Template not found: #{path}"]]
- end
- }
-
- # Serve, by priority:
- # 1 - any static files that exist in the public dir
- # 2 - scripts and stylesheets, compiling them before serving
- # 3 - index.html or compiled templates matching the path requested
- run lambda { |env|
- response = FileServer.call env
- response = Compiler.call env if response[0] == 404
- response = Template.call env if response[0] == 404
- response
- }
+# The preview server. Any middlewares that it needs to use should be
+# pushed into Hopla.middlewares.
+Hopla.middlewares = []
+
+def Hopla.make_preview_server
+ Rack::Builder.app do
+ static_server = Rack::File.new Hopla.Public
+
+ # Load all middlewares required by extras.
+ Hopla.middlewares.each { |middleware, *options| use middleware, *options }
+
+ # Tiny middleware for serving an index.html file for "directory"
+ # paths. E.g.: serves '/coco/index.html' if you request '/coco/'.
+ # It'll serve a compiled template for a request path should a static
+ # HTML file not exist.
+ template_server = lambda { |env|
+ env['PATH_INFO'] = '/' if ENV['FORCE_INDEX']
+ noext = env['PATH_INFO'].sub /\.\w+$/, ''
+ path = noext[-1] == "/" ? noext/'index' : noext
+ static = Dir["#{Hopla.Public/path}.html"][0]
+ template = Dir["#{Hopla.Templates/path}.*"][0]
+ if static
+ [200, {'Content-Type' => 'text/html'}, File.open(static)]
+ elsif template
+ [200, {'Content-Type' => 'text/html'}, [Tilt.new(template).render]]
+ else
+ [404, {'Content-Type' => 'text/plain'}, ["Template not found: #{path}"]]
+ end
+ }
+
+ # Serve, by priority:
+ # 1 - any static files that exist in the public dir.
+ # 2 - scripts and stylesheets, compiling them before serving.
+ # 3 - index.html or compiled templates matching the path requested.
+ run lambda { |env|
+ response = static_server.call env
+ response = Hopla.compiler.call env if response[0] == 404
+ response = template_server.call env if response[0] == 404
+ response
+ }
+ end
end
# ---
+# Steal everything going to stdout and ensure it conforms with
+# our aesthetic standards
+def $stdout.puts *args
+ Hopla.logger.info *args
+end
+
+# These rake tasks are part of Hopla core. Of "non-private" nature are
+# the preview server and compile tasks.
namespace :hopla do
+
+ # Load all extra tasks it finds in extras/
+ Dir["#{Hopla.Extras}/*.rb"].each do |extra|
+ require extra
+ end
+
# Runs Hopla
task :run => [:check] do
- $logger.info "ὅπλα / Hopla starting. Listening on port 4567".red
- Rack::Server.start :app => server, :Port => 4567
+ Hopla.logger.info "ὅπλα / Hopla starting. Listening on port 4567".red
+ Rack::Server.start :app => Hopla.make_preview_server, :Port => 4567
end
# Compiles all templates, and assets referred to in said templates
task :compile do
- Dir["#{Templates}/**/*"].each do |template|
- target = Public/template.sub(Templates, '').sub(/.\w+$/, '.html')
+ Dir["#{Hopla.Templates}/**/*"].each do |template|
+ target = Hopla.Public/template.sub(Hopla.Templates, '').sub(/.\w+$/, '.html')
File.open(target, 'w') do |file| file << Tilt.new(template).render; end
- $logger.info "Compiled #{template.red}"
+ Hopla.logger.info "Compiled #{template.red}"
end
- # For each HTML file in the public directory
- Dir["#{Public}/**/*.html"].each do |html|
+ # For each HTML file in the public directory...
+ Dir["#{Hopla.Public}/**/*.html"].each do |html|
# .. open it with Nokogiri
document = Nokogiri::HTML File.read(html)
@@ -149,39 +166,43 @@ namespace :hopla do
# ... get each script with a "src" attribute
document.css('script[src]').each do |script|
# ... if asset found in sprockets, compile/write it to public/
- if asset = Compiler[script['src'].sub(/^\//, '')]
- asset.write_to Public/script['src']
- $logger.info "Compiled #{script['src'].sub(/^\//, '').red}"
+ relative_asset_path = script['src'].sub(/^\//, '')
+ if asset = Hopla.compiler[relative_asset_path]
+ asset.write_to Hopla.Public/script['src']
+ Hopla.logger.info "Compiled #{relative_asset_path.red}"
end
end
# ... get each stylesheet
document.css('link[rel="stylesheet"][href]').each do |css|
# ... if asset found in sprockets, compile/write it to public/
- if asset = Compiler[css['href'].sub(/^\//, '')]
- asset.write_to Public/css['href']
- $logger.info "Compiled #{css['href'].sub(/^\//, '').red}"
+ relative_asset_path = css['href'].sub(/^\//, '')
+ if asset = Hopla.compiler[relative_asset_path]
+ asset.write_to Hopla.Public/css['href']
+ Hopla.logger.info "Compiled #{relative_asset_path.red}"
end
end
end
end
- # Creates all the directories needed for Hopla
+ # Creates all the directories needed for Hopla.
task :setup do
- $logger.info "Creating necessary directories..."
- FileUtils.mkdir_p Scripts
- FileUtils.mkdir_p Styles
- FileUtils.mkdir_p Public
- FileUtils.mkdir_p Templates
+ Hopla.logger.info "Creating necessary directories..."
+ FileUtils.mkdir_p Hopla.Scripts
+ FileUtils.mkdir_p Hopla.Styles
+ FileUtils.mkdir_p Hopla.Public
+ FileUtils.mkdir_p Hopla.Templates
end
- # Checks whether the necessary directories exist
+ # Checks whether the necessary directories exist.
task :check do
- needs_setup = [Scripts, Styles, Public, Templates].any? do |dir|
+ needs_setup = [Hopla.Scripts, Hopla.Styles, Hopla.Public, Hopla.Templates].any? do |dir|
not File.directory? dir
end
Rake::Task['hopla:setup'].invoke if needs_setup
end
end
+# ---
+# Default rake task for when ran as `rake hopla`
task :hopla => ['hopla:run']
Please sign in to comment.
Something went wrong with that request. Please try again.