From ba97a3064ff547012ef79eb534159ef1c155a7a7 Mon Sep 17 00:00:00 2001 From: Christoph Chilian Date: Thu, 6 Sep 2012 19:23:31 +0200 Subject: [PATCH 001/148] optimized the 'build_routes'-function to work well in combination with the 'sinatra-assetpack'-Gem --- lib/sinatra_static.rb | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/sinatra_static.rb b/lib/sinatra_static.rb index b39c214..b5e4e90 100644 --- a/lib/sinatra_static.rb +++ b/lib/sinatra_static.rb @@ -9,37 +9,37 @@ class SinatraStatic require 'term/ansicolor' class ColorString < String include Term::ANSIColor - end - - def initialize(app) - @app = app + end + + def initialize(app) + @app = app end def build!(dir) handle_error_no_each_route! unless @app.respond_to?(:each_route) - handle_error_dir_not_found!(dir) unless dir_exists?(dir) + handle_error_dir_not_found!(dir) unless dir_exists?(dir) build_routes(dir) end private def build_routes(dir) - @app.each_route do |route| - next unless route.verb == 'GET' + @app.each_route do |route| + next if route.verb != 'GET' or not route.path.is_a? String build_path(route.path, dir) - end - end + end + end - def build_path(path, dir) + def build_path(path, dir) ::FileUtils.mkdir_p(dir_for_path(path, dir)) - ::File.open(file_for_path(path, dir), 'w+') do |f| - f.write(get_path(path).body) - end + ::File.open(file_for_path(path, dir), 'w+') do |f| + f.write(get_path(path).body) + end end def get_path(path) - self.get(path).tap do |resp| - handle_error_non_200!(path) unless resp.status == 200 + self.get(path).tap do |resp| + handle_error_non_200!(path) unless resp.status == 200 end end @@ -55,8 +55,8 @@ def dir_exists?(dir) ::File.exists?(dir) && ::File.directory?(dir) end - def dir_for_path(path, dir) - file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] + def dir_for_path(path, dir) + file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] end def file_extensions @@ -65,13 +65,13 @@ def file_extensions def env ENV['RACK_ENV'] - end + end def handle_error_no_each_route! handle_error!("can't call app.each_route, did you include sinatra-advanced-routes?") end - def handle_error_dir_not_found!(dir) + def handle_error_dir_not_found!(dir) handle_error!("can't find output directory: #{dir}") end @@ -79,7 +79,7 @@ def handle_error_non_200!(path) handle_error!("GET #{path} returned non-200 status code...") end - def handle_error!(desc) + def handle_error!(desc) puts ColorString.new("failed: #{desc}").red; exit! end From e76a75cdad6a588b30928d78f45a6bb7774cc551 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 17:35:47 -0500 Subject: [PATCH 002/148] Reformat & simplify Readme --- readme.md | 44 +++++++++++++++++++++++++++++++ readme.rdoc | 74 ----------------------------------------------------- 2 files changed, 44 insertions(+), 74 deletions(-) create mode 100644 readme.md delete mode 100644 readme.rdoc diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6f01fcb --- /dev/null +++ b/readme.md @@ -0,0 +1,44 @@ +# sinatra-static + +> Exports your Sinatra app to static files. +Requires "sinatra-advanced-routes". +Get requests and response-status 200 only (no redirects). you also have to copy the public-dir yourself (if you're using it). + +## Installation + +Add `sinatra-static` to your Gemfile + + gem 'sinatra-static', '>= 0.1.1' + +## Usage + + builder = SinatraStatic.new(App) + builder.build!('public/') + +## Getting started + +Sample Sinatra application : + + require 'sinatra' + require 'sinatra/advanced_routes' + require 'sinatra_static' + + class App < Sinatra::Base + + get '/' do + "homepage" + end + + get '/contact' do + "contact" + end + + end + + builder = SinatraStatic.new(App) + builder.build!('public/') + +Will generate this output when run : + + public/index.html -> "homepage" + public/contact/index.html -> "contact" diff --git a/readme.rdoc b/readme.rdoc deleted file mode 100644 index dd5da1d..0000000 --- a/readme.rdoc +++ /dev/null @@ -1,74 +0,0 @@ -= sinatra-static - -export your sinatra app to a directory of static files. requires "sinatra-advanced-routes". get requests and response-status 200 only (no redirects). you also have to copy the public-dir yourself (if you're using it). - - -== usage - - require 'sinatra_static' - - builder = SinatraStatic.new(MySinatraApp) - builder.build!('/Users/paul/my_static_site') - - -= example - -this simple app: - - require 'sinatra' - require "sinatra/advanced_routes" - require 'sinatra_static' - - class MyApp::App < Sinatra::Base - - get '/' do - "my homepage" - end - - get '/blog' do - "blog index" - end - - get '/blog/ajax.html' do - "blog index w/o layout" - end - - %w(page1 page2 page3).each do |page| - get "/blog/#{page}" do - "blog page: #{page}" - end - end - - get '/dynamic.js' do - "my generated javascript" - end - - get '/data.json' do - "my generated json" - end - - end - - builder = SinatraStatic.new(MyApp:App) - builder.build!('/Users/paul/my_static_site') - - -will generate this output: - - ~/my_static_site/index.html -> "my homepage" - ~/my_static_site/blog/index.html -> "blog index" - ~/my_static_site/blog/ajax.html -> "blog index w/o layout" - ~/my_static_site/blog/page1/index.html -> "blog page: page1" - ~/my_static_site/blog/page2/index.html -> "blog page: page2" - ~/my_static_site/blog/page3/index.html -> "blog page: page3" - ~/my_static_site/dynamic.js -> "my generated javascript" - ~/my_static_site/data.json -> "my generated json" - - -= installation - - gem install sinatra-static - -or in your Gemfile - - gem 'sinatra-static', '>= 0.1.1' From 15211c14a70e881edfca9252a07850f9605f8de5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 17:39:06 -0500 Subject: [PATCH 003/148] Add missing advanced routes registration in sample app --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 6f01fcb..58cecd4 100644 --- a/readme.md +++ b/readme.md @@ -25,6 +25,8 @@ Sample Sinatra application : class App < Sinatra::Base + register Sinatra::AdvancedRoutes + get '/' do "homepage" end From e594d19e41639401b6a0dac93a3d1ba1515c01a8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 17:48:45 -0500 Subject: [PATCH 004/148] Format Ruby code & minor adjustements --- readme.md | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index 58cecd4..0d9f69a 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,8 @@ # sinatra-static -> Exports your Sinatra app to static files. -Requires "sinatra-advanced-routes". -Get requests and response-status 200 only (no redirects). you also have to copy the public-dir yourself (if you're using it). +> Exports your Sinatra app to static files. Get requests and response-status 200 only (no redirects). + +Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) ## Installation @@ -12,35 +12,39 @@ Add `sinatra-static` to your Gemfile ## Usage - builder = SinatraStatic.new(App) - builder.build!('public/') +```ruby +builder = SinatraStatic.new(App) +builder.build!('public/') +``` ## Getting started -Sample Sinatra application : - - require 'sinatra' - require 'sinatra/advanced_routes' - require 'sinatra_static' +Sample Sinatra application building static pages : - class App < Sinatra::Base +```ruby +require 'sinatra' +require 'sinatra/advanced_routes' +require 'sinatra_static' - register Sinatra::AdvancedRoutes +class App < Sinatra::Base - get '/' do - "homepage" - end + register Sinatra::AdvancedRoutes - get '/contact' do - "contact" - end + get '/' do + "homepage" + end + get '/contact' do + "contact" end - builder = SinatraStatic.new(App) - builder.build!('public/') +end + +builder = SinatraStatic.new(App) +builder.build!('public/') +``` -Will generate this output when run : +Running your app ex. `ruby app.rb` will automatically generate theses files : public/index.html -> "homepage" public/contact/index.html -> "contact" From 01cd8b9fb40a331134556e6fa6d79ccffe97b410 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 17:52:14 -0500 Subject: [PATCH 005/148] Add optional advanced assets management instructions --- readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readme.md b/readme.md index 0d9f69a..f7c4352 100644 --- a/readme.md +++ b/readme.md @@ -48,3 +48,11 @@ Running your app ex. `ruby app.rb` will automatically generate theses files : public/index.html -> "homepage" public/contact/index.html -> "contact" + +## Advanced assets management + +If you wish to generate your assets (CSS, JS, images) with an assets packaging system, +you may use [Sinatra-AssetPack](https://github.com/rstacruz/sinatra-assetpack) and build +your assets in the same target directory with `rake assetpack:build`. + +IMPORTANT : to achieve `Sinatra-AssetPack` and `Sinatra-Static` compatibility, see [pull request #1](https://github.com/paulasmuth/sinatra-static/pull/1) \ No newline at end of file From 776dcee94f5f0c8de5adf7d473e3c5dee0227911 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 17:53:17 -0500 Subject: [PATCH 006/148] Minor README adjustments --- readme.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index f7c4352..d2322ae 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,10 @@ # sinatra-static -> Exports your Sinatra app to static files. Get requests and response-status 200 only (no redirects). - -Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) +> Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). ## Installation -Add `sinatra-static` to your Gemfile +Add `sinatra-static` to your Gemfile : gem 'sinatra-static', '>= 0.1.1' @@ -31,11 +29,15 @@ class App < Sinatra::Base register Sinatra::AdvancedRoutes get '/' do - "homepage" + "homepage" end get '/contact' do - "contact" + "contact" + end + + get '/data.json' do + "{json: 1}" end end @@ -48,11 +50,12 @@ Running your app ex. `ruby app.rb` will automatically generate theses files : public/index.html -> "homepage" public/contact/index.html -> "contact" + public/data.json -> "{json: 1}" -## Advanced assets management +### Advanced assets management If you wish to generate your assets (CSS, JS, images) with an assets packaging system, you may use [Sinatra-AssetPack](https://github.com/rstacruz/sinatra-assetpack) and build -your assets in the same target directory with `rake assetpack:build`. +your assets in the same target directory with `rake assetpack:build` task. -IMPORTANT : to achieve `Sinatra-AssetPack` and `Sinatra-Static` compatibility, see [pull request #1](https://github.com/paulasmuth/sinatra-static/pull/1) \ No newline at end of file +IMPORTANT : to achieve `Sinatra-AssetPack` and `Sinatra-Static` compatibility, see [pull request #1](https://github.com/paulasmuth/sinatra-static/pull/1). \ No newline at end of file From 50bb31ffd94bbeec18f3a2083e0da55e96a35439 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 17 Nov 2012 18:25:18 -0500 Subject: [PATCH 007/148] Update gemspec with new readme --- sinatra-static.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec index 83c7675..da1a126 100644 --- a/sinatra-static.gemspec +++ b/sinatra-static.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| "Gemfile.lock", "sinatra-static.gemspec", "lib/sinatra_static.rb", - "readme.rdoc" + "readme.md" ] s.homepage = "http://github.com/paulasmuth/sinatra-static" s.licenses = ["MIT"] From b21bd11505b5829ddc09c037bc09d08d4aab9300 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 14:12:18 -0500 Subject: [PATCH 008/148] Update gems & use gemspec as Gemfile source --- Gemfile | 6 +----- Gemfile.lock | 34 +++++++++++++++++++++------------- sinatra-static.gemspec | 31 ++++++------------------------- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/Gemfile b/Gemfile index eb3befe..df87cd4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,2 @@ source :rubygems -gem 'sinatra' -gem 'sinatra-advanced-routes' -gem 'term-ansicolor' -gem 'rack' -gem 'rack-test' +gemspec \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 9ae4f16..993eca3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,18 +1,29 @@ +PATH + remote: . + specs: + sinatra-static (0.1.1) + rack + rack-test + sinatra + sinatra-advanced-routes + term-ansicolor + GEM remote: http://rubygems.org/ specs: - backports (2.3.0) + backports (2.6.5) monkey-lib (0.5.4) backports - rack (1.3.4) - rack-protection (1.1.4) + rack (1.4.1) + rack-protection (1.2.0) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - sinatra (1.3.1) - rack (>= 1.3.4, ~> 1.3) - rack-protection (>= 1.1.2, ~> 1.1) - tilt (>= 1.3.3, ~> 1.3) + rake (10.0.2) + sinatra (1.3.3) + rack (~> 1.3, >= 1.3.6) + rack-protection (~> 1.2) + tilt (~> 1.3, >= 1.3.3) sinatra-advanced-routes (0.5.1) monkey-lib (~> 0.5.0) sinatra (~> 1.0) @@ -27,8 +38,5 @@ PLATFORMS ruby DEPENDENCIES - rack - rack-test - sinatra - sinatra-advanced-routes - term-ansicolor + rake + sinatra-static! diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec index da1a126..8831ca2 100644 --- a/sinatra-static.gemspec +++ b/sinatra-static.gemspec @@ -17,30 +17,11 @@ Gem::Specification.new do |s| s.licenses = ["MIT"] s.require_paths = ["lib"] s.rubygems_version = "1.8.10" - s.summary = "export your sinatra app to a directory of static files" - - if s.respond_to? :specification_version then - s.specification_version = 3 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - end - else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - end + s.summary = "export your sinatra app to a directory of static files" + s.add_runtime_dependency 'term-ansicolor' + s.add_runtime_dependency 'sinatra' + s.add_runtime_dependency 'sinatra-advanced-routes' + s.add_runtime_dependency 'rack' + s.add_runtime_dependency 'rack-test' end From bdfc708c8742a314fe445b429e6590427248ffee Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 14:12:57 -0500 Subject: [PATCH 009/148] Add Rakefile to run tests --- Rakefile | 6 ++++++ sinatra-static.gemspec | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 Rakefile diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..cc3744c --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +desc "Runs tests" +task :test do + Dir['test/*_test.rb'].each { |f| load f } +end + +task :default => :test \ No newline at end of file diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec index 8831ca2..59ff7f2 100644 --- a/sinatra-static.gemspec +++ b/sinatra-static.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'sinatra' s.add_runtime_dependency 'sinatra-advanced-routes' s.add_runtime_dependency 'rack' - s.add_runtime_dependency 'rack-test' + s.add_development_dependency 'rack-test' + s.add_development_dependency 'rake' end From eb16a32c8604b011343b84246e2ccfe90f0fe4c2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 15:29:55 -0500 Subject: [PATCH 010/148] Add awesome_print --- Gemfile.lock | 4 +++- sinatra-static.gemspec | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 993eca3..2155eab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,6 @@ PATH specs: sinatra-static (0.1.1) rack - rack-test sinatra sinatra-advanced-routes term-ansicolor @@ -11,6 +10,7 @@ PATH GEM remote: http://rubygems.org/ specs: + awesome_print (1.1.0) backports (2.6.5) monkey-lib (0.5.4) backports @@ -38,5 +38,7 @@ PLATFORMS ruby DEPENDENCIES + awesome_print + rack-test rake sinatra-static! diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec index 59ff7f2..4db7300 100644 --- a/sinatra-static.gemspec +++ b/sinatra-static.gemspec @@ -24,5 +24,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'rack' s.add_development_dependency 'rack-test' s.add_development_dependency 'rake' + s.add_development_dependency 'awesome_print' end From 274c2480dd121f067422f4773bc127e741f9fa59 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 15:30:23 -0500 Subject: [PATCH 011/148] Add failing tests --- .gitignore | 1 + test/app/.gitkeep | 0 test/build_test.rb | 32 ++++++++++++++++++++++++++++++ test/test_helper.rb | 47 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 .gitignore create mode 100644 test/app/.gitkeep create mode 100644 test/build_test.rb create mode 100644 test/test_helper.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9afaabf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test/app/public/ \ No newline at end of file diff --git a/test/app/.gitkeep b/test/app/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/build_test.rb b/test/build_test.rb new file mode 100644 index 0000000..7d1632f --- /dev/null +++ b/test/build_test.rb @@ -0,0 +1,32 @@ +require File.expand_path('../test_helper', __FILE__) + +class SinatraStaticBuildTest < UnitTest + include Rack::Test::Methods + + class App < UnitTest::App + get '/' do + "homepage" + end + get '/contact' do + "contact" + end + get '/data.json' do + "{test: 'ok'}" + end + end + + def test_build + # Temporary public folder + public_path = File.join(App.root, 'public') + FileUtils.rm_rf File.join(App.root, 'public') + FileUtils.mkdir public_path + + builder = SinatraStatic.new(App) + builder.build!(public_path) + + assert File.read(File.join(App.root, 'public/index.html')).include?('homepage') + assert File.read(File.join(App.root, 'public/contact/index.html')).include?('contact') + assert File.read(File.join(App.root, 'public/data.json')).include?("{test: 'ok'}") + end + +end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..360ac25 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,47 @@ +require 'rack/test' +require 'test/unit' +require 'sinatra/advanced_routes' +require 'sinatra_static' +require 'awesome_print' + +# Helper based on sinatra-assetpack test helper +# © 2011, Rico Sta. Cruz. Released under the MIT License +# @link http://www.opensource.org/licenses/mit-license.php +# @link https://github.com/rstacruz/sinatra-assetpack + +class UnitTest < Test::Unit::TestCase + include Rack::Test::Methods + + class App < Sinatra::Base + set :root, File.expand_path('../app', __FILE__) + enable :raise_errors + disable :show_exceptions + register Sinatra::AdvancedRoutes + end + + def setup + Sinatra::Base.set :environment, :test + end + + def d + puts "-"*80 + puts "#{last_response.status}" + y last_response.original_headers + puts "-"*80 + puts "" + puts last_response.body.gsub(/^/m, ' ') + puts "" + end + + def body + last_response.body.strip + end + + def r(*a) + File.join app.root, *a + end + + def assert_includes(haystack, needle) + assert haystack.include?(needle), "Expected #{haystack.inspect} to include #{needle.inspect}." + end +end \ No newline at end of file From 77088a6238086744a441d95e161af4774d9e7c4c Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 15:36:36 -0500 Subject: [PATCH 012/148] Add travis-ci config --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ef77b6a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: ruby +rvm: + - "1.9.3" + - "1.9.2" + - "1.8.7" +branches: + only: + - master \ No newline at end of file From b4a1f043438d61f95eedef4282b6041ad847ea36 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 15:54:12 -0500 Subject: [PATCH 013/148] Remove json/csv example as it is currently broken. Ref #1 --- readme.md | 5 ----- test/build_test.rb | 4 ---- 2 files changed, 9 deletions(-) diff --git a/readme.md b/readme.md index d2322ae..de70976 100644 --- a/readme.md +++ b/readme.md @@ -36,10 +36,6 @@ class App < Sinatra::Base "contact" end - get '/data.json' do - "{json: 1}" - end - end builder = SinatraStatic.new(App) @@ -50,7 +46,6 @@ Running your app ex. `ruby app.rb` will automatically generate theses files : public/index.html -> "homepage" public/contact/index.html -> "contact" - public/data.json -> "{json: 1}" ### Advanced assets management diff --git a/test/build_test.rb b/test/build_test.rb index 7d1632f..03b8836 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -10,9 +10,6 @@ class App < UnitTest::App get '/contact' do "contact" end - get '/data.json' do - "{test: 'ok'}" - end end def test_build @@ -26,7 +23,6 @@ def test_build assert File.read(File.join(App.root, 'public/index.html')).include?('homepage') assert File.read(File.join(App.root, 'public/contact/index.html')).include?('contact') - assert File.read(File.join(App.root, 'public/data.json')).include?("{test: 'ok'}") end end \ No newline at end of file From 74e8a6d38372369ff1596c21271e7f2da2bf8dda Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 15:54:17 -0500 Subject: [PATCH 014/148] Add travis build status --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index de70976..f44ee78 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,8 @@ > Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). +[![Build Status](https://travis-ci.org/hooktstudios/sinatra-static.png)](https://travis-ci.org/hooktstudios/sinatra-static) + ## Installation Add `sinatra-static` to your Gemfile : From 0686764165c60d867e61225ae507e5a77e86e1d2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 16:05:57 -0500 Subject: [PATCH 015/148] Add missing dependency for 1.8.7 --- Gemfile.lock | 2 ++ sinatra-static.gemspec | 1 + 2 files changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 2155eab..098f89e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,6 +32,7 @@ GEM monkey-lib (~> 0.5.0) sinatra (~> 1.0) term-ansicolor (1.0.7) + test-unit (2.5.2) tilt (1.3.3) PLATFORMS @@ -42,3 +43,4 @@ DEPENDENCIES rack-test rake sinatra-static! + test-unit diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec index 4db7300..e46a89f 100644 --- a/sinatra-static.gemspec +++ b/sinatra-static.gemspec @@ -25,5 +25,6 @@ Gem::Specification.new do |s| s.add_development_dependency 'rack-test' s.add_development_dependency 'rake' s.add_development_dependency 'awesome_print' + s.add_development_dependency 'test-unit' end From 97f69fa19d3ec2938ae4534c4fbe7e97acc665e7 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 16:14:26 -0500 Subject: [PATCH 016/148] Remove notice for issue fixed in this fork --- readme.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/readme.md b/readme.md index f44ee78..ee5d34a 100644 --- a/readme.md +++ b/readme.md @@ -54,5 +54,3 @@ Running your app ex. `ruby app.rb` will automatically generate theses files : If you wish to generate your assets (CSS, JS, images) with an assets packaging system, you may use [Sinatra-AssetPack](https://github.com/rstacruz/sinatra-assetpack) and build your assets in the same target directory with `rake assetpack:build` task. - -IMPORTANT : to achieve `Sinatra-AssetPack` and `Sinatra-Static` compatibility, see [pull request #1](https://github.com/paulasmuth/sinatra-static/pull/1). \ No newline at end of file From dba60687c901a4ee222747864b4a434bbb0af3eb Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 25 Nov 2012 17:19:05 -0500 Subject: [PATCH 017/148] Add Gemfile require options for easy setup --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ee5d34a..b1a7ec0 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,9 @@ Add `sinatra-static` to your Gemfile : - gem 'sinatra-static', '>= 0.1.1' +```ruby +gem 'sinatra-static', :require => 'sinatra_static' +``` ## Usage From 7dd939043434d4d446ea2efbc55e86e4420634ff Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Mon, 26 Nov 2012 23:44:07 -0500 Subject: [PATCH 018/148] Add Code Climate badge --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index b1a7ec0..26b8d47 100644 --- a/readme.md +++ b/readme.md @@ -3,6 +3,7 @@ > Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). [![Build Status](https://travis-ci.org/hooktstudios/sinatra-static.png)](https://travis-ci.org/hooktstudios/sinatra-static) +[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-static) ## Installation From 11b43f465ca35e91747b0b21eb3132b39447d42b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 20:59:22 -0500 Subject: [PATCH 019/148] Add MIT licence as specified in original gemspec --- LICENCE | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 LICENCE diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..a0fcc38 --- /dev/null +++ b/LICENCE @@ -0,0 +1,25 @@ + +LICENSE + +The MIT License + +Copyright (c) 2011-2013 Paul Asmuth, Jean-Philippe Doyle, Hookt Studios inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + From 30f79c3ce180bb8d9f3234e4c3b757e69ef84490 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 21:22:22 -0500 Subject: [PATCH 020/148] Release new gem as 'sinatra-export' and use Sinatra namespace --- Gemfile.lock | 6 +-- lib/sinatra/export.rb | 88 ++++++++++++++++++++++++++++++++++++++++++ lib/sinatra_static.rb | 86 ----------------------------------------- readme.md | 10 ++--- sinatra-export.gemspec | 31 +++++++++++++++ sinatra-static.gemspec | 30 -------------- test/build_test.rb | 4 +- test/test_helper.rb | 2 +- 8 files changed, 130 insertions(+), 127 deletions(-) create mode 100644 lib/sinatra/export.rb delete mode 100644 lib/sinatra_static.rb create mode 100644 sinatra-export.gemspec delete mode 100644 sinatra-static.gemspec diff --git a/Gemfile.lock b/Gemfile.lock index 098f89e..5e1cb47 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-static (0.1.1) + sinatra-export (0.9) rack sinatra sinatra-advanced-routes @@ -15,7 +15,7 @@ GEM monkey-lib (0.5.4) backports rack (1.4.1) - rack-protection (1.2.0) + rack-protection (1.3.2) rack rack-test (0.6.2) rack (>= 1.0) @@ -42,5 +42,5 @@ DEPENDENCIES awesome_print rack-test rake - sinatra-static! + sinatra-export! test-unit diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb new file mode 100644 index 0000000..f7957ad --- /dev/null +++ b/lib/sinatra/export.rb @@ -0,0 +1,88 @@ +module Sinatra + class Export + + @@file_extensions = %w(css js xml json html csv) + + attr_accessor :app + + include Rack::Test::Methods + + require 'term/ansicolor' + class ColorString < String + include Term::ANSIColor + end + + def initialize(app) + @app = app + end + + def build!(dir) + handle_error_no_each_route! unless @app.respond_to?(:each_route) + handle_error_dir_not_found!(dir) unless dir_exists?(dir) + build_routes(dir) + end + + private + + def build_routes(dir) + @app.each_route do |route| + next if route.verb != 'GET' or not route.path.is_a? String + build_path(route.path, dir) + end + end + + def build_path(path, dir) + ::FileUtils.mkdir_p(dir_for_path(path, dir)) + ::File.open(file_for_path(path, dir), 'w+') do |f| + f.write(get_path(path).body) + end + end + + def get_path(path) + self.get(path).tap do |resp| + handle_error_non_200!(path) unless resp.status == 200 + end + end + + def file_for_path(path, dir) + if path.match(/[^\/\.]+.(#{file_extensions.join("|")})$/) + ::File.join(dir, path) + else + ::File.join(dir, path, 'index.html') + end + end + + def dir_exists?(dir) + ::File.exists?(dir) && ::File.directory?(dir) + end + + def dir_for_path(path, dir) + file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] + end + + def file_extensions + @@file_extensions + end + + def env + ENV['RACK_ENV'] + end + + def handle_error_no_each_route! + handle_error!("can't call app.each_route, did you include sinatra-advanced-routes?") + end + + def handle_error_dir_not_found!(dir) + handle_error!("can't find output directory: #{dir}") + end + + def handle_error_non_200!(path) + handle_error!("GET #{path} returned non-200 status code...") + end + + def handle_error!(desc) + puts ColorString.new("failed: #{desc}").red; exit! + end + + end +end \ No newline at end of file diff --git a/lib/sinatra_static.rb b/lib/sinatra_static.rb deleted file mode 100644 index b5e4e90..0000000 --- a/lib/sinatra_static.rb +++ /dev/null @@ -1,86 +0,0 @@ -class SinatraStatic - - @@file_extensions = %w(css js xml json html csv) - - attr_accessor :app - - include Rack::Test::Methods - - require 'term/ansicolor' - class ColorString < String - include Term::ANSIColor - end - - def initialize(app) - @app = app - end - - def build!(dir) - handle_error_no_each_route! unless @app.respond_to?(:each_route) - handle_error_dir_not_found!(dir) unless dir_exists?(dir) - build_routes(dir) - end - -private - - def build_routes(dir) - @app.each_route do |route| - next if route.verb != 'GET' or not route.path.is_a? String - build_path(route.path, dir) - end - end - - def build_path(path, dir) - ::FileUtils.mkdir_p(dir_for_path(path, dir)) - ::File.open(file_for_path(path, dir), 'w+') do |f| - f.write(get_path(path).body) - end - end - - def get_path(path) - self.get(path).tap do |resp| - handle_error_non_200!(path) unless resp.status == 200 - end - end - - def file_for_path(path, dir) - if path.match(/[^\/\.]+.(#{file_extensions.join("|")})$/) - ::File.join(dir, path) - else - ::File.join(dir, path, 'index.html') - end - end - - def dir_exists?(dir) - ::File.exists?(dir) && ::File.directory?(dir) - end - - def dir_for_path(path, dir) - file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] - end - - def file_extensions - @@file_extensions - end - - def env - ENV['RACK_ENV'] - end - - def handle_error_no_each_route! - handle_error!("can't call app.each_route, did you include sinatra-advanced-routes?") - end - - def handle_error_dir_not_found!(dir) - handle_error!("can't find output directory: #{dir}") - end - - def handle_error_non_200!(path) - handle_error!("GET #{path} returned non-200 status code...") - end - - def handle_error!(desc) - puts ColorString.new("failed: #{desc}").red; exit! - end - -end diff --git a/readme.md b/readme.md index 26b8d47..529f04a 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# sinatra-static +# sinatra-export > Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). @@ -7,16 +7,16 @@ ## Installation -Add `sinatra-static` to your Gemfile : +Add to your Gemfile : ```ruby -gem 'sinatra-static', :require => 'sinatra_static' +gem 'sinatra-export' ``` ## Usage ```ruby -builder = SinatraStatic.new(App) +builder = Sinatra::Export.new(App) builder.build!('public/') ``` @@ -43,7 +43,7 @@ class App < Sinatra::Base end -builder = SinatraStatic.new(App) +builder = Sinatra::Export.new(App) builder.build!('public/') ``` diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec new file mode 100644 index 0000000..0e963cd --- /dev/null +++ b/sinatra-export.gemspec @@ -0,0 +1,31 @@ +Gem::Specification.new do |s| + s.name = 'sinatra-export' + s.version = '0.9' + + s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] + s.date = '2013-01-16' + s.description = 'Export your sinatra app to a directory of static files.' + s.summary = 'Sinatra static export.' + s.email = 'jeanphilippe.doyle@hooktstudios.com' + s.files = [ + 'Gemfile', + 'Gemfile.lock', + 'sinatra-export.gemspec', + 'lib/sinatra/export.rb', + 'readme.md' + ] + s.homepage = 'http://github.com/hooktstudios/sinatra-export' + s.license = 'MIT' + s.required_ruby_version = '>= 1.8.7' + + s.add_runtime_dependency 'term-ansicolor' + s.add_runtime_dependency 'sinatra' + s.add_runtime_dependency 'sinatra-advanced-routes' + s.add_runtime_dependency 'rack' + + s.add_development_dependency 'rack-test' + s.add_development_dependency 'rake' + s.add_development_dependency 'awesome_print' + s.add_development_dependency 'test-unit' +end + diff --git a/sinatra-static.gemspec b/sinatra-static.gemspec deleted file mode 100644 index e46a89f..0000000 --- a/sinatra-static.gemspec +++ /dev/null @@ -1,30 +0,0 @@ -Gem::Specification.new do |s| - s.name = "sinatra-static" - s.version = "0.1.1" - - s.authors = ["Paul Asmuth"] - s.date = "2011-10-16" - s.description = "export your sinatra app to a directory of static files" - s.email = "paul@paulasmuth.com" - s.files = [ - "Gemfile", - "Gemfile.lock", - "sinatra-static.gemspec", - "lib/sinatra_static.rb", - "readme.md" - ] - s.homepage = "http://github.com/paulasmuth/sinatra-static" - s.licenses = ["MIT"] - s.require_paths = ["lib"] - s.rubygems_version = "1.8.10" - s.summary = "export your sinatra app to a directory of static files" - s.add_runtime_dependency 'term-ansicolor' - s.add_runtime_dependency 'sinatra' - s.add_runtime_dependency 'sinatra-advanced-routes' - s.add_runtime_dependency 'rack' - s.add_development_dependency 'rack-test' - s.add_development_dependency 'rake' - s.add_development_dependency 'awesome_print' - s.add_development_dependency 'test-unit' -end - diff --git a/test/build_test.rb b/test/build_test.rb index 03b8836..5a84c98 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -1,6 +1,6 @@ require File.expand_path('../test_helper', __FILE__) -class SinatraStaticBuildTest < UnitTest +class SinatraExportBuildTest < UnitTest include Rack::Test::Methods class App < UnitTest::App @@ -18,7 +18,7 @@ def test_build FileUtils.rm_rf File.join(App.root, 'public') FileUtils.mkdir public_path - builder = SinatraStatic.new(App) + builder = Sinatra::Export.new(App) builder.build!(public_path) assert File.read(File.join(App.root, 'public/index.html')).include?('homepage') diff --git a/test/test_helper.rb b/test/test_helper.rb index 360ac25..ae77a8b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,7 +1,7 @@ require 'rack/test' require 'test/unit' require 'sinatra/advanced_routes' -require 'sinatra_static' +require 'sinatra/export' require 'awesome_print' # Helper based on sinatra-assetpack test helper From aa888beb7214e71b30aae606e6a7c6face0c51ed Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 21:31:13 -0500 Subject: [PATCH 021/148] Update travis and code-climate badges --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 529f04a..9a02576 100644 --- a/readme.md +++ b/readme.md @@ -2,8 +2,8 @@ > Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). -[![Build Status](https://travis-ci.org/hooktstudios/sinatra-static.png)](https://travis-ci.org/hooktstudios/sinatra-static) -[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-static) +[![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png)](https://travis-ci.org/hooktstudios/sinatra-export) +[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) ## Installation From f2763b337ed0b0df60775849be41e4668b5e45ed Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 21:42:48 -0500 Subject: [PATCH 022/148] Fix readme exemple name --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 9a02576..77b3b33 100644 --- a/readme.md +++ b/readme.md @@ -27,7 +27,7 @@ Sample Sinatra application building static pages : ```ruby require 'sinatra' require 'sinatra/advanced_routes' -require 'sinatra_static' +require 'sinatra/export' class App < Sinatra::Base From 46c712f0273f798bf9cd6cdc35c119d5f12718a4 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 21:49:42 -0500 Subject: [PATCH 023/148] Add rake task and update instructions. Fix #2 --- lib/sinatra/export.rb | 2 ++ lib/sinatra/export/rake.rb | 35 +++++++++++++++++++++++++++++++++++ readme.md | 34 +++++++++++++++++++--------------- sinatra-export.gemspec | 1 + 4 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 lib/sinatra/export/rake.rb diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index f7957ad..0979c07 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -1,3 +1,5 @@ +require 'rack/test' + module Sinatra class Export diff --git a/lib/sinatra/export/rake.rb b/lib/sinatra/export/rake.rb new file mode 100644 index 0000000..94da847 --- /dev/null +++ b/lib/sinatra/export/rake.rb @@ -0,0 +1,35 @@ +# Rake task based on sinatra-assetpack test helper +# © 2011, Rico Sta. Cruz. Released under the MIT License +# @link http://www.opensource.org/licenses/mit-license.php +# @link https://github.com/rstacruz/sinatra-assetpack + +unless defined?(APP_FILE) && defined?(APP_CLASS) + $stderr.write "Error: Please set APP_FILE, APP_CLASS before setting up Sinatra::Export rake tasks.\n" + $stderr.write "Example:\n" + $stderr.write " APP_FILE = 'app.rb'\n" + $stderr.write " APP_CLASS = 'App'\n" + $stderr.write " APP_PUBLIC = 'public'\n" + $stderr.write " require 'sinatra/export/rake'\n" + $stderr.write "\n" + exit +end + +def class_from_string(str) + str.split('::').inject(Object) do |mod, class_name| + mod.const_get(class_name) + end +end + +def app + require File.expand_path(APP_FILE, Dir.pwd) + class_from_string(APP_CLASS) +end + +namespace :sinatra do + desc "Export static application" + task :export do + require 'sinatra/export' + builder = Sinatra::Export.new(app) + builder.build!(APP_PUBLIC) + end +end \ No newline at end of file diff --git a/readme.md b/readme.md index 77b3b33..5d2b2ef 100644 --- a/readme.md +++ b/readme.md @@ -7,20 +7,23 @@ ## Installation -Add to your Gemfile : +Add to your `Gemfile` : ```ruby gem 'sinatra-export' ``` -## Usage +Setup your `Rakefile` : -```ruby -builder = Sinatra::Export.new(App) -builder.build!('public/') +``` +APP_FILE = 'app.rb' +APP_CLASS = 'App' +APP_PUBLIC = 'public' + +require 'sinatra/export/rake' ``` -## Getting started +## Quick Start Sample Sinatra application building static pages : @@ -34,25 +37,26 @@ class App < Sinatra::Base register Sinatra::AdvancedRoutes get '/' do - "homepage" + "

My homepage

" end get '/contact' do - "contact" + "

My contact page

" end end - -builder = Sinatra::Export.new(App) -builder.build!('public/') ``` -Running your app ex. `ruby app.rb` will automatically generate theses files : +Running your app ex. `rake sinatra:export` will automatically generate theses files : + + public/index.html -> "

My homepage

" + public/contact/index.html -> "

My contact page

" + +## Usage - public/index.html -> "homepage" - public/contact/index.html -> "contact" + rake sinatra:export -### Advanced assets management +### Advanced Assets Management If you wish to generate your assets (CSS, JS, images) with an assets packaging system, you may use [Sinatra-AssetPack](https://github.com/rstacruz/sinatra-assetpack) and build diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 0e963cd..d819a58 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -12,6 +12,7 @@ Gem::Specification.new do |s| 'Gemfile.lock', 'sinatra-export.gemspec', 'lib/sinatra/export.rb', + 'lib/sinatra/export/rake.rb', 'readme.md' ] s.homepage = 'http://github.com/hooktstudios/sinatra-export' From e5d1b06f1ebb95a447320724405bd5e415368744 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 21:59:03 -0500 Subject: [PATCH 024/148] Use Sinatra :public_folder setting --- lib/sinatra/export.rb | 3 ++- lib/sinatra/export/rake.rb | 4 +--- readme.md | 5 ++++- test/build_test.rb | 12 ++++++------ 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 0979c07..789895d 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -18,7 +18,8 @@ def initialize(app) @app = app end - def build!(dir) + def build! + dir = @app.public_folder handle_error_no_each_route! unless @app.respond_to?(:each_route) handle_error_dir_not_found!(dir) unless dir_exists?(dir) build_routes(dir) diff --git a/lib/sinatra/export/rake.rb b/lib/sinatra/export/rake.rb index 94da847..55ea042 100644 --- a/lib/sinatra/export/rake.rb +++ b/lib/sinatra/export/rake.rb @@ -8,7 +8,6 @@ $stderr.write "Example:\n" $stderr.write " APP_FILE = 'app.rb'\n" $stderr.write " APP_CLASS = 'App'\n" - $stderr.write " APP_PUBLIC = 'public'\n" $stderr.write " require 'sinatra/export/rake'\n" $stderr.write "\n" exit @@ -29,7 +28,6 @@ def app desc "Export static application" task :export do require 'sinatra/export' - builder = Sinatra::Export.new(app) - builder.build!(APP_PUBLIC) + Sinatra::Export.new(app).build! end end \ No newline at end of file diff --git a/readme.md b/readme.md index 5d2b2ef..7293bfe 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,6 @@ Setup your `Rakefile` : ``` APP_FILE = 'app.rb' APP_CLASS = 'App' -APP_PUBLIC = 'public' require 'sinatra/export/rake' ``` @@ -56,6 +55,10 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi rake sinatra:export +Or invoke it manually : + + Sinatra::Export.new(App).build! + ### Advanced Assets Management If you wish to generate your assets (CSS, JS, images) with an assets packaging system, diff --git a/test/build_test.rb b/test/build_test.rb index 5a84c98..7041046 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -14,15 +14,15 @@ class App < UnitTest::App def test_build # Temporary public folder - public_path = File.join(App.root, 'public') - FileUtils.rm_rf File.join(App.root, 'public') - FileUtils.mkdir public_path + public_folder = App.public_folder + FileUtils.rm_rf public_folder + FileUtils.mkdir public_folder builder = Sinatra::Export.new(App) - builder.build!(public_path) + builder.build! - assert File.read(File.join(App.root, 'public/index.html')).include?('homepage') - assert File.read(File.join(App.root, 'public/contact/index.html')).include?('contact') + assert File.read(File.join(public_folder, 'index.html')).include?('homepage') + assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') end end \ No newline at end of file From f479fce1b15f1683ddc802a81dc395d30c1df4a1 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 22:31:13 -0500 Subject: [PATCH 025/148] Create NEWS to track gem changes --- NEWS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 NEWS diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..559c0b9 --- /dev/null +++ b/NEWS @@ -0,0 +1,3 @@ +New In 0.9.1 + +* API CHANGE: Now calling .build! without path parameter, using Sinatra application :public_folder setting. \ No newline at end of file From 0a191f8a986fcfc70cc385999a63a204e6137528 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 10 Jan 2013 22:51:46 -0500 Subject: [PATCH 026/148] Update news and release version 0.9.1 --- NEWS | 3 ++- sinatra-export.gemspec | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 559c0b9..f6c2933 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ New In 0.9.1 -* API CHANGE: Now calling .build! without path parameter, using Sinatra application :public_folder setting. \ No newline at end of file +* API CHANGE: Now calling .build! without path parameter, using Sinatra application :public_folder setting. +* Feature: Added a rake task sinatra:export \ No newline at end of file diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index d819a58..ea92bfc 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9' + s.version = '0.9.1' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.date = '2013-01-16' From 75bdbbff738e696cb543520d41dd4f6242791146 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 18:57:17 -0500 Subject: [PATCH 027/148] Update description --- readme.md | 2 +- sinatra-export.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 7293bfe..0bee014 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # sinatra-export -> Exports your Sinatra app to static files. Depends on [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes). +> Exports all your Sinatra application routes to static files in your public folder. [![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png)](https://travis-ci.org/hooktstudios/sinatra-export) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index ea92bfc..1632b12 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -4,7 +4,7 @@ Gem::Specification.new do |s| s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.date = '2013-01-16' - s.description = 'Export your sinatra app to a directory of static files.' + s.description = 'Exports all your Sinatra application routes to static files in your public folder' s.summary = 'Sinatra static export.' s.email = 'jeanphilippe.doyle@hooktstudios.com' s.files = [ From f3a5da6272ce12dd4882dbea6eaefe174ae79b72 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 18:57:59 -0500 Subject: [PATCH 028/148] Minor readme update --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 0bee014..0ae584a 100644 --- a/readme.md +++ b/readme.md @@ -15,7 +15,7 @@ gem 'sinatra-export' Setup your `Rakefile` : -``` +```ruby APP_FILE = 'app.rb' APP_CLASS = 'App' From 4e0e54c32f83163f6bbd18f2c5f6d5e34c1ea1c2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 18:58:14 -0500 Subject: [PATCH 029/148] Readme as README --- readme.md => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename readme.md => README.md (100%) diff --git a/readme.md b/README.md similarity index 100% rename from readme.md rename to README.md From 4c18203ce5794c0b118d1ed854781538ca620b8b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 19:02:59 -0500 Subject: [PATCH 030/148] Add details about sinatra-advanced-routes dependency --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 0ae584a..44c16aa 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,14 @@ Add to your `Gemfile` : ```ruby gem 'sinatra-export' +# required Sinatra Extension for sinatra-export +gem 'sinatra-advanced-routes' +``` + +Setup your application with [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) : + +```ruby +register Sinatra::AdvancedRoutes ``` Setup your `Rakefile` : From 660c5de4958191b2d00425428f1b47dc3f480eaf Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 19:22:35 -0500 Subject: [PATCH 031/148] More README formatting --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 44c16aa..278c81c 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,13 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi ## Usage - rake sinatra:export + $ rake sinatra:export Or invoke it manually : - Sinatra::Export.new(App).build! +````ruby +Sinatra::Export.new(App).build! +``` ### Advanced Assets Management From 797de18051d3683ad00c95b548ef54352a412b24 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 11 Jan 2013 19:27:24 -0500 Subject: [PATCH 032/148] sinatra-advanced-routes is already in gem dependencies, no need to add manually --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 278c81c..9f43def 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,6 @@ Add to your `Gemfile` : ```ruby gem 'sinatra-export' -# required Sinatra Extension for sinatra-export -gem 'sinatra-advanced-routes' ``` Setup your application with [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) : From 74ce42fbabd1f5bd78f8710b310ec8e16e868760 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:09:25 -0500 Subject: [PATCH 033/148] Get path content before creating file for write. Fix #1 --- lib/sinatra/export.rb | 3 ++- test/build_test.rb | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 789895d..ca46444 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -35,9 +35,10 @@ def build_routes(dir) end def build_path(path, dir) + body = get_path(path).body ::FileUtils.mkdir_p(dir_for_path(path, dir)) ::File.open(file_for_path(path, dir), 'w+') do |f| - f.write(get_path(path).body) + f.write(body) end end diff --git a/test/build_test.rb b/test/build_test.rb index 7041046..a67f50f 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -10,6 +10,9 @@ class App < UnitTest::App get '/contact' do "contact" end + get '/data.json' do + "{test: 'ok'}" + end end def test_build @@ -23,6 +26,7 @@ def test_build assert File.read(File.join(public_folder, 'index.html')).include?('homepage') assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') + assert File.read(File.join(App.root, 'public/data.json')).include?("{test: 'ok'}") end end \ No newline at end of file From 36cc6e83db1a001670d6093e51893529af81b2cf Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:10:18 -0500 Subject: [PATCH 034/148] Move require to file top --- lib/sinatra/export.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index ca46444..f901369 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -1,4 +1,5 @@ require 'rack/test' +require 'term/ansicolor' module Sinatra class Export @@ -9,7 +10,7 @@ class Export include Rack::Test::Methods - require 'term/ansicolor' + class ColorString < String include Term::ANSIColor end From 1809a903373637e1c8db0b2bc5d383765402fbea Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:13:40 -0500 Subject: [PATCH 035/148] Update README with JSON example --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9f43def..56fba2e 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,10 @@ class App < Sinatra::Base "

My contact page

" end + get '/data.json' do + "{test: 'ok'}" + end + end ``` @@ -56,6 +60,7 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi public/index.html -> "

My homepage

" public/contact/index.html -> "

My contact page

" + public/data.json -> "{test: 'ok'}" ## Usage From 574a5b6a9dea05cf3e529fc83e38701ea6e5afd0 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:17:20 -0500 Subject: [PATCH 036/148] Bump to 0.9.2 --- Gemfile.lock | 2 +- NEWS | 4 ++++ sinatra-export.gemspec | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5e1cb47..7ec18d3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (0.9) + sinatra-export (0.9.2) rack sinatra sinatra-advanced-routes diff --git a/NEWS b/NEWS index f6c2933..375e7f6 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +New In 0.9.2 + +* Bug fix: Correctly support path with file extension (.json, .csv, etc.). Issue #1 + New In 0.9.1 * API CHANGE: Now calling .build! without path parameter, using Sinatra application :public_folder setting. diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 1632b12..4733fba 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9.1' + s.version = '0.9.2' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.date = '2013-01-16' @@ -13,7 +13,7 @@ Gem::Specification.new do |s| 'sinatra-export.gemspec', 'lib/sinatra/export.rb', 'lib/sinatra/export/rake.rb', - 'readme.md' + 'README.md' ] s.homepage = 'http://github.com/hooktstudios/sinatra-export' s.license = 'MIT' From 943d2ff8210b9e1f184ae28e0c058075f6647ab5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:19:18 -0500 Subject: [PATCH 037/148] Test against more ruby versions --- .travis.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef77b6a..3cff7d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,17 @@ language: ruby rvm: - - "1.9.3" - - "1.9.2" - - "1.8.7" -branches: - only: - - master \ No newline at end of file + - 1.8.7 + - 1.9.2 + - 1.9.3 + - rbx-18mode + - rbx-19mode + - jruby-18mode + - jruby-19mode + - jruby-head + - ruby-head +matrix: + allow_failures: + - rvm: rbx-18mode + - rvm: rbx-19mode + - rvm: jruby-head + - rvm: ruby-head \ No newline at end of file From 12324d7704c26144f0d85e9d24e0c3a7d84af15d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:32:05 -0500 Subject: [PATCH 038/148] Refer to updated Sinatra extensions forks --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 56fba2e..b08e1e1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Add to your `Gemfile` : gem 'sinatra-export' ``` -Setup your application with [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) : +Setup your application with [sinatra-advanced-routes](https://github.com/hooktstudios/sinatra-advanced-routes) : ```ruby register Sinatra::AdvancedRoutes @@ -72,8 +72,11 @@ Or invoke it manually : Sinatra::Export.new(App).build! ``` -### Advanced Assets Management +### Assets management and more If you wish to generate your assets (CSS, JS, images) with an assets packaging system, -you may use [Sinatra-AssetPack](https://github.com/rstacruz/sinatra-assetpack) and build +you may use [Sinatra-AssetPack](https://github.com/hooktstudios/sinatra-assetpack) and build your assets in the same target directory with `rake assetpack:build` task. + +You may also have a look at [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) +boilerplate to setup a simple exportable Sinatra app, using both gems. \ No newline at end of file From 798c9dbaf8232434324726892063adfd4206c661 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 12 Jan 2013 18:34:39 -0500 Subject: [PATCH 039/148] Minor README update --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b08e1e1..054c892 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,9 @@ Sinatra::Export.new(App).build! ### Assets management and more -If you wish to generate your assets (CSS, JS, images) with an assets packaging system, -you may use [Sinatra-AssetPack](https://github.com/hooktstudios/sinatra-assetpack) and build -your assets in the same target directory with `rake assetpack:build` task. +If you wish to generate your assets (css, images, etc) with a packaging system, +you may use [Sinatra-AssetPack](https://github.com/hooktstudios/sinatra-assetpack) +and build your assets in the same target directory with `rake assetpack:build` task. You may also have a look at [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) boilerplate to setup a simple exportable Sinatra app, using both gems. \ No newline at end of file From 3bc7d99fe8e49292cae0506c837b6278512c4867 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 20 Jan 2013 17:47:58 -0500 Subject: [PATCH 040/148] Update dependencies --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7ec18d3..690e818 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,15 +11,15 @@ GEM remote: http://rubygems.org/ specs: awesome_print (1.1.0) - backports (2.6.5) + backports (2.7.0) monkey-lib (0.5.4) backports - rack (1.4.1) + rack (1.4.4) rack-protection (1.3.2) rack rack-test (0.6.2) rack (>= 1.0) - rake (10.0.2) + rake (10.0.3) sinatra (1.3.3) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) @@ -32,7 +32,7 @@ GEM monkey-lib (~> 0.5.0) sinatra (~> 1.0) term-ansicolor (1.0.7) - test-unit (2.5.2) + test-unit (2.5.3) tilt (1.3.3) PLATFORMS From c20a621a6113d1c2542b5b18abdc7d8680277eea Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 20 Jan 2013 17:48:46 -0500 Subject: [PATCH 041/148] Add dependency status --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 054c892..1994f32 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ > Exports all your Sinatra application routes to static files in your public folder. [![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png)](https://travis-ci.org/hooktstudios/sinatra-export) +[![Dependency Status](https://gemnasium.com/hooktstudios/sinatra-export.png)](https://gemnasium.com/hooktstudios/sinatra-export) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) ## Installation From 25f1efe1390d48e39b0617515ad3a973462d0adb Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Fri, 25 Jan 2013 09:49:51 -0500 Subject: [PATCH 042/148] Update test-unit --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 690e818..efc5971 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,10 +11,10 @@ GEM remote: http://rubygems.org/ specs: awesome_print (1.1.0) - backports (2.7.0) + backports (2.7.1) monkey-lib (0.5.4) backports - rack (1.4.4) + rack (1.5.0) rack-protection (1.3.2) rack rack-test (0.6.2) @@ -32,7 +32,7 @@ GEM monkey-lib (~> 0.5.0) sinatra (~> 1.0) term-ansicolor (1.0.7) - test-unit (2.5.3) + test-unit (2.5.4) tilt (1.3.3) PLATFORMS From c5ece0606e25584ecc0254584374e5e778c91843 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Tue, 12 Feb 2013 14:28:00 -0500 Subject: [PATCH 043/148] Update badges --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1994f32..a8f1b4b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ [![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png)](https://travis-ci.org/hooktstudios/sinatra-export) [![Dependency Status](https://gemnasium.com/hooktstudios/sinatra-export.png)](https://gemnasium.com/hooktstudios/sinatra-export) -[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) +[![Code Climate](https://codeclimate.com/github/hooktstudios/sinatra-export.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) +[![Gem Version](https://badge.fury.io/rb/sinatra-export.png)](https://rubygems.org/gems/sinatra-export) ## Installation From f756f50bca7c3f35e3bfeab781a239ccabd808d5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Wed, 13 Feb 2013 22:10:24 -0500 Subject: [PATCH 044/148] Add credits to HS --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a8f1b4b..5010c3c 100644 --- a/README.md +++ b/README.md @@ -81,4 +81,10 @@ you may use [Sinatra-AssetPack](https://github.com/hooktstudios/sinatra-assetpac and build your assets in the same target directory with `rake assetpack:build` task. You may also have a look at [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) -boilerplate to setup a simple exportable Sinatra app, using both gems. \ No newline at end of file +boilerplate to setup a simple exportable Sinatra app, using both gems. + +## Credits + +![hooktstudios](http://hooktstudios.com/logo.png) + +[sinatra-export](https://rubygems.org/gems/sinatra-export) is maintained and funded by [hooktstudios](http://hooktstudios.com) \ No newline at end of file From 37a9dd451f9ef246bcb1768b3021e817e626a9e3 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Wed, 13 Feb 2013 22:51:45 -0500 Subject: [PATCH 045/148] Update README with additional resources --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5010c3c..cf26b05 100644 --- a/README.md +++ b/README.md @@ -68,20 +68,17 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi $ rake sinatra:export -Or invoke it manually : +Or invoke it manually within ruby code : ````ruby Sinatra::Export.new(App).build! ``` -### Assets management and more +## Other resources -If you wish to generate your assets (css, images, etc) with a packaging system, -you may use [Sinatra-AssetPack](https://github.com/hooktstudios/sinatra-assetpack) -and build your assets in the same target directory with `rake assetpack:build` task. - -You may also have a look at [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) -boilerplate to setup a simple exportable Sinatra app, using both gems. +* [capistrano-s3](http://github.com/hooktstudios/capistrano-s3) : build and deploy a static website to Amazon S3 +* [sinatra-assetpack](https://github.com/rstacruz/sinatra-assetpack) : package your assets transparently in Sinatra +* [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) : boilerplate to setup complete static website ## Credits From 8425f003fac5199cb38b215d68b0b1d9899ea9d8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Wed, 13 Feb 2013 23:02:57 -0500 Subject: [PATCH 046/148] Add contributing guide --- CONTRIBUTING.md | 23 +++++++++++++++++++++++ README.md | 9 +++++++++ 2 files changed, 32 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4168c86 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +> If I have seen further, it is by standing on the shoulders of giants. - Isaac Newton + +We love working with people around the globe and making earth a better place. + +Please follow theses simples steps to contribute to this project. + +1. Fork the repo. + +2. Run the test before doing anything. + +3. Add a test for your code modification. + +4. Submit a pull request and ensure test passes on travis-ci for all supported ruby versions. + +## Running the tests + +As simple as `rake`. Default rake task is test. + +## Syntax + +Follow [Ruby Styleguide](https://github.com/styleguide/ruby) by Github and existing code. \ No newline at end of file diff --git a/README.md b/README.md index cf26b05..517c866 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,15 @@ Sinatra::Export.new(App).build! * [sinatra-assetpack](https://github.com/rstacruz/sinatra-assetpack) : package your assets transparently in Sinatra * [sinatra-static-bp](https://github.com/hooktstudios/sinatra-static-bp) : boilerplate to setup complete static website +## Contributing + +Guidelines to contributions : + +1. Use [GitHub Issue](http://github.com/thoughtbot/hooktstudios/sinatra-export). +2. Run the tests. + +See `CONTRIBUTING.md` for more details on contributing and running test. + ## Credits ![hooktstudios](http://hooktstudios.com/logo.png) From da3df0de498c77a70578ab936af6f21d28382b28 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Wed, 13 Feb 2013 23:08:40 -0500 Subject: [PATCH 047/148] Add link to contributing guide & update text [ci skip] --- CONTRIBUTING.md | 18 ++++++++++++------ README.md | 7 +------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4168c86..7cd1c57 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,21 +2,27 @@ > If I have seen further, it is by standing on the shoulders of giants. - Isaac Newton -We love working with people around the globe and making earth a better place. +We love to work with people around the globe and make earth a better place for mankind! -Please follow theses simples steps to contribute to this project. +Please follow theses simples steps to contribute to this project : 1. Fork the repo. -2. Run the test before doing anything. +2. Run the tests before doing anything. -3. Add a test for your code modification. +3. Add test(s) for your code modification. -4. Submit a pull request and ensure test passes on travis-ci for all supported ruby versions. +4. Rebase your code onto upstream master (this repository) if not up to date. + +5. Squash or fixup your commits to achieve a clean commit log. + +6. Submit a pull request and ensure tests passes on travis-ci for all supported ruby versions. ## Running the tests -As simple as `rake`. Default rake task is test. +As simple as running the `rake` command. + +The default `rake` task is `rake test`. ## Syntax diff --git a/README.md b/README.md index 517c866..74978ed 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,7 @@ Sinatra::Export.new(App).build! ## Contributing -Guidelines to contributions : - -1. Use [GitHub Issue](http://github.com/thoughtbot/hooktstudios/sinatra-export). -2. Run the tests. - -See `CONTRIBUTING.md` for more details on contributing and running test. +See [CONTRIBUTING.md](https://github.com/hooktstudios/sinatra-export/blob/master/CONTRIBUTING.md) for more details on contributing and running test. ## Credits From 1cf315142eaa08adf16c669b9c3c0b23e203c4b2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Wed, 13 Feb 2013 23:41:43 -0500 Subject: [PATCH 048/148] Link to github (website in french only) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74978ed..7c4e6d2 100644 --- a/README.md +++ b/README.md @@ -88,4 +88,4 @@ See [CONTRIBUTING.md](https://github.com/hooktstudios/sinatra-export/blob/master ![hooktstudios](http://hooktstudios.com/logo.png) -[sinatra-export](https://rubygems.org/gems/sinatra-export) is maintained and funded by [hooktstudios](http://hooktstudios.com) \ No newline at end of file +[sinatra-export](https://rubygems.org/gems/sinatra-export) is maintained and funded by [hooktstudios](https://github.com/hooktstudios) \ No newline at end of file From ecaf3c33ea431dac24993927c88ea5728c0e4e9c Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 28 Feb 2013 11:48:23 -0500 Subject: [PATCH 049/148] Update rack dependency for CVE-2013-0263 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index efc5971..47e15a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,7 +14,7 @@ GEM backports (2.7.1) monkey-lib (0.5.4) backports - rack (1.5.0) + rack (1.5.2) rack-protection (1.3.2) rack rack-test (0.6.2) From 79436925f2c12f94523cf0d45d5a9fd589afde43 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 28 Feb 2013 11:48:44 -0500 Subject: [PATCH 050/148] Ignore generated gems --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9afaabf..d2f099c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -test/app/public/ \ No newline at end of file +test/app/public/ +*.gem \ No newline at end of file From 4265fa515c1525f7df96468a0e19cba261582495 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:07:45 -0500 Subject: [PATCH 051/148] =?UTF-8?q?LICENCE=20->=C2=A0LICENSE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENCE => LICENSE | 0 sinatra-export.gemspec | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename LICENCE => LICENSE (100%) diff --git a/LICENCE b/LICENSE similarity index 100% rename from LICENCE rename to LICENSE diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 4733fba..cd1c6ce 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -13,7 +13,8 @@ Gem::Specification.new do |s| 'sinatra-export.gemspec', 'lib/sinatra/export.rb', 'lib/sinatra/export/rake.rb', - 'README.md' + 'README.md', + 'LICENSE' ] s.homepage = 'http://github.com/hooktstudios/sinatra-export' s.license = 'MIT' From efebc0c13edd179c24bfd36102cb8ea836bc36fc Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:09:19 -0500 Subject: [PATCH 052/148] Move debug & tests gems to gem not gemspec --- Gemfile | 12 ++++++++++++ Gemfile.lock | 9 +++++++++ sinatra-export.gemspec | 5 ----- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index df87cd4..201e5ae 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,14 @@ source :rubygems + +group :development do + gem 'debugger' + gem 'awesome_print' +end + +group :test do + gem 'rack-test' + gem 'rake' + gem 'test-unit' +end + gemspec \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 47e15a0..3479388 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,6 +12,14 @@ GEM specs: awesome_print (1.1.0) backports (2.7.1) + columnize (0.3.6) + debugger (1.2.4) + columnize (>= 0.3.1) + debugger-linecache (~> 1.1.1) + debugger-ruby_core_source (~> 1.1.7) + debugger-linecache (1.1.2) + debugger-ruby_core_source (>= 1.1.1) + debugger-ruby_core_source (1.1.7) monkey-lib (0.5.4) backports rack (1.5.2) @@ -40,6 +48,7 @@ PLATFORMS DEPENDENCIES awesome_print + debugger rack-test rake sinatra-export! diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index cd1c6ce..09fa81c 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -24,10 +24,5 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'sinatra' s.add_runtime_dependency 'sinatra-advanced-routes' s.add_runtime_dependency 'rack' - - s.add_development_dependency 'rack-test' - s.add_development_dependency 'rake' - s.add_development_dependency 'awesome_print' - s.add_development_dependency 'test-unit' end From 47d59b77d4cf87448b6e04a5b910d8c9ad16912b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:10:21 -0500 Subject: [PATCH 053/148] Update depencencies --- Gemfile.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3479388..77be1ca 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,28 +11,28 @@ GEM remote: http://rubygems.org/ specs: awesome_print (1.1.0) - backports (2.7.1) + backports (3.0.3) columnize (0.3.6) - debugger (1.2.4) + debugger (1.3.3) columnize (>= 0.3.1) debugger-linecache (~> 1.1.1) - debugger-ruby_core_source (~> 1.1.7) + debugger-ruby_core_source (~> 1.2.0) debugger-linecache (1.1.2) debugger-ruby_core_source (>= 1.1.1) - debugger-ruby_core_source (1.1.7) + debugger-ruby_core_source (1.2.0) monkey-lib (0.5.4) backports rack (1.5.2) - rack-protection (1.3.2) + rack-protection (1.4.0) rack rack-test (0.6.2) rack (>= 1.0) rake (10.0.3) - sinatra (1.3.3) - rack (~> 1.3, >= 1.3.6) - rack-protection (~> 1.2) + sinatra (1.3.5) + rack (~> 1.4) + rack-protection (~> 1.3) tilt (~> 1.3, >= 1.3.3) - sinatra-advanced-routes (0.5.1) + sinatra-advanced-routes (0.5.2) monkey-lib (~> 0.5.0) sinatra (~> 1.0) sinatra-sugar (~> 0.5.0) @@ -41,7 +41,7 @@ GEM sinatra (~> 1.0) term-ansicolor (1.0.7) test-unit (2.5.4) - tilt (1.3.3) + tilt (1.3.4) PLATFORMS ruby From fc1e6a556d65f3fdc7970189441f36fe303cd8a6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:16:37 -0500 Subject: [PATCH 054/148] Specify gem groups for travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3cff7d7..1f23c05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby +bundler_args: "--without development" rvm: - 1.8.7 - 1.9.2 From a041ccbc29276e89cceabc651395b4616091bdb8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:18:54 -0500 Subject: [PATCH 055/148] Remove awesome_print --- test/test_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index ae77a8b..d529733 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -2,7 +2,6 @@ require 'test/unit' require 'sinatra/advanced_routes' require 'sinatra/export' -require 'awesome_print' # Helper based on sinatra-assetpack test helper # © 2011, Rico Sta. Cruz. Released under the MIT License From 9e0288d3d571a4b169970cfe474bf24391569374 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:22:39 -0500 Subject: [PATCH 056/148] Release 0.9.3 --- Gemfile.lock | 2 +- NEWS | 4 ++++ sinatra-export.gemspec | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 77be1ca..285ef2b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (0.9.2) + sinatra-export (0.9.3) rack sinatra sinatra-advanced-routes diff --git a/NEWS b/NEWS index 375e7f6..6a1e758 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +New In 0.9.3 + +* Removed unnecessary development dependencies. + New In 0.9.2 * Bug fix: Correctly support path with file extension (.json, .csv, etc.). Issue #1 diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 09fa81c..15875e0 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9.2' + s.version = '0.9.3' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.date = '2013-01-16' From a17166d30b49f8e1338da6c365a650e098813fd3 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 15:25:16 -0500 Subject: [PATCH 057/148] Add ruby 2.0.0 --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1f23c05..b9f0774 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ rvm: - 1.8.7 - 1.9.2 - 1.9.3 + - 2.0.0 - rbx-18mode - rbx-19mode - jruby-18mode @@ -15,4 +16,5 @@ matrix: - rvm: rbx-18mode - rvm: rbx-19mode - rvm: jruby-head - - rvm: ruby-head \ No newline at end of file + - rvm: ruby-head + - rvm: 2.0.0 \ No newline at end of file From 0eb32a19fb709e19b85d0db708d536ef6cb125ad Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 17:03:28 -0500 Subject: [PATCH 058/148] Set file mtime according to response Last-Modified header --- lib/sinatra/export.rb | 13 ++++++++++--- test/build_test.rb | 8 +++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index f901369..7638ad0 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -36,11 +36,18 @@ def build_routes(dir) end def build_path(path, dir) - body = get_path(path).body - ::FileUtils.mkdir_p(dir_for_path(path, dir)) - ::File.open(file_for_path(path, dir), 'w+') do |f| + response = get_path(path) + body = response.body + mtime = response.headers.key?("Last-Modified") ? + Time.httpdate(response.headers["Last-Modified"]) : Time.now + file_path = file_for_path(path, dir) + dir_path = dir_for_path(path, dir) + + ::FileUtils.mkdir_p(dir_path) + ::File.open(file_path, 'w+') do |f| f.write(body) end + ::FileUtils.touch(file_path, :mtime => mtime) end def get_path(path) diff --git a/test/build_test.rb b/test/build_test.rb index a67f50f..2e68e9e 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -13,6 +13,10 @@ class App < UnitTest::App get '/data.json' do "{test: 'ok'}" end + get '/yesterday' do + last_modified Time.new(2002, 10, 31) + "old content" + end end def test_build @@ -26,7 +30,9 @@ def test_build assert File.read(File.join(public_folder, 'index.html')).include?('homepage') assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') - assert File.read(File.join(App.root, 'public/data.json')).include?("{test: 'ok'}") + assert File.read(File.join(public_folder, 'data.json')).include?("{test: 'ok'}") + + assert File.mtime(File.join(public_folder, 'yesterday/index.html')) == Time.new(2002, 10, 31) end end \ No newline at end of file From 4ea3f0cc11f0b4a2a1e335da66265519a88564b8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 17:13:15 -0500 Subject: [PATCH 059/148] Use 1.8.7 compatible time method --- test/build_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/build_test.rb b/test/build_test.rb index 2e68e9e..dd45b92 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -14,7 +14,7 @@ class App < UnitTest::App "{test: 'ok'}" end get '/yesterday' do - last_modified Time.new(2002, 10, 31) + last_modified Time.local(2002, 10, 31) "old content" end end @@ -32,7 +32,7 @@ def test_build assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') assert File.read(File.join(public_folder, 'data.json')).include?("{test: 'ok'}") - assert File.mtime(File.join(public_folder, 'yesterday/index.html')) == Time.new(2002, 10, 31) + assert File.mtime(File.join(public_folder, 'yesterday/index.html')) == Time.local(2002, 10, 31) end end \ No newline at end of file From 2e73fb2edf942dec6cbab0b0662275e444013813 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 17:13:52 -0500 Subject: [PATCH 060/148] Skip debugger on 1.8.7 [ci skip] --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 201e5ae..9d178ed 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source :rubygems group :development do - gem 'debugger' + gem 'debugger' unless RUBY_VERSION < '1.9' gem 'awesome_print' end From 66abfb798fda43af17f9e6a2fb656f8b613be83e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 17:15:30 -0500 Subject: [PATCH 061/148] Release 0.9.4 [ci skip] --- Gemfile.lock | 2 +- NEWS | 4 ++++ sinatra-export.gemspec | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 285ef2b..23697b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (0.9.3) + sinatra-export (0.9.4) rack sinatra sinatra-advanced-routes diff --git a/NEWS b/NEWS index 6a1e758..765ce9f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +New In 0.9.4 + +* Now set files mtime according to response Last-Modified header + New In 0.9.3 * Removed unnecessary development dependencies. diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 15875e0..3a04022 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9.3' + s.version = '0.9.4' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.date = '2013-01-16' From ab32411b8726ad9dcbaca030c2466da6e684b132 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sat, 2 Mar 2013 17:17:19 -0500 Subject: [PATCH 062/148] Remove forced date [ci skip] --- sinatra-export.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 3a04022..18aac70 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -3,7 +3,6 @@ Gem::Specification.new do |s| s.version = '0.9.4' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] - s.date = '2013-01-16' s.description = 'Exports all your Sinatra application routes to static files in your public folder' s.summary = 'Sinatra static export.' s.email = 'jeanphilippe.doyle@hooktstudios.com' From de14b28923365883bfa83da8a85ff49144edce1c Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 3 Mar 2013 15:20:08 -0500 Subject: [PATCH 063/148] Force HTTPS rubygems --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 9d178ed..c1ce2b3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source :rubygems +source 'https://rubygems.org' group :development do gem 'debugger' unless RUBY_VERSION < '1.9' diff --git a/Gemfile.lock b/Gemfile.lock index 23697b4..b85d0b5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ PATH term-ansicolor GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: awesome_print (1.1.0) backports (3.0.3) From a588008638347365a64f35fe15b3cad5ea6d9253 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Mon, 11 Mar 2013 19:44:02 -0400 Subject: [PATCH 064/148] Update dependencies --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b85d0b5..29fbbf4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,9 +11,9 @@ GEM remote: https://rubygems.org/ specs: awesome_print (1.1.0) - backports (3.0.3) + backports (3.1.1) columnize (0.3.6) - debugger (1.3.3) + debugger (1.4.0) columnize (>= 0.3.1) debugger-linecache (~> 1.1.1) debugger-ruby_core_source (~> 1.2.0) @@ -39,9 +39,9 @@ GEM sinatra-sugar (0.5.1) monkey-lib (~> 0.5.0) sinatra (~> 1.0) - term-ansicolor (1.0.7) + term-ansicolor (1.1.1) test-unit (2.5.4) - tilt (1.3.4) + tilt (1.3.5) PLATFORMS ruby From e042356fd748db2630abc5f6b6b54c55d13da955 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Mon, 11 Mar 2013 19:45:30 -0400 Subject: [PATCH 065/148] Release 0.2.5 now signed gem --- Gemfile.lock | 2 +- NEWS | 4 ++++ certs/j15e.pem | 20 ++++++++++++++++++++ sinatra-export.gemspec | 4 +++- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 certs/j15e.pem diff --git a/Gemfile.lock b/Gemfile.lock index 29fbbf4..aeca572 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (0.9.4) + sinatra-export (0.9.5) rack sinatra sinatra-advanced-routes diff --git a/NEWS b/NEWS index 765ce9f..313e558 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +New in 0.9.5 + +* Improvement : signed gem. + New In 0.9.4 * Now set files mtime according to response Last-Modified header diff --git a/certs/j15e.pem b/certs/j15e.pem new file mode 100644 index 0000000..9ac7d0d --- /dev/null +++ b/certs/j15e.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRjCCAi6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBJMRswGQYDVQQDDBJqZWFu +cGhpbGlwcGUuZG95bGUxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT +8ixkARkWA2NvbTAeFw0xMzAzMTEyMjM5MjNaFw0xNDAzMTEyMjM5MjNaMEkxGzAZ +BgNVBAMMEmplYW5waGlsaXBwZS5kb3lsZTEVMBMGCgmSJomT8ixkARkWBWdtYWls +MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEApQtzOyMoi48Pc0BRF++BXc2ulECpOypwYqnzIdbE5+iLownixYB3KkKm +VxIlo9pYWIp5JR+Uphv/P9vKJAIjfldtlus6o8xFT0HujXyEMMbFMGHH01PvDYkx +vnMw5O6YVdtbsKvjknB4JOcOmxQAeXBunLBJk0huOLALlDW38UZF3AKNVPpR+Gst +gTZCIAPq22wB9I0HYfyCitjrMVK4jTHgjPjNNQn4BhuhkqEWr5JkVtipGCUFyl45 +2ISskOPckLW/qwCq4vyjVK6JIZb2Ei9DHtip44u7KjFEX5QdvHyu81xatMmtKvYn +WWKZ/2HCdWRRiPSuHmBR/QlMlUN69QIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1Ud +DgQWBBQk1vhL7od7qZLEfBssQNqzht1wwDALBgNVHQ8EBAMCBLAwDQYJKoZIhvcN +AQEFBQADggEBADglXYkTD1Btadr2ehKDOSATfLVeh9ThwZ6PeKP8bPWKOrHPbTN8 +Aandvv6g6samg7p/viRwsE29MTAcfqCdFp8v35ase2PyiXrJ0QJP7r3CBo+nwGVO +hybD84/vTA9CSBaFX2Xtj0dC5o6eW6/vWoVeJUcMNX/O/r8lRWn24WhFkEzW9n1R +2CVeZs78AXWTyU0l0dyswpav0AczXg4UK3Y2M9oYyBmdfem6m614SOrOFBIGjmF4 +kzgF4O2OL+8O23we4E1LvfRn5gV77Dij6s9V4HHzMBuLwnNb8T+6lOnUWbtiIddD +e8c8i7PlrzhVJ/8sXUJsCkyE8d2MyRyjlxM= +-----END CERTIFICATE----- diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index 18aac70..dbe389d 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,11 +1,13 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9.4' + s.version = '0.9.5' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.description = 'Exports all your Sinatra application routes to static files in your public folder' s.summary = 'Sinatra static export.' s.email = 'jeanphilippe.doyle@hooktstudios.com' + s.cert_chain = ['certs/j15e.pem'] + s.signing_key = File.expand_path('~/.gem/private_key.pem') if $0 =~ /gem\z/ s.files = [ 'Gemfile', 'Gemfile.lock', From 5e29e90100e1902735cabb232db190452e5992f8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Mon, 11 Mar 2013 20:50:47 -0300 Subject: [PATCH 066/148] Update README with updated sinatra-advanced-routes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c4e6d2..0f415a9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Add to your `Gemfile` : gem 'sinatra-export' ``` -Setup your application with [sinatra-advanced-routes](https://github.com/hooktstudios/sinatra-advanced-routes) : +Setup your application with [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) : ```ruby register Sinatra::AdvancedRoutes @@ -88,4 +88,4 @@ See [CONTRIBUTING.md](https://github.com/hooktstudios/sinatra-export/blob/master ![hooktstudios](http://hooktstudios.com/logo.png) -[sinatra-export](https://rubygems.org/gems/sinatra-export) is maintained and funded by [hooktstudios](https://github.com/hooktstudios) \ No newline at end of file +[sinatra-export](https://rubygems.org/gems/sinatra-export) is maintained and funded by [hooktstudios](https://github.com/hooktstudios) From e8ca2df4105895c34f3d0635a5cb304665c7433d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 16:22:56 -0400 Subject: [PATCH 067/148] Update dependencies (Sinatra 1.3.5 -> 1.4.1) --- Gemfile.lock | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index aeca572..0f3f65e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,25 +13,24 @@ GEM awesome_print (1.1.0) backports (3.1.1) columnize (0.3.6) - debugger (1.4.0) + debugger (1.5.0) columnize (>= 0.3.1) - debugger-linecache (~> 1.1.1) + debugger-linecache (~> 1.2.0) debugger-ruby_core_source (~> 1.2.0) - debugger-linecache (1.1.2) - debugger-ruby_core_source (>= 1.1.1) + debugger-linecache (1.2.0) debugger-ruby_core_source (1.2.0) monkey-lib (0.5.4) backports rack (1.5.2) - rack-protection (1.4.0) + rack-protection (1.5.0) rack rack-test (0.6.2) rack (>= 1.0) rake (10.0.3) - sinatra (1.3.5) - rack (~> 1.4) - rack-protection (~> 1.3) - tilt (~> 1.3, >= 1.3.3) + sinatra (1.4.1) + rack (~> 1.5, >= 1.5.2) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) sinatra-advanced-routes (0.5.2) monkey-lib (~> 0.5.0) sinatra (~> 1.0) From b17633a048b23ac9fd87b7a7061405e9a26d5bb5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:09:43 -0400 Subject: [PATCH 068/148] Fix build status badge to master branch [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f415a9..8e6fbb6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > Exports all your Sinatra application routes to static files in your public folder. -[![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png)](https://travis-ci.org/hooktstudios/sinatra-export) +[![Build Status](https://travis-ci.org/hooktstudios/sinatra-export.png?branch=master)](https://travis-ci.org/hooktstudios/sinatra-export) [![Dependency Status](https://gemnasium.com/hooktstudios/sinatra-export.png)](https://gemnasium.com/hooktstudios/sinatra-export) [![Code Climate](https://codeclimate.com/github/hooktstudios/sinatra-export.png)](https://codeclimate.com/github/hooktstudios/sinatra-export) [![Gem Version](https://badge.fury.io/rb/sinatra-export.png)](https://rubygems.org/gems/sinatra-export) From b2852d85f636e99c0c13d63668e716eba9712a41 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 17:20:52 -0400 Subject: [PATCH 069/148] Rewrite as a sinatra extension : calls/register --- lib/sinatra/export/rake.rb | 3 +-- test/build_test.rb | 11 ++++++++--- test/test_helper.rb | 4 +--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/sinatra/export/rake.rb b/lib/sinatra/export/rake.rb index 55ea042..2508637 100644 --- a/lib/sinatra/export/rake.rb +++ b/lib/sinatra/export/rake.rb @@ -27,7 +27,6 @@ def app namespace :sinatra do desc "Export static application" task :export do - require 'sinatra/export' - Sinatra::Export.new(app).build! + app.build! end end \ No newline at end of file diff --git a/test/build_test.rb b/test/build_test.rb index dd45b92..fe23bb6 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -1,22 +1,28 @@ require File.expand_path('../test_helper', __FILE__) +require 'sinatra/export' class SinatraExportBuildTest < UnitTest - include Rack::Test::Methods class App < UnitTest::App + register Sinatra::Export + get '/' do "homepage" end + get '/contact' do "contact" end + get '/data.json' do "{test: 'ok'}" end + get '/yesterday' do last_modified Time.local(2002, 10, 31) "old content" end + end def test_build @@ -25,8 +31,7 @@ def test_build FileUtils.rm_rf public_folder FileUtils.mkdir public_folder - builder = Sinatra::Export.new(App) - builder.build! + App.build! assert File.read(File.join(public_folder, 'index.html')).include?('homepage') assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') diff --git a/test/test_helper.rb b/test/test_helper.rb index d529733..cd5201f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,7 +1,6 @@ require 'rack/test' require 'test/unit' -require 'sinatra/advanced_routes' -require 'sinatra/export' +require 'sinatra/base' # Helper based on sinatra-assetpack test helper # © 2011, Rico Sta. Cruz. Released under the MIT License @@ -15,7 +14,6 @@ class App < Sinatra::Base set :root, File.expand_path('../app', __FILE__) enable :raise_errors disable :show_exceptions - register Sinatra::AdvancedRoutes end def setup From 3a96e9d7ff8c2279628a489574e72812e26b4ec8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:00:23 -0400 Subject: [PATCH 070/148] Rewrite as a real Sinatra registrable extension. Fix #5 --- lib/sinatra/export.rb | 159 +++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 7638ad0..08fe127 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -1,100 +1,101 @@ +require 'sinatra/base' +require 'sinatra/advanced_routes' require 'rack/test' require 'term/ansicolor' module Sinatra - class Export + module Export - @@file_extensions = %w(css js xml json html csv) - - attr_accessor :app - - include Rack::Test::Methods - - - class ColorString < String - include Term::ANSIColor - end - - def initialize(app) - @app = app + def self.registered(app) + if app.extensions.nil? or !app.extensions.include?(Sinatra::AdvancedRoutes) + app.register Sinatra::AdvancedRoutes + end + app.set :export_extensions, %w(css js xml json html csv) + app.extend ClassMethods end - def build! - dir = @app.public_folder - handle_error_no_each_route! unless @app.respond_to?(:each_route) - handle_error_dir_not_found!(dir) unless dir_exists?(dir) - build_routes(dir) + module ClassMethods + def build! + Builder.new(self).build! + end end - private + class Builder + include Rack::Test::Methods - def build_routes(dir) - @app.each_route do |route| - next if route.verb != 'GET' or not route.path.is_a? String - build_path(route.path, dir) + class ColorString < String + include Term::ANSIColor end - end - def build_path(path, dir) - response = get_path(path) - body = response.body - mtime = response.headers.key?("Last-Modified") ? - Time.httpdate(response.headers["Last-Modified"]) : Time.now - file_path = file_for_path(path, dir) - dir_path = dir_for_path(path, dir) - - ::FileUtils.mkdir_p(dir_path) - ::File.open(file_path, 'w+') do |f| - f.write(body) + def initialize(app) + @app = app end - ::FileUtils.touch(file_path, :mtime => mtime) - end - def get_path(path) - self.get(path).tap do |resp| - handle_error_non_200!(path) unless resp.status == 200 + def app + @app end - end - def file_for_path(path, dir) - if path.match(/[^\/\.]+.(#{file_extensions.join("|")})$/) - ::File.join(dir, path) - else - ::File.join(dir, path, 'index.html') + def build! + dir = app.public_folder + handle_error_dir_not_found!(dir) unless dir_exists?(dir) + app.each_route do |route| + next if route.verb != 'GET' or not route.path.is_a? String + build_path(route.path, dir) + end end - end - - def dir_exists?(dir) - ::File.exists?(dir) && ::File.directory?(dir) - end - def dir_for_path(path, dir) - file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] + private + + def build_path(path, dir) + response = get_path(path) + body = response.body + mtime = response.headers.key?("Last-Modified") ? + Time.httpdate(response.headers["Last-Modified"]) : Time.now + file_path = file_for_path(path, dir) + dir_path = dir_for_path(path, dir) + + ::FileUtils.mkdir_p(dir_path) + ::File.open(file_path, 'w+') do |f| + f.write(body) + end + ::FileUtils.touch(file_path, :mtime => mtime) + end + + def get_path( path) + get(path).tap do |resp| + handle_error_non_200!(path) unless resp.status == 200 + end + end + + def file_for_path(path, dir) + if path.match(/[^\/\.]+.(#{app.settings.export_extensions.join("|")})$/) + ::File.join(dir, path) + else + ::File.join(dir, path, 'index.html') + end + end + + def dir_exists?(dir) + ::File.exists?(dir) && ::File.directory?(dir) + end + + def dir_for_path(path, dir) + file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] + end + + def handle_error_dir_not_found!(dir) + handle_error!("can't find output directory: #{dir}") + end + + def handle_error_non_200!(path) + handle_error!("GET #{path} returned non-200 status code...") + end + + def handle_error!(desc) + puts ColorString.new("failed: #{desc}").red; exit! + end end - - def file_extensions - @@file_extensions - end - - def env - ENV['RACK_ENV'] - end - - def handle_error_no_each_route! - handle_error!("can't call app.each_route, did you include sinatra-advanced-routes?") - end - - def handle_error_dir_not_found!(dir) - handle_error!("can't find output directory: #{dir}") - end - - def handle_error_non_200!(path) - handle_error!("GET #{path} returned non-200 status code...") - end - - def handle_error!(desc) - puts ColorString.new("failed: #{desc}").red; exit! - end - end + + register Sinatra::Export end \ No newline at end of file From 535adb3480595db9308de7f7a63bad7030ae3442 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:02:28 -0400 Subject: [PATCH 071/148] Update README : advanced routes is now auto-registered --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8e6fbb6..457c87c 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,6 @@ Add to your `Gemfile` : gem 'sinatra-export' ``` -Setup your application with [sinatra-advanced-routes](https://github.com/rkh/sinatra-advanced-routes) : - -```ruby -register Sinatra::AdvancedRoutes -``` - Setup your `Rakefile` : ```ruby @@ -36,12 +30,11 @@ Sample Sinatra application building static pages : ```ruby require 'sinatra' -require 'sinatra/advanced_routes' require 'sinatra/export' class App < Sinatra::Base - register Sinatra::AdvancedRoutes + register Sinatra::Export get '/' do "

My homepage

" @@ -71,7 +64,7 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi Or invoke it manually within ruby code : ````ruby -Sinatra::Export.new(App).build! +App.build! ``` ## Other resources From c202c858e022c72d6b42858201619a3f4e25cb2a Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:05:07 -0400 Subject: [PATCH 072/148] Rename build! -> export! --- README.md | 2 +- lib/sinatra/export.rb | 2 +- lib/sinatra/export/rake.rb | 2 +- test/build_test.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 457c87c..c8ade5b 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi Or invoke it manually within ruby code : ````ruby -App.build! +App.export! ``` ## Other resources diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 08fe127..3dc45f8 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -15,7 +15,7 @@ def self.registered(app) end module ClassMethods - def build! + def export! Builder.new(self).build! end end diff --git a/lib/sinatra/export/rake.rb b/lib/sinatra/export/rake.rb index 2508637..7ba0d92 100644 --- a/lib/sinatra/export/rake.rb +++ b/lib/sinatra/export/rake.rb @@ -27,6 +27,6 @@ def app namespace :sinatra do desc "Export static application" task :export do - app.build! + app.export! end end \ No newline at end of file diff --git a/test/build_test.rb b/test/build_test.rb index fe23bb6..7b2a7f5 100644 --- a/test/build_test.rb +++ b/test/build_test.rb @@ -31,7 +31,7 @@ def test_build FileUtils.rm_rf public_folder FileUtils.mkdir public_folder - App.build! + App.export! assert File.read(File.join(public_folder, 'index.html')).include?('homepage') assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') From 4bedc3c9b894603fba39d2695b1a1bedd4402615 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:15:46 -0400 Subject: [PATCH 073/148] Update NEWS for 1.0.0 --- NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 313e558..37eccc9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +New in 1.0.0 + +* You must now register Sinatra::Export extension. +* Sinatra::AdvancedRoutes is now auto loaded. +* Renamed build! method export!. + New in 0.9.5 * Improvement : signed gem. From d6c76e0e49d6b50cd3c327ed1ef8afb397e3a0cc Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:20:20 -0400 Subject: [PATCH 074/148] Improve changelog format & rename file [ci skip] --- NEWS => CHANGELOG.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) rename NEWS => CHANGELOG.md (78%) diff --git a/NEWS b/CHANGELOG.md similarity index 78% rename from NEWS rename to CHANGELOG.md index 37eccc9..a8fb35a 100644 --- a/NEWS +++ b/CHANGELOG.md @@ -1,26 +1,28 @@ -New in 1.0.0 +# Changelog + +## 1.0.0 - 2013-03-17 * You must now register Sinatra::Export extension. -* Sinatra::AdvancedRoutes is now auto loaded. +* Sinatra::AdvancedRoutes is now auto loaded. (#5) * Renamed build! method export!. -New in 0.9.5 +## 0.9.5 * Improvement : signed gem. -New In 0.9.4 +## 0.9.4 * Now set files mtime according to response Last-Modified header -New In 0.9.3 +## 0.9.3 * Removed unnecessary development dependencies. -New In 0.9.2 +## 0.9.2 * Bug fix: Correctly support path with file extension (.json, .csv, etc.). Issue #1 -New In 0.9.1 +## 0.9.1 * API CHANGE: Now calling .build! without path parameter, using Sinatra application :public_folder setting. * Feature: Added a rake task sinatra:export \ No newline at end of file From e03179f682e20d0abaec19190cae1cdb48a7a12b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:30:14 -0400 Subject: [PATCH 075/148] Add upgrade note for 1.0.0 --- UPGRADING | 14 ++++++++++++++ sinatra-export.gemspec | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 UPGRADING diff --git a/UPGRADING b/UPGRADING new file mode 100644 index 0000000..6913362 --- /dev/null +++ b/UPGRADING @@ -0,0 +1,14 @@ +################################################## +# NOTE FOR UPGRADING FROM PRE-1.0 VERSION # +################################################## + +Sinatra::Export is now a Sinatra extension +and advanced routes are auto-loaded. + +To upgrade, replace in your application : + + register Sinatra::AdvancedRoutes + +with : + + register Sinatra::Export \ No newline at end of file diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index dbe389d..e7b2896 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -15,12 +15,17 @@ Gem::Specification.new do |s| 'lib/sinatra/export.rb', 'lib/sinatra/export/rake.rb', 'README.md', - 'LICENSE' + 'LICENSE', + 'UPGRADING' ] s.homepage = 'http://github.com/hooktstudios/sinatra-export' s.license = 'MIT' s.required_ruby_version = '>= 1.8.7' + if File.exists?('UPGRADING') + s.post_install_message = File.read("UPGRADING") + end + s.add_runtime_dependency 'term-ansicolor' s.add_runtime_dependency 'sinatra' s.add_runtime_dependency 'sinatra-advanced-routes' From c9f26a11aaabdd6194875a6a7f395180efdbc7c2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:30:44 -0400 Subject: [PATCH 076/148] Release 1.0.0 [ci skip] --- Gemfile.lock | 2 +- sinatra-export.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0f3f65e..8136435 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (0.9.5) + sinatra-export (1.0.0) rack sinatra sinatra-advanced-routes diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index e7b2896..c858cd6 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '0.9.5' + s.version = '1.0.0' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.description = 'Exports all your Sinatra application routes to static files in your public folder' From 6ade092f318ecec17b9c67b6fd3dd890eb81b8c6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:40:18 -0400 Subject: [PATCH 077/148] Use lean classic Sinatra style for README --- README.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c8ade5b..e725c8d 100644 --- a/README.md +++ b/README.md @@ -32,22 +32,16 @@ Sample Sinatra application building static pages : require 'sinatra' require 'sinatra/export' -class App < Sinatra::Base - - register Sinatra::Export - - get '/' do - "

My homepage

" - end - - get '/contact' do - "

My contact page

" - end +get '/' do + "

My homepage

" +end - get '/data.json' do - "{test: 'ok'}" - end +get '/contact' do + "

My contact page

" +end +get '/data.json' do + "{test: 'ok'}" end ``` From 92c3c4a6287db2952449e2a80f2425047909d8d3 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:49:47 -0400 Subject: [PATCH 078/148] Update README with default classic app class --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e725c8d..83caf7e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Setup your `Rakefile` : ```ruby APP_FILE = 'app.rb' -APP_CLASS = 'App' +APP_CLASS = 'Sinatra::Application' require 'sinatra/export/rake' ``` From d0eb3dddf5d3c1f3a1e1ac165ae6f5b32606e32d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:49:59 -0400 Subject: [PATCH 079/148] Add missing dependencies --- Gemfile.lock | 2 ++ sinatra-export.gemspec | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 8136435..43f36d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,8 @@ PATH specs: sinatra-export (1.0.0) rack + rack-test + rake sinatra sinatra-advanced-routes term-ansicolor diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index c858cd6..de84f87 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -30,5 +30,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'sinatra' s.add_runtime_dependency 'sinatra-advanced-routes' s.add_runtime_dependency 'rack' + s.add_runtime_dependency 'rake' + s.add_runtime_dependency 'rack-test' end From 56aabf4a8ccb9edbd20884eed2eadd02b9dff13e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:50:06 -0400 Subject: [PATCH 080/148] Update tilt --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 43f36d8..199f8e1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,7 +42,7 @@ GEM sinatra (~> 1.0) term-ansicolor (1.1.1) test-unit (2.5.4) - tilt (1.3.5) + tilt (1.3.6) PLATFORMS ruby From c034b78cc6eb858cd55d3c4a801af305325bdee6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 18:53:14 -0400 Subject: [PATCH 081/148] Release 1.0.1 [ci skip] --- CHANGELOG.md | 4 ++++ Gemfile.lock | 2 +- sinatra-export.gemspec | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8fb35a..7f8f078 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.0.1 - 2013-03-17 + +* Add missing rake & rack-test depencendies + ## 1.0.0 - 2013-03-17 * You must now register Sinatra::Export extension. diff --git a/Gemfile.lock b/Gemfile.lock index 199f8e1..a6b9524 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sinatra-export (1.0.0) + sinatra-export (1.0.1) rack rack-test rake diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index de84f87..d2cb83a 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-export' - s.version = '1.0.0' + s.version = '1.0.1' s.authors = ['Jean-Philippe Doyle', 'Paul Asmuth'] s.description = 'Exports all your Sinatra application routes to static files in your public folder' From 2e7f09e987e9be27fe84fcff7a2af4db562f81ec Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 17 Mar 2013 21:39:52 -0300 Subject: [PATCH 082/148] Update README with classic app class usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83caf7e..42dcd7f 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Running your app ex. `rake sinatra:export` will automatically generate theses fi Or invoke it manually within ruby code : ````ruby -App.export! +Sinatra::Application.export! ``` ## Other resources From 55448c511cc130e5db95d8ca6099b0956749565d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 28 Apr 2013 16:51:05 -0400 Subject: [PATCH 083/148] Update README with leaner install instructions [ci skip] --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 42dcd7f..9732aa9 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,13 @@ ## Installation -Add to your `Gemfile` : - ```ruby +# Gemfile gem 'sinatra-export' ``` -Setup your `Rakefile` : - ```ruby +# Rakefile APP_FILE = 'app.rb' APP_CLASS = 'Sinatra::Application' From 5f58a538139ded453f8c5a95cda51d1c96b9fd4b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Sun, 28 Apr 2013 17:14:00 -0400 Subject: [PATCH 084/148] =?UTF-8?q?Update=20LICENSE=20->=C2=A0LICENSE.md?= =?UTF-8?q?=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE => LICENSE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename LICENSE => LICENSE.md (99%) diff --git a/LICENSE b/LICENSE.md similarity index 99% rename from LICENSE rename to LICENSE.md index a0fcc38..9b314ef 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,5 +1,4 @@ - -LICENSE +# LICENSE The MIT License From b553ec6169b02c3281b47dc836ae84a41e7a3d3a Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 4 Dec 2015 21:53:49 +0000 Subject: [PATCH 085/148] Use an env var to make the build directory configurable for now. --- lib/sinatra/export.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 3dc45f8..40a275d 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -36,7 +36,7 @@ def app end def build! - dir = app.public_folder + dir = ENV["EXPORT_BUILD_DIR"] || app.public_folder handle_error_dir_not_found!(dir) unless dir_exists?(dir) app.each_route do |route| next if route.verb != 'GET' or not route.path.is_a? String From 7d8131d2d4c772171a7a59e1fff916e4dea91acc Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 4 Dec 2015 21:58:11 +0000 Subject: [PATCH 086/148] Mostly updated to use Pathname, but need to do file_for_path --- lib/sinatra/export.rb | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 40a275d..3757f10 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -2,6 +2,7 @@ require 'sinatra/advanced_routes' require 'rack/test' require 'term/ansicolor' +require 'pathname' module Sinatra module Export @@ -37,7 +38,7 @@ def app def build! dir = ENV["EXPORT_BUILD_DIR"] || app.public_folder - handle_error_dir_not_found!(dir) unless dir_exists?(dir) + handle_error_dir_not_found!(dir) unless dir.exists?(dir) && dir.directory? app.each_route do |route| next if route.verb != 'GET' or not route.path.is_a? String build_path(route.path, dir) @@ -54,7 +55,7 @@ def build_path(path, dir) file_path = file_for_path(path, dir) dir_path = dir_for_path(path, dir) - ::FileUtils.mkdir_p(dir_path) + dir_path.mkdir_p ::File.open(file_path, 'w+') do |f| f.write(body) end @@ -69,22 +70,18 @@ def get_path( path) def file_for_path(path, dir) if path.match(/[^\/\.]+.(#{app.settings.export_extensions.join("|")})$/) - ::File.join(dir, path) + dir.join path else - ::File.join(dir, path, 'index.html') + dir.join( path ).join( 'index.html' ) end end - def dir_exists?(dir) - ::File.exists?(dir) && ::File.directory?(dir) - end - def dir_for_path(path, dir) file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] end def handle_error_dir_not_found!(dir) - handle_error!("can't find output directory: #{dir}") + handle_error!("can't find output directory: #{dir.to_s}") end def handle_error_non_200!(path) From fee77a7e6581d565fa8596870c8eeb45a9ddeff0 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 4 Dec 2015 22:01:34 +0000 Subject: [PATCH 087/148] Cleaned up the patterns to make them more readable. --- lib/sinatra/export.rb | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 3757f10..4f74519 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -68,16 +68,32 @@ def get_path( path) end end + + FILE_FOR_PATH_PATTERN = %r{ + [^/\.]+ + . + ( + #{app.settings.export_extensions.join("|")} + ) + $}x + def file_for_path(path, dir) - if path.match(/[^\/\.]+.(#{app.settings.export_extensions.join("|")})$/) + if path.match(FILE_FOR_PATH_PATTERN) dir.join path else dir.join( path ).join( 'index.html' ) end end + + DIR_FOR_PATH_PATTERN = %r{ + (.*) + / + [^/]+ + $}x + def dir_for_path(path, dir) - file_for_path(path, dir).match(/(.*)\/[^\/]+$/)[1] + file_for_path(path, dir).match(DIR_FOR_PATH_PATTERN)[1] end def handle_error_dir_not_found!(dir) From 50f1d113944ece2a47476d931ca6461961d1d00e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 15:51:38 +0000 Subject: [PATCH 088/148] Ignore bundler artefacts. --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d2f099c..e27e6a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ test/app/public/ -*.gem \ No newline at end of file +*.gem +.bundle/ +bin/ +vendor/ +vendor.noindex/ From bc4faf36a27ab1727342801ce75e806549e974ec Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 15:51:57 +0000 Subject: [PATCH 089/148] Use pry instead. --- Gemfile | 2 +- Gemfile.lock | 59 +++++++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/Gemfile b/Gemfile index c1ce2b3..9514d1a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' group :development do - gem 'debugger' unless RUBY_VERSION < '1.9' + gem "pry-byebug" gem 'awesome_print' end diff --git a/Gemfile.lock b/Gemfile.lock index a6b9524..e8c0cbe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,45 +12,48 @@ PATH GEM remote: https://rubygems.org/ specs: - awesome_print (1.1.0) - backports (3.1.1) - columnize (0.3.6) - debugger (1.5.0) - columnize (>= 0.3.1) - debugger-linecache (~> 1.2.0) - debugger-ruby_core_source (~> 1.2.0) - debugger-linecache (1.2.0) - debugger-ruby_core_source (1.2.0) - monkey-lib (0.5.4) - backports - rack (1.5.2) - rack-protection (1.5.0) + awesome_print (1.6.1) + byebug (8.2.1) + coderay (1.1.0) + method_source (0.8.2) + power_assert (0.2.6) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-byebug (3.3.0) + byebug (~> 8.0) + pry (~> 0.10) + rack (1.6.4) + rack-protection (1.5.3) rack - rack-test (0.6.2) + rack-test (0.6.3) rack (>= 1.0) - rake (10.0.3) - sinatra (1.4.1) - rack (~> 1.5, >= 1.5.2) + rake (10.4.2) + sinatra (1.4.6) + rack (~> 1.4) rack-protection (~> 1.4) - tilt (~> 1.3, >= 1.3.4) - sinatra-advanced-routes (0.5.2) - monkey-lib (~> 0.5.0) + tilt (>= 1.3, < 3) + sinatra-advanced-routes (0.5.3) sinatra (~> 1.0) - sinatra-sugar (~> 0.5.0) - sinatra-sugar (0.5.1) - monkey-lib (~> 0.5.0) - sinatra (~> 1.0) - term-ansicolor (1.1.1) - test-unit (2.5.4) - tilt (1.3.6) + slop (3.6.0) + term-ansicolor (1.3.2) + tins (~> 1.0) + test-unit (3.1.5) + power_assert + tilt (2.0.1) + tins (1.8.1) PLATFORMS ruby DEPENDENCIES awesome_print - debugger + pry-byebug rack-test rake sinatra-export! test-unit + +BUNDLED WITH + 1.10.2 From 2cde863c6988061f44353a5ce465635bd2ec2a12 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 22:57:58 +0000 Subject: [PATCH 090/148] Ignore coverage generated files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e27e6a9..a225ae9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ test/app/public/ bin/ vendor/ vendor.noindex/ +coverage/ From cef71e222e8c3d657dcbaad1f918c03261757661 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 22:58:18 +0000 Subject: [PATCH 091/148] Using rspec. --- Gemfile | 6 ++++-- Gemfile.lock | 35 +++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 9514d1a..775b160 100644 --- a/Gemfile +++ b/Gemfile @@ -2,13 +2,15 @@ source 'https://rubygems.org' group :development do gem "pry-byebug" - gem 'awesome_print' end group :test do gem 'rack-test' gem 'rake' - gem 'test-unit' + gem 'rspec' + gem 'rspec-its' + gem 'simplecov' + gem 'fakefs', :require => "fakefs/safe" end gemspec \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index e8c0cbe..ccc72f7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,11 +12,13 @@ PATH GEM remote: https://rubygems.org/ specs: - awesome_print (1.6.1) byebug (8.2.1) coderay (1.1.0) + diff-lcs (1.2.5) + docile (1.1.5) + fakefs (0.6.7) + json (1.8.3) method_source (0.8.2) - power_assert (0.2.6) pry (0.10.3) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -30,6 +32,27 @@ GEM rack-test (0.6.3) rack (>= 1.0) rake (10.4.2) + rspec (3.4.0) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-core (3.4.1) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) + simplecov (0.11.1) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) sinatra (1.4.6) rack (~> 1.4) rack-protection (~> 1.4) @@ -39,8 +62,6 @@ GEM slop (3.6.0) term-ansicolor (1.3.2) tins (~> 1.0) - test-unit (3.1.5) - power_assert tilt (2.0.1) tins (1.8.1) @@ -48,12 +69,14 @@ PLATFORMS ruby DEPENDENCIES - awesome_print + fakefs pry-byebug rack-test rake + rspec + rspec-its + simplecov sinatra-export! - test-unit BUNDLED WITH 1.10.2 From cf0659f844dfdc841f9053634a212f581624c548 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 23:00:57 +0000 Subject: [PATCH 092/148] Added specs --- .rspec | 2 + spec/export_spec.rb | 96 +++++++++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 38 ++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 .rspec create mode 100644 spec/export_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..16f9cdb --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/spec/export_spec.rb b/spec/export_spec.rb new file mode 100644 index 0000000..d4fd26f --- /dev/null +++ b/spec/export_spec.rb @@ -0,0 +1,96 @@ +require 'spec_helper' +require 'sinatra' +require_relative "../lib/sinatra/export.rb" + +describe "Sinatra Export" do + + shared_context "app" do + def app + Sinatra.new do + register Sinatra::Export + + configure do + set :root, File.join(__dir__, "support/fixtures", "app") + enable :raise_errors + disable :show_exceptions + end + + get '/' do + "homepage" + end + + get '/contact' do + "contact" + end + + get '/data.json' do + "{test: 'ok'}" + end + + get '/yesterday' do + last_modified Time.local(2002, 10, 31) + "old content" + end + end + end + end + + shared_examples "Server is up" do + before { get "/" } + subject { last_response } + it { should be_ok } + end + + + context "Using the default settings" do + include_context "app" + include_examples "Server is up" + + describe "Exporting" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! + end + + subject { + File.join(app.public_folder, 'index.html') + } + it { should be_a_kind_of String } + it { File.read(subject).should include 'homepage' } + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + end + end + + context "Using an env var" do + before :all do + ENV["EXPORT_BUILD_DIR"] = File.expand_path("support/fixtures/static/001", __dir__ ) + end + + include_context "app" + include_examples "Server is up" + + describe "Exporting" do + before :all do + FileUtils.mkdir_p ENV["EXPORT_BUILD_DIR"] + app.export! + end + + subject { + File.join(ENV["EXPORT_BUILD_DIR"], 'index.html') + } + it { should be_a_kind_of String } + it { File.read(subject).should include 'homepage' } + + after :all do + FileUtils.rm_rf ENV["EXPORT_BUILD_DIR"] + end + end + + + end + + +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..645be36 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,38 @@ +# encoding: UTF-8 + +require 'rspec' +require 'rspec/its' +Spec_dir = File.expand_path( File.dirname __FILE__ ) + + +# code coverage +require 'simplecov' +SimpleCov.start do + add_filter "/vendor/" + add_filter "/bin/" + add_filter "/spec/" +end + +require "rack/test" +ENV['RACK_ENV'] ||= 'test' +ENV["EXPECT_WITH"] ||= "racktest" + + +require "logger" +logger = Logger.new STDOUT +logger.level = Logger::DEBUG +logger.datetime_format = '%a %d-%m-%Y %H%M ' +LOgger = logger + + +Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f| + logger.info "requiring #{f}" + require f +end + + +RSpec.configure do |config| + config.include Rack::Test::Methods + config.expect_with(:rspec) { |c| c.syntax = :should } +end + From 576930ec15a72efcad8bf5b0aecdeab404d32748 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 23:11:25 +0000 Subject: [PATCH 093/148] Updated to make the export directory choosable, and the start of being able to choose the paths. --- lib/sinatra/export.rb | 65 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 4f74519..3d9b19c 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -36,32 +36,52 @@ def app @app end - def build! - dir = ENV["EXPORT_BUILD_DIR"] || app.public_folder - handle_error_dir_not_found!(dir) unless dir.exists?(dir) && dir.directory? - app.each_route do |route| - next if route.verb != 'GET' or not route.path.is_a? String - build_path(route.path, dir) + + def build! paths: nil, skips: [] + dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) + handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? + + paths = self if paths.nil? + + paths.send( :each ) do |path| + #next if skips.include? path + build_path(path, dir) end end private + + def each + app.each_route do |route| + next if route.verb != 'GET' or not route.path.respond_to? :to_s + yield route.path + end + end + def build_path(path, dir) response = get_path(path) body = response.body mtime = response.headers.key?("Last-Modified") ? Time.httpdate(response.headers["Last-Modified"]) : Time.now - file_path = file_for_path(path, dir) - dir_path = dir_for_path(path, dir) - dir_path.mkdir_p + pattern = %r{ + [^/\.]+ + \. + ( + #{app.settings.export_extensions.join("|")} + ) + $}x + file_path = Pathname( File.join dir, path ) + file_path = file_path.join( 'index.html' ) unless path.match(pattern) + ::FileUtils.mkdir_p( file_path.dirname ) ::File.open(file_path, 'w+') do |f| f.write(body) end ::FileUtils.touch(file_path, :mtime => mtime) end + def get_path( path) get(path).tap do |resp| handle_error_non_200!(path) unless resp.status == 200 @@ -69,33 +89,6 @@ def get_path( path) end - FILE_FOR_PATH_PATTERN = %r{ - [^/\.]+ - . - ( - #{app.settings.export_extensions.join("|")} - ) - $}x - - def file_for_path(path, dir) - if path.match(FILE_FOR_PATH_PATTERN) - dir.join path - else - dir.join( path ).join( 'index.html' ) - end - end - - - DIR_FOR_PATH_PATTERN = %r{ - (.*) - / - [^/]+ - $}x - - def dir_for_path(path, dir) - file_for_path(path, dir).match(DIR_FOR_PATH_PATTERN)[1] - end - def handle_error_dir_not_found!(dir) handle_error!("can't find output directory: #{dir.to_s}") end From fe92e4f47163250ff536b876e70e65d4a7cd1374 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 6 Dec 2015 23:52:45 +0000 Subject: [PATCH 094/148] Pass on the arguments. --- lib/sinatra/export.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 3d9b19c..bbe93ad 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -16,8 +16,8 @@ def self.registered(app) end module ClassMethods - def export! - Builder.new(self).build! + def export! paths: nil, skips: [] + Builder.new(self).build! paths: paths, skips: skips end end From 9e87021fdcd1ba2b51d3ba20fe4503e29ddc3729 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 7 Dec 2015 01:32:41 +0000 Subject: [PATCH 095/148] Added in missing specs. --- spec/export_spec.rb | 61 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/spec/export_spec.rb b/spec/export_spec.rb index d4fd26f..6769523 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -51,12 +51,31 @@ def app FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") app.export! end - - subject { - File.join(app.public_folder, 'index.html') - } - it { should be_a_kind_of String } - it { File.read(subject).should include 'homepage' } + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end after :all do FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) @@ -78,11 +97,31 @@ def app app.export! end - subject { - File.join(ENV["EXPORT_BUILD_DIR"], 'index.html') - } - it { should be_a_kind_of String } - it { File.read(subject).should include 'homepage' } + context "index" do + subject { + File.join(ENV["EXPORT_BUILD_DIR"], 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(ENV["EXPORT_BUILD_DIR"], 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(ENV["EXPORT_BUILD_DIR"], 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(ENV["EXPORT_BUILD_DIR"], 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end after :all do FileUtils.rm_rf ENV["EXPORT_BUILD_DIR"] From cf5acc66c04f6a4a16f4fbac323ba98705907c21 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 7 Dec 2015 01:41:36 +0000 Subject: [PATCH 096/148] Processes only paths given. --- spec/export_spec.rb | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 6769523..e49be97 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -125,6 +125,53 @@ def app after :all do FileUtils.rm_rf ENV["EXPORT_BUILD_DIR"] + ENV["EXPORT_BUILD_DIR"] = nil + end + end + + + end + + context "Given paths" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + end + + include_context "app" + include_examples "Server is up" + + describe "Exporting" do + before :all do + app.export! paths: ["/", "/contact"] + end + + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.exist?(subject).should be_falsy } + end + context "yesterday" do + subject { + File.join(app.public_folder, 'yesterday/index.html') + } + it { File.exist?(subject).should be_falsy } + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) end end From bf1f2819c39bc32023ed0c46a53ee959b602cbaf Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 7 Dec 2015 01:51:58 +0000 Subject: [PATCH 097/148] Can pass paths to skip. --- lib/sinatra/export.rb | 2 +- spec/export_spec.rb | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index bbe93ad..b1ca381 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -44,7 +44,7 @@ def build! paths: nil, skips: [] paths = self if paths.nil? paths.send( :each ) do |path| - #next if skips.include? path + next if skips.include? path build_path(path, dir) end end diff --git a/spec/export_spec.rb b/spec/export_spec.rb index e49be97..455a6b1 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -178,5 +178,52 @@ def app end + context "Given skips" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + end + + include_context "app" + include_examples "Server is up" + + describe "Exporting" do + before :all do + app.export! skips: ["/", "/contact"] + end + + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.exist?(subject).should be_falsy } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.exist?(subject).should be_falsy } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + end + + + end + end \ No newline at end of file From ab8c993d303786ce9ac70d80c8a437b514c0c18d Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 8 Dec 2015 13:07:04 +0000 Subject: [PATCH 098/148] Shouldn't have removed this. --- Gemfile | 1 + Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 775b160..61d811b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' group :development do + gem "term-ansicolor" gem "pry-byebug" end diff --git a/Gemfile.lock b/Gemfile.lock index ccc72f7..c6b8e9c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,6 @@ PATH specs: sinatra-export (1.0.1) rack - rack-test rake sinatra sinatra-advanced-routes @@ -77,6 +76,7 @@ DEPENDENCIES rspec-its simplecov sinatra-export! + term-ansicolor BUNDLED WITH 1.10.2 From 299fb793266d518c8442f1e11f50a0fa8c8b21e5 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 8 Dec 2015 18:49:22 +0000 Subject: [PATCH 099/148] Updated lock file. --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index c6b8e9c..3a97968 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ PATH specs: sinatra-export (1.0.1) rack + rack-test rake sinatra sinatra-advanced-routes From 2c9e1dfb864ebc2f321a1f8e6612e34a19ecb1ce Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 8 Dec 2015 18:51:21 +0000 Subject: [PATCH 100/148] Lock file shouldn't be tracked. --- .gitignore | 1 + Gemfile.lock | 83 ---------------------------------------------------- 2 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index a225ae9..f9c51ff 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ bin/ vendor/ vendor.noindex/ coverage/ +Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 3a97968..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,83 +0,0 @@ -PATH - remote: . - specs: - sinatra-export (1.0.1) - rack - rack-test - rake - sinatra - sinatra-advanced-routes - term-ansicolor - -GEM - remote: https://rubygems.org/ - specs: - byebug (8.2.1) - coderay (1.1.0) - diff-lcs (1.2.5) - docile (1.1.5) - fakefs (0.6.7) - json (1.8.3) - method_source (0.8.2) - pry (0.10.3) - coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - pry-byebug (3.3.0) - byebug (~> 8.0) - pry (~> 0.10) - rack (1.6.4) - rack-protection (1.5.3) - rack - rack-test (0.6.3) - rack (>= 1.0) - rake (10.4.2) - rspec (3.4.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) - rspec-core (3.4.1) - rspec-support (~> 3.4.0) - rspec-expectations (3.4.0) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-its (1.2.0) - rspec-core (>= 3.0.0) - rspec-expectations (>= 3.0.0) - rspec-mocks (3.4.0) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-support (3.4.1) - simplecov (0.11.1) - docile (~> 1.1.0) - json (~> 1.8) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.0) - sinatra (1.4.6) - rack (~> 1.4) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) - sinatra-advanced-routes (0.5.3) - sinatra (~> 1.0) - slop (3.6.0) - term-ansicolor (1.3.2) - tins (~> 1.0) - tilt (2.0.1) - tins (1.8.1) - -PLATFORMS - ruby - -DEPENDENCIES - fakefs - pry-byebug - rack-test - rake - rspec - rspec-its - simplecov - sinatra-export! - term-ansicolor - -BUNDLED WITH - 1.10.2 From cb9ca80994f59e64d7a80cd612131ab440c3aa22 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 8 Dec 2015 18:51:42 +0000 Subject: [PATCH 101/148] A little bit of convenience. --- spec/spec_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 645be36..47cd06a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,6 +2,7 @@ require 'rspec' require 'rspec/its' +require 'pry-byebug' if ENV["WITH_PRY"] Spec_dir = File.expand_path( File.dirname __FILE__ ) From b9854e4cd53af9b585abed65c6e247be3af56e6f Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 8 Dec 2015 18:52:35 +0000 Subject: [PATCH 102/148] Using an external iterator so that the provided block can add extra paths. First step, works as before after coversion to enumerator. --- lib/sinatra/export.rb | 57 +++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index b1ca381..92e7010 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -16,8 +16,12 @@ def self.registered(app) end module ClassMethods - def export! paths: nil, skips: [] - Builder.new(self).build! paths: paths, skips: skips + # @example + # app.export paths: "/" do |body| + # # something here + # end + def export! paths: nil, skips: [], &block + Builder.new(self).build! paths: paths, skips: skips, &block end end @@ -37,30 +41,47 @@ def app end - def build! paths: nil, skips: [] + def build!( paths: nil, skips: [], &block ) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? - paths = self if paths.nil? - - paths.send( :each ) do |path| - next if skips.include? path - build_path(path, dir) + if paths.nil? + paths_e = self.send( :route_paths ).to_enum + else + paths_e = paths.to_enum end + + catch(:no_more_paths) { + while true + begin + path = paths_e.next + unless skips.include? path + response = get_path(path) + file_path = build_path(path: path, dir: dir, response: response) + block.call response, path if block + end + rescue StopIteration + throw(:no_more_paths) + end + end + } end private - def each + def route_paths + route_paths = [] app.each_route do |route| next if route.verb != 'GET' or not route.path.respond_to? :to_s - yield route.path + route_paths << route.path end + route_paths end - def build_path(path, dir) - response = get_path(path) + + # @return [String] file_path + def build_path(path:, dir:, response:) body = response.body mtime = response.headers.key?("Last-Modified") ? Time.httpdate(response.headers["Last-Modified"]) : Time.now @@ -75,10 +96,16 @@ def build_path(path, dir) file_path = Pathname( File.join dir, path ) file_path = file_path.join( 'index.html' ) unless path.match(pattern) ::FileUtils.mkdir_p( file_path.dirname ) - ::File.open(file_path, 'w+') do |f| - f.write(body) - end + write_path content: body, path: file_path ::FileUtils.touch(file_path, :mtime => mtime) + file_path + end + + + def write_path content:, path: + ::File.open(path, 'w+') do |f| + f.write(content) + end end From 2669c8c76923a86ec179080760e5edbda3ccb02e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 14:31:12 +0000 Subject: [PATCH 103/148] Make a bit more 'object' --- lib/sinatra/export.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 92e7010..9e49235 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -21,7 +21,7 @@ module ClassMethods # # something here # end def export! paths: nil, skips: [], &block - Builder.new(self).build! paths: paths, skips: skips, &block + Builder.new(self,paths: paths, skips: skips).build! &block end end @@ -32,8 +32,10 @@ class ColorString < String include Term::ANSIColor end - def initialize(app) + def initialize(app, paths: nil, skips: nil ) @app = app + @paths = paths + @skips = skips || [] end def app @@ -41,21 +43,23 @@ def app end - def build!( paths: nil, skips: [], &block ) + def build!( &block ) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? - if paths.nil? + + if @paths.nil? paths_e = self.send( :route_paths ).to_enum else - paths_e = paths.to_enum + paths_e = @paths.to_enum end catch(:no_more_paths) { while true begin path = paths_e.next - unless skips.include? path + # TODO handle named captures paths + unless @skips.include? path response = get_path(path) file_path = build_path(path: path, dir: dir, response: response) block.call response, path if block From f35c1eba64b6b709c434d266bcc888c13a1849b0 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 18:25:24 +0000 Subject: [PATCH 104/148] Will ignore named parameter paths; can provide block with self as param; uses external iterator to hit all provided paths; --- lib/sinatra/export.rb | 51 ++++++++++++++++++++++++------------- spec/export_spec.rb | 59 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 9e49235..b7c723e 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -17,11 +17,13 @@ def self.registered(app) module ClassMethods # @example - # app.export paths: "/" do |body| - # # something here + # app.export paths: "/" do |builder| + # if builder.last_response.body.include? "/echo-1" + # builder.paths << "/echo-1" + # end # end def export! paths: nil, skips: [], &block - Builder.new(self,paths: paths, skips: skips).build! &block + @builder ||= Builder.new(self,paths: paths, skips: skips).build! &block end end @@ -32,12 +34,24 @@ class ColorString < String include Term::ANSIColor end - def initialize(app, paths: nil, skips: nil ) + # paths | use_routes | + # f t t + # t t t + # t f/nil f + # f f/nil f + def initialize(app, paths: nil, skips: nil, use_routes: nil ) @app = app - @paths = paths + @use_routes = + paths.nil? && use_routes.nil? ? + true : + use_routes + @paths = paths || [] @skips = skips || [] + @enum = [] end + attr_accessor :paths, :skips, :last_response, :last_path + def app @app end @@ -47,24 +61,23 @@ def build!( &block ) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? - - if @paths.nil? - paths_e = self.send( :route_paths ).to_enum - else - paths_e = @paths.to_enum + if @use_routes + @enum.push self.send( :route_paths ).to_enum end + @enum.push @paths.to_enum catch(:no_more_paths) { + enum = get_enum while true begin - path = paths_e.next - # TODO handle named captures paths - unless @skips.include? path - response = get_path(path) - file_path = build_path(path: path, dir: dir, response: response) - block.call response, path if block - end + last_path = enum.next + next if last_path =~ /((:\w+)|\*)/ # keys and splats + next if @skips.include? last_path + @last_response = get_path(last_path) + file_path = build_path(path: last_path, dir: dir, response: last_response) + block.call self if block rescue StopIteration + retry if enum = get_enum throw(:no_more_paths) end end @@ -73,6 +86,10 @@ def build!( &block ) private + def get_enum + @enum.shift + end + def route_paths route_paths = [] diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 455a6b1..32a93b6 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -16,7 +16,7 @@ def app end get '/' do - "homepage" + "

homepage

echo-1

" end get '/contact' do @@ -31,6 +31,10 @@ def app last_modified Time.local(2002, 10, 31) "old content" end + + get "/echo-:this" do |this| + this.to_s + end end end end @@ -226,4 +230,57 @@ def app end + context "Using a block" do + include_context "app" + include_examples "Server is up" + + describe "Exporting" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! do |builder| + if builder.last_response.body.include? "/echo-1" + builder.paths << "/echo-1" + end + end + end + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end + + context "named parameters" do + subject { + File.join(app.public_folder, 'echo-1/index.html') + } + it { File.read(subject).should include '1' } + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + end + end + + end \ No newline at end of file From a7908d502fcbae042ac64170c735aa3349d20724 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 18:29:15 +0000 Subject: [PATCH 105/148] Bit of yardoc. --- lib/sinatra/export.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index b7c723e..43eb958 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -34,11 +34,11 @@ class ColorString < String include Term::ANSIColor end - # paths | use_routes | - # f t t - # t t t - # t f/nil f - # f f/nil f + + # @param [Sinatra::Base] app The Sinatra app + # @param [Array] paths Paths that will be requested by the builder. + # @param [Array] skips: Paths that will be ignored by the builder. + # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. def initialize(app, paths: nil, skips: nil, use_routes: nil ) @app = app @use_routes = From 854b522afef06e7283ed434edf49233e802cff80 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 18:32:55 +0000 Subject: [PATCH 106/148] So it doesn't get caught by simplecov. --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 47cd06a..db7af05 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,7 +9,7 @@ # code coverage require 'simplecov' SimpleCov.start do - add_filter "/vendor/" + add_filter "/vendor.noindex/" add_filter "/bin/" add_filter "/spec/" end From 6a0704c7747b2bafba430ad2e730f85bf9ddcebd Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 19:09:33 +0000 Subject: [PATCH 107/148] Can provide a Builder instance to use. --- lib/sinatra/export.rb | 9 ++++- spec/export_spec.rb | 93 +++++++++++++++++++++++++++++++++---------- 2 files changed, 79 insertions(+), 23 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 43eb958..729adde 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -13,6 +13,7 @@ def self.registered(app) end app.set :export_extensions, %w(css js xml json html csv) app.extend ClassMethods + app.set :builder, nil end module ClassMethods @@ -23,7 +24,13 @@ module ClassMethods # end # end def export! paths: nil, skips: [], &block - @builder ||= Builder.new(self,paths: paths, skips: skips).build! &block + @builder ||= + if self.builder + self.builder + else + Builder.new(self,paths: paths, skips: skips) + end + @builder.build! &block end end diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 32a93b6..06bc184 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -49,12 +49,17 @@ def app context "Using the default settings" do include_context "app" include_examples "Server is up" + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end describe "Exporting" do - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! - end + context "index" do subject { File.join(app.public_folder, 'index.html') @@ -80,10 +85,6 @@ def app it { subject.read.should include 'old content' } its(:mtime) { should == Time.local(2002, 10, 31) } end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end end end @@ -141,6 +142,11 @@ def app FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") end + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + + include_context "app" include_examples "Server is up" @@ -173,12 +179,7 @@ def app } it { File.exist?(subject).should be_falsy } end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end - end - + end end @@ -187,6 +188,10 @@ def app FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") end + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + include_context "app" include_examples "Server is up" @@ -220,10 +225,6 @@ def app it { subject.read.should include 'old content' } its(:mtime) { should == Time.local(2002, 10, 31) } end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end end @@ -233,10 +234,16 @@ def app context "Using a block" do include_context "app" include_examples "Server is up" + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end describe "Exporting" do before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") app.export! do |builder| if builder.last_response.body.include? "/echo-1" builder.paths << "/echo-1" @@ -275,12 +282,54 @@ def app } it { File.read(subject).should include '1' } end + end + end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + context "Given a builder" do + include_context "app" + include_examples "Server is up" + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + + describe "Exporting" do + before :all do + app.builder = Sinatra::Export::Builder.new(self,paths: ["/", "/contact"]) + app.export! + end + + + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } end end + end - end \ No newline at end of file From 1380280e83d1c565a29378a0b1c874f870f9095c Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 19:15:12 +0000 Subject: [PATCH 108/148] Added some yardoc. --- lib/sinatra/export.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 729adde..da13e98 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -93,6 +93,7 @@ def build!( &block ) private + # @return [Enumerator] The next enumerator to provide paths for the builder. def get_enum @enum.shift end From e035d8b4937a6d9b12cff7cd655237c01e5cafd3 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 9 Dec 2015 19:27:57 +0000 Subject: [PATCH 109/148] Added filtering to the content that gets written. --- lib/sinatra/export.rb | 12 +++++++++--- spec/export_spec.rb | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index da13e98..04a7949 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -23,12 +23,12 @@ module ClassMethods # builder.paths << "/echo-1" # end # end - def export! paths: nil, skips: [], &block + def export! paths: nil, skips: [], filters: [], &block @builder ||= if self.builder self.builder else - Builder.new(self,paths: paths, skips: skips) + Builder.new(self,paths: paths, skips: skips, filters: filters ) end @builder.build! &block end @@ -46,7 +46,7 @@ class ColorString < String # @param [Array] paths Paths that will be requested by the builder. # @param [Array] skips: Paths that will be ignored by the builder. # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. - def initialize(app, paths: nil, skips: nil, use_routes: nil ) + def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) @app = app @use_routes = paths.nil? && use_routes.nil? ? @@ -55,6 +55,7 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil ) @paths = paths || [] @skips = skips || [] @enum = [] + @filters = filters end attr_accessor :paths, :skips, :last_response, :last_path @@ -132,6 +133,11 @@ def build_path(path:, dir:, response:) def write_path content:, path: + if @filters && !@filters.empty? + content = @filters.inject(content) do |current_content,filter| + filter.call current_content + end + end ::File.open(path, 'w+') do |f| f.write(content) end diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 06bc184..677f99b 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -332,4 +332,47 @@ def app end + + context "Given filters" do + include_context "app" + include_examples "Server is up" + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! filters: [->(text){ text.upcase }] + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + + describe "Exporting" do + + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'HOMEPAGE' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'CONTACT' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{TEST: 'OK'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'OLD CONTENT' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end + end + end + end \ No newline at end of file From 9fc3c3e2179947de06832df996d4e2ae152a84c8 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Thu, 10 Dec 2015 15:41:43 +0000 Subject: [PATCH 110/148] A convenience method to make checking the path is usable a bit easier. --- lib/sinatra/export.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 04a7949..6769920 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -79,7 +79,7 @@ def build!( &block ) while true begin last_path = enum.next - next if last_path =~ /((:\w+)|\*)/ # keys and splats + next unless route_path_usable?(last_path) next if @skips.include? last_path @last_response = get_path(last_path) file_path = build_path(path: last_path, dir: dir, response: last_response) @@ -94,6 +94,16 @@ def build!( &block ) private + # A convenience method to keep this logic together + # and reusable + # @param [String,Regexp] path + # @return [TrueClass] Whether the path is a straightforward path (i.e. usable) or it's a regex or path with named captures / wildcards (i.e. unusable). + def route_path_usable? path + res = path.respond_to?( :~ ) || # skip regex + path =~ /((:\w+)|\*)/ # keys and splats + !res + end + # @return [Enumerator] The next enumerator to provide paths for the builder. def get_enum @enum.shift @@ -103,7 +113,8 @@ def get_enum def route_paths route_paths = [] app.each_route do |route| - next if route.verb != 'GET' or not route.path.respond_to? :to_s + next if route.verb != 'GET' + next unless route_path_usable?(route.path) route_paths << route.path end route_paths From c744bbce710c68fab6e4591fd8744945345b3277 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Thu, 10 Dec 2015 20:08:34 +0000 Subject: [PATCH 111/148] Ignore paths with special characters in them. --- lib/sinatra/export.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 6769920..7a2bee0 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -100,7 +100,8 @@ def build!( &block ) # @return [TrueClass] Whether the path is a straightforward path (i.e. usable) or it's a regex or path with named captures / wildcards (i.e. unusable). def route_path_usable? path res = path.respond_to?( :~ ) || # skip regex - path =~ /((:\w+)|\*)/ # keys and splats + path =~ /(?:\:\w+)|\*/ || # keys and splats + path =~ /[\?\%\\]/ # special chars !res end From 3a2db19a5bf202d8bb071f7aecb261917e553a59 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Thu, 10 Dec 2015 22:24:23 +0000 Subject: [PATCH 112/148] Handle paths with special chars and question marks better. --- lib/sinatra/export.rb | 10 +++++---- spec/export_spec.rb | 47 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 7a2bee0..00f98e4 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -81,6 +81,7 @@ def build!( &block ) last_path = enum.next next unless route_path_usable?(last_path) next if @skips.include? last_path + last_path = last_path.chop if last_path.end_with? "?" @last_response = get_path(last_path) file_path = build_path(path: last_path, dir: dir, response: last_response) block.call self if block @@ -99,9 +100,10 @@ def build!( &block ) # @param [String,Regexp] path # @return [TrueClass] Whether the path is a straightforward path (i.e. usable) or it's a regex or path with named captures / wildcards (i.e. unusable). def route_path_usable? path - res = path.respond_to?( :~ ) || # skip regex - path =~ /(?:\:\w+)|\*/ || # keys and splats - path =~ /[\?\%\\]/ # special chars + res = path.respond_to?( :~ ) || # skip regex + path =~ /(?:\:\w+)|\*/ || # keys and splats + path =~ /[\%\\]/ || # special chars + path[0..-2].include?("?") # an ending ? is acceptable, it'll be chomped !res end @@ -156,7 +158,7 @@ def write_path content:, path: end - def get_path( path) + def get_path path get(path).tap do |resp| handle_error_non_200!(path) unless resp.status == 200 end diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 677f99b..b2615a8 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -19,7 +19,7 @@ def app "

homepage

echo-1

" end - get '/contact' do + get '/contact/?' do "contact" end @@ -197,7 +197,7 @@ def app describe "Exporting" do before :all do - app.export! skips: ["/", "/contact"] + app.export! skips: ["/", "/contact/?"] end context "index" do @@ -375,4 +375,47 @@ def app end end + + context "Using the default settings" do + include_context "app" + include_examples "Server is up" + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + + describe "Exporting" do + + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end + end + end + end \ No newline at end of file From 922911c7a3422bcfc9f6e717d957321946509349 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 11 Dec 2015 04:39:39 +0000 Subject: [PATCH 113/148] Tidied up the specs; bit of formatting; added an @visited so that logging can be done, or to stop revisiting paths. --- lib/sinatra/export.rb | 13 +-- spec/export_spec.rb | 205 +++++++++++++----------------------------- 2 files changed, 70 insertions(+), 148 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 00f98e4..27d9192 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -52,13 +52,14 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) paths.nil? && use_routes.nil? ? true : use_routes - @paths = paths || [] - @skips = skips || [] - @enum = [] - @filters = filters + @paths = paths || [] + @skips = skips || [] + @enum = [] + @filters = filters + @visited = [] end - attr_accessor :paths, :skips, :last_response, :last_path + attr_accessor :paths, :skips, :last_response, :last_path, :visited def app @app @@ -85,12 +86,14 @@ def build!( &block ) @last_response = get_path(last_path) file_path = build_path(path: last_path, dir: dir, response: last_response) block.call self if block + @visited |= [last_path] rescue StopIteration retry if enum = get_enum throw(:no_more_paths) end end } + self end private diff --git a/spec/export_spec.rb b/spec/export_spec.rb index b2615a8..56900e8 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -49,16 +49,16 @@ def app context "Using the default settings" do include_context "app" include_examples "Server is up" - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! - end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end + describe "Straightfoward exporting" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + @builder = app.export! + end - describe "Exporting" do + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end context "index" do subject { @@ -85,74 +85,20 @@ def app it { subject.read.should include 'old content' } its(:mtime) { should == Time.local(2002, 10, 31) } end - end - end - - context "Using an env var" do - before :all do - ENV["EXPORT_BUILD_DIR"] = File.expand_path("support/fixtures/static/001", __dir__ ) + describe "visited" do + subject { @builder.visited } + it { should =~ ["/", "/contact/", "/data.json", "/yesterday"] } + end end - include_context "app" - include_examples "Server is up" - - describe "Exporting" do + describe "Given paths" do before :all do - FileUtils.mkdir_p ENV["EXPORT_BUILD_DIR"] - app.export! - end - - context "index" do - subject { - File.join(ENV["EXPORT_BUILD_DIR"], 'index.html') - } - it { File.read(subject).should include 'homepage' } - end - context "contact" do - subject { - File.join(ENV["EXPORT_BUILD_DIR"], 'contact/index.html') - } - it { File.read(subject).should include 'contact' } - end - context "data.json" do - subject { - File.join(ENV["EXPORT_BUILD_DIR"], 'data.json') - } - it { File.read(subject).should include "{test: 'ok'}" } - end - context "yesterday" do - subject { - File.new File.join(ENV["EXPORT_BUILD_DIR"], 'yesterday/index.html') - } - it { subject.read.should include 'old content' } - its(:mtime) { should == Time.local(2002, 10, 31) } + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! paths: ["/", "/contact"] end after :all do - FileUtils.rm_rf ENV["EXPORT_BUILD_DIR"] - ENV["EXPORT_BUILD_DIR"] = nil - end - end - - - end - - context "Given paths" do - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end - - - include_context "app" - include_examples "Server is up" - - describe "Exporting" do - before :all do - app.export! paths: ["/", "/contact"] + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) end context "index" do @@ -179,27 +125,18 @@ def app } it { File.exist?(subject).should be_falsy } end - end - - end - - context "Given skips" do - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end - - include_context "app" - include_examples "Server is up" - - describe "Exporting" do + + context "Given skips" do before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") app.export! skips: ["/", "/contact/?"] end + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + context "index" do subject { File.join(app.public_folder, 'index.html') @@ -226,30 +163,21 @@ def app its(:mtime) { should == Time.local(2002, 10, 31) } end end - - - end - - context "Using a block" do - include_context "app" - include_examples "Server is up" - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - end - - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end - - describe "Exporting" do + context "Using a block" do before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") app.export! do |builder| if builder.last_response.body.include? "/echo-1" builder.paths << "/echo-1" end end end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + context "index" do subject { File.join(app.public_folder, 'index.html') @@ -283,25 +211,17 @@ def app it { File.read(subject).should include '1' } end end - end - - context "Given a builder" do - include_context "app" - include_examples "Server is up" - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end - - describe "Exporting" do + context "Given a builder" do before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") app.builder = Sinatra::Export::Builder.new(self,paths: ["/", "/contact"]) app.export! end + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end context "index" do subject { @@ -329,23 +249,16 @@ def app its(:mtime) { should == Time.local(2002, 10, 31) } end end - - end - - - context "Given filters" do - include_context "app" - include_examples "Server is up" - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! filters: [->(text){ text.upcase }] - end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end + context "Given filters" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! filters: [->(text){ text.upcase }] + end - describe "Exporting" do + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end context "index" do subject { @@ -375,47 +288,53 @@ def app end end - - context "Using the default settings" do - include_context "app" - include_examples "Server is up" + context "Using an env var" do before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! + ENV["EXPORT_BUILD_DIR"] = File.expand_path("support/fixtures/static/001", __dir__ ) end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end + include_context "app" + include_examples "Server is up" describe "Exporting" do + before :all do + FileUtils.mkdir_p ENV["EXPORT_BUILD_DIR"] + app.export! + end context "index" do subject { - File.join(app.public_folder, 'index.html') + File.join(ENV["EXPORT_BUILD_DIR"], 'index.html') } it { File.read(subject).should include 'homepage' } end context "contact" do subject { - File.join(app.public_folder, 'contact/index.html') + File.join(ENV["EXPORT_BUILD_DIR"], 'contact/index.html') } it { File.read(subject).should include 'contact' } end context "data.json" do subject { - File.join(app.public_folder, 'data.json') + File.join(ENV["EXPORT_BUILD_DIR"], 'data.json') } it { File.read(subject).should include "{test: 'ok'}" } end context "yesterday" do subject { - File.new File.join(app.public_folder, 'yesterday/index.html') + File.new File.join(ENV["EXPORT_BUILD_DIR"], 'yesterday/index.html') } it { subject.read.should include 'old content' } its(:mtime) { should == Time.local(2002, 10, 31) } end + + after :all do + FileUtils.rm_rf ENV["EXPORT_BUILD_DIR"] + ENV["EXPORT_BUILD_DIR"] = nil + end end + + end end \ No newline at end of file From 4bed3271b0689e8b518d8cd5cd09ead994722ca9 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 11 Dec 2015 07:35:38 +0000 Subject: [PATCH 114/148] Can define status for a page, so can generate a 404. --- lib/sinatra/export.rb | 13 +++++++------ spec/export_spec.rb | 13 ++++++++++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 27d9192..1d7616e 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -79,11 +79,11 @@ def build!( &block ) enum = get_enum while true begin - last_path = enum.next + last_path, status = enum.next next unless route_path_usable?(last_path) next if @skips.include? last_path last_path = last_path.chop if last_path.end_with? "?" - @last_response = get_path(last_path) + @last_response = get_path(last_path, status) file_path = build_path(path: last_path, dir: dir, response: last_response) block.call self if block @visited |= [last_path] @@ -161,9 +161,10 @@ def write_path content:, path: end - def get_path path + def get_path path, status=nil + status ||= 200 get(path).tap do |resp| - handle_error_non_200!(path) unless resp.status == 200 + handle_error_incorrect_status!(path,status) unless resp.status == status end end @@ -172,8 +173,8 @@ def handle_error_dir_not_found!(dir) handle_error!("can't find output directory: #{dir.to_s}") end - def handle_error_non_200!(path) - handle_error!("GET #{path} returned non-200 status code...") + def handle_error_incorrect_status!(status) + handle_error!("GET #{path} returned non-#{status} status code...") end def handle_error!(desc) diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 56900e8..673990c 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -35,6 +35,10 @@ def app get "/echo-:this" do |this| this.to_s end + + not_found do + 'This is nowhere to be found.' + end end end end @@ -94,7 +98,7 @@ def app describe "Given paths" do before :all do FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! paths: ["/", "/contact"] + app.export! paths: ["/", "/contact", ["/404.html", 404]] end after :all do @@ -125,6 +129,13 @@ def app } it { File.exist?(subject).should be_falsy } end + + context "404" do + subject { + File.join(app.public_folder, '404.html') + } + it { File.read(subject).should include 'This is nowhere to be found.' } + end end context "Given skips" do From fb850bb58b8ecf1df576ab4c5a0f18f308b32dac Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 11 Dec 2015 07:36:51 +0000 Subject: [PATCH 115/148] Fixed method signature. --- lib/sinatra/export.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 1d7616e..d6db726 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -173,7 +173,7 @@ def handle_error_dir_not_found!(dir) handle_error!("can't find output directory: #{dir.to_s}") end - def handle_error_incorrect_status!(status) + def handle_error_incorrect_status!(path,status) handle_error!("GET #{path} returned non-#{status} status code...") end From d53d8678d74fe91785d5795be53ea31bac525bca Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Fri, 11 Dec 2015 07:51:28 +0000 Subject: [PATCH 116/148] Can receive either a URI or a string for the path now. --- lib/sinatra/export.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index d6db726..ceabb9d 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -43,8 +43,8 @@ class ColorString < String # @param [Sinatra::Base] app The Sinatra app - # @param [Array] paths Paths that will be requested by the builder. - # @param [Array] skips: Paths that will be ignored by the builder. + # @param [Array,Array] paths Paths that will be requested by the builder. + # @param [Array] skips: Paths that will be ignored by the builder. # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) @app = app @@ -80,6 +80,9 @@ def build!( &block ) while true begin last_path, status = enum.next + last_path = last_path.respond_to?(:path) ? + last_path.path : + last_path.to_s next unless route_path_usable?(last_path) next if @skips.include? last_path last_path = last_path.chop if last_path.end_with? "?" From b994c5e85dcec2aa03b02bfd13e04afd83f9396f Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sat, 12 Dec 2015 03:22:02 +0000 Subject: [PATCH 117/148] Tidied up the names and made clear that the instance var for @last_path is being used, not a local. --- lib/sinatra/export.rb | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index ceabb9d..8def836 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -54,7 +54,7 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) use_routes @paths = paths || [] @skips = skips || [] - @enum = [] + @enums = [] @filters = filters @visited = [] end @@ -71,27 +71,27 @@ def build!( &block ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? if @use_routes - @enum.push self.send( :route_paths ).to_enum + @enums.push self.send( :route_paths ).to_enum end - @enum.push @paths.to_enum + @enums.push @paths.to_enum catch(:no_more_paths) { - enum = get_enum + enum = @enums.shift while true begin - last_path, status = enum.next - last_path = last_path.respond_to?(:path) ? - last_path.path : - last_path.to_s - next unless route_path_usable?(last_path) - next if @skips.include? last_path - last_path = last_path.chop if last_path.end_with? "?" - @last_response = get_path(last_path, status) - file_path = build_path(path: last_path, dir: dir, response: last_response) + @last_path, status = enum.next + @last_path = @last_path.respond_to?(:path) ? + @last_path.path : + @last_path.to_s + next unless route_path_usable?(@last_path) + next if @skips.include? @last_path + @last_path = @last_path.chop if @last_path.end_with? "?" + @last_response = get_path(@last_path, status) + file_path = build_path(path: @last_path, dir: dir, response: last_response) block.call self if block - @visited |= [last_path] + @visited |= [@last_path] rescue StopIteration - retry if enum = get_enum + retry if enum = @enums.shift throw(:no_more_paths) end end @@ -113,11 +113,6 @@ def route_path_usable? path !res end - # @return [Enumerator] The next enumerator to provide paths for the builder. - def get_enum - @enum.shift - end - def route_paths route_paths = [] From 687570bdfcf28a30d5a5214caf9d31cf791dae6e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sat, 12 Dec 2015 03:22:41 +0000 Subject: [PATCH 118/148] Useful for when trying to check dynamic methods' callers, like forwardable in rack test. --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 61d811b..334a0e8 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source 'https://rubygems.org' group :development do gem "term-ansicolor" gem "pry-byebug" + gem "pry-stack_explorer" end group :test do From aeac0888c3030dbb4e734061aac5e781c26fb947 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 13 Dec 2015 02:18:20 +0000 Subject: [PATCH 119/148] More description in the errors, can check for errored pages too. --- lib/sinatra/export.rb | 40 ++++++++++++++++++++++++++++------------ spec/export_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 8def836..6bb6d5b 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -37,6 +37,10 @@ def export! paths: nil, skips: [], filters: [], &block class Builder include Rack::Test::Methods + DEFAULT_ERROR_HANDLER = ->(desc) { + puts ColorString.new("failed: #{desc}").red; + } + class ColorString < String include Term::ANSIColor end @@ -57,9 +61,11 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) @enums = [] @filters = filters @visited = [] + @errored = [] + @error_handler = DEFAULT_ERROR_HANDLER end - attr_accessor :paths, :skips, :last_response, :last_path, :visited + attr_accessor :paths, :skips, :last_response, :last_path, :visited, :errored def app @app @@ -86,10 +92,14 @@ def build!( &block ) next unless route_path_usable?(@last_path) next if @skips.include? @last_path @last_path = @last_path.chop if @last_path.end_with? "?" - @last_response = get_path(@last_path, status) - file_path = build_path(path: @last_path, dir: dir, response: last_response) - block.call self if block - @visited |= [@last_path] + desc = catch(:status_error) { + @last_response = get_path(@last_path, status) + file_path = build_path(path: @last_path, dir: dir, response: last_response) + block.call self if block + } + desc ? + @errored |= [@last_path] : + @visited |= [@last_path] rescue StopIteration retry if enum = @enums.shift throw(:no_more_paths) @@ -101,6 +111,10 @@ def build!( &block ) private + def status_error desc + throw :status_error, desc + end + # A convenience method to keep this logic together # and reusable # @param [String,Regexp] path @@ -162,22 +176,24 @@ def write_path content:, path: def get_path path, status=nil status ||= 200 get(path).tap do |resp| - handle_error_incorrect_status!(path,status) unless resp.status == status + handle_error_incorrect_status!(path,expected: status, actual: resp.status) unless resp.status == status end end def handle_error_dir_not_found!(dir) - handle_error!("can't find output directory: #{dir.to_s}") + @error_handler.call("can't find output directory: #{dir.to_s}") end - def handle_error_incorrect_status!(path,status) - handle_error!("GET #{path} returned non-#{status} status code...") + def handle_error_incorrect_status!(path,expected:,actual:) + desc = "GET #{path} returned #{actual} status code instead of #{expected}" + @error_handler.call(desc) + status_error desc end - def handle_error!(desc) - puts ColorString.new("failed: #{desc}").red; exit! - end +# def handle_error!(desc) +# puts ColorString.new("failed: #{desc}").red; exit! +# end end end diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 673990c..aad5713 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -39,6 +39,10 @@ def app not_found do 'This is nowhere to be found.' end + + get "/this-will-send-non-200/*" do + halt 401, "No thanks!" + end end end end @@ -93,6 +97,22 @@ def app subject { @builder.visited } it { should =~ ["/", "/contact/", "/data.json", "/yesterday"] } end + + describe "Raising errors" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + end + + context "this-will-send-non-200/for-sure" do + subject { @builder = app.export! paths: ["/this-will-send-non-200/for-sure"] } + its(:errored) { should =~ ["/this-will-send-non-200/for-sure"] } + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + + end end describe "Given paths" do From 4bae87302dc88124a9e6485d32d08173f790ee3e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 13 Dec 2015 02:22:57 +0000 Subject: [PATCH 120/148] =?UTF-8?q?Added=20expect=20syntax.=20Not=20sure?= =?UTF-8?q?=20why=20RSpec=20can't=20do=20all=20this=20nonsense=20for=20me,?= =?UTF-8?q?=20but=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index db7af05..664b528 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -34,6 +34,6 @@ RSpec.configure do |config| config.include Rack::Test::Methods - config.expect_with(:rspec) { |c| c.syntax = :should } + config.expect_with(:rspec) { |c| c.syntax = [ :should , :expect ] } end From e7cfa81992aab0b931123fe8ac234a2a823d34eb Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 13 Dec 2015 03:04:58 +0000 Subject: [PATCH 121/148] Can pass an alternative error handler now. --- lib/sinatra/export.rb | 4 ++-- spec/export_spec.rb | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 6bb6d5b..db9b50c 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -50,7 +50,7 @@ class ColorString < String # @param [Array,Array] paths Paths that will be requested by the builder. # @param [Array] skips: Paths that will be ignored by the builder. # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. - def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) + def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [], error_handler: nil ) @app = app @use_routes = paths.nil? && use_routes.nil? ? @@ -65,7 +65,7 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [] ) @error_handler = DEFAULT_ERROR_HANDLER end - attr_accessor :paths, :skips, :last_response, :last_path, :visited, :errored + attr_accessor :paths, :skips, :last_response, :last_path, :visited, :errored, :error_handler def app @app diff --git a/spec/export_spec.rb b/spec/export_spec.rb index aad5713..4d02856 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -104,8 +104,17 @@ def app end context "this-will-send-non-200/for-sure" do - subject { @builder = app.export! paths: ["/this-will-send-non-200/for-sure"] } - its(:errored) { should =~ ["/this-will-send-non-200/for-sure"] } + context "Using the default error handler" do + subject { @builder = app.export! paths: ["/this-will-send-non-200/for-sure"] } + its(:errored) { should =~ ["/this-will-send-non-200/for-sure"] } + end + context "Supplying an error handler" do + it "should raise error" do + expect { + @builder = app.export! paths: ["/this-will-send-non-200/for-sure"], error_handler: ->(desc){ fail "Please stop" } + }.to raise_error + end + end end after :all do From 48209e0858703875939c9fd71b18185371407716 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Sun, 13 Dec 2015 08:12:55 +0000 Subject: [PATCH 122/148] Should be using app not self. Fixed. --- spec/export_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 4d02856..76b242c 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -255,7 +255,7 @@ def app context "Given a builder" do before :all do FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.builder = Sinatra::Export::Builder.new(self,paths: ["/", "/contact"]) + app.builder = Sinatra::Export::Builder.new(app,paths: ["/", "/contact"]) app.export! end From 7ba4f77f127c804e23fe437b9945f836165e4b38 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 03:56:30 +0000 Subject: [PATCH 123/148] Couldn't get fakefs to work with this in the end, removing. --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 334a0e8..95f5d13 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,6 @@ group :test do gem 'rspec' gem 'rspec-its' gem 'simplecov' - gem 'fakefs', :require => "fakefs/safe" end gemspec \ No newline at end of file From 5f4fad32f9705460656a82ae21697ef9f0efafba Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:20:05 +0000 Subject: [PATCH 124/148] Should pass on the use_routes too. Fixed. --- lib/sinatra/export.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index db9b50c..8d5fb4f 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -28,7 +28,7 @@ def export! paths: nil, skips: [], filters: [], &block if self.builder self.builder else - Builder.new(self,paths: paths, skips: skips, filters: filters ) + Builder.new(self,paths: paths, skips: skips, filters: filters, use_routes: use_routes ) end @builder.build! &block end From 28d8b619a992f82d6b6add127183dd5b715df739 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:20:21 +0000 Subject: [PATCH 125/148] No point having yard docs without yard. --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 95f5d13..fc269bb 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ group :development do gem "term-ansicolor" gem "pry-byebug" gem "pry-stack_explorer" + gem "yard" end group :test do From 10f946cb55e1ec0c33f56e730d210abaa0ad483e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:21:03 +0000 Subject: [PATCH 126/148] Don't track yard generated files. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f9c51ff..71fbc63 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ vendor/ vendor.noindex/ coverage/ Gemfile.lock +doc/ +.yardoc/ From 7e94b72b68f4dbc8e92a5931c148dbb9b5a30f8e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:39:53 +0000 Subject: [PATCH 127/148] Pass on the error_handler. --- lib/sinatra/export.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 8d5fb4f..64df47b 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -23,12 +23,12 @@ module ClassMethods # builder.paths << "/echo-1" # end # end - def export! paths: nil, skips: [], filters: [], &block + def export! paths: nil, skips: [], filters: [], use_routes: nil, error_handler: nil, &block @builder ||= if self.builder self.builder else - Builder.new(self,paths: paths, skips: skips, filters: filters, use_routes: use_routes ) + Builder.new(self,paths: paths, skips: skips, filters: filters, use_routes: use_routes, error_handler: error_handler ) end @builder.build! &block end From 640aec23719a1a1e5aa5c4f6392467205b73f5ed Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:53:04 +0000 Subject: [PATCH 128/148] A bit of formatting, a lot more yard docs, and fixed the attributes to the right modes. --- lib/sinatra/export.rb | 86 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 64df47b..c2e9b68 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -17,26 +17,62 @@ def self.registered(app) end module ClassMethods + # @example - # app.export paths: "/" do |builder| + # # The default: Will use the paths from Sinatra Namespace + # app.export! + # + # # Skip a path + # app.export! skips: ["/admin"] + # + # # Only visit the homepage and the site map + # app.export! paths: ["/", "/site-map"] + # + # # Visit the 404 error page by supplying the expected + # # status code (so as not to trigger an error) + # app.export! paths: ["/", ["/404.html",404]] + # + # # Filter out mentions of localhost:4567 + # filter = ->(content){ content.gsub("localhost:4567, "example.org") } + # app.export! filters: [filter] + # + # # Use routes found by Sinatra AdvancedRoutes *and* + # # ones supplied via `paths` + # app.export! paths: ["/crazy/deep/page/path"], use_routes: true + # + # # Supply a path and scan the output for an internal link + # # adding it to the list of paths to be visited + # app.export! paths: "/" do |builder| # if builder.last_response.body.include? "/echo-1" # builder.paths << "/echo-1" # end # end + # + # @param [Array,Array] paths Paths that will be requested by the exporter. + # @param [Array] skips: Paths that will be ignored by the exporter. + # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. + # @param [Array<#call>] filters Filters will be applied to every file as it is written in the order given. + # @param [#call] error_handler Define your own error handling. Takes one argument, a description of the error. + # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. + # @note By default the output files with be written to the public folder. Set the EXPORT_BUILD_DIR env var to choose a different location. def export! paths: nil, skips: [], filters: [], use_routes: nil, error_handler: nil, &block @builder ||= if self.builder self.builder else - Builder.new(self,paths: paths, skips: skips, filters: filters, use_routes: use_routes, error_handler: error_handler ) + Builder.new(self, paths: paths, skips: skips, filters: filters, use_routes: use_routes, error_handler: error_handler ) end @builder.build! &block end end + + # Visits the paths and builds pages from the output class Builder include Rack::Test::Methods + # Default error handler + # @yieldparam [String] desc Description of the error. DEFAULT_ERROR_HANDLER = ->(desc) { puts ColorString.new("failed: #{desc}").red; } @@ -47,9 +83,8 @@ class ColorString < String # @param [Sinatra::Base] app The Sinatra app - # @param [Array,Array] paths Paths that will be requested by the builder. - # @param [Array] skips: Paths that will be ignored by the builder. - # @param [TrueClass] use_routes Whether to use Sinatra AdvancedRoutes to look for paths to send to the builder. + # @param (see ClassMethods#export!) + # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [], error_handler: nil ) @app = app @use_routes = @@ -62,16 +97,48 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [], error_ @filters = filters @visited = [] @errored = [] - @error_handler = DEFAULT_ERROR_HANDLER + @error_handler = error_handler || DEFAULT_ERROR_HANDLER end - attr_accessor :paths, :skips, :last_response, :last_path, :visited, :errored, :error_handler + # @!attribute [r] last_response + # @return [Rack::Response] The last page requested's response + attr_reader :last_response + + # @!attribute [r] last_path + # @return [String] The last path requested + attr_reader :last_path + + # @!attribute [r] visited + # @return [Array] List of paths visited by the builder + attr_reader :visited + + # @!attribute [r] errored + # @return [Array] List of paths visited by the builder that called the error handler + attr_reader :errored + + # @!attribute [w] error_handler + # Error handler (see ClassMethods#export!) + # @return [nil] + attr_writer :error_handler + + # @!attribute paths + # Paths to visit (see ClassMethods#export!) + # @return [Array] + attr_accessor :paths + + # @!attribute skips + # Paths to be skipped (see ClassMethods#export!) + # @return [Array] + attr_accessor :skips + def app @app end + # Processes the routes and builds the output files. + # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. def build!( &block ) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? @@ -111,6 +178,7 @@ def build!( &block ) private + # a convenience wrapper for throwing status errors def status_error desc throw :status_error, desc end @@ -190,10 +258,6 @@ def handle_error_incorrect_status!(path,expected:,actual:) @error_handler.call(desc) status_error desc end - -# def handle_error!(desc) -# puts ColorString.new("failed: #{desc}").red; exit! -# end end end From ee766482a092e366a6eb8a2f46a5add267d45b14 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:56:27 +0000 Subject: [PATCH 129/148] More yardoc. --- lib/sinatra/export.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index c2e9b68..9dbd96e 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -139,6 +139,7 @@ def app # Processes the routes and builds the output files. # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. + # @return [self] def build!( &block ) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? From 1d737aa6a5a77d2fd95afae5eb7d4e6146929bb3 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 04:58:56 +0000 Subject: [PATCH 130/148] And more yardoc. --- lib/sinatra/export.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 9dbd96e..e0a633a 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -197,6 +197,9 @@ def route_path_usable? path end + # Wrapper around Sinatra::AdvancedRoutes#each_route + # to filter what comes through. + # @return [Array] def route_paths route_paths = [] app.each_route do |route| From bf6d0eaf5bc6f2d2ee8315e1828a6c8a6ba24e5a Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Mon, 14 Dec 2015 05:15:09 +0000 Subject: [PATCH 131/148] Reached my limit for yardocking. --- lib/sinatra/export.rb | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index e0a633a..e3a96b4 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -5,8 +5,11 @@ require 'pathname' module Sinatra + + # Export a Sinatra app to static files! module Export + # required for all Sinatra Extensions, see http://www.sinatrarb.com/extensions.html def self.registered(app) if app.extensions.nil? or !app.extensions.include?(Sinatra::AdvancedRoutes) app.register Sinatra::AdvancedRoutes @@ -16,13 +19,15 @@ def self.registered(app) app.set :builder, nil end + # These will get extended onto the Sinatra app module ClassMethods + # The entry method. Run this to export the app to files. # @example # # The default: Will use the paths from Sinatra Namespace # app.export! # - # # Skip a path + # # Skip a path (or paths) # app.export! skips: ["/admin"] # # # Only visit the homepage and the site map @@ -101,7 +106,7 @@ def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [], error_ end # @!attribute [r] last_response - # @return [Rack::Response] The last page requested's response + # @return [Rack::MockResponse] The last page requested's response attr_reader :last_response # @!attribute [r] last_path @@ -211,6 +216,11 @@ def route_paths end + # Builds the output dirs and file + # based on the response. + # @param [String] path + # @param [Pathname,String] dir + # @param [Rack::MockResponse] response # @return [String] file_path def build_path(path:, dir:, response:) body = response.body @@ -233,6 +243,10 @@ def build_path(path:, dir:, response:) end + # Write the response to file. + # Uses whatever filters were set, on the content. + # @param [String] content + # @param [Pathname,String] path def write_path content:, path: if @filters && !@filters.empty? content = @filters.inject(content) do |current_content,filter| @@ -245,6 +259,10 @@ def write_path content:, path: end + # Wrapper around Rack::Test's `get` + # @param [String] path + # @param [Integer] status The expected response status code. Anything different and the error handler is called. Defaults to 200. + # @return [Rack::MockResponse] def get_path path, status=nil status ||= 200 get(path).tap do |resp| @@ -257,6 +275,11 @@ def handle_error_dir_not_found!(dir) @error_handler.call("can't find output directory: #{dir.to_s}") end + + # Handles the error caused by a mismatch in status code expectations. + # @param [String] path The route path. + # @param [#to_s] expected The status code that was expected. + # @param [#to_s] actual The actual status code received. def handle_error_incorrect_status!(path,expected:,actual:) desc = "GET #{path} returned #{actual} status code instead of #{expected}" @error_handler.call(desc) From 741d4cae4260752e699c682f8d7c90a3fae39e42 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 10:40:15 +0000 Subject: [PATCH 132/148] Removed unit tests; made RSpec the default Rake task. --- Rakefile | 9 ++++----- test/app/.gitkeep | 0 test/build_test.rb | 43 ------------------------------------------- test/test_helper.rb | 44 -------------------------------------------- 4 files changed, 4 insertions(+), 92 deletions(-) delete mode 100644 test/app/.gitkeep delete mode 100644 test/build_test.rb delete mode 100644 test/test_helper.rb diff --git a/Rakefile b/Rakefile index cc3744c..9e961e3 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,5 @@ -desc "Runs tests" -task :test do - Dir['test/*_test.rb'].each { |f| load f } -end +require 'rspec/core/rake_task' -task :default => :test \ No newline at end of file +RSpec::Core::RakeTask.new(:spec) + +task :default => :spec \ No newline at end of file diff --git a/test/app/.gitkeep b/test/app/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/build_test.rb b/test/build_test.rb deleted file mode 100644 index 7b2a7f5..0000000 --- a/test/build_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require File.expand_path('../test_helper', __FILE__) -require 'sinatra/export' - -class SinatraExportBuildTest < UnitTest - - class App < UnitTest::App - register Sinatra::Export - - get '/' do - "homepage" - end - - get '/contact' do - "contact" - end - - get '/data.json' do - "{test: 'ok'}" - end - - get '/yesterday' do - last_modified Time.local(2002, 10, 31) - "old content" - end - - end - - def test_build - # Temporary public folder - public_folder = App.public_folder - FileUtils.rm_rf public_folder - FileUtils.mkdir public_folder - - App.export! - - assert File.read(File.join(public_folder, 'index.html')).include?('homepage') - assert File.read(File.join(public_folder, 'contact/index.html')).include?('contact') - assert File.read(File.join(public_folder, 'data.json')).include?("{test: 'ok'}") - - assert File.mtime(File.join(public_folder, 'yesterday/index.html')) == Time.local(2002, 10, 31) - end - -end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index cd5201f..0000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'rack/test' -require 'test/unit' -require 'sinatra/base' - -# Helper based on sinatra-assetpack test helper -# © 2011, Rico Sta. Cruz. Released under the MIT License -# @link http://www.opensource.org/licenses/mit-license.php -# @link https://github.com/rstacruz/sinatra-assetpack - -class UnitTest < Test::Unit::TestCase - include Rack::Test::Methods - - class App < Sinatra::Base - set :root, File.expand_path('../app', __FILE__) - enable :raise_errors - disable :show_exceptions - end - - def setup - Sinatra::Base.set :environment, :test - end - - def d - puts "-"*80 - puts "#{last_response.status}" - y last_response.original_headers - puts "-"*80 - puts "" - puts last_response.body.gsub(/^/m, ' ') - puts "" - end - - def body - last_response.body.strip - end - - def r(*a) - File.join app.root, *a - end - - def assert_includes(haystack, needle) - assert haystack.include?(needle), "Expected #{haystack.inspect} to include #{needle.inspect}." - end -end \ No newline at end of file From 7ad0da7c771f5c87cf29ee78321adc27519985dd Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 10:41:28 +0000 Subject: [PATCH 133/148] Formatting, one line ternary preferred. --- lib/sinatra/export.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index e3a96b4..1136e58 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -92,10 +92,7 @@ class ColorString < String # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. def initialize(app, paths: nil, skips: nil, use_routes: nil, filters: [], error_handler: nil ) @app = app - @use_routes = - paths.nil? && use_routes.nil? ? - true : - use_routes + @use_routes = paths.nil? && use_routes.nil? ? true : use_routes @paths = paths || [] @skips = skips || [] @enums = [] From c818807b8a79d0ccd28b1538ebe6c82ad3fb9d4f Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 10:42:20 +0000 Subject: [PATCH 134/148] Use a do block, nothing will be returned with that throw/catch. --- lib/sinatra/export.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 1136e58..8b59a72 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -151,7 +151,7 @@ def build!( &block ) end @enums.push @paths.to_enum - catch(:no_more_paths) { + catch(:no_more_paths) do enum = @enums.shift while true begin @@ -175,7 +175,7 @@ def build!( &block ) throw(:no_more_paths) end end - } + end self end From 442613175037dab6363d8360c5d6653ef9e76349 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 10:44:04 +0000 Subject: [PATCH 135/148] Formatting, added parens and removed spaces to method definitions and calls. --- lib/sinatra/export.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 8b59a72..8242a37 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -142,12 +142,12 @@ def app # Processes the routes and builds the output files. # @yield [builder] Gives a Builder instance to the block (see Builder) that is called for every path visited. # @return [self] - def build!( &block ) + def build!(&block) dir = Pathname( ENV["EXPORT_BUILD_DIR"] || app.public_folder ) handle_error_dir_not_found!(dir) unless dir.exist? && dir.directory? if @use_routes - @enums.push self.send( :route_paths ).to_enum + @enums.push self.send(:route_paths).to_enum end @enums.push @paths.to_enum @@ -260,7 +260,7 @@ def write_path content:, path: # @param [String] path # @param [Integer] status The expected response status code. Anything different and the error handler is called. Defaults to 200. # @return [Rack::MockResponse] - def get_path path, status=nil + def get_path(path, status=nil) status ||= 200 get(path).tap do |resp| handle_error_incorrect_status!(path,expected: status, actual: resp.status) unless resp.status == status From ef7eb48318d157d3b41eb6a1cbc90a5bf50a150a Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 10:53:30 +0000 Subject: [PATCH 136/148] Updated Travis settings, no more 1.8 or 1.9. --- .travis.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9f0774..f3eed33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,15 @@ language: ruby bundler_args: "--without development" rvm: - - 1.8.7 - - 1.9.2 - - 1.9.3 - - 2.0.0 - - rbx-18mode - - rbx-19mode - - jruby-18mode - - jruby-19mode + - 2.2.3 +# see note about issue at https://docs.travis-ci.com/user/languages/ruby/#Choosing-Ruby-versions-and-implementations-to-test-against + - rbx-2 +# - jruby-19mode - jruby-head - ruby-head matrix: allow_failures: - - rvm: rbx-18mode - - rvm: rbx-19mode + - rvm: rbx-2 +# - jruby-19mode - rvm: jruby-head - - rvm: ruby-head - - rvm: 2.0.0 \ No newline at end of file + - rvm: ruby-head \ No newline at end of file From 082f25fdec4dbafe0d011b6666cb63ff3d7fb9b2 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 11:03:51 +0000 Subject: [PATCH 137/148] Updated Rake so old 'rake test' will still run the same. --- Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 9e961e3..dbfc575 100644 --- a/Rakefile +++ b/Rakefile @@ -2,4 +2,5 @@ require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :spec \ No newline at end of file +task :default => :spec +task :test => :spec \ No newline at end of file From c410d0611ef3dabef3fd4360ce92bf10cce78015 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 11:56:36 +0000 Subject: [PATCH 138/148] Updated README with examples. [skip ci] --- README.md | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/README.md b/README.md index 9732aa9..0759333 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,131 @@ Or invoke it manually within ruby code : Sinatra::Application.export! ``` +## Advanced usage ## + +### Supplied paths ### + +If you wish to specify specific paths to be visited (only): + +````ruby +Sinatra::Application.export! paths: ["/", "/contact"] +``` + +Only the homepage and the contact page would be visited (these would be visited anyway, but lets start off simple!) If you wanted the paths you specify *and* any paths that Sinatra::AdvancedRoutes can find then you could use: + +````ruby +Sinatra::Application.export! paths: ["/", "/contact"], use_routes: true +``` + +Now all the routes listed above would be found. But what if you have some routes with wildcards or named captures? + +````ruby +get '/articles/:slug' do + # an article is retrieved via params["slug"] + # but we'll stub one in for this example: + markdown("# I have wonderful news! #\n\nYou can use wildcard routes now.\n") +end +``` + +You could access that route as well via: + +````ruby +Sinatra::Application.export! paths: ["/articles/i-have-wonderful-news"], use_routes: true +``` + +### Supplying statuses ### + +Perhaps you would like a static 404 page. + +````ruby +not_found do + halt 404, haml(:not_found) +end +``` + +By default, Sinatra Export will only use routes that return an HTTP status code of 200. If you want non 200 pages then supply the path with the expected status in an array, for example: + +````ruby +Sinatra::Application.export! paths: ["/articles/i-have-wonderful-news",["/404.html",400]], use_routes: true +``` + +Among the static files output you will find 404.html. + +### Skipping pages ### + +If you want to ignore certain pages no matter what, supply them via the `skip` keyword in a list: + +````ruby +Sinatra::Application.export! skips: ["/contact","/data.json"] +``` + +Only the "/" route will be output. This will work with supplied paths or routes found via `use_routes`. + +### Non standard directory for output ### + +By default, Sinatra Export will place the generated static files into the Sinatra app's public folder. If you want to put them somewhere else then you can use the `EXPORT_BUILD_DIR` environment variable. For example: + +````ruby +ENV["EXPORT_BUILD_DIR"] = File.join ENV["HOME"], "projects/static" +Sinatra::Application.export! +``` + +The files would be in "~/projects/static" + +## Super advanced usage ## + +### Error handling ### + +By default, Sinatra Export will skip routes that are non 200 status unless you supply the expected status for a page. When it hits an unexpected status it will output an error in red text to the terminal and continue processing. If you want to change this, you can supply your own error handler. For example, to stop processing when you hit an unexpected status code: + +````ruby +Sinatra::Application.export! paths: ["/this-path-doesnt-exist"], error_handler: ->(desc){ fail "Didn't expect that! #{desc}" } +``` + +All that's needed is something that responds to `call` - so a proc, block or lambda - that takes 1 argument, a description string of the error. + +### Supplying a process block ### + +`export!` can take a block that will be run for every page that is processed. Inside the block, and instance of the `Builder` class (the one that does all the work, see the API docs for more) will be accessible. For example, let's add a path during the processing: + +````ruby +get '/this-route-has-an-internal-link' do + "Follow this link!" +end +``` + +Now to find that link: + +````ruby +require 'hpricot' # nokogiri is available too +Sinatra::Application.export! do |builder| + doc = Hpricot(builder.last_response.body) + (doc/"a").map{|elem| URI( elem.attributes["href"] ) } + .map(&:path).each do |path| + builder.paths.push path unless builder.paths.include? path + end +end +``` + +You'd probably want to check the links weren't external too. + +**Note!** If you know something about arrays and some of the set like methods available then you'll think that the last block given to each could've been made shorter by using `|=` instead of `push` with `unless`. Be warned that under the hood the Builder is using an Enumerator to check each of the `paths`, and by using `|=` the paths will somehow become disassociated with the enumerator and your work will be in vain! + +There's other stuff you could do in that block, the builder gives you access to `paths`, `skips` (both read/write); `visited` (a list of the paths visited so far), `errored` (a list of the paths that have called the error handler), the `last_path` (which inside the block will be the current path) and the `last_response`, so you can access things like the `last_response.status` and `last_response.body`. + +### Filtering ### + +If you want to apply a filter to every path that is written then you can supply those via the `filters` keyword: + +````ruby +require 'hpricot' # nokogiri is available too +Sinatra::Application.export! filters: [->(text){ text.upcase }] +``` + +That would upcase everything. If you wanted you could do things like remove mentions of "localhost" or whatever. + +`filter` takes an array, each item should respond to `call` and take 1 argument, the text to be filtered. Each filter will be applied in the order of the array. + ## Other resources * [capistrano-s3](http://github.com/hooktstudios/capistrano-s3) : build and deploy a static website to Amazon S3 From d2d9808f2a0300a0b008b098c7df7e83531387cc Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:04:11 +0000 Subject: [PATCH 139/148] Added yard generation task to Rakefile. [skip ci] --- Rakefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index dbfc575..8164cd4 100644 --- a/Rakefile +++ b/Rakefile @@ -3,4 +3,12 @@ require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :default => :spec -task :test => :spec \ No newline at end of file +task :test => :spec + +require 'yard' + +YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb'] # optional + t.options = ['--any', '--extra', '--opts'] # optional + t.stats_options = ['--list-undoc'] # optional +end \ No newline at end of file From db3be482874886e9ed92bec41af70a8eb4d9077b Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:05:20 +0000 Subject: [PATCH 140/148] Updated README with yard gen instructions. [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0759333..39f7bec 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ All that's needed is something that responds to `call` - so a proc, block or lam ### Supplying a process block ### -`export!` can take a block that will be run for every page that is processed. Inside the block, and instance of the `Builder` class (the one that does all the work, see the API docs for more) will be accessible. For example, let's add a path during the processing: +`export!` can take a block that will be run for every page that is processed. Inside the block, and instance of the `Builder` class (the one that does all the work, see the API docs via `rake yard` for more) will be accessible. For example, let's add a path during the processing: ````ruby get '/this-route-has-an-internal-link' do From f2ba27e549cae929f9081080392b3610d13b44b2 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:35:55 +0000 Subject: [PATCH 141/148] Expanded on filtering example. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 39f7bec..0943c9e 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,11 @@ Sinatra::Application.export! filters: [->(text){ text.upcase }] That would upcase everything. If you wanted you could do things like remove mentions of "localhost" or whatever. +````ruby +require 'hpricot' # nokogiri is available too +Sinatra::Application.export! filters: [->(text){ text.gsub("localhost", "example.org" }, ->(text){ text.gsub("http://", "https://" }] +``` + `filter` takes an array, each item should respond to `call` and take 1 argument, the text to be filtered. Each filter will be applied in the order of the array. ## Other resources From c7313a2bdc2703a1b514678021838f09ad09229e Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:36:48 +0000 Subject: [PATCH 142/148] Moved block prior to build_path so that the block can do further work before the files are written. Added example to README. --- README.md | 12 +++++ lib/sinatra/export.rb | 3 +- spec/export_spec.rb | 116 ++++++++++++++++++++++++++++-------------- 3 files changed, 92 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 0943c9e..a3c5364 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,18 @@ You'd probably want to check the links weren't external too. There's other stuff you could do in that block, the builder gives you access to `paths`, `skips` (both read/write); `visited` (a list of the paths visited so far), `errored` (a list of the paths that have called the error handler), the `last_path` (which inside the block will be the current path) and the `last_response`, so you can access things like the `last_response.status` and `last_response.body`. +Another example, filtering while processing: + +````ruby +Sinatra::Application.export! do |builder| + # set it using an array because Rack::Response#body is actually + # an array that is joined to output a string + builder.last_response.body = [builder.last_response.body.upcase!] +end +``` + +Now all the output would be upcased. There is more on filtering below, but as you can see, you can process things on the fly. + ### Filtering ### If you want to apply a filter to every path that is written then you can supply those via the `filters` keyword: diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 8242a37..15df7bf 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -164,8 +164,9 @@ def build!(&block) @last_path = @last_path.chop if @last_path.end_with? "?" desc = catch(:status_error) { @last_response = get_path(@last_path, status) - file_path = build_path(path: @last_path, dir: dir, response: last_response) block.call self if block + file_path = build_path(path: @last_path, dir: dir, response: last_response) + nil } desc ? @errored |= [@last_path] : diff --git a/spec/export_spec.rb b/spec/export_spec.rb index 76b242c..0c7184a 100644 --- a/spec/export_spec.rb +++ b/spec/export_spec.rb @@ -205,50 +205,90 @@ def app end context "Using a block" do - before :all do - FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") - app.export! do |builder| - if builder.last_response.body.include? "/echo-1" - builder.paths << "/echo-1" + context "To add a path" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! do |builder| + if builder.last_response.body.include? "/echo-1" + builder.paths << "/echo-1" + end end end - end - after :all do - FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) - end + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end - context "index" do - subject { - File.join(app.public_folder, 'index.html') - } - it { File.read(subject).should include 'homepage' } - end - context "contact" do - subject { - File.join(app.public_folder, 'contact/index.html') - } - it { File.read(subject).should include 'contact' } - end - context "data.json" do - subject { - File.join(app.public_folder, 'data.json') - } - it { File.read(subject).should include "{test: 'ok'}" } - end - context "yesterday" do - subject { - File.new File.join(app.public_folder, 'yesterday/index.html') - } - it { subject.read.should include 'old content' } - its(:mtime) { should == Time.local(2002, 10, 31) } + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'homepage' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'contact' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{test: 'ok'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'old content' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end + + context "named parameters" do + subject { + File.join(app.public_folder, 'echo-1/index.html') + } + it { File.read(subject).should include '1' } + end end - context "named parameters" do - subject { - File.join(app.public_folder, 'echo-1/index.html') - } - it { File.read(subject).should include '1' } + context "To filter output" do + before :all do + FileUtils.mkdir_p File.join(__dir__, "support/fixtures", "app/public") + app.export! do |builder| + builder.last_response.body = [builder.last_response.body.upcase!] + end + end + + after :all do + FileUtils.rm_rf File.join(__dir__, "support/fixtures", "app" ) + end + context "index" do + subject { + File.join(app.public_folder, 'index.html') + } + it { File.read(subject).should include 'HOMEPAGE' } + end + context "contact" do + subject { + File.join(app.public_folder, 'contact/index.html') + } + it { File.read(subject).should include 'CONTACT' } + end + context "data.json" do + subject { + File.join(app.public_folder, 'data.json') + } + it { File.read(subject).should include "{TEST: 'OK'}" } + end + context "yesterday" do + subject { + File.new File.join(app.public_folder, 'yesterday/index.html') + } + it { subject.read.should include 'OLD CONTENT' } + its(:mtime) { should == Time.local(2002, 10, 31) } + end end end From c1fb3ba69e054dda4ad04624e89521b90e5b0d5d Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:44:43 +0000 Subject: [PATCH 143/148] Added missing Ruby versions 2.0.0 and 2.1.0. to Travis config. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f3eed33..9fa3b5e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: ruby bundler_args: "--without development" rvm: + - 2.0.0 + - 2.1.0 - 2.2.3 # see note about issue at https://docs.travis-ci.com/user/languages/ruby/#Choosing-Ruby-versions-and-implementations-to-test-against - rbx-2 From fd4f6892033c00445b583a01adcc6ae3a8a247c2 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Tue, 15 Dec 2015 12:49:36 +0000 Subject: [PATCH 144/148] Added yard to the gemspec or else Travis borks. --- sinatra-export.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/sinatra-export.gemspec b/sinatra-export.gemspec index d2cb83a..dbcb036 100644 --- a/sinatra-export.gemspec +++ b/sinatra-export.gemspec @@ -32,5 +32,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'rack' s.add_runtime_dependency 'rake' s.add_runtime_dependency 'rack-test' + s.add_development_dependency 'rack-test' end From f1ca39a8adf51a5584f83ef6580a87f7ccc04570 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 16 Dec 2015 01:34:20 +0000 Subject: [PATCH 145/148] Suggested changes to make Travis happier. --- .travis.yml | 4 ++-- Gemfile | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9fa3b5e..31944b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: ruby bundler_args: "--without development" rvm: - - 2.0.0 - - 2.1.0 + - 2.0.0-p647 + - 2.1.7 - 2.2.3 # see note about issue at https://docs.travis-ci.com/user/languages/ruby/#Choosing-Ruby-versions-and-implementations-to-test-against - rbx-2 diff --git a/Gemfile b/Gemfile index fc269bb..8f0b386 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,10 @@ group :development do gem "term-ansicolor" gem "pry-byebug" gem "pry-stack_explorer" - gem "yard" +end + +group :development, :test do + gem 'yard' end group :test do From d519d0edc427f230800c2aae5d7006c55cf2dedc Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 16 Dec 2015 01:45:17 +0000 Subject: [PATCH 146/148] Make yard optional in the Rakefile to make Travis happy. --- Rakefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Rakefile b/Rakefile index 8164cd4..988d86a 100644 --- a/Rakefile +++ b/Rakefile @@ -5,10 +5,12 @@ RSpec::Core::RakeTask.new(:spec) task :default => :spec task :test => :spec -require 'yard' - -YARD::Rake::YardocTask.new do |t| - t.files = ['lib/**/*.rb'] # optional - t.options = ['--any', '--extra', '--opts'] # optional - t.stats_options = ['--list-undoc'] # optional +begin + require 'yard' + YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb'] # optional + t.options = ['--any', '--extra', '--opts'] # optional + t.stats_options = ['--list-undoc'] # optional + end +rescue LoadError end \ No newline at end of file From 8fc30b6941d1923c71b76115574fcc9ffd23c26d Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 16 Dec 2015 01:59:59 +0000 Subject: [PATCH 147/148] Added required argument checks for Ruby v2.0. --- lib/sinatra/export.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 15df7bf..85cebcf 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -220,7 +220,13 @@ def route_paths # @param [Pathname,String] dir # @param [Rack::MockResponse] response # @return [String] file_path - def build_path(path:, dir:, response:) + def build_path(path: nil, dir: nil, response: nil) + # These argument checks are for Ruby v2.0 as it + # doesn't support required keyword args. + fail ArgumentError, "'path' is a required argument to build_path" if path.nil? + fail ArgumentError, "'dir' is a required argument to build_path" if dir.nil? + fail ArgumentError, "'response' is a required argument to build_path" if response.nil? + body = response.body mtime = response.headers.key?("Last-Modified") ? Time.httpdate(response.headers["Last-Modified"]) : Time.now From 90e253c17d43910422ebde51a05029fedcd5a2b4 Mon Sep 17 00:00:00 2001 From: Iain Barnett Date: Wed, 16 Dec 2015 02:05:07 +0000 Subject: [PATCH 148/148] More argument checks. --- lib/sinatra/export.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/sinatra/export.rb b/lib/sinatra/export.rb index 85cebcf..dd69d47 100644 --- a/lib/sinatra/export.rb +++ b/lib/sinatra/export.rb @@ -251,7 +251,12 @@ def build_path(path: nil, dir: nil, response: nil) # Uses whatever filters were set, on the content. # @param [String] content # @param [Pathname,String] path - def write_path content:, path: + def write_path( content: nil, path: nil ) + # These argument checks are for Ruby v2.0 as it + # doesn't support required keyword args. + fail ArgumentError, "'content' is a required argument to write_path" if content.nil? + fail ArgumentError, "'path' is a required argument to write_path" if path.nil? + if @filters && !@filters.empty? content = @filters.inject(content) do |current_content,filter| filter.call current_content @@ -284,7 +289,12 @@ def handle_error_dir_not_found!(dir) # @param [String] path The route path. # @param [#to_s] expected The status code that was expected. # @param [#to_s] actual The actual status code received. - def handle_error_incorrect_status!(path,expected:,actual:) + def handle_error_incorrect_status!(path, expected: nil,actual: nil) + # These argument checks are for Ruby v2.0 as it + # doesn't support required keyword args. + fail ArgumentError, "'expected' is a required argument to handle_error_incorrect_status!" if expected.nil? + fail ArgumentError, "'actual' is a required argument to handle_error_incorrect_status!" if actual.nil? + desc = "GET #{path} returned #{actual} status code instead of #{expected}" @error_handler.call(desc) status_error desc