serve 1.5.0.pre5 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/CHANGELOG.rdoc +4 -2
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +13 -8
  4. data/VERSION +1 -1
  5. data/lib/serve/application.rb +34 -17
  6. data/lib/serve/{templates → bootstrap}/Gemfile +3 -3
  7. data/lib/serve/{templates/README.markdown → bootstrap/README.md} +0 -0
  8. data/lib/serve/{templates → bootstrap}/compass.config +0 -0
  9. data/lib/serve/{templates → bootstrap}/config.ru +1 -1
  10. data/lib/serve/{templates → bootstrap}/gitignore +0 -0
  11. data/lib/serve/export.rb +3 -12
  12. data/lib/serve/path.rb +24 -0
  13. data/lib/serve/project.rb +96 -53
  14. data/lib/serve/templates/default/public/images/serve-logo.png +0 -0
  15. data/lib/serve/templates/default/stylesheets/modules/_all.scss +3 -0
  16. data/lib/serve/templates/default/stylesheets/modules/_links.scss +15 -0
  17. data/lib/serve/templates/default/stylesheets/modules/_typography.scss +133 -0
  18. data/lib/serve/templates/default/stylesheets/modules/_utility.scss +15 -0
  19. data/lib/serve/templates/default/stylesheets/partials/_base.scss +47 -0
  20. data/lib/serve/templates/default/stylesheets/partials/_content.scss +37 -0
  21. data/lib/serve/templates/default/stylesheets/partials/_layout.scss +42 -0
  22. data/lib/serve/templates/default/stylesheets/screen.scss +7 -0
  23. data/lib/serve/templates/default/views/_layout.html.erb +1 -0
  24. data/lib/serve/templates/default/views/index.redirect +15 -0
  25. data/lib/serve/templates/default/views/layouts/default.html.erb +31 -0
  26. data/lib/serve/templates/default/views/view_helpers.rb +25 -0
  27. data/lib/serve/templates/default/views/welcome.html.erb +36 -0
  28. data/spec/application_spec.rb +21 -19
  29. data/spec/project_spec.rb +34 -34
  30. data/{lib/serve/templates → spec/stylesheets}/application.scss +0 -0
  31. data/{lib/serve/templates → spec/views}/_layout.html.erb +0 -0
  32. data/{lib/serve/templates → spec/views}/hello.html.erb +0 -0
  33. data/{lib/serve/templates → spec/views}/index.redirect +0 -0
  34. data/{lib/serve/templates → spec/views}/view_helpers.rb +0 -0
  35. metadata +31 -24
data/CHANGELOG.rdoc CHANGED
@@ -1,7 +1,9 @@
1
1
  = Change Log
2
2
 
3
- == edge
4
- * Make Textile partials work. Closes #29. [rmetzler, jlong]
3
+ == 1.5.0 (July 12, 2011)
4
+ * Integrated bundler into config.ru and added a default Gemfile. [jlong]
5
+ * Added new --template option which allows you to specify a project template when creating a new project. [jlong]
6
+ * Made Textile partials work. Closes #29. [rmetzler, jlong]
5
7
  * Fixed problem with export that caused filenames with underscore to be excluded. [bmaland]
6
8
  * Updated generated config.ru to require Sass. Closes #20. [jlong]
7
9
  * Updated project README and other files to be more friendly to new users [jlong]
data/Gemfile CHANGED
@@ -25,7 +25,7 @@ group :development do
25
25
  end
26
26
 
27
27
  group :website do
28
- gem 'serve', '~> 1.5.0.pre4'
28
+ gem 'serve', :git => 'git://github.com/jlong/serve.git'
29
29
  gem 'css_parser', '~> 1.1.9'
30
30
  gem 'maruku', '~> 0.6.0'
31
31
  end
data/Gemfile.lock CHANGED
@@ -1,3 +1,15 @@
1
+ GIT
2
+ remote: git://github.com/jlong/serve.git
3
+ revision: 17f3e31c7ccb9ec75bc8d056d3147731e12655f6
4
+ specs:
5
+ serve (1.5.0.pre5)
6
+ activesupport (~> 3.0)
7
+ i18n
8
+ rack (~> 1.2)
9
+ rack-test (~> 0.5)
10
+ tilt (~> 1.3)
11
+ tzinfo
12
+
1
13
  GEM
2
14
  remote: http://rubygems.org/
3
15
  specs:
@@ -49,13 +61,6 @@ GEM
49
61
  diff-lcs (~> 1.1.2)
50
62
  rspec-mocks (2.6.0)
51
63
  sass (3.1.4)
52
- serve (1.5.0.pre4)
53
- activesupport (~> 3.0.7)
54
- i18n (~> 0.5.0)
55
- rack (~> 1.2.1)
56
- rack-test (~> 0.5.7)
57
- tilt (~> 1.3.1)
58
- tzinfo (~> 0.3.23)
59
64
  slim (0.9.4)
60
65
  temple (~> 0.3.0)
61
66
  tilt (~> 1.2)
@@ -89,7 +94,7 @@ DEPENDENCIES
89
94
  rdoc (~> 3.8.0)
90
95
  rspec (~> 2.6.0)
91
96
  sass (~> 3.1.1)
92
- serve (~> 1.5.0.pre4)
97
+ serve!
93
98
  slim (~> 0.9.4)
94
99
  tilt (~> 1.3)
95
100
  tzinfo
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0.pre5
1
+ 1.5.0
@@ -84,7 +84,7 @@ module Serve
84
84
  "Examples:",
85
85
  " #{program} # launch server in current directory",
86
86
  " #{program} 2100 # launch server on port 2100",
87
- " #{program} mockups # launch server for mockups directory",
87
+ " #{program} project # launch server for project directory",
88
88
  " #{program} create project # new structured project in project dir",
89
89
  " #{program} convert project # convert a Compass project in directory",
90
90
  " #{program} export project output # export project to output directory",
@@ -129,7 +129,9 @@ module Serve
129
129
  " ",
130
130
  "Options:",
131
131
  " -j, --javascript The name of the JavaScript Framework you'd like to use.",
132
- " (Only valid for create and convert commands.)",
132
+ " (Only for create and convert.)",
133
+ " -t, --template The name of the template project to base the project on.",
134
+ " Builtins: blank, default. (Only for create.)",
133
135
  " -h, --help Show this message and quit.",
134
136
  " -v, --version Show the program version number and quit.",
135
137
  " ",
@@ -172,36 +174,51 @@ module Serve
172
174
  return File.expand_path(dir)
173
175
  end
174
176
  end
175
- Dir.pwd
177
+ '.'
176
178
  end
177
179
 
178
- def extract_javascript_framework(args, *opts)
179
- framework = nil
180
+ def extract_arg_and_value(args, opts)
180
181
  opts.each do |opt|
181
- framework = args.pop if args.delete(opt)
182
+ index = args.index(opt)
183
+ next unless index
184
+ key = args.delete_at(index)
185
+ value = args[index]
186
+ if value !~ /^-/
187
+ args.delete_at(index)
188
+ return value
189
+ end
182
190
  end
183
- framework
191
+ nil
192
+ end
193
+
194
+ def extract_javascript_framework(args)
195
+ extract_arg_and_value args, %w(-j --javascript)
196
+ end
197
+
198
+ def extract_template(args)
199
+ extract_arg_and_value args, %w(-t --template)
184
200
  end
185
201
 
186
202
  def extract_create(args)
187
203
  if args.delete('create')
188
- framework = extract_javascript_framework(args, '-j', '--javascript')
189
- name = args.shift
190
- raise InvalidArgumentsError unless name
204
+ framework = extract_javascript_framework(args)
205
+ template = extract_template(args)
206
+ directory = args.pop || '.'
191
207
  {
192
- :framework => framework,
193
- :name => name,
194
- :directory => (args.last ? File.expand_path(args.shift) : Dir.pwd)
208
+ :directory => directory,
209
+ :framework => framework,
210
+ :template => template
195
211
  }
196
212
  end
197
213
  end
198
214
 
199
215
  def extract_convert(args)
200
216
  if args.delete('convert')
201
- framework = extract_javascript_framework(args, '-j', '--javascript')
217
+ framework = extract_javascript_framework(args)
218
+ directory = args.pop || '.'
202
219
  {
203
- :directory => (args.first ? File.expand_path(args.pop) : Dir.pwd),
204
- :framework => framework
220
+ :directory => directory,
221
+ :framework => framework
205
222
  }
206
223
  end
207
224
  end
@@ -209,7 +226,7 @@ module Serve
209
226
  def extract_export(args)
210
227
  if args.delete('export')
211
228
  input, output = args.shift, args.shift
212
- input, output = Dir.pwd, input if output.nil?
229
+ input, output = '.', input if output.nil?
213
230
  output ||= 'html'
214
231
  {
215
232
  :input => input,
@@ -3,14 +3,14 @@ source :rubygems
3
3
  gem 'serve', '#{Serve.version}'
4
4
 
5
5
  # Use edge instead:
6
- # gem 'serve', :get => 'git://github.com/jlong/serve.git'
6
+ # gem 'serve', :git => 'git://github.com/jlong/serve.git'
7
7
 
8
8
  # Use Compass and Sass
9
9
  gem 'compass'
10
10
 
11
11
  # Markdown and Textile
12
- # gem 'rdiscount'
13
- # gem 'RedCloth'
12
+ # gem 'rdiscount' # Markdown
13
+ # gem 'RedCloth' # Textile
14
14
 
15
15
  # Other templating languages
16
16
  # gem 'erubis'
File without changes
@@ -1,4 +1,4 @@
1
- #\\ -p 4000
1
+ #\ -p 4000
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler'
File without changes
data/lib/serve/export.rb CHANGED
@@ -29,13 +29,13 @@ module Serve
29
29
  def collect_files
30
30
  if rackified?
31
31
  @root = "#{@input}/views"
32
- @views = files_from_path("#{@input}/views")
32
+ @views = glob_path("#{@input}/views")
33
33
  @redirects, @views = @views.partition { |fn| fn =~ %r{\.redirect$} }
34
34
  @views.reject! { |fn| fn =~ /view_helpers.rb$/} # remove view_helpers.rb
35
- @public = files_from_path("#{@input}/public")
35
+ @public = glob_path("#{@input}/public")
36
36
  else
37
37
  @root = @input
38
- files = files_from_path(@input)
38
+ files = glob_path(@input)
39
39
  extensions = Serve::DynamicHandler.extensions
40
40
  @views, files = files.partition { |fn| fn =~ %r{#{extensions.join('|')}$} }
41
41
  files.reject! { |fn| fn =~ /view_helpers.rb$/} # remove view_helpers.rb
@@ -63,15 +63,6 @@ module Serve
63
63
  @public.each { |fn| copy_file(fn) }
64
64
  end
65
65
 
66
- def files_from_path(path)
67
- result = nil
68
- FileUtils.cd(path) do
69
- result = Dir["**/*"]
70
- result.reject! { |fn| File.directory?(fn) }
71
- end
72
- result
73
- end
74
-
75
66
  def compile_view(filename)
76
67
  from_path = rackified? ? "#{@input}/views/#{filename}" : "#{@input}/#{filename}"
77
68
 
data/lib/serve/path.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'pathname'
2
+ require 'fileutils'
2
3
 
3
4
  module Serve #:nodoc:
4
5
  module Path #:nodoc:
@@ -9,5 +10,28 @@ module Serve #:nodoc:
9
10
  Pathname.new(File.expand_path(path)).relative_path_from(Pathname.new(Dir.pwd)).to_s
10
11
  end
11
12
 
13
+ # Retrieve all files from a path
14
+ def glob_path(path, directories = false)
15
+ result = nil
16
+
17
+ FileUtils.cd(path) do
18
+ # glob files
19
+ result = Dir.glob("**/*", File::FNM_DOTMATCH)
20
+
21
+ # reject the directories
22
+ result.reject! { |fn| File.directory?(fn) } unless directories
23
+
24
+ # reject dot files or .empty
25
+ result.reject! { |fn| %r{(^|/)(\.{1,2}|\.empty)$}.match(fn) }
26
+
27
+ # reject git files (allow .gitignore)
28
+ result.reject! { |fn| %r{\.git(/|$)}.match(fn) }
29
+ end
30
+
31
+ result.sort!
32
+
33
+ result
34
+ end
35
+
12
36
  end
13
37
  end
data/lib/serve/project.rb CHANGED
@@ -9,13 +9,12 @@ module Serve #:nodoc:
9
9
  # Serve::Project.new(options).convert
10
10
  #
11
11
  class Project #:nodoc:
12
- attr_reader :name, :location, :framework
12
+ attr_reader :location, :framework, :template
13
13
 
14
14
  def initialize(options)
15
- @name = options[:name]
16
- @location = normalize_location(options[:directory], @name)
17
- @full_name = git_config('user.name') || 'Your Full Name'
15
+ @location = normalize_path(options[:directory])
18
16
  @framework = options[:framework]
17
+ @template = options[:template] || 'default'
19
18
  end
20
19
 
21
20
  # Create a new Serve project
@@ -27,12 +26,10 @@ module Serve #:nodoc:
27
26
  public/stylesheets
28
27
  stylesheets
29
28
  ).each { |path| make_path path }
30
- create_file 'stylesheets/application.scss', read_template('application.scss')
31
- create_file 'views/_layout.html.erb', read_template('_layout.html.erb')
32
- create_file 'views/hello.html.erb', read_template('hello.html.erb')
33
- create_file 'views/view_helpers.rb', read_template('view_helpers.rb')
34
- create_file 'views/index.redirect', read_template('index.redirect')
29
+ copy_project_template @template
35
30
  install_javascript_framework @framework
31
+ copy_readme
32
+ post_create_message
36
33
  end
37
34
 
38
35
  def self.create(options={})
@@ -44,14 +41,19 @@ module Serve #:nodoc:
44
41
  setup_base
45
42
  move_file 'images', 'public/'
46
43
  move_file 'stylesheets', 'public/'
47
- if File.directory? 'javascripts'
44
+ if File.directory? "#{@location}/javascripts"
48
45
  move_file 'javascripts', 'public/'
49
46
  else
50
47
  make_path 'public/javascripts'
51
48
  end
52
- move_file 'src', 'stylesheets'
49
+ if File.directory? "#{@location}/src"
50
+ move_file 'src', 'stylesheets'
51
+ elsif File.directory? "#{@location}/sass"
52
+ move_file 'sass', 'styleheets'
53
+ end
53
54
  install_javascript_framework @framework
54
- note_old_compass_config
55
+ copy_readme
56
+ post_convert_message
55
57
  end
56
58
 
57
59
  def self.convert(options={})
@@ -66,25 +68,47 @@ module Serve #:nodoc:
66
68
 
67
69
  # Files required for both a new server project and for an existing compass project.
68
70
  def setup_base
71
+ make_path
69
72
  %w(
70
- .
71
73
  public
72
74
  tmp
73
75
  views
74
76
  ).each { |path| make_path path }
75
- create_file 'Gemfile', read_template('Gemfile')
76
- create_file 'config.ru', read_template('config.ru')
77
- create_file '.gitignore', read_template('gitignore')
78
- create_file 'compass.config', read_template('compass.config')
79
- create_file 'README.markdown', read_template('README.markdown')
77
+ create_file 'Gemfile', read_bootstrap_file('Gemfile', true)
78
+ create_file 'config.ru', read_bootstrap_file('config.ru')
79
+ create_file '.gitignore', read_bootstrap_file('gitignore')
80
+ create_file 'compass.config', read_bootstrap_file('compass.config')
80
81
  create_empty_file 'tmp/restart.txt'
81
82
  end
82
83
 
84
+ # Copy files from project template
85
+ def copy_project_template(name)
86
+ source = lookup_template_directory(name)
87
+ raise 'invalid template' unless source
88
+
89
+ files = glob_path(source, true)
90
+
91
+ files.each do |filename|
92
+ from_path = "#{source}/#{filename}"
93
+ to_path = "#{@location}/#{filename}"
94
+ if File.directory? from_path
95
+ make_path filename
96
+ else
97
+ if File.file? to_path
98
+ log_action "exists", to_path
99
+ else
100
+ log_action "create", to_path
101
+ FileUtils.cp from_path, to_path
102
+ end
103
+ end
104
+ end
105
+ end
106
+
83
107
  # Install a JavaScript framework if one was specified
84
108
  def install_javascript_framework(framework)
85
109
  if framework
86
110
  if valid_javascript_framework?(framework)
87
- path = normalize_path(@location, "public/javascripts")
111
+ path = "#{@location}/public/javascripts"
88
112
  filename = javascript_filename(framework, path)
89
113
  if File.exists? filename
90
114
  log_action 'exists', filename
@@ -99,53 +123,70 @@ module Serve #:nodoc:
99
123
  end
100
124
  end
101
125
 
102
- # Display note about old compass config if it exists
103
- def note_old_compass_config
104
- old_config = normalize_path(@location, 'config.rb')
105
- if File.exists? old_config
106
- puts ""
126
+ # Copy readme file if not included in template
127
+ def copy_readme
128
+ create_file 'README.md', read_bootstrap_file('README.md'), :silent
129
+ end
130
+
131
+ # Display post create message
132
+ def post_create_message(action_message = "You created a new Serve project.")
133
+ puts ""
134
+ puts "Woohoo! #{action_message}"
135
+ puts ""
136
+ puts "A couple of basic files are in place ready for you to edit."
137
+ puts "Remember to edit the project Gemfile and run:"
138
+ puts ""
139
+ puts " bundle install"
140
+ puts ""
141
+ puts "To start serving your project, run:"
142
+ puts ""
143
+ puts " cd \"#{@location}\""
144
+ puts " serve"
145
+ puts ""
146
+ puts "Then go to http://localhost:4000 in your web browser."
147
+ puts ""
148
+ puts "Have fun!"
149
+ puts ""
150
+ end
151
+
152
+ # Display post convert message
153
+ def post_convert_message
154
+ post_create_message "You converted your Compass project to a Serve project."
155
+ if File.exists? "#{@location}/config.rb"
107
156
  puts "============================================================================"
108
- puts " Please Note: You still need to copy your unique settings from config.rb to "
109
- puts " compass.config. Remove config.rb when you are finished."
157
+ puts "Please Note: You still need to copy your unique settings from config.rb to "
158
+ puts "compass.config. Remove config.rb when you are finished."
110
159
  puts "============================================================================"
111
160
  puts ""
112
161
  end
113
162
  end
114
163
 
115
- # Read and eval a template by name
116
- def read_template(name)
117
- contents = IO.read(normalize_path(File.dirname(__FILE__), "templates", name))
118
- instance_eval "%{#{contents}}"
119
- end
120
-
121
- # Grab data by key from the git config file if it exists
122
- def git_config(key)
123
- value = `git config #{key}`.chomp
124
- value.empty? ? nil : value
125
- rescue
126
- nil
164
+ # Read and optionally eval a bootstrap template by name
165
+ def read_bootstrap_file(name, eval = false)
166
+ contents = IO.read(normalize_path(File.dirname(__FILE__), "bootstrap", name))
167
+ eval ? instance_eval("%{#{contents}}") : contents
127
168
  end
128
169
 
129
170
  # Create a file with contents
130
- def create_file(file, contents)
131
- path = normalize_path(@location, file)
171
+ def create_file(file, contents, exists=:noisy)
172
+ path = "#{@location}/#{file}"
132
173
  unless File.exists? path
133
174
  log_action "create", path
134
175
  File.open(path, 'w+') { |f| f.puts contents }
135
176
  else
136
- log_action "exists", path
177
+ log_action "exists", path if exists == :noisy
137
178
  end
138
179
  end
139
180
 
140
181
  # Create an empty file
141
182
  def create_empty_file(file)
142
- path = normalize_path(@location, file)
183
+ path = "#{@location}/#{file}"
143
184
  FileUtils.touch(path)
144
185
  end
145
186
 
146
187
  # Make every directory in a given path
147
- def make_path(path)
148
- path = normalize_path(@location, path)
188
+ def make_path(path=nil)
189
+ path = File.join(*[@location, path].compact)
149
190
  unless File.exists? path
150
191
  log_action "create", path
151
192
  FileUtils.mkdir_p(path)
@@ -156,8 +197,8 @@ module Serve #:nodoc:
156
197
 
157
198
  # Move a file from => to (relative to the project location)
158
199
  def move_file(from, to)
159
- from_path = normalize_path(@location, from)
160
- to_path = normalize_path(@location, to)
200
+ from_path = "#{@location}/#{from}"
201
+ to_path = "#{@location}/#{to}"
161
202
  if File.exists? from_path
162
203
  to = to + from if to[-1..-1] == "/"
163
204
  log_action "move", "#{@location}/{#{from} => #{to}}"
@@ -165,17 +206,19 @@ module Serve #:nodoc:
165
206
  end
166
207
  end
167
208
 
168
- # Normalize the path of the target directory
169
- def normalize_location(path, name = nil)
170
- path = File.join(path, underscore(name)) if name
171
- path = normalize_path(path)
172
- path
173
- end
174
-
175
209
  # Convert dashes and spaces to underscores
176
210
  def underscore(string)
177
211
  string.gsub(/-|\s+/, '_')
178
212
  end
179
213
 
214
+ def default_templates_directory
215
+ "#{File.dirname(__FILE__)}/templates"
216
+ end
217
+
218
+ def lookup_template_directory(name)
219
+ path = "#{default_templates_directory}/#{name}"
220
+ path = normalize_path(name) unless File.directory?(path)
221
+ path if File.directory?(path)
222
+ end
180
223
  end
181
224
  end