serve 0.11.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +12 -0
- data/Gemfile +15 -10
- data/Gemfile.lock +30 -16
- data/LICENSE +2 -1
- data/README.rdoc +78 -47
- data/Rakefile +1 -3
- data/VERSION +1 -1
- data/lib/serve/application.rb +95 -12
- data/lib/serve/javascripts.rb +62 -0
- data/lib/serve/out.rb +38 -0
- data/lib/serve/project.rb +176 -0
- data/lib/serve/templates/LICENSE +20 -0
- data/lib/serve/templates/README.markdown +46 -0
- data/lib/serve/templates/_layout.html.erb +11 -0
- data/lib/serve/templates/application.sass +12 -0
- data/lib/serve/templates/compass.config +28 -0
- data/lib/serve/templates/config.ru +35 -0
- data/lib/serve/templates/gitignore +24 -0
- data/lib/serve/templates/hello.html.erb +3 -0
- data/lib/serve/templates/index.redirect +1 -0
- data/lib/serve/templates/view_helpers.rb +5 -0
- data/spec/application_spec.rb +36 -7
- data/spec/project_spec.rb +107 -0
- data/spec/spec_helper.rb +1 -6
- metadata +64 -17
- data/spec/spec.opts +0 -1
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Serve
|
5
|
+
module JavaScripts
|
6
|
+
|
7
|
+
# JavaScript Versions
|
8
|
+
GOOGLE_AJAX_APIS = 'http://ajax.googleapis.com/ajax/libs'
|
9
|
+
JQUERY_VERSION = '1' # the latest stable version of 1.x.x
|
10
|
+
JQUERY_UI_VERSION = '1'
|
11
|
+
PROTOTYPE_VERSION = '1'
|
12
|
+
SCRIPTACULOUS_VERSION = '1'
|
13
|
+
MOOTOOLS_VERSION = '1'
|
14
|
+
|
15
|
+
JAVASCRIPT_FRAMEWORKS = %w(jquery jquery-ui mootools prototype scriptaculous)
|
16
|
+
|
17
|
+
def fetch_javascript(framework, download_path)
|
18
|
+
filename = javascript_filename(framework, download_path)
|
19
|
+
framework_url = javascript_framework_url(framework)
|
20
|
+
lines = open(framework_url) { |io| io.read }
|
21
|
+
open(filename, "w+") { |io| io.write(lines) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def supported_javascript_frameworks
|
25
|
+
JAVASCRIPT_FRAMEWORKS
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_javascript_framework?(framework)
|
29
|
+
framework = framework.downcase
|
30
|
+
JAVASCRIPT_FRAMEWORKS.include?(framework)
|
31
|
+
end
|
32
|
+
|
33
|
+
def javascript_filename(framework, path)
|
34
|
+
File.join(path, "#{framework}.js")
|
35
|
+
end
|
36
|
+
|
37
|
+
def javascript_framework_url(framework)
|
38
|
+
self.send(framework.tr('-', '_') + "_url")
|
39
|
+
end
|
40
|
+
|
41
|
+
def jquery_url
|
42
|
+
"#{GOOGLE_AJAX_APIS}/jquery/#{JQUERY_VERSION}/jquery.min.js"
|
43
|
+
end
|
44
|
+
|
45
|
+
def jquery_ui_url
|
46
|
+
"#{GOOGLE_AJAX_APIS}/jqueryui/#{JQUERY_UI_VERSION}/jquery-ui.min.js"
|
47
|
+
end
|
48
|
+
|
49
|
+
def mootools_url
|
50
|
+
"#{GOOGLE_AJAX_APIS}/mootools/#{MOOTOOLS_VERSION}/mootools-yui-compressed.js"
|
51
|
+
end
|
52
|
+
|
53
|
+
def prototype_url
|
54
|
+
"#{GOOGLE_AJAX_APIS}/prototype/#{PROTOTYPE_VERSION}/prototype.js"
|
55
|
+
end
|
56
|
+
|
57
|
+
def scriptaculous_url
|
58
|
+
"#{GOOGLE_AJAX_APIS}/scriptaculous/#{SCRIPTACULOUS_VERSION}/scriptaculous.js"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/serve/out.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Serve #:nodoc:
|
2
|
+
|
3
|
+
# Utility methods for handling output to the terminal
|
4
|
+
module Out #:nodoc:
|
5
|
+
|
6
|
+
def stdout
|
7
|
+
@stdout ||= $stdout
|
8
|
+
end
|
9
|
+
|
10
|
+
def stdout=(value)
|
11
|
+
@stdout = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def stderr
|
15
|
+
@stderr ||= $stderr
|
16
|
+
end
|
17
|
+
|
18
|
+
def stderr=(value)
|
19
|
+
@stderr = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def puts(*args)
|
23
|
+
stdout.puts(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def print(*args)
|
27
|
+
stderr.print(*args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def log_action(name, message)
|
31
|
+
print " " * (12 - name.length)
|
32
|
+
print name
|
33
|
+
print " "
|
34
|
+
puts message
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'serve/out'
|
3
|
+
require 'serve/javascripts'
|
4
|
+
|
5
|
+
module Serve #:nodoc:
|
6
|
+
#
|
7
|
+
# Serve::Project.new(options).create
|
8
|
+
# Serve::Project.new(options).convert
|
9
|
+
#
|
10
|
+
class Project #:nodoc:
|
11
|
+
attr_reader :name, :location, :framework
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
@name = options[:name]
|
15
|
+
@location = normalize_location(options[:directory], @name)
|
16
|
+
@full_name = git_config('user.name') || 'Your Full Name'
|
17
|
+
@framework = options[:framework]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Create a new Serve project
|
21
|
+
def create
|
22
|
+
setup_base
|
23
|
+
%w(
|
24
|
+
public/images
|
25
|
+
public/javascripts
|
26
|
+
public/stylesheets
|
27
|
+
sass
|
28
|
+
).each { |path| make_path path }
|
29
|
+
create_file 'sass/application.sass', read_template('application.sass')
|
30
|
+
create_file 'views/_layout.html.erb', read_template('_layout.html.erb')
|
31
|
+
create_file 'views/hello.html.erb', read_template('hello.html.erb')
|
32
|
+
create_file 'views/view_helpers.rb', read_template('view_helpers.rb')
|
33
|
+
create_file 'views/index.redirect', read_template('index.redirect')
|
34
|
+
install_javascript_framework @framework
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert an existing Compass project to a Serve project
|
38
|
+
def convert
|
39
|
+
setup_base
|
40
|
+
move_file 'images', 'public/'
|
41
|
+
move_file 'stylesheets', 'public/'
|
42
|
+
if File.directory? 'javascripts'
|
43
|
+
move_file 'javascripts', 'public/'
|
44
|
+
else
|
45
|
+
make_path 'public/javascripts'
|
46
|
+
end
|
47
|
+
move_file 'src', 'sass'
|
48
|
+
install_javascript_framework @framework
|
49
|
+
note_old_compass_config
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
include Serve::Out
|
55
|
+
|
56
|
+
include Serve::JavaScripts
|
57
|
+
|
58
|
+
# Files required for both a new server project and for an existing compass project.
|
59
|
+
def setup_base
|
60
|
+
%w(
|
61
|
+
.
|
62
|
+
public
|
63
|
+
tmp
|
64
|
+
views
|
65
|
+
).each { |path| make_path path }
|
66
|
+
create_file 'config.ru', read_template('config.ru')
|
67
|
+
create_file 'LICENSE', read_template('LICENSE')
|
68
|
+
create_file '.gitignore', read_template('gitignore')
|
69
|
+
create_file 'compass.config', read_template('compass.config')
|
70
|
+
create_file 'README.markdown', read_template('README.markdown')
|
71
|
+
create_empty_file 'tmp/restart.txt'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Install a JavaScript framework if one was specified
|
75
|
+
def install_javascript_framework(framework)
|
76
|
+
if framework
|
77
|
+
if valid_javascript_framework?(framework)
|
78
|
+
path = normalize_path(@location, "public/javascripts")
|
79
|
+
filename = javascript_filename(framework, path)
|
80
|
+
if File.exists? filename
|
81
|
+
log_action 'exists', filename
|
82
|
+
else
|
83
|
+
log_action 'install', filename
|
84
|
+
fetch_javascript framework, path
|
85
|
+
end
|
86
|
+
else
|
87
|
+
puts "*** #{framework} javascript framework not supported. ***"
|
88
|
+
puts "Supported frameworks: #{ supported_javascript_frameworks.join(', ') }"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Display note about old compass config if it exists
|
94
|
+
def note_old_compass_config
|
95
|
+
old_config = normalize_path(@location, 'config.rb')
|
96
|
+
if File.exists? old_config
|
97
|
+
puts ""
|
98
|
+
puts "============================================================================"
|
99
|
+
puts " Please Note: You still need to copy your unique settings from config.rb to "
|
100
|
+
puts " compass.config. Remove config.rb when you are finished."
|
101
|
+
puts "============================================================================"
|
102
|
+
puts ""
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Read and eval a template by name
|
107
|
+
def read_template(name)
|
108
|
+
contents = IO.read(normalize_path(File.dirname(__FILE__), "templates", name))
|
109
|
+
instance_eval "%{#{contents}}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# Create a file with contents
|
113
|
+
def create_file(file, contents)
|
114
|
+
path = normalize_path(@location, file)
|
115
|
+
unless File.exists? path
|
116
|
+
log_action "create", path
|
117
|
+
File.open(path, 'w+') { |f| f.puts contents }
|
118
|
+
else
|
119
|
+
log_action "exists", path
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Create an empty file
|
124
|
+
def create_empty_file(file)
|
125
|
+
path = normalize_path(@location, file)
|
126
|
+
FileUtils.touch(path)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Make every directory in a given path
|
130
|
+
def make_path(path)
|
131
|
+
path = normalize_path(@location, path)
|
132
|
+
unless File.exists? path
|
133
|
+
log_action "create", path
|
134
|
+
FileUtils.mkdir_p(path)
|
135
|
+
else
|
136
|
+
log_action "exists", path
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Move a file from => to (relative to the project location)
|
141
|
+
def move_file(from, to)
|
142
|
+
from_path = normalize_path(@location, from)
|
143
|
+
to_path = normalize_path(@location, to)
|
144
|
+
if File.exists? from_path
|
145
|
+
to = to + from if to[-1..-1] == "/"
|
146
|
+
log_action "move", "#{@location}/{#{from} => #{to}}"
|
147
|
+
FileUtils.mv from_path, to_path
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Convert dashes and spaces to underscores
|
152
|
+
def underscore(string)
|
153
|
+
string.gsub(/-|\s+/, '_')
|
154
|
+
end
|
155
|
+
|
156
|
+
# Grab data by key from the git config file if it exists
|
157
|
+
def git_config(key)
|
158
|
+
value = `git config #{key}`.chomp
|
159
|
+
value.empty? ? nil : value
|
160
|
+
end
|
161
|
+
|
162
|
+
# Normalize the path of the target directory
|
163
|
+
def normalize_location(path, name = nil)
|
164
|
+
path = File.join(path, underscore(name)) if name
|
165
|
+
path = normalize_path(path)
|
166
|
+
path
|
167
|
+
end
|
168
|
+
|
169
|
+
# Normalize a path relative to the current working directory
|
170
|
+
def normalize_path(*paths)
|
171
|
+
path = File.join(*paths)
|
172
|
+
Pathname.new(File.expand_path(path)).relative_path_from(Pathname.new(Dir.pwd)).to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) #{Time.now.year} #{@full_name}
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
What is this?
|
2
|
+
=============
|
3
|
+
|
4
|
+
This is a simple HTML prototype written in HAML or ERB that is designed to be
|
5
|
+
viewed with Serve.
|
6
|
+
|
7
|
+
What is Serve? Serve is a rapid prototyping framework for Rails applications.
|
8
|
+
It is designed to compliment Rails development and enforce a strict separation
|
9
|
+
of concerns between designer and developer. Using Serve with Rails allows the
|
10
|
+
designer to happily work in his own space creating an HTML prototype of the
|
11
|
+
application, while the developer works on the Rails application and copies
|
12
|
+
over HTML from the prototype as needed. This allows the designer to focus on
|
13
|
+
presentation and flow while the developer can focus on the implementation.
|
14
|
+
|
15
|
+
|
16
|
+
How do I install and run Serve?
|
17
|
+
-------------------------------
|
18
|
+
|
19
|
+
Serve is distributed as a gem to make it easy to get up and running. To
|
20
|
+
install, type the following at the command prompt:
|
21
|
+
|
22
|
+
gem install serve
|
23
|
+
|
24
|
+
(OSX and Unix users may need to prefix the command with `sudo`.)
|
25
|
+
|
26
|
+
After Serve is installed, you can start it up in a given directory like this:
|
27
|
+
|
28
|
+
serve
|
29
|
+
|
30
|
+
This will start Serve on port 4000. You can now view the prototype in your
|
31
|
+
Web browser at this URL:
|
32
|
+
|
33
|
+
<http://localhost:4000>
|
34
|
+
|
35
|
+
Click around. You will find that Serve enables you to prototype most
|
36
|
+
functionality without writing a single line of backend code.
|
37
|
+
|
38
|
+
|
39
|
+
Rack and Passenger
|
40
|
+
------------------
|
41
|
+
|
42
|
+
Astute users may notice that this project is also a simple Rack application.
|
43
|
+
This means that it is easy to deploy it on Passenger or rack it up with the
|
44
|
+
`rackup` command. For more information about using Serve and Passenger see:
|
45
|
+
|
46
|
+
<http://bit.ly/serve-and-passenger>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# Compass Configuration
|
3
|
+
#
|
4
|
+
|
5
|
+
# HTTP paths
|
6
|
+
http_path = '/'
|
7
|
+
http_stylesheets_path = '/stylesheets'
|
8
|
+
http_images_path = '/images'
|
9
|
+
http_javascripts_path = '/javascripts'
|
10
|
+
|
11
|
+
# File system locations
|
12
|
+
sass_dir = 'sass'
|
13
|
+
css_dir = 'public/stylesheets'
|
14
|
+
images_dir = 'public/images'
|
15
|
+
javascripts_dir = 'public/javascripts'
|
16
|
+
|
17
|
+
# Set to true for easier debugging
|
18
|
+
line_comments = false
|
19
|
+
|
20
|
+
# CSS output style - :nested, :expanded, :compact, or :compressed
|
21
|
+
output_style = :expanded
|
22
|
+
|
23
|
+
# Determine whether Compass asset helper functions generate relative
|
24
|
+
# or absolute paths
|
25
|
+
relative_assets = true
|
26
|
+
|
27
|
+
# Learn more:
|
28
|
+
# http://compass-style.org/docs/tutorials/configuration-reference/
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#\\ -p 4000
|
2
|
+
|
3
|
+
gem 'activesupport'
|
4
|
+
gem 'serve'
|
5
|
+
|
6
|
+
require 'serve'
|
7
|
+
require 'serve/rack'
|
8
|
+
|
9
|
+
require 'sass/plugin/rack'
|
10
|
+
require 'compass'
|
11
|
+
|
12
|
+
# The project root directory
|
13
|
+
root = ::File.dirname(__FILE__)
|
14
|
+
|
15
|
+
# Compass
|
16
|
+
Compass.add_project_configuration(root + '/compass.config')
|
17
|
+
Compass.configure_sass_plugin!
|
18
|
+
|
19
|
+
# Rack Middleware
|
20
|
+
use Rack::ShowStatus # Nice looking 404s and other messages
|
21
|
+
use Rack::ShowExceptions # Nice looking errors
|
22
|
+
use Sass::Plugin::Rack # Compile Sass on the fly
|
23
|
+
|
24
|
+
# Rack Application
|
25
|
+
if ENV['SERVER_SOFTWARE'] =~ /passenger/i
|
26
|
+
# Passendger only needs the adapter
|
27
|
+
run Serve::RackAdapter.new(root + '/views')
|
28
|
+
else
|
29
|
+
# We use Rack::Cascade and Rack::Directory on other platforms to handle static
|
30
|
+
# assets
|
31
|
+
run Rack::Cascade.new([
|
32
|
+
Serve::RackAdapter.new(root + '/views'),
|
33
|
+
Rack::Directory.new(root + '/public')
|
34
|
+
])
|
35
|
+
end
|