slick 0.16.3 → 0.17.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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -8
  3. data/.slick +0 -0
  4. data/.travis.yml +3 -5
  5. data/LICENSE +20 -0
  6. data/README.md +3 -32
  7. data/Rakefile +1 -0
  8. data/config.rb +8 -0
  9. data/config.ru +4 -0
  10. data/exe/slick +8 -0
  11. data/lib/slick.rb +50 -3
  12. data/lib/slick/command.rb +29 -0
  13. data/lib/slick/commands/create_database.rb +9 -0
  14. data/lib/slick/commands/drop_database.rb +9 -0
  15. data/lib/slick/commands/init_database.rb +9 -0
  16. data/lib/slick/commands/list_commands.rb +14 -0
  17. data/lib/slick/commands/migrate_database.rb +9 -0
  18. data/lib/slick/commands/reset_database.rb +10 -0
  19. data/lib/slick/commands/start_console.rb +14 -0
  20. data/lib/slick/commands/start_server.rb +14 -0
  21. data/lib/slick/concern.rb +19 -0
  22. data/lib/slick/database.rb +168 -0
  23. data/lib/slick/database/abstract_row.rb +13 -0
  24. data/lib/slick/database/column.rb +64 -0
  25. data/lib/slick/database/migration.rb +36 -0
  26. data/lib/slick/database/migrator.rb +67 -0
  27. data/lib/slick/database/row.rb +127 -0
  28. data/lib/slick/database/table.rb +381 -0
  29. data/lib/slick/database/union.rb +86 -0
  30. data/lib/slick/helper.rb +24 -0
  31. data/lib/slick/helpers.rb +4 -0
  32. data/lib/slick/helpers/dir.rb +6 -0
  33. data/lib/slick/helpers/echo.rb +6 -0
  34. data/lib/slick/helpers/grab.rb +10 -0
  35. data/lib/slick/helpers/html_builder.rb +180 -0
  36. data/lib/slick/helpers/text_builder.rb +22 -0
  37. data/lib/slick/monkey_patches/html_escape.rb +8 -0
  38. data/lib/slick/monkey_patches/html_unescape.rb +8 -0
  39. data/lib/slick/monkey_patches/paramify.rb +11 -0
  40. data/lib/slick/monkey_patches/pluralize.rb +8 -0
  41. data/lib/slick/monkey_patches/require_all.rb +18 -0
  42. data/lib/slick/monkey_patches/singularize.rb +8 -0
  43. data/lib/slick/monkey_patches/url_encode.rb +8 -0
  44. data/lib/slick/monkey_patches/url_escape.rb +8 -0
  45. data/lib/slick/monkey_patches/url_unescape.rb +8 -0
  46. data/lib/slick/project.rb +53 -0
  47. data/lib/slick/project_watcher.rb +36 -0
  48. data/lib/slick/registry.rb +39 -0
  49. data/lib/slick/request.rb +6 -0
  50. data/lib/slick/resource_factories/config.rb +14 -0
  51. data/lib/slick/resource_factories/database.rb +6 -0
  52. data/lib/slick/resource_factories/database_schema_cache.rb +6 -0
  53. data/lib/slick/resource_factories/database_session_cache.rb +6 -0
  54. data/lib/slick/resource_factories/env.rb +14 -0
  55. data/lib/slick/resource_factories/environment.rb +6 -0
  56. data/lib/slick/resource_factories/file.rb +6 -0
  57. data/lib/slick/resource_factories/params.rb +6 -0
  58. data/lib/slick/resource_factories/project.rb +6 -0
  59. data/lib/slick/resource_factories/request.rb +6 -0
  60. data/lib/slick/resource_factories/response.rb +6 -0
  61. data/lib/slick/resource_factories/web.rb +11 -0
  62. data/lib/slick/resource_factory.rb +35 -0
  63. data/lib/slick/resource_provider.rb +51 -0
  64. data/lib/slick/response.rb +14 -0
  65. data/lib/slick/util.rb +72 -0
  66. data/lib/slick/util/inflections.rb +122 -0
  67. data/lib/slick/util/params_hash.rb +38 -0
  68. data/lib/slick/version.rb +1 -1
  69. data/lib/slick/web.rb +4 -0
  70. data/lib/slick/web/dir.rb +92 -0
  71. data/lib/slick/web/file.rb +66 -0
  72. data/lib/slick/web/file_interpreter.rb +24 -0
  73. data/lib/slick/web/file_interpreters/erb.rb +33 -0
  74. data/lib/slick/web/file_interpreters/js.rb +17 -0
  75. data/lib/slick/web/file_interpreters/rb.rb +14 -0
  76. data/lib/slick/web/file_interpreters/sass.rb +30 -0
  77. data/lib/slick/web/node.rb +35 -0
  78. data/lib/slick/workspace.rb +8 -0
  79. data/slick.gemspec +15 -4
  80. data/web/_layout.erb +13 -0
  81. data/web/index.erb +7 -0
  82. data/web/javascripts/index.js +2 -0
  83. data/web/stylesheets/index.scss +2 -0
  84. metadata +127 -11
  85. data/Gemfile.lock +0 -22
  86. data/bin/console +0 -14
  87. data/bin/setup +0 -8
@@ -0,0 +1,38 @@
1
+
2
+ class Slick::Util::ParamsHash < Hash
3
+
4
+ def initialize
5
+ super
6
+ end
7
+
8
+ def []=(key, value)
9
+ super(key.to_s, value)
10
+ end
11
+
12
+ def[](key)
13
+ super(key.to_s)
14
+ end
15
+
16
+ def merge!(hash)
17
+ hash.each{|key, value| self[key] = value }
18
+ end
19
+
20
+ def merge(hash)
21
+ out = clone
22
+ out.merge!(hash)
23
+ out
24
+ end
25
+
26
+ def key?(name)
27
+ super(name.to_s)
28
+ end
29
+
30
+ def method_missing(name, *args, &block)
31
+ if args.length == 0 && !block
32
+ self[name]
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Slick
2
- VERSION = "0.16.3"
2
+ VERSION = "0.17.0"
3
3
  end
@@ -0,0 +1,4 @@
1
+
2
+ module Slick::Web
3
+
4
+ end
@@ -0,0 +1,92 @@
1
+
2
+ require "slick/web/node"
3
+
4
+ class Slick::Web::Dir < Slick::Web::Node
5
+
6
+ attr_reader :children
7
+
8
+ def initialize(*args)
9
+ super
10
+ @children = {}
11
+ end
12
+
13
+ def merge_dir(path)
14
+ Dir.open(path).each do |name|
15
+ next if name.match(/\A\.{1,2}\z/)
16
+ current_path = "#{path}/#{name}"
17
+ if File.file?(current_path)
18
+ children[name] ||= Slick::Web::File.new(self, name)
19
+ children[name].paths << current_path
20
+ else
21
+ children[name] ||= Slick::Web::Dir.new(self, name)
22
+ children[name].merge_dir(current_path)
23
+ end
24
+ end
25
+ end
26
+
27
+ def find_file(path)
28
+ if self[path]
29
+ if self[path].dir?
30
+ file = self["#{path}/index"]
31
+ file if file && file.file?
32
+ else
33
+ self[path]
34
+ end
35
+ end
36
+ end
37
+
38
+ def [](path)
39
+ _index[_normalize_path(path)]
40
+ end
41
+
42
+ def inspect
43
+ out = []
44
+ out << ""
45
+ children.each do |name, node|
46
+ out << " * #{name}" if node.dir?
47
+ end
48
+ children.each do |name, node|
49
+ out << " * #{name}" if node.file?
50
+ end
51
+ out << ""
52
+ out.join("\n")
53
+ end
54
+
55
+ def method_missing(name, *args, &block)
56
+ if args.length == 0
57
+ self[name]
58
+ else
59
+ super
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def _normalize_path(path)
66
+ path = path.to_s
67
+ while path.match(/\/\.\//)
68
+ path.sub!(/\/\.\//, '/')
69
+ end
70
+ while path.match(/\/[^\/]+\/\.\.\//)
71
+ path.sub!(/\/[^\/]+\/\.\.\//, '')
72
+ end
73
+ path.sub!(/\A[\/\.]*/, '')
74
+ path.sub!(/[\/\.]*\z/, '')
75
+ path
76
+ end
77
+
78
+ def _index()
79
+ @_index ||= begin
80
+ out = {'' => self}
81
+ children.each do |name, child|
82
+ out[name] = child
83
+ if matches = name.match(/\A(.+?)\.(.+)\z/i)
84
+ out[matches[1]] = child if matches[2].downcase == 'rb' || !out[matches[1]]
85
+ end
86
+ child.send(:_index).each{ |name2, child2| out["#{name}/#{name2}"] = child2 } if child.dir?
87
+ end
88
+ out
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,66 @@
1
+
2
+ require "slick/web/node"
3
+
4
+ class Slick::Web::File < Slick::Web::Node
5
+
6
+ attr_reader :paths
7
+
8
+ def initialize(*args)
9
+ super
10
+ @paths = []
11
+ end
12
+
13
+ def path
14
+ paths.last
15
+ end
16
+
17
+ def extension
18
+ @extension ||= if matches = name.match(/\.(.+)\z/i)
19
+ matches[1].downcase
20
+ else
21
+ ""
22
+ end
23
+ end
24
+
25
+ def render(params = {}, &block)
26
+ previous_file = Slick.resource_provider["file"]
27
+ previous_params = Slick.resource_provider["params"]
28
+ Slick.resource_provider["file"] = self
29
+ Slick.resource_provider["params"] = params
30
+ Slick::Web::FileInterpreter.interpret(self, &block)
31
+ Slick.resource_provider["file"] = previous_file
32
+ Slick.resource_provider["params"] = previous_params
33
+ self
34
+ end
35
+
36
+ def grab(params = {}, &block)
37
+ _self = self
38
+ Slick::Workspace.new.instance_eval do
39
+ grab{_self.render(params, &block)}
40
+ end
41
+ end
42
+
43
+ def url(params = {})
44
+ path = relative_path
45
+ candidate_path = path.sub(/\.[^\/]+\z/, '')
46
+ if root.find_file(candidate_path) == self
47
+ path = candidate_path
48
+ candidate_path = path.sub(/\/[^\/]*\z/, '')
49
+ candidate_path = '/' if candidate_path == ''
50
+ path = candidate_path if root.find_file(candidate_path) == self
51
+ end
52
+ out = [path]
53
+
54
+ if params.count > 0
55
+ out << '?'
56
+ out << params.url_encode
57
+ end
58
+
59
+ out.join
60
+ end
61
+
62
+ def inspect
63
+ relative_path
64
+ end
65
+
66
+ end
@@ -0,0 +1,24 @@
1
+
2
+ require "slick/registry"
3
+ require "rack/mime"
4
+
5
+ class Slick::Web::FileInterpreter
6
+
7
+ class << self
8
+
9
+ include Slick::Registry
10
+
11
+ def interpret(file, &block)
12
+ create(file.extension).interpret(file, &(block || Proc.new{}))
13
+ end
14
+
15
+ end
16
+
17
+ include Slick::Helpers
18
+
19
+ def interpret(file, &block)
20
+ response.headers['Content-Type'] = Rack::Mime.mime_type(".#{self.class.name}")
21
+ response.body << File.read(file.path)
22
+ end
23
+
24
+ end
@@ -0,0 +1,33 @@
1
+
2
+ require "slick/web/file_interpreter"
3
+
4
+ Class.new Slick::Web::FileInterpreter do
5
+
6
+ register "erb"
7
+
8
+ def interpret(file, &block)
9
+ _self = self
10
+ file.instance_eval do
11
+ Slick::Workspace.new.instance_eval(@compiled_contents ||= _self.compile(file), file.path)
12
+ end
13
+ end
14
+
15
+ def compile(file)
16
+ File.read(file.path).gsub(/.*?<%={0,1}.*?%>|.+/m) do |chunk|
17
+ if matches = chunk.match(/\A(.*?)(<%={0,1})(.*?)%>\z/m)
18
+ if matches[2] == '<%='
19
+ "echo '#{escape(matches[1])}'; text #{matches[3]};"
20
+ else
21
+ "echo '#{escape(matches[1])}'; #{matches[3]};"
22
+ end
23
+ else
24
+ "echo '#{escape(chunk)}';"
25
+ end
26
+ end
27
+ end
28
+
29
+ def escape(html)
30
+ html.gsub(/'/, '\\\\\'')
31
+ end
32
+
33
+ end
@@ -0,0 +1,17 @@
1
+
2
+ require "slick/web/file_interpreter"
3
+
4
+ Class.new Slick::Web::FileInterpreter do
5
+
6
+ register "js"
7
+
8
+ def interpret(file, &block)
9
+ bundle_file = dir.find_file(file.name.sub(/\.js/, '-bundle.js'))
10
+ if bundle_file
11
+ bundle_file.render
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,14 @@
1
+
2
+ require "slick/web/file_interpreter"
3
+
4
+ Class.new Slick::Web::FileInterpreter do
5
+
6
+ register "rb"
7
+
8
+ def interpret(file, &block)
9
+ file.instance_eval do
10
+ Slick::Workspace.new.instance_eval(@contents ||= File.read(file.path), file.path)
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,30 @@
1
+
2
+ require "sassc"
3
+ require "slick/web/file_interpreter"
4
+
5
+ ['sass', 'scss'].each do |extension|
6
+ Class.new Slick::Web::FileInterpreter do
7
+
8
+ register extension
9
+
10
+ def interpret(file, &block)
11
+ response.headers['Content-Type'] = "text/css"
12
+ response.body << file.instance_eval do
13
+ @cache ||= SassC::Engine.new(File.read(file.path), {
14
+ filename: file.relative_path,
15
+ importer: Class.new(SassC::Importer) do
16
+ def imports(path, parent_path)
17
+ file = Slick.web.find_file("#{parent_path.sub(/[^\/]*\z/, '')}#{path}")
18
+ if file && ['sass', 'scss', 'css'].include?(file.extension)
19
+ SassC::Importer::Import.new(file.relative_path, source: File.read(file.path), source_map_path: file.path)
20
+ else
21
+ raise "Can't resolve path: #{path}"
22
+ end
23
+ end
24
+ end
25
+ }).render
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+
2
+ class Slick::Web::Node
3
+
4
+ attr_reader :parent, :name
5
+
6
+ def initialize(parent = nil, name = nil)
7
+ @parent = parent
8
+ @name = name
9
+ end
10
+
11
+ def relative_path
12
+ @relative_path ||= begin
13
+ out = []
14
+ current = self
15
+ while current
16
+ out.unshift(current.name)
17
+ current = current.parent
18
+ end
19
+ out.join('/')
20
+ end
21
+ end
22
+
23
+ def root
24
+ @root ||= parent ? parent.root : self
25
+ end
26
+
27
+ def file?
28
+ kind_of?(Slick::Web::File)
29
+ end
30
+
31
+ def dir?
32
+ kind_of?(Slick::Web::Dir)
33
+ end
34
+
35
+ end
@@ -0,0 +1,8 @@
1
+
2
+ require "slick/helpers"
3
+
4
+ class Slick::Workspace
5
+
6
+ include Slick::Helpers
7
+
8
+ end
@@ -8,19 +8,30 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Jody Salt"]
9
9
  spec.email = ["jody@jodysalt.com"]
10
10
 
11
- spec.summary = "A web framework"
12
- spec.description = "A web framework"
11
+ spec.summary = "An entrepreneurial web framework that allows small (or one-man) teams to be highly productive."
12
+
13
+ # spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
15
+ # spec.metadata["homepage_uri"] = spec.homepage
16
+ # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
17
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
13
18
 
14
19
  # Specify which files should be added to the gem when it is released.
15
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
16
21
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
22
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
23
  end
24
+
19
25
  spec.bindir = "exe"
20
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
27
  spec.require_paths = ["lib"]
22
28
 
23
- spec.add_development_dependency "bundler", "~> 2.0"
24
- spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_dependency "mysql2", "~> 0.5"
30
+ spec.add_dependency "bundler", "~> 2.0"
31
+ spec.add_dependency "rack", "~> 2.2"
32
+ spec.add_dependency "sassc", "~> 2.3"
33
+
34
+ spec.add_development_dependency "rake", "~> 13.0"
25
35
  spec.add_development_dependency "minitest", "~> 5.0"
36
+
26
37
  end
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= params[:title] %></title>
5
+ <% link :rel => "stylesheet", :type => "text/css", :href => web.stylesheets.index.url %>
6
+ <% script :src => web.javascripts.index.url %>
7
+ </head>
8
+ <body>
9
+ <hr>
10
+ <% yield %>
11
+ asdas
12
+ </body>
13
+ </html>
@@ -0,0 +1,7 @@
1
+ <% dir._layout.render :title => "Hello World" do %>
2
+
3
+ <% h1 "Hello World!" %>
4
+
5
+ <p>This is a test!</p>
6
+
7
+ <% end %>
@@ -0,0 +1,2 @@
1
+
2
+ // nothing here
@@ -0,0 +1,2 @@
1
+
2
+ // nothing here