blossom 0.0.12 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/blossom +141 -44
- data/lib/blossom.rb +266 -92
- data/lib/blossom/version.rb +3 -0
- metadata +24 -39
    
        data/bin/blossom
    CHANGED
    
    | @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 3 | 
            +
            BLOSSOM_HOME = File.join(File.dirname(__FILE__), "..")
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require "fileutils"
         | 
| 6 | 
            +
            require "#{BLOSSOM_HOME}/lib/blossom"
         | 
| 5 7 |  | 
| 6 8 | 
             
            include FileUtils
         | 
| 7 9 |  | 
| @@ -9,83 +11,178 @@ def make_file(name, content) | |
| 9 11 | 
             
              File.open(name, "w") { |file| file.write(content) }
         | 
| 10 12 | 
             
            end
         | 
| 11 13 |  | 
| 12 | 
            -
            def  | 
| 13 | 
            -
               | 
| 14 | 
            +
            def copy_file(name, destination)
         | 
| 15 | 
            +
              FileUtils.cp "#{BLOSSOM_HOME}/#{name}", "#{destination}/#{name}"
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            def usage
         | 
| 19 | 
            +
              "Usage: #$0 PROJECT-NAME"
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            def die(message)
         | 
| 23 | 
            +
              error message
         | 
| 24 | 
            +
              exit 1
         | 
| 25 | 
            +
            end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            def error(message)
         | 
| 28 | 
            +
              warn "Blossom: Error: #{message}"
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            def run(command)
         | 
| 32 | 
            +
              puts "$ #{command}"
         | 
| 33 | 
            +
              system command or die "Command failed: #{command}"
         | 
| 14 34 | 
             
            end
         | 
| 15 35 |  | 
| 16 36 | 
             
            if ARGV.empty?
         | 
| 17 | 
            -
               | 
| 37 | 
            +
              puts usage
         | 
| 18 38 | 
             
            elsif ARGV[0].start_with? "-"
         | 
| 19 39 | 
             
              case ARGV[0]
         | 
| 20 40 | 
             
              when "--version", "-v"
         | 
| 21 41 | 
             
                puts Blossom::VERSION
         | 
| 22 42 | 
             
              when "--help", "-h", "-?"
         | 
| 23 | 
            -
                 | 
| 43 | 
            +
                puts usage
         | 
| 24 44 | 
             
              else
         | 
| 25 | 
            -
                 | 
| 45 | 
            +
                error "Unrecognized option: #{ARGV[0]}"
         | 
| 46 | 
            +
                warn usage
         | 
| 47 | 
            +
                exit 1
         | 
| 26 48 | 
             
              end
         | 
| 27 49 | 
             
            else
         | 
| 28 50 | 
             
              name = ARGV.first
         | 
| 29 51 | 
             
              name_symbol = name =~ /\W|^\d/ ? ":'#{name}'" : ":#{name}"
         | 
| 30 | 
            -
               | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 52 | 
            +
              name_pretty = name.capitalize.gsub(/[-_]/, " ")
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              if File.exist? name
         | 
| 55 | 
            +
                die "File already exists: #{name}"
         | 
| 56 | 
            +
              else
         | 
| 57 | 
            +
                puts "Blossom creating project: #{name}"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                puts "$ mkdir #{name}; cd #{name}"
         | 
| 60 | 
            +
                mkdir name; cd name
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                puts "Installing Blossom boilerplate."
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                make_file "#{name}.blossom", <<"^D"
         | 
| 65 | 
            +
            ## This is the Blossom configuration file.
         | 
| 66 | 
            +
            ##
         | 
| 67 | 
            +
            ## All settings are listed here with their default values.
         | 
| 68 | 
            +
            ## To change a setting, you have to uncomment the line first.
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            ## The directory in which to put arbitrary public files:
         | 
| 71 | 
            +
            # Public-Directory: public
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            ## Files with these extensions are always public:
         | 
| 74 | 
            +
            # Public-Extensions: js css html png jpg
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            ## The maximum amount of time browsers may cache the site:
         | 
| 77 | 
            +
            # Max-Cache-Time: 1 day
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            ## Whether or not to remove the "www." part of the domain:
         | 
| 80 | 
            +
            # Remove-WWW-From-Domain: yes
         | 
| 81 | 
            +
            ^D
         | 
| 33 82 |  | 
| 34 83 | 
             
                make_file ".gitignore", "tmp\n"
         | 
| 35 84 |  | 
| 36 | 
            -
                make_file "config.ru",  | 
| 85 | 
            +
                make_file "config.ru", <<"^D"
         | 
| 37 86 | 
             
            require "rubygems"
         | 
| 38 87 | 
             
            require "bundler/setup"
         | 
| 39 88 | 
             
            require "blossom"
         | 
| 40 89 |  | 
| 41 | 
            -
            run Blossom | 
| 42 | 
            -
             | 
| 90 | 
            +
            run Blossom __FILE__
         | 
| 91 | 
            +
            ^D
         | 
| 43 92 |  | 
| 44 | 
            -
                make_file "Gemfile",  | 
| 93 | 
            +
                make_file "Gemfile", <<"^D"
         | 
| 45 94 | 
             
            source :rubygems
         | 
| 46 95 |  | 
| 47 | 
            -
            gem  | 
| 48 | 
            -
             | 
| 96 | 
            +
            gem "blossom", "~> #{Blossom::VERSION}"
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            # Uncomment the following if you want to use CoffeeScript.
         | 
| 99 | 
            +
            # (See further instructions in #{name}.js.)
         | 
| 100 | 
            +
            #
         | 
| 101 | 
            +
            # gem "rack-coffee"
         | 
| 102 | 
            +
            ^D
         | 
| 49 103 |  | 
| 50 | 
            -
                 | 
| 104 | 
            +
                mkdir "public"
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                make_file "#{name}.haml", <<"^D"
         | 
| 51 107 | 
             
            !!!
         | 
| 52 108 | 
             
            %html
         | 
| 53 109 | 
             
              %head
         | 
| 54 110 | 
             
                %meta(charset="utf-8")
         | 
| 55 | 
            -
                %title  | 
| 56 | 
            -
                %meta(name="description" content=" | 
| 111 | 
            +
                %title [insert title here]
         | 
| 112 | 
            +
                %meta(name="description" content="[insert description here]")
         | 
| 57 113 | 
             
                %link(rel="stylesheet" href="#{name}.css")
         | 
| 114 | 
            +
                %script(src="#{name}.js")
         | 
| 115 | 
            +
                /[if lt IE 9]
         | 
| 116 | 
            +
                  %script(src="//html5shiv.googlecode.com/svn/trunk/html5.js")
         | 
| 58 117 | 
             
              %body
         | 
| 59 | 
            -
                %h1  | 
| 60 | 
            -
             | 
| 118 | 
            +
                %h1 #{name}.haml
         | 
| 119 | 
            +
            ^D
         | 
| 61 120 |  | 
| 62 | 
            -
                make_file "#{name}.sass",  | 
| 121 | 
            +
                make_file "#{name}.sass", <<"^D"
         | 
| 63 122 | 
             
            @import compass/reset
         | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
              width: 600px
         | 
| 67 | 
            -
              margin: auto
         | 
| 123 | 
            +
            @import compass/utilities
         | 
| 124 | 
            +
            @import compass/css3
         | 
| 68 125 |  | 
| 69 126 | 
             
            h1
         | 
| 70 | 
            -
              font:  | 
| 71 | 
            -
              margin-top:  | 
| 72 | 
            -
             | 
| 127 | 
            +
              font: 48px monospace
         | 
| 128 | 
            +
              margin-top: 1em
         | 
| 129 | 
            +
              text-align: center
         | 
| 130 | 
            +
            ^D
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                make_file "#{name}.sinatra.rb", <<"^D"
         | 
| 133 | 
            +
            # Put any custom Sinatra routes or configuration here.
         | 
| 134 | 
            +
            # See <http://www.sinatrarb.com/documentation> for help.
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            # This is also where you insert middleware (just remember to add
         | 
| 137 | 
            +
            # any new dependencies to your Gemfile and to run \`bundle\'):
         | 
| 138 | 
            +
            #
         | 
| 139 | 
            +
            # require "some/middleware"
         | 
| 140 | 
            +
            # use Some::Middleware
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            # get "/hello" do
         | 
| 143 | 
            +
            #   "Hello World"
         | 
| 144 | 
            +
            # end
         | 
| 145 | 
            +
            ^D
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                make_file "#{name}.js", <<"^D"
         | 
| 148 | 
            +
            // If you do not want to use CoffeeScript, you can delete this comment.
         | 
| 149 | 
            +
            // If you do, first install the CoffeeScript compiler and Rack::Coffee:
         | 
| 150 | 
            +
            //
         | 
| 151 | 
            +
            //    $ npm install -g coffee-script
         | 
| 152 | 
            +
            //    $ sudo gem install rack-coffee
         | 
| 153 | 
            +
            //    $ echo 'gem "rack-coffee"' >> Gemfile
         | 
| 154 | 
            +
            //    $ bundle
         | 
| 155 | 
            +
            //
         | 
| 156 | 
            +
            // Then simply delete this file and create #{name}.coffee instead.
         | 
| 157 | 
            +
            ^D
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                run "bundle --local"
         | 
| 160 | 
            +
                run "git init"
         | 
| 161 | 
            +
                run "git add -A"
         | 
| 162 | 
            +
                run "git commit -m 'Create project.'"
         | 
| 163 | 
            +
                
         | 
| 164 | 
            +
                puts <<"^D"
         | 
| 73 165 |  | 
| 74 | 
            -
             | 
| 166 | 
            +
            Application created!  Now type \`cd #{name}\' and then \`rackup\'.
         | 
| 167 | 
            +
            This will run your application at <http://localhost:9292/>.
         | 
| 75 168 |  | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 169 | 
            +
            Start hacking in \`#{name}.haml\' and \`#{name}.sass\'.  If you
         | 
| 170 | 
            +
            create \`x.haml\', it will show up at <http://localhost:9292/x>.
         | 
| 171 | 
            +
             | 
| 172 | 
            +
            Public files go in the \`public/\' directory, but you can put images
         | 
| 173 | 
            +
            and Javascript files directly in the root directory if you want.
         | 
| 174 | 
            +
            This (and other things) can be configured in \`#{name}.blossom\'.
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            Put any custom middleware or Sinatra code in \`#{name}.sinatra.rb\',
         | 
| 177 | 
            +
            but remember to restart your application after changing this file.
         | 
| 178 | 
            +
             | 
| 179 | 
            +
            If you restart your application a lot, there is a drop-in replacement
         | 
| 180 | 
            +
            for rackup called Shotgun <https://github.com/rtomayko/shotgun>:
         | 
| 181 | 
            +
             | 
| 182 | 
            +
               $ sudo gem install shotgun
         | 
| 183 | 
            +
               $ shotgun # Like rackup, except with automatic reloading.
         | 
| 184 | 
            +
             | 
| 185 | 
            +
            Good luck and have fun! :-)
         | 
| 186 | 
            +
            ^D
         | 
| 90 187 | 
             
              end
         | 
| 91 188 | 
             
            end
         | 
    
        data/lib/blossom.rb
    CHANGED
    
    | @@ -1,115 +1,289 @@ | |
| 1 | 
            -
            require " | 
| 1 | 
            +
            require "blossom/version"
         | 
| 2 2 |  | 
| 3 | 
            -
            require " | 
| 3 | 
            +
            require "sass"
         | 
| 4 | 
            +
            require "compass"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require "haml"
         | 
| 7 | 
            +
            require "rack"
         | 
| 8 | 
            +
            require "rack/normalize-domain"
         | 
| 4 9 | 
             
            require "sinatra/base"
         | 
| 5 | 
            -
            require " | 
| 6 | 
            -
            require "rack/strip-www"
         | 
| 7 | 
            -
            require "hassle"
         | 
| 10 | 
            +
            require "yaml"
         | 
| 8 11 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
               | 
| 12 | 
            +
            begin
         | 
| 13 | 
            +
              require "rack/coffee"
         | 
| 14 | 
            +
            rescue LoadError
         | 
| 11 15 | 
             
            end
         | 
| 12 16 |  | 
| 13 | 
            -
             | 
| 14 | 
            -
               | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
                value
         | 
| 18 | 
            -
              when :minutes, :minute
         | 
| 19 | 
            -
                value * 60
         | 
| 20 | 
            -
              when :hours, :hour
         | 
| 21 | 
            -
                value * 60 * 60
         | 
| 22 | 
            -
              when :days, :day
         | 
| 23 | 
            -
                value * days
         | 
| 24 | 
            -
              when :weeks, :week
         | 
| 25 | 
            -
                value * days * 7
         | 
| 26 | 
            -
              when :months, :month
         | 
| 27 | 
            -
                value * days * 30
         | 
| 28 | 
            -
              when :years, :year
         | 
| 29 | 
            -
                value * days * 365
         | 
| 30 | 
            -
              else
         | 
| 31 | 
            -
                raise ArgumentError, "Unrecognized unit: #{unit}"
         | 
| 17 | 
            +
            module Blossom
         | 
| 18 | 
            +
              def self.fail(message)
         | 
| 19 | 
            +
                info "Error: #{message}"
         | 
| 20 | 
            +
                exit 1
         | 
| 32 21 | 
             
              end
         | 
| 33 | 
            -
            end
         | 
| 34 22 |  | 
| 35 | 
            -
            def  | 
| 36 | 
            -
             | 
| 37 | 
            -
                cache = options[:cache]
         | 
| 38 | 
            -
                use Hassle
         | 
| 39 | 
            -
                use Rack::StripWWW unless options[:strip_www?] == false
         | 
| 40 | 
            -
                defined? Rack::Coffee and use Rack::Coffee,
         | 
| 41 | 
            -
                  :static => false,
         | 
| 42 | 
            -
                  :urls => "/",
         | 
| 43 | 
            -
                  :cache => !!cache,
         | 
| 44 | 
            -
                  :ttl => cache && Blossom.get_seconds(*cache)
         | 
| 45 | 
            -
                run Blossom::Base(root_file, index, options)
         | 
| 23 | 
            +
              def self.info(message)
         | 
| 24 | 
            +
                Kernel.warn "[Blossom] #{message}"
         | 
| 46 25 | 
             
              end
         | 
| 47 26 | 
             
            end
         | 
| 48 27 |  | 
| 49 | 
            -
            def Blossom | 
| 50 | 
            -
               | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
                
         | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
                    
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                   | 
| 74 | 
            -
             | 
| 75 | 
            -
                   | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 28 | 
            +
            def Blossom(root_filename)
         | 
| 29 | 
            +
              Blossom::Application.new(File.dirname(root_filename))
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            class Blossom::Application < Rack::Builder
         | 
| 33 | 
            +
              def initialize(root)
         | 
| 34 | 
            +
                super()
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                @root = root
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                determine_name!
         | 
| 39 | 
            +
                load_configuration!
         | 
| 40 | 
            +
                configure!
         | 
| 41 | 
            +
                build_rack!
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              # --------------------------------------------------------
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def compass_options
         | 
| 47 | 
            +
                return \
         | 
| 48 | 
            +
                  :cache_dir         => "tmp/sass-cache",
         | 
| 49 | 
            +
                  :http_images_path  => "/",
         | 
| 50 | 
            +
                  :images_dir        => @config.public_directory,
         | 
| 51 | 
            +
                  :line_comments     => false,
         | 
| 52 | 
            +
                  :output_style      => :compact,
         | 
| 53 | 
            +
                  :project_path      => @root,
         | 
| 54 | 
            +
                  :sass_dir          => ""
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def coffee_options
         | 
| 58 | 
            +
                return \
         | 
| 59 | 
            +
                  :cache   => @config.cache_content?,
         | 
| 60 | 
            +
                  :static  => false,
         | 
| 61 | 
            +
                  :ttl     => @config.content_max_age,
         | 
| 62 | 
            +
                  :urls    => "/"
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              def haml_options
         | 
| 66 | 
            +
                return \
         | 
| 67 | 
            +
                  :format        => :html5,
         | 
| 68 | 
            +
                  :attr_wrapper  => '"'
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              def sass_options
         | 
| 72 | 
            +
                Compass.sass_engine_options
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              # --------------------------------------------------------
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def determine_name!
         | 
| 78 | 
            +
                names = glob("*.blossom")
         | 
| 79 | 
            +
                case names.size
         | 
| 80 | 
            +
                when 0
         | 
| 81 | 
            +
                  Blossom.fail "Missing configuration file: NAME.blossom"
         | 
| 82 | 
            +
                when 1
         | 
| 83 | 
            +
                  @name = names[0].sub(/\.blossom$/, '')
         | 
| 84 | 
            +
                else
         | 
| 85 | 
            +
                  Blossom.fail "Multiple configuration files: #{names * ', '}"
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def load_configuration!
         | 
| 90 | 
            +
                @config = Configuration.new(configuration_hash)
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              def configuration_hash
         | 
| 94 | 
            +
                case result = YAML.load_file(configuration_filename)
         | 
| 95 | 
            +
                when false then {} # Empty file.
         | 
| 96 | 
            +
                when Hash then result
         | 
| 97 | 
            +
                else Blossom.fail "Bad configuration file: #{configuration_filename}"
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              rescue Errno::ENOENT
         | 
| 100 | 
            +
                {}
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              # --------------------------------------------------------
         | 
| 104 | 
            +
             | 
| 105 | 
            +
              def configuration_filename
         | 
| 106 | 
            +
                filename("#@name.blossom") end
         | 
| 107 | 
            +
              def sinatra_code_filename
         | 
| 108 | 
            +
                filename("#@name.sinatra.rb") end
         | 
| 109 | 
            +
              def public_dirname
         | 
| 110 | 
            +
                filename(@config.public_directory) end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              def glob(glob)
         | 
| 113 | 
            +
                Dir[filename(glob)].map { |name| File.basename(name) } end
         | 
| 114 | 
            +
              def filename(*components)
         | 
| 115 | 
            +
                File.join(@root, *components) end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              # --------------------------------------------------------
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              def configure!
         | 
| 120 | 
            +
                compass_options.each do |key, value|
         | 
| 121 | 
            +
                  Compass.configuration.send("#{key}=", value)
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                Compass.configure_sass_plugin!
         | 
| 125 | 
            +
              end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
              def build_rack!
         | 
| 128 | 
            +
                use_rack_normalize_domain!
         | 
| 129 | 
            +
                use_rack_coffee!
         | 
| 130 | 
            +
                run sinatra_app
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
              def use_rack_normalize_domain!
         | 
| 134 | 
            +
                if @config.strip_www?
         | 
| 135 | 
            +
                  use Rack::NormalizeDomain
         | 
| 136 | 
            +
                  Blossom.info "Normalizing domains by removing initial www."
         | 
| 137 | 
            +
                else
         | 
| 138 | 
            +
                  Blossom.info "Not normalizing domains."
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              def use_rack_coffee!
         | 
| 143 | 
            +
                if defined? Rack::Coffee
         | 
| 144 | 
            +
                  use Rack::Coffee, coffee_options
         | 
| 145 | 
            +
                  Blossom.info "Using CoffeeScript."
         | 
| 146 | 
            +
                else
         | 
| 147 | 
            +
                  Blossom.info "Not using CoffeeScript."
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
              def sinatra_app
         | 
| 152 | 
            +
                app = Sinatra.new
         | 
| 153 | 
            +
                app.set :blossom, self
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                app.set :root, @root
         | 
| 156 | 
            +
                app.set :index, @name.to_sym
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                app.set :views, @root
         | 
| 159 | 
            +
                app.set :public, public_dirname
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                app.set :haml, haml_options
         | 
| 162 | 
            +
                app.set :sass, sass_options
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                if custom_sinatra_code
         | 
| 165 | 
            +
                  app.class_eval(custom_sinatra_code)
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                # Need variable here for lexical scoping.
         | 
| 169 | 
            +
                max_age = @config.max_age
         | 
| 170 | 
            +
                app.before { cache_control :max_age => max_age }
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                app.register do
         | 
| 173 | 
            +
                  def path_exists? suffix
         | 
| 174 | 
            +
                    condition do
         | 
| 175 | 
            +
                      basename = File.basename(request.path_info)
         | 
| 176 | 
            +
                      File.exist? File.join(settings.root, "#{basename}.#{suffix}")
         | 
| 177 | 
            +
                    end
         | 
| 78 178 | 
             
                  end
         | 
| 79 179 |  | 
| 80 | 
            -
                   | 
| 81 | 
            -
                     | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 180 | 
            +
                  def file_exists? suffix
         | 
| 181 | 
            +
                    condition do
         | 
| 182 | 
            +
                      basename = File.basename(request.path_info)
         | 
| 183 | 
            +
                      barename = basename.sub(/\.[^.]*$/, '')
         | 
| 184 | 
            +
                      File.exist? File.join(settings.root, "#{barename}.#{suffix}")
         | 
| 185 | 
            +
                    end
         | 
| 186 | 
            +
                  end
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                @config.public_extensions.each do |extension|
         | 
| 190 | 
            +
                  app.get "/:name.#{extension}", :file_exists? => extension do
         | 
| 191 | 
            +
                    send_file "#{params[:name]}.#{extension}"
         | 
| 84 192 | 
             
                  end
         | 
| 193 | 
            +
                end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                app.get "/:name.css", :file_exists? => :sass do
         | 
| 196 | 
            +
                  content_type :css
         | 
| 197 | 
            +
                  sass params[:name].to_sym
         | 
| 198 | 
            +
                end
         | 
| 85 199 |  | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 200 | 
            +
                app.get "/:name", :path_exists? => :haml do
         | 
| 201 | 
            +
                  haml params[:name].to_sym
         | 
| 202 | 
            +
                end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                app.get "/" do
         | 
| 205 | 
            +
                  haml settings.index
         | 
| 206 | 
            +
                end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                app
         | 
| 209 | 
            +
              end
         | 
| 210 | 
            +
             | 
| 211 | 
            +
              def custom_sinatra_code
         | 
| 212 | 
            +
                File.read(sinatra_code_filename) rescue nil
         | 
| 213 | 
            +
              end
         | 
| 214 | 
            +
             | 
| 215 | 
            +
              # --------------------------------------------------------
         | 
| 216 | 
            +
             | 
| 217 | 
            +
              class Configuration < Struct.new(:user_data)
         | 
| 218 | 
            +
                DEFAULTS = YAML.load <<"^D"
         | 
| 219 | 
            +
            Public-Directory: public
         | 
| 220 | 
            +
            Public-Extensions: js css html png jpg
         | 
| 221 | 
            +
            Max-Cache-Time: 1 day
         | 
| 222 | 
            +
            Remove-WWW-From-Domain: yes
         | 
| 223 | 
            +
            ^D
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                def public_directory
         | 
| 226 | 
            +
                  get("Public-Directory").string end
         | 
| 227 | 
            +
                def strip_www?
         | 
| 228 | 
            +
                  get("Remove-WWW-From-Domain").boolean end
         | 
| 229 | 
            +
                def max_age
         | 
| 230 | 
            +
                  get("Max-Cache-Time").duration end
         | 
| 231 | 
            +
                def public_extensions
         | 
| 232 | 
            +
                  get("Public-Extensions").words end
         | 
| 233 | 
            +
             | 
| 234 | 
            +
              private
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                def get(name)
         | 
| 237 | 
            +
                  if user_data.include? name
         | 
| 238 | 
            +
                    Value.new(user_data[name])
         | 
| 239 | 
            +
                  else
         | 
| 240 | 
            +
                    Value.new(DEFAULTS[name])
         | 
| 241 | 
            +
                  end
         | 
| 242 | 
            +
                end
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                class Value < Struct.new(:value)
         | 
| 245 | 
            +
                  def string
         | 
| 246 | 
            +
                    value.to_s
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                  def words
         | 
| 250 | 
            +
                    value.gsub(/^\s+|\s$/, "").split(/\s+/)
         | 
| 251 | 
            +
                  end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                  def boolean
         | 
| 254 | 
            +
                    if value == true or value == false
         | 
| 255 | 
            +
                      value
         | 
| 256 | 
            +
                    else
         | 
| 257 | 
            +
                      fail "Must be \`yes' or \`no\': #{name}"
         | 
| 258 | 
            +
                    end
         | 
| 89 259 | 
             
                  end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                   | 
| 92 | 
            -
                    if  | 
| 93 | 
            -
                       | 
| 94 | 
            -
                      { 'Cache-Control' => "max-age=#{seconds}" }
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                  def duration
         | 
| 262 | 
            +
                    if value =~ /^((?:\d+\.)?\d+) ([a-z]+?)s?$/
         | 
| 263 | 
            +
                      $1.to_f * time_unit($2.to_sym)
         | 
| 95 264 | 
             
                    else
         | 
| 96 | 
            -
                      {}
         | 
| 265 | 
            +
                      error "Bad duration: #{value}"
         | 
| 97 266 | 
             
                    end
         | 
| 98 267 | 
             
                  end
         | 
| 99 | 
            -
                end
         | 
| 100 268 |  | 
| 101 | 
            -
                 | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 269 | 
            +
                private
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                  def fail(message)
         | 
| 272 | 
            +
                    Blossom.fail "Configuration: #{value}: #{message}"
         | 
| 273 | 
            +
                  end
         | 
| 105 274 |  | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 275 | 
            +
                  def time_unit(name)
         | 
| 276 | 
            +
                    case name
         | 
| 277 | 
            +
                    when :second then 1
         | 
| 278 | 
            +
                    when :minute then 60
         | 
| 279 | 
            +
                    when :hour then 60 * 60
         | 
| 280 | 
            +
                    when :day then 24 * time_unit(:hour)
         | 
| 281 | 
            +
                    when :week then 7 * time_unit(:day)
         | 
| 282 | 
            +
                    when :month then 30 * time_unit(:day)
         | 
| 283 | 
            +
                    when :year then 365 * time_unit(:day)
         | 
| 284 | 
            +
                    else fail "Unknown time unit: #{name}"
         | 
| 285 | 
            +
                    end
         | 
| 286 | 
            +
                  end
         | 
| 113 287 | 
             
                end
         | 
| 114 288 | 
             
              end
         | 
| 115 289 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,12 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: blossom
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
               | 
| 5 | 
            -
              prerelease: 
         | 
| 4 | 
            +
              prerelease: false
         | 
| 6 5 | 
             
              segments: 
         | 
| 7 6 | 
             
              - 0
         | 
| 7 | 
            +
              - 1
         | 
| 8 8 | 
             
              - 0
         | 
| 9 | 
            -
               | 
| 10 | 
            -
              version: 0.0.12
         | 
| 9 | 
            +
              version: 0.1.0
         | 
| 11 10 | 
             
            platform: ruby
         | 
| 12 11 | 
             
            authors: 
         | 
| 13 12 | 
             
            - Daniel Brockman
         | 
| @@ -15,81 +14,70 @@ autorequire: | |
| 15 14 | 
             
            bindir: bin
         | 
| 16 15 | 
             
            cert_chain: []
         | 
| 17 16 |  | 
| 18 | 
            -
            date:  | 
| 17 | 
            +
            date: 2012-01-10 00:00:00 +01:00
         | 
| 18 | 
            +
            default_executable: 
         | 
| 19 19 | 
             
            dependencies: 
         | 
| 20 20 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 21 21 | 
             
              name: sinatra
         | 
| 22 22 | 
             
              prerelease: false
         | 
| 23 23 | 
             
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 24 | 
            -
                none: false
         | 
| 25 24 | 
             
                requirements: 
         | 
| 26 25 | 
             
                - - ~>
         | 
| 27 26 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 28 | 
            -
                    hash: 23
         | 
| 29 27 | 
             
                    segments: 
         | 
| 30 28 | 
             
                    - 1
         | 
| 31 29 | 
             
                    - 0
         | 
| 32 | 
            -
                     | 
| 33 | 
            -
                    version: 1.0.0
         | 
| 30 | 
            +
                    version: "1.0"
         | 
| 34 31 | 
             
              type: :runtime
         | 
| 35 32 | 
             
              version_requirements: *id001
         | 
| 36 33 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 37 | 
            -
              name:  | 
| 34 | 
            +
              name: sass
         | 
| 38 35 | 
             
              prerelease: false
         | 
| 39 36 | 
             
              requirement: &id002 !ruby/object:Gem::Requirement 
         | 
| 40 | 
            -
                none: false
         | 
| 41 37 | 
             
                requirements: 
         | 
| 42 38 | 
             
                - - ~>
         | 
| 43 39 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 44 | 
            -
                    hash: 7
         | 
| 45 40 | 
             
                    segments: 
         | 
| 46 41 | 
             
                    - 3
         | 
| 47 | 
            -
                    -  | 
| 48 | 
            -
                    -  | 
| 49 | 
            -
                    version: 3. | 
| 42 | 
            +
                    - 1
         | 
| 43 | 
            +
                    - 1
         | 
| 44 | 
            +
                    version: 3.1.1
         | 
| 50 45 | 
             
              type: :runtime
         | 
| 51 46 | 
             
              version_requirements: *id002
         | 
| 52 47 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 53 | 
            -
              name:  | 
| 48 | 
            +
              name: haml
         | 
| 54 49 | 
             
              prerelease: false
         | 
| 55 50 | 
             
              requirement: &id003 !ruby/object:Gem::Requirement 
         | 
| 56 | 
            -
                none: false
         | 
| 57 51 | 
             
                requirements: 
         | 
| 58 52 | 
             
                - - ~>
         | 
| 59 53 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 60 | 
            -
                    hash: 55
         | 
| 61 54 | 
             
                    segments: 
         | 
| 62 | 
            -
                    -  | 
| 63 | 
            -
                    -  | 
| 64 | 
            -
                    -  | 
| 65 | 
            -
                    version:  | 
| 55 | 
            +
                    - 3
         | 
| 56 | 
            +
                    - 1
         | 
| 57 | 
            +
                    - 1
         | 
| 58 | 
            +
                    version: 3.1.1
         | 
| 66 59 | 
             
              type: :runtime
         | 
| 67 60 | 
             
              version_requirements: *id003
         | 
| 68 61 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 69 | 
            -
              name:  | 
| 62 | 
            +
              name: compass
         | 
| 70 63 | 
             
              prerelease: false
         | 
| 71 64 | 
             
              requirement: &id004 !ruby/object:Gem::Requirement 
         | 
| 72 | 
            -
                none: false
         | 
| 73 65 | 
             
                requirements: 
         | 
| 74 66 | 
             
                - - ~>
         | 
| 75 67 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 76 | 
            -
                    hash: 23
         | 
| 77 68 | 
             
                    segments: 
         | 
| 78 69 | 
             
                    - 0
         | 
| 79 | 
            -
                    -  | 
| 80 | 
            -
                     | 
| 81 | 
            -
                    version: 0.2.0
         | 
| 70 | 
            +
                    - 10
         | 
| 71 | 
            +
                    version: "0.10"
         | 
| 82 72 | 
             
              type: :runtime
         | 
| 83 73 | 
             
              version_requirements: *id004
         | 
| 84 74 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 85 | 
            -
              name:  | 
| 75 | 
            +
              name: rack-normalize-domain
         | 
| 86 76 | 
             
              prerelease: false
         | 
| 87 77 | 
             
              requirement: &id005 !ruby/object:Gem::Requirement 
         | 
| 88 | 
            -
                none: false
         | 
| 89 78 | 
             
                requirements: 
         | 
| 90 79 | 
             
                - - ~>
         | 
| 91 80 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 92 | 
            -
                    hash: 29
         | 
| 93 81 | 
             
                    segments: 
         | 
| 94 82 | 
             
                    - 0
         | 
| 95 83 | 
             
                    - 0
         | 
| @@ -98,8 +86,7 @@ dependencies: | |
| 98 86 | 
             
              type: :runtime
         | 
| 99 87 | 
             
              version_requirements: *id005
         | 
| 100 88 | 
             
            description: 
         | 
| 101 | 
            -
            email: 
         | 
| 102 | 
            -
            - daniel@brockman.se
         | 
| 89 | 
            +
            email: daniel@gointeractive.se
         | 
| 103 90 | 
             
            executables: 
         | 
| 104 91 | 
             
            - blossom
         | 
| 105 92 | 
             
            extensions: []
         | 
| @@ -107,8 +94,10 @@ extensions: [] | |
| 107 94 | 
             
            extra_rdoc_files: []
         | 
| 108 95 |  | 
| 109 96 | 
             
            files: 
         | 
| 110 | 
            -
            - lib/blossom.rb
         | 
| 111 97 | 
             
            - bin/blossom
         | 
| 98 | 
            +
            - lib/blossom.rb
         | 
| 99 | 
            +
            - lib/blossom/version.rb
         | 
| 100 | 
            +
            has_rdoc: true
         | 
| 112 101 | 
             
            homepage: http://github.com/dbrock/blossom
         | 
| 113 102 | 
             
            licenses: []
         | 
| 114 103 |  | 
| @@ -118,27 +107,23 @@ rdoc_options: [] | |
| 118 107 | 
             
            require_paths: 
         | 
| 119 108 | 
             
            - lib
         | 
| 120 109 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 121 | 
            -
              none: false
         | 
| 122 110 | 
             
              requirements: 
         | 
| 123 111 | 
             
              - - ">="
         | 
| 124 112 | 
             
                - !ruby/object:Gem::Version 
         | 
| 125 | 
            -
                  hash: 3
         | 
| 126 113 | 
             
                  segments: 
         | 
| 127 114 | 
             
                  - 0
         | 
| 128 115 | 
             
                  version: "0"
         | 
| 129 116 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 130 | 
            -
              none: false
         | 
| 131 117 | 
             
              requirements: 
         | 
| 132 118 | 
             
              - - ">="
         | 
| 133 119 | 
             
                - !ruby/object:Gem::Version 
         | 
| 134 | 
            -
                  hash: 3
         | 
| 135 120 | 
             
                  segments: 
         | 
| 136 121 | 
             
                  - 0
         | 
| 137 122 | 
             
                  version: "0"
         | 
| 138 123 | 
             
            requirements: []
         | 
| 139 124 |  | 
| 140 125 | 
             
            rubyforge_project: 
         | 
| 141 | 
            -
            rubygems_version: 1. | 
| 126 | 
            +
            rubygems_version: 1.3.6
         | 
| 142 127 | 
             
            signing_key: 
         | 
| 143 128 | 
             
            specification_version: 3
         | 
| 144 129 | 
             
            summary: Quick-start web development with Haml, Sass and Compass.
         |