work-bench 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea/
6
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ * неудобное конфигурирование, не работает из коробки
2
+ * странное поведение подстановки файлов
3
+ * проблемы с локалью
data/bin/workbench ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+
5
+ require 'workbench'
@@ -0,0 +1,49 @@
1
+ module Workbench
2
+
3
+ class Application
4
+
5
+ attr_reader :app
6
+
7
+ def initialize
8
+
9
+ @app = Rack::Builder.new {
10
+ use Rack::Reloader, 0
11
+ use Rack::CommonLogger
12
+ use Rack::ShowExceptions
13
+ use Rack::ContentLength
14
+
15
+ Compass.configuration do |config|
16
+ config.project_path = $root
17
+ config.http_path = '/'
18
+ config.http_images_path = '/img'
19
+ config.http_stylesheets_path = '/css'
20
+ config.http_javascripts_path = '/js'
21
+ config.sass_dir = 'sass'
22
+ config.css_dir = 'public/css'
23
+ config.images_dir = 'public/img'
24
+ config.javascripts_dir = 'public/js'
25
+ config.relative_assets = false
26
+ config.output_style = :compact
27
+ config.line_comments = false
28
+ end
29
+
30
+ Compass.configure_sass_plugin!
31
+
32
+ use Sass::Plugin::Rack
33
+ use Rack::StaticCache, :urls => [ '/css', '/js', '/img', '/favicon.ico' ], :root => './public', :versioning => false
34
+
35
+ run Workbench::Server.new
36
+ }.to_app
37
+ end
38
+
39
+ def start port, workers
40
+ Unicorn::HttpServer.new(@app, {
41
+ :listeners => [port],
42
+ :worker_processes => workers,
43
+ :preload_app => true
44
+ }).start.join
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,84 @@
1
+ module Workbench
2
+
3
+ class Cli < Thor
4
+
5
+ include Thor::Actions
6
+
7
+ map '-T' => :help, 'h' => :help, 'i' => :init, 's' => :start
8
+
9
+ def self.source_root
10
+ File.join(File.dirname(__FILE__), '..', '..', 'template')
11
+ end
12
+
13
+ def self.destination_root
14
+ $root
15
+ end
16
+
17
+ desc 'start [--port] [--workers]', 'Start server in current directory'
18
+ long_desc 'Start server in current directory'
19
+ method_option :port, :aliases => '-p', :type => :numeric, :default => 4000, :desc => 'Port'
20
+ method_option :workers, :aliases => '-w', :type => :numeric, :default => 4, :desc => 'Workers'
21
+ def start
22
+ puts 'Starting HTTP server...'
23
+
24
+ app = Workbench::App.new
25
+ app.start options[:port], options[:workers]
26
+
27
+ end
28
+
29
+ desc 'init [--js=frameworks]', 'Initialize empty project in current directory'
30
+ long_desc 'Initialize empty project in current directory'
31
+ method_option :js, :type => :array, :default => ['jquery'], :desc => 'Install specific JS frameworks', :banner => 'jquery jquery-ui json'
32
+ def init
33
+ puts 'Create empty project'
34
+ empty_directory 'haml'
35
+ empty_directory 'sass'
36
+ empty_directory 'public/css'
37
+ empty_directory 'public/js'
38
+ empty_directory 'public/img'
39
+
40
+ copy_file 'normalize.scss', 'sass/normalize.scss'
41
+
42
+ unless options[:js].include? 'jquery'
43
+ options[:js].push('jquery')
44
+ end
45
+
46
+ invoke :js
47
+
48
+ copy_file 'scripts.js', 'public/js/scripts.js'
49
+ copy_file 'style.sass', 'sass/style.sass'
50
+ copy_file 'index.haml', 'haml/index.haml'
51
+ copy_file 'Gemfile', 'Gemfile'
52
+ copy_file '.rvmrc', '.rvmrc'
53
+ end
54
+
55
+ desc 'js [--js=frameworks]', 'Add javascript library to project'
56
+ method_option :js, :type => :array, :desc => 'Install specific JS frameworks', :banner => 'jquery jquery-ui json'
57
+ method_option :list, :default => false, :desc => 'Show available frameworks', :banner => ''
58
+ def js
59
+ js_libs = Workbench::JSLibs.list
60
+
61
+ if options[:list]
62
+ puts 'Available JS library'
63
+ js_libs.each do |index, item|
64
+ puts " * #{index} => #{item}"
65
+ end
66
+ else
67
+ options[:js].each do |js|
68
+ if js_libs[js]
69
+ get js_libs[js], "public/js/#{File.basename(js_libs[js])}"
70
+ end
71
+ end if options[:js]
72
+ end
73
+ end
74
+
75
+ desc 'export [PATH]', 'Export project'
76
+ method_option :fix, :type => :boolean, :desc => 'Fix relative urls'
77
+ def export path = 'export'
78
+ export = Workbench::Exporter.new $root, File.join($root, path), options[:fix]
79
+ export.process
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,7 @@
1
+ require 'unicorn'
2
+ require 'haml'
3
+ require 'sass/plugin/rack'
4
+ require 'compass'
5
+ require 'rack/contrib'
6
+ require 'rack/test'
7
+ require 'thor'
@@ -0,0 +1,86 @@
1
+ module Workbench
2
+
3
+ class Exporter
4
+
5
+ def initialize src, dest, fix = false
6
+ @fix = fix
7
+ @src = src
8
+ @dest = dest
9
+ @browser = Rack::Test::Session.new(Rack::MockSession.new(Workbench::Application.new.app))
10
+ end
11
+
12
+ def process
13
+ puts 'Export project'
14
+ compile_sass
15
+ copy_public_folder
16
+ copy_views
17
+ end
18
+
19
+ private
20
+
21
+ def save_file path, content
22
+ if @fix
23
+ content = content.gsub "url('/", "url('"
24
+ content = content.gsub 'src="/', 'src="'
25
+ end
26
+ puts content
27
+ File.open(path, 'w+') { |f| f.puts content }
28
+ end
29
+
30
+ def log_action msg
31
+ puts '=> ' + msg
32
+ end
33
+
34
+ def get_url path
35
+ @browser.get path, {}, {'REQUEST_URI' => ['http://example.org', path].join('/')}
36
+ response = @browser.last_response
37
+ response.body
38
+ end
39
+
40
+ def compile_sass
41
+ sass_files = get_file_list 'sass'
42
+ sass_files.each do |file|
43
+ ext = File.extname file
44
+ path = "css/#{file.gsub(ext, '.css')}"
45
+ body = get_url path
46
+ save_file "#{@src}/public/#{path}", body
47
+ end
48
+ end
49
+
50
+ def copy_public_folder
51
+ FileUtils.mkdir(@dest) unless Dir.exist? @dest
52
+ file_list = get_file_list 'public'
53
+ file_list.each do |filename|
54
+ dirname = File.join(@dest, File.dirname(filename))
55
+ FileUtils.mkdir_p(dirname) unless Dir.exist? dirname
56
+ FileUtils.cp( File.join(@src, 'public', filename), File.join(@dest, filename))
57
+ log_action "Copy #{filename}"
58
+ end
59
+ end
60
+
61
+ def copy_views
62
+ file_list = get_file_list 'haml'
63
+ file_list.each do |filename|
64
+ body = get_url filename
65
+ filename = filename.gsub('.haml', '.html')
66
+ dirname = File.dirname(File.join(@dest, filename))
67
+ FileUtils.mkdir_p(dirname) unless Dir.exist? dirname
68
+ save_file "#{@dest}/#{filename}", body
69
+ log_action "Copy #{filename}"
70
+ end
71
+ end
72
+
73
+ def get_file_list relative_path
74
+ path = File.join(@src, relative_path)
75
+ result = nil
76
+ FileUtils.cd(path) do
77
+ result = Dir.glob("**/*", File::FNM_DOTMATCH)
78
+ result.reject! { |fn| File.directory?(fn) }
79
+ result.reject! { |fn| fn =~ /(^_|\/_)/ }
80
+ end
81
+ result
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,14 @@
1
+ module Haml
2
+
3
+ module Helpers
4
+
5
+ def render template
6
+ dir = File.dirname $file
7
+ template = template + '.haml'
8
+ template_dir = File.dirname(template)
9
+ basename = File.basename(template)
10
+ Workbench::Renderer.new(File.join(dir, template_dir, "_#{basename}")).render
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Workbench
2
+
3
+ class JSLibs
4
+
5
+ def self.list
6
+ {
7
+ 'jquery' => 'http://code.jquery.com/jquery.js', # latest jQuery
8
+ 'jquery-ui' => 'http://yandex.st/jquery-ui/1.8.16/jquery-ui.js',
9
+ 'jquery-cookie' => 'http://yandex.st/jquery/cookie/1.0/jquery.cookie.js',
10
+ 'jquery-easing' => 'http://yandex.st/jquery/easing/1.3/jquery.easing.js',
11
+ 'json' => 'http://yandex.st/json2/2011-01-18/json2.js'
12
+ }
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,22 @@
1
+ module Workbench
2
+
3
+ class Renderer
4
+
5
+ def initialize file, options = {}
6
+ @file = file
7
+ @options = {
8
+ :escape_attrs => true,
9
+ :attr_wrapper => '"',
10
+ :format => :html4
11
+ }.merge(options)
12
+
13
+ end
14
+
15
+ def render
16
+ engine = Haml::Engine.new(File.read(@file), @options)
17
+ engine.render
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,27 @@
1
+ module Workbench
2
+
3
+ class Server
4
+
5
+ def call(env)
6
+ req = Rack::Request.new(env)
7
+ file = File.join($root, 'haml', '/' == req.path ? 'index.haml' : req.path)
8
+ $file = file
9
+ ext = File.extname(file)
10
+ if ext.empty?
11
+ file = file + '.haml'
12
+ ext = '.haml'
13
+ end
14
+ if File.exists?(file) && '.haml' != ext
15
+ Rack::File.new(File.join($root, 'haml')).call(env)
16
+ else
17
+ if File.exists? file
18
+ [ 200, {'Content-Type' => 'text/html'}, [Workbench::Renderer.new(file).render] ]
19
+ else
20
+ [ 404, {'Content-Type' => 'text/html'}, ['File not found: '+req.path] ]
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,3 @@
1
+ module Workbench
2
+ VERSION = "0.3.0"
3
+ end
data/lib/workbench.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'workbench/version'
2
+ require 'workbench/dependencies'
3
+ require 'workbench/js_libs'
4
+ require 'workbench/application'
5
+ require 'workbench/cli'
6
+ require 'workbench/server'
7
+ require 'workbench/renderer'
8
+ require 'workbench/haml_helpers'
9
+ require 'workbench/exporter'
10
+
11
+ $root = ENV['PWD']
12
+
13
+ Workbench::Cli.start
14
+
data/template/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2
data/template/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'workbench', :path => '/Users/Inferno/Projects/experiments/workbench'
@@ -0,0 +1,11 @@
1
+ !!! Strict
2
+ %html
3
+ %head
4
+ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
5
+ %title Проект
6
+ %link{:href => "/css/style.css", :media => "all", :rel => "stylesheet", :type => "text/css"}
7
+ %script{:src => "/js/jquery.js", :type => "text/javascript"}
8
+ %script{:src => "/js/scripts.js", :type => "text/javascript"}
9
+ %body
10
+
11
+ %h1 Hi man!
@@ -0,0 +1,2 @@
1
+ /* normalize.css 2011-07-06T20:20 UTC //github.com/jonathantneal/normalize.css */
2
+ article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}html{cursor:default;font-size:100%;overflow-y:scroll;-webkit-tap-highlight-color:transparent;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body,form,input,button,select,textarea{font-size:100%;margin:0}a,a:active,a:hover{outline:none}a:focus{outline:thin dotted}abbr{_border-bottom:expression(this.title ? '1px dotted':'none')}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}mark{background:#FF0;color:#000}pre,code,kbd,samp{font-family:monospace,monospace;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small,sub,sup{font-size:75%}sub,sup{line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}nav ul{list-style:none}audio[controls],canvas,video{display:inline-block;*display:inline}audio{display:none;_display:expression(this.controls ? 'inline':'none');*zoom:1}audio[controls]{display:inline-block}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}legend{*margin-left:-7px}button,input,select,textarea{-webkit-appearance:none;border-radius:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;_overflow:expression(this.type == 'button|reset|submit' ? 'visible':'')}button,input[type="button"],input[type="reset"],input[type="submit"]{overflow:visible}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}
@@ -0,0 +1,3 @@
1
+ $(function(){
2
+ // You code here
3
+ });
@@ -0,0 +1,2 @@
1
+ @import compass
2
+ @import normalize
data/workbench.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "workbench/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "work-bench"
7
+ s.version = Workbench::VERSION
8
+ s.authors = ["Konstantin Savelyev"]
9
+ s.email = ["konstantin.savelyev@gmail.com"]
10
+ s.homepage = "http://lenta.ru"
11
+ s.summary = "A quick web server for prototyping."
12
+ s.description = "A quick web server for prototyping."
13
+
14
+ s.rubyforge_project = "work-bench"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "rack"
22
+ s.add_dependency "rack-test"
23
+ s.add_dependency "unicorn"
24
+ s.add_dependency "haml"
25
+ s.add_dependency "compass"
26
+ s.add_dependency "rack-asset-compiler"
27
+ s.add_dependency "rack-cache"
28
+ s.add_dependency "rack-contrib"
29
+ s.add_dependency "thor"
30
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: work-bench
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Konstantin Savelyev
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &70296905361460 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70296905361460
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack-test
27
+ requirement: &70296905360780 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70296905360780
36
+ - !ruby/object:Gem::Dependency
37
+ name: unicorn
38
+ requirement: &70296905360240 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70296905360240
47
+ - !ruby/object:Gem::Dependency
48
+ name: haml
49
+ requirement: &70296905359500 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70296905359500
58
+ - !ruby/object:Gem::Dependency
59
+ name: compass
60
+ requirement: &70296905358340 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70296905358340
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-asset-compiler
71
+ requirement: &70296905356960 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70296905356960
80
+ - !ruby/object:Gem::Dependency
81
+ name: rack-cache
82
+ requirement: &70296905356320 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *70296905356320
91
+ - !ruby/object:Gem::Dependency
92
+ name: rack-contrib
93
+ requirement: &70296905355060 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *70296905355060
102
+ - !ruby/object:Gem::Dependency
103
+ name: thor
104
+ requirement: &70296905353980 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: *70296905353980
113
+ description: A quick web server for prototyping.
114
+ email:
115
+ - konstantin.savelyev@gmail.com
116
+ executables:
117
+ - workbench
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - .gitignore
122
+ - Gemfile
123
+ - Rakefile
124
+ - TODO
125
+ - bin/workbench
126
+ - lib/workbench.rb
127
+ - lib/workbench/application.rb
128
+ - lib/workbench/cli.rb
129
+ - lib/workbench/dependencies.rb
130
+ - lib/workbench/exporter.rb
131
+ - lib/workbench/haml_helpers.rb
132
+ - lib/workbench/js_libs.rb
133
+ - lib/workbench/renderer.rb
134
+ - lib/workbench/server.rb
135
+ - lib/workbench/version.rb
136
+ - template/.rvmrc
137
+ - template/Gemfile
138
+ - template/index.haml
139
+ - template/normalize.scss
140
+ - template/scripts.js
141
+ - template/style.sass
142
+ - workbench.gemspec
143
+ homepage: http://lenta.ru
144
+ licenses: []
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubyforge_project: work-bench
163
+ rubygems_version: 1.8.10
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: A quick web server for prototyping.
167
+ test_files: []