sharp 0.3.6 → 0.3.7

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.
@@ -0,0 +1 @@
1
+ sharp
@@ -0,0 +1 @@
1
+ 2.0.0
data/bin/sharp CHANGED
@@ -4,6 +4,7 @@ require 'sharp'
4
4
 
5
5
  case ARGV[0]
6
6
  when "console"
7
+ ENV['SHARP_COMMAND'] ||= 'console'
7
8
  require File.expand_path('app/boot', Dir.pwd)
8
9
  require 'irb'
9
10
  ARGV.clear
@@ -12,11 +12,13 @@ require 'sharp/config'
12
12
  require 'sharp/view'
13
13
  require 'sharp/generator'
14
14
  require 'sharp/version'
15
+ require 'sharp/logging'
16
+ require 'sharp/rack'
15
17
 
16
18
  module Sharp
17
19
  class << self
18
20
  attr_reader :app
19
- delegate :logger, :logger=, :boot, :root, :router, :env, :config, :route, :get, :post, :put, :delete, :head, :to => :app
21
+ delegate :logger, :logger=, :boot, :root, :router, :env, :command, :config, :route, :get, :post, :put, :delete, :head, :to => :app
20
22
  delegate :routes, :to => :router
21
23
  end
22
24
 
@@ -33,120 +35,53 @@ module Sharp
33
35
  end
34
36
 
35
37
  class Application
36
- DEFAULT_ENV = {
37
- "SCRIPT_NAME" => "",
38
- "SERVER_NAME" => "localhost",
39
- "SERVER_PORT" => "80",
40
- "HTTP_HOST" => "localhost",
41
- "HTTP_ACCEPT" => "*/*",
42
- "HTTP_USER_AGENT" => "Sharp #{VERSION}",
43
- "rack.input" => StringIO.new,
44
- "rack.errors" => StringIO.new,
45
- "rack.url_scheme" => "http"
46
- }.freeze
47
-
48
- attr_reader :root, :router
49
-
50
- def self.boot(root)
51
- app = new(root)
52
- app.boot
53
- app
54
- end
38
+ include Logging
39
+ include Rack
40
+
41
+ attr_reader :root
55
42
 
56
43
  def initialize(root)
57
44
  @root = Pathname.new(root)
58
45
  end
59
46
 
60
47
  def boot
61
- if @booted
62
- false
63
- else
64
- pre_initialization
65
- load_i18n
66
- load_load_path
67
- load_routes
68
- post_initialization
69
- finish_boot
48
+ unless booted?
49
+ logger.info "Booting Sharp #{VERSION} #{env} #{command}..."
50
+ ms = Benchmark.ms do
51
+ pre_initialization
52
+ load_i18n
53
+ load_load_path
54
+ load_routes
55
+ post_initialization
56
+ finish_boot
57
+ end
58
+ logger.info("Booted in %0.1fms" % ms)
70
59
  end
60
+ self
71
61
  end
72
62
 
73
- def router
74
- @router ||= Rack::Router.new
75
- end
76
-
77
- # Generates a Rack env Hash
78
- def self.env(method, path, env={})
79
- uri = URI.parse(path)
80
- DEFAULT_ENV.merge(env || {}).merge(
81
- 'REQUEST_METHOD' => method.to_s.upcase,
82
- 'PATH_INFO' => uri.path,
83
- 'QUERY_STRING' => uri.query,
84
- 'rack.input' => StringIO.new)
85
- end
86
-
87
- def route(method, path, env={})
88
- router.match(self.class.env(method, path, env={}))
89
- end
90
-
91
- def get(path, env={})
92
- router.call(self.class.env(:get, path, env={}))
93
- end
94
-
95
- def post(path, env={})
96
- router.call(self.class.env(:post, path, env={}))
97
- end
98
-
99
- def put(path, env={})
100
- router.call(self.class.env(:put, path, env={}))
101
- end
102
-
103
- def delete(path, env={})
104
- router.call(self.class.env(:delete, path, env={}))
105
- end
106
-
107
- def head(path, env={})
108
- router.call(self.class.env(:head, path, env={}))
109
- end
110
-
63
+ # This represents which environment is being used.
64
+ # This is controlled via the RACK_ENV environment variable.
65
+ #
66
+ # @return [Symbol] The environment
111
67
  def env
112
68
  @env ||= ENV['RACK_ENV'].present? ? ENV['RACK_ENV'].to_sym : :development
113
69
  end
114
70
 
115
- def logger
116
- @logger ||= begin
117
- logger = if ENV['SHARP_LOGGER'].to_s.downcase == 'stdout'
118
- Logger.new(STDOUT)
119
- else
120
- log_dir = root.join("log")
121
- unless File.exists?(log_dir)
122
- FileUtils.mkdir(log_dir)
123
- end
124
- Logger.new(File.join(log_dir, "#{env}.log"))
125
- end
126
-
127
- logger.formatter = logger_formatter
128
- logger
129
- end
130
- end
131
-
132
- def objects_logger_is_attached_to
133
- @objects_logger_is_attached_to ||= [self]
134
- end
135
-
136
- def attach_logger(obj)
137
- objects_logger_is_attached_to << obj
138
- obj.logger = logger
139
- end
140
-
141
- def logger=(logger)
142
- objects_logger_is_attached_to.each do |object|
143
- object.logger = logger
144
- end
145
- end
146
-
147
- def logger_formatter
148
- @logger_formatter ||= proc do |severity, datetime, progname, msg|
149
- "#{datetime} #{severity} #{msg}\n"
71
+ # The command represents what external command is running Sharp. Typical values are:
72
+ #
73
+ # * *server* - A rack server like WEBrick, Thin, Unicorn, Puma, etc.
74
+ # * *console* - An IRB session
75
+ #
76
+ # If Sharp is just being run in a script or something, this will be nil.
77
+ # You can set this to any value you like using the SHARP_COMMAND environment variable.
78
+ #
79
+ # @return [Symbol|nil] The command running sharp
80
+ def command
81
+ if defined? @command
82
+ @command
83
+ else
84
+ @command = ENV['SHARP_COMMAND'].downcase.to_sym if ENV['SHARP_COMMAND'].present?
150
85
  end
151
86
  end
152
87
 
@@ -161,35 +96,56 @@ module Sharp
161
96
  protected
162
97
 
163
98
  def pre_initialization
164
- attach_logger(Rack::Action)
165
- Dir.glob(root.join("app/initializers/pre/*.rb")) {|file| load file }
99
+ attach_logger(::Rack::Action)
100
+ Dir.glob(root.join("app/initializers/pre/*.rb")) do |file|
101
+ ms = Benchmark.ms { load file }
102
+ logger.info("Loaded pre-initializer #{file.sub(/^#{root}\/+/,'')} in %0.1fms" % ms)
103
+ end
166
104
  end
167
105
 
168
106
  def load_i18n
169
- if Object.const_defined?("I18n")
170
- Dir.glob(root.join("config/locales/*.yml")) do |file|
171
- I18n.load_path << file
107
+ ms = Benchmark.ms do
108
+ if Object.const_defined?("I18n")
109
+ Dir.glob(root.join("config/locales/*.yml")) do |file|
110
+ I18n.load_path << file
111
+ end
172
112
  end
173
113
  end
114
+ logger.info("Loaded i18n in %0.1fms" % ms)
174
115
  end
175
116
 
176
117
  def load_load_path
177
118
  load_path.each do |path|
178
119
  $:.unshift(root.join(path))
179
- Dir.glob(root.join("#{path}/**/*.rb")) {|file| require file }
120
+ n = 0
121
+ ms = Benchmark.ms do
122
+ Dir.glob(root.join("#{path}/**/*.rb")) do |file|
123
+ require file
124
+ n += 1
125
+ end
126
+ end
127
+ logger.info("Required #{n} #{"file".pluralize(n)} in #{path} in %0.1fms" % ms)
180
128
  end
181
129
  end
182
130
 
183
131
  def load_routes
184
- require File.expand_path "app/routes", root
132
+ ms = Benchmark.ms { require File.expand_path "app/routes", root }
133
+ logger.info("Loaded #{router.routes.size} #{"routes".pluralize(router.routes.size)} in %0.1fms" % ms)
185
134
  end
186
135
 
187
136
  def post_initialization
188
- Dir.glob(root.join("app/initializers/post/*.rb")) {|file| load file }
137
+ Dir.glob(root.join("app/initializers/post/*.rb")) do |file|
138
+ ms = Benchmark.ms { load file }
139
+ logger.info("Loaded post-initializer #{file.sub(/^#{root}\/+/,'')} in %0.1fms" % ms)
140
+ end
189
141
  end
190
142
 
191
143
  def finish_boot
192
144
  @booted = true
193
145
  end
146
+
147
+ def booted?
148
+ !!@booted
149
+ end
194
150
  end
195
151
  end
@@ -0,0 +1,85 @@
1
+ module Sharp
2
+ module Logging
3
+
4
+ # http://stackoverflow.com/a/6407200/41984
5
+ class MultiIO
6
+ def initialize(*targets)
7
+ @targets = targets
8
+ end
9
+
10
+ def add_target(target)
11
+ @targets << target
12
+ end
13
+
14
+ def write(*args)
15
+ @targets.each {|t| t.write(*args)}
16
+ end
17
+
18
+ def close
19
+ @targets.each(&:close)
20
+ end
21
+ end
22
+
23
+ def log_file
24
+ @log_file ||= begin
25
+ log_dir = root.join("log")
26
+
27
+ unless File.exists?(log_dir)
28
+ FileUtils.mkdir(log_dir)
29
+ end
30
+
31
+ File.expand_path("#{env}.log", log_dir)
32
+ end
33
+ end
34
+
35
+ def log_io
36
+ @log_io ||= begin
37
+ io = MultiIO.new(File.open(log_file, 'a'))
38
+
39
+ if env == :development && [:server, :console].include?(command)
40
+ io.add_target(STDOUT)
41
+ end
42
+
43
+ io
44
+ end
45
+ end
46
+
47
+ def log_level
48
+ @log_level ||= begin
49
+ ENV['SHARP_LOG_LEVEL'] ||= env == :production ? 'info' : 'debug'
50
+ Logger.const_get(ENV['SHARP_LOG_LEVEL'].upcase)
51
+ end
52
+ end
53
+
54
+ def logger
55
+ @logger ||= begin
56
+ logger = Logger.new(log_io)
57
+ logger.formatter = logger_formatter
58
+ logger.level = log_level
59
+ logger
60
+ end
61
+ end
62
+
63
+ def objects_logger_is_attached_to
64
+ @objects_logger_is_attached_to ||= [self]
65
+ end
66
+
67
+ def attach_logger(obj)
68
+ objects_logger_is_attached_to << obj
69
+ obj.logger = logger
70
+ end
71
+
72
+ def logger=(logger)
73
+ objects_logger_is_attached_to.each do |object|
74
+ object.logger = logger
75
+ end
76
+ end
77
+
78
+ def logger_formatter
79
+ @logger_formatter ||= proc do |severity, datetime, progname, msg|
80
+ "#{datetime} #{severity} #{msg}\n"
81
+ end
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,63 @@
1
+ module Sharp
2
+ module Rack
3
+ DEFAULT_ENV = {
4
+ "SCRIPT_NAME" => "",
5
+ "SERVER_NAME" => "localhost",
6
+ "SERVER_PORT" => "80",
7
+ "HTTP_HOST" => "localhost",
8
+ "HTTP_ACCEPT" => "*/*",
9
+ "HTTP_USER_AGENT" => "Sharp #{VERSION}",
10
+ "rack.input" => StringIO.new,
11
+ "rack.errors" => StringIO.new,
12
+ "rack.url_scheme" => "http"
13
+ }.freeze
14
+
15
+ def self.included(cls)
16
+ cls.class_eval do
17
+ extend ClassMethods
18
+
19
+ attr_writer :router
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ # Generates a Rack env Hash
25
+ def env(method, path, env={})
26
+ uri = URI.parse(path)
27
+ DEFAULT_ENV.merge(env || {}).merge(
28
+ 'REQUEST_METHOD' => method.to_s.upcase,
29
+ 'PATH_INFO' => uri.path,
30
+ 'QUERY_STRING' => uri.query,
31
+ 'rack.input' => StringIO.new)
32
+ end
33
+ end
34
+
35
+ def router
36
+ @router ||= ::Rack::Router.new
37
+ end
38
+
39
+ def route(method, path, env={})
40
+ router.match(self.class.env(method, path, env={}))
41
+ end
42
+
43
+ def get(path, env={})
44
+ router.call(self.class.env(:get, path, env={}))
45
+ end
46
+
47
+ def post(path, env={})
48
+ router.call(self.class.env(:post, path, env={}))
49
+ end
50
+
51
+ def put(path, env={})
52
+ router.call(self.class.env(:put, path, env={}))
53
+ end
54
+
55
+ def delete(path, env={})
56
+ router.call(self.class.env(:delete, path, env={}))
57
+ end
58
+
59
+ def head(path, env={})
60
+ router.call(self.class.env(:head, path, env={}))
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module Sharp
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "sharp"
5
- gem.version = "0.3.6"
5
+ gem.version = "0.3.7"
6
6
  gem.authors = ["Paul Barry"]
7
7
  gem.email = ["mail@paulbarry.com"]
8
8
  gem.description = %q{A Ruby and Rack-based web framework}
metadata CHANGED
@@ -1,69 +1,78 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sharp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Paul Barry
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-26 00:00:00.000000000 Z
12
+ date: 2013-05-07 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: curtain
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: rack-router
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - '>='
51
+ - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: '0'
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - '>='
59
+ - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: rack-action
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
- - - '>='
67
+ - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0'
62
70
  type: :runtime
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - '>='
75
+ - - ! '>='
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0'
69
78
  description: A Ruby and Rack-based web framework
@@ -75,7 +84,8 @@ extensions: []
75
84
  extra_rdoc_files: []
76
85
  files:
77
86
  - .gitignore
78
- - .rvmrc
87
+ - .ruby-gemset
88
+ - .ruby-version
79
89
  - .yardopts
80
90
  - Gemfile
81
91
  - LICENSE.txt
@@ -87,6 +97,8 @@ files:
87
97
  - lib/sharp/action.rb
88
98
  - lib/sharp/config.rb
89
99
  - lib/sharp/generator.rb
100
+ - lib/sharp/logging.rb
101
+ - lib/sharp/rack.rb
90
102
  - lib/sharp/version.rb
91
103
  - lib/sharp/view.rb
92
104
  - sharp.gemspec
@@ -115,25 +127,26 @@ files:
115
127
  - template/vendor/assets/stylesheets/.gitkeep
116
128
  homepage: http://github.com/pjb3/sharp
117
129
  licenses: []
118
- metadata: {}
119
130
  post_install_message:
120
131
  rdoc_options: []
121
132
  require_paths:
122
133
  - lib
123
134
  required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
124
136
  requirements:
125
- - - '>='
137
+ - - ! '>='
126
138
  - !ruby/object:Gem::Version
127
139
  version: '0'
128
140
  required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
129
142
  requirements:
130
- - - '>='
143
+ - - ! '>='
131
144
  - !ruby/object:Gem::Version
132
145
  version: '0'
133
146
  requirements: []
134
147
  rubyforge_project:
135
- rubygems_version: 2.0.0
148
+ rubygems_version: 1.8.25
136
149
  signing_key:
137
- specification_version: 4
150
+ specification_version: 3
138
151
  summary: A Ruby and Rack-based web framework
139
152
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: cf65dbc4e7f862641ed2fa05e82b8e458baeaa00
4
- data.tar.gz: 807ca9b84328f0a12e6ed1ec8764753607b750c4
5
- SHA512:
6
- metadata.gz: a05dd4be7be6089c5306ba0412c1763bc0cde434541f3d4bf62efe198dd87382b4a7a977607f8e9a953468cc8bcad153c22b05ab9a37250ce8da36edd46c4ec0
7
- data.tar.gz: 73aea111c4fd89353d918b30eaba5b748ad3b2c9f0e73b92c0b0c57ab833291f71c3ead0af01c3f4a85a492ab5498226aa5088458adf9a14ed5b70aaafbf377d
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm 2.0.0@sharp --create