gumdrop 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog.md CHANGED
@@ -1,3 +1,13 @@
1
+ # v0.8.0
2
+ - Leveraging Thor for new CLI support.
3
+ - Added watch command to watch filesystem and auto-compile.
4
+ - You can now add commands to the gumdrop command for your site. Use `tasks` block in Gumdrop file.
5
+ - Report rendering errors better.
6
+ - Code cleanup and reorganization.
7
+ - Generators keep track of generated content.
8
+ - Bugfix: Files without layouts won't throw an exception.
9
+ - New subdued output mode, cli '-s' flag
10
+
1
11
  # v0.7.5
2
12
  - Gumdrop dev server will serve up files from output_dir if the file isn't found in the source tree.
3
13
  - Added new template: blank
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gumdrop (0.7.5)
5
+ active_support
6
+ bundle
7
+ i18n
8
+ sinatra
9
+ thor
10
+ tilt
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ active_support (3.0.0)
16
+ activesupport (= 3.0.0)
17
+ activesupport (3.0.0)
18
+ bundle (0.0.1)
19
+ bundler
20
+ i18n (0.6.0)
21
+ rack (1.4.1)
22
+ rack-protection (1.2.0)
23
+ rack
24
+ sinatra (1.3.2)
25
+ rack (~> 1.3, >= 1.3.6)
26
+ rack-protection (~> 1.2)
27
+ tilt (~> 1.3, >= 1.3.3)
28
+ thor (0.15.3)
29
+ tilt (1.3.3)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ gumdrop!
data/bin/gumdrop CHANGED
@@ -1,13 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
-
4
3
  # Copyright (c) 2011 M@ McCray. All rights reserved.
5
4
 
6
- $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
7
-
5
+ # $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
8
6
  require 'rubygems'
7
+ require 'bundler/setup'
8
+ require 'gumdrop'
9
+ Bundler.require if File.exists?('Gemfile')
9
10
 
10
- # require 'bundler/setup'
11
-
12
- require "gumdrop"
13
- require "gumdrop/cli"
11
+ begin
12
+ if Gumdrop.in_site_folder?
13
+ Gumdrop::CLI::Internal.start
14
+ else
15
+ Gumdrop::CLI::External.start
16
+ end
17
+ rescue Interrupt => e
18
+ puts "\nQuitting..."
19
+ exit 1
20
+ rescue SystemExit => e
21
+ exit e.status
22
+ end
data/gumdrop.gemspec CHANGED
@@ -27,7 +27,8 @@ Gem::Specification.new do |s|
27
27
  s.add_dependency 'sinatra'
28
28
  s.add_dependency 'tilt'
29
29
  s.add_dependency 'active_support'
30
- s.add_dependency 'trollop'
30
+ s.add_dependency 'listen'
31
+ s.add_dependency 'thor'
31
32
  s.add_dependency 'i18n'
32
33
  s.add_dependency 'bundle'
33
34
 
data/lib/gumdrop.rb CHANGED
@@ -6,24 +6,33 @@ require 'active_support/all'
6
6
 
7
7
  module Gumdrop
8
8
 
9
- autoload :Callbacks, "gumdrop/callbacks"
10
- autoload :Context, "gumdrop/context"
11
- autoload :Content, "gumdrop/content"
9
+ autoload :Context, "gumdrop/context"
10
+ autoload :Content, "gumdrop/content"
12
11
  autoload :DataManager, "gumdrop/data_manager"
13
- autoload :Generator, "gumdrop/generator"
14
- autoload :HashObject, "gumdrop/hash_object"
15
- autoload :Pager, "gumdrop/data_manager"
16
- autoload :Server, "gumdrop/server"
17
- autoload :VERSION, "gumdrop/version"
12
+ autoload :Generator, "gumdrop/generator"
13
+ autoload :HashObject, "gumdrop/support/hash_object"
14
+ autoload :Pager, "gumdrop/data_manager"
15
+ autoload :Server, "gumdrop/server"
16
+ autoload :VERSION, "gumdrop/version"
18
17
  autoload :ViewHelpers, "gumdrop/view_helpers"
18
+
19
+ module CLI
20
+ autoload :External, "gumdrop/cli/external"
21
+ autoload :Internal, "gumdrop/cli/internal"
22
+ end
23
+
24
+ module Support
25
+ autoload :BasePackager, "gumdrop/support/base_packager"
26
+ autoload :Callbacks, "gumdrop/support/callbacks"
27
+ autoload :Stitch, "gumdrop/support/stitch"
28
+ autoload :Sprockets, "gumdrop/support/sprockets"
29
+ end
19
30
 
20
31
  class << self
21
32
 
22
33
  def run(opts={})
23
- site_file= Gumdrop.fetch_site_file
24
- unless site_file.nil?
25
- site= Site.new site_file, opts
26
-
34
+ site= fetch_site opts
35
+ unless site.nil?
27
36
  old= Dir.pwd
28
37
  Dir.chdir site.root_path
29
38
 
@@ -31,7 +40,8 @@ module Gumdrop
31
40
 
32
41
  Dir.chdir old
33
42
 
34
- puts "Done." unless opts[:quiet] or opts[:quiet_given]
43
+ puts "\n" if opts[:subdued]
44
+
35
45
  else
36
46
  puts "Not in a valid Gumdrop site directory."
37
47
  end
@@ -41,9 +51,24 @@ module Gumdrop
41
51
  !fetch_site_file(filename).nil?
42
52
  end
43
53
 
54
+ def fetch_site(opts={}, prefer_existing=true)
55
+ if defined?(SITE) and prefer_existing
56
+ SITE.opts= opts unless opts.empty?
57
+ SITE
58
+ else
59
+ site_file= Gumdrop.fetch_site_file
60
+ unless site_file.nil?
61
+ Site.new site_file, opts
62
+ else
63
+ nil
64
+ end
65
+ end
66
+ end
67
+
44
68
  def fetch_site_file(filename="Gumdrop")
45
69
  here= Dir.pwd
46
70
  found= File.file? File.join( here, filename )
71
+ # TODO: Should be smarter -- This is a hack for Windows support "C:\"
47
72
  while !found and File.directory?(here) and File.dirname(here).length > 3
48
73
  here= File.expand_path File.join(here, '../')
49
74
  found= File.file? File.join( here, filename )
@@ -0,0 +1,55 @@
1
+ require 'fileutils'
2
+ require 'thor'
3
+
4
+ module Gumdrop::CLI
5
+ class External < Thor
6
+ include Thor::Actions
7
+
8
+ def self.source_root
9
+ File.expand_path('../../../..', __FILE__)
10
+ end
11
+
12
+ desc 'new [NAME]', 'Create new gumdrop project'
13
+ method_option :template, aliases:'-t', desc:'Template to start from', required:true
14
+ def new(name)
15
+ template= options[:template] || 'default'
16
+
17
+ if File.directory? gem_template_path(template)
18
+ say "New site from template: #{template} (gem)"
19
+ directory(gem_template_path(template), name)
20
+
21
+ elsif File.directory? home_template_path(template)
22
+ say "New site from template: #{template} (local)"
23
+ directory(home_template_path(template), name)
24
+
25
+ else
26
+ say "Unknown template!!\n"
27
+ say "Please select from one of the following:\n\n"
28
+ self.templates
29
+ end
30
+ end
31
+
32
+ desc 'templates', 'List templates'
33
+ def templates
34
+ say "Gem templates:"
35
+ Dir[ gem_template_path ].each do |name|
36
+ say " - #{File.basename name}" if File.directory?(name)
37
+ end
38
+ say "Local templates:"
39
+ Dir[ home_template_path t].each do |name|
40
+ say " - #{File.basename name}" if File.directory?(name)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def gem_template_path(template='*')
47
+ File.join(self.class.source_root, 'templates', template)
48
+ end
49
+
50
+ def home_template_path(template='*')
51
+ File.expand_path File.join( "~", ".gumdrop", 'templates', template)
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,75 @@
1
+ require 'fileutils'
2
+ require 'listen'
3
+ require 'thor'
4
+
5
+ module Gumdrop::CLI
6
+ class Internal < Thor
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.expand_path('../../..', __FILE__)
11
+ end
12
+
13
+ desc 'build', 'Build project'
14
+ method_option :env, default:'production', aliases:'-e'
15
+ method_option :assets, aliases:'-a', type: :array, desc:"List of assets to render."
16
+ method_option :quiet, default:false, aliases:'-q', type: :boolean
17
+ method_option :subdued, default:false, aliases:'-s', type: :boolean, desc:"Subdued output (....)"
18
+ method_option :resume, default:false, aliases:'-r', type: :boolean, desc:"Auto resume rendering after any errors"
19
+ def build()
20
+ Gumdrop.run(options)
21
+ end
22
+
23
+ desc 'server', 'Run development server'
24
+ method_option :env, default:'production', aliases:'-e'
25
+ def server
26
+ Gumdrop::Server
27
+ end
28
+
29
+ desc 'watch', "Watch filesystem for changes and recompile"
30
+ method_option :env, default:'production', aliases:'-e'
31
+ method_option :quiet, default:false, aliases:'-q', type: :boolean
32
+ method_option :subdued, default:false, aliases:'-s', type: :boolean, desc:"Subdued output (....)"
33
+ method_option :resume, default:false, aliases:'-r', type: :boolean, desc:"Auto resume rendering after any errors"
34
+ def watch
35
+ Gumdrop.run options
36
+ paths= [SITE.src_path]
37
+ paths << SITE.data_path if File.directory? SITE.data_path
38
+ Listen.to(*paths, :latency => 0.5) do |m, a, r|
39
+ SITE.rebuild
40
+ end
41
+ end
42
+
43
+ desc 'template [NAME]', "Create local template from this project"
44
+ def template(name)
45
+ template= name
46
+ template_path = home_template_path name
47
+ if File.exists? template_path
48
+ say "A template named '#{name}' already exists!"
49
+
50
+ else
51
+ say "Creating template: #{name}"
52
+ say " ~/.gumdrop/templates/#{name}"
53
+ site_root= Gumdrop.site_dirname
54
+ FileUtils.mkdir_p File.dirname(template_path)
55
+ FileUtils.cp_r File.join(site_root, "."), template_path
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def home_path(name="")
62
+ File.expand_path File.join("~", ".gumdrop", name)
63
+ end
64
+
65
+ def home_template_path(template)
66
+ home_path 'tempaltes', template
67
+ end
68
+
69
+ def local_path(name="")
70
+ File.join( ".", name ) # ?
71
+ end
72
+ end
73
+ end
74
+
75
+ SITE= Gumdrop::Site.new Gumdrop.fetch_site_file unless defined?( SITE )
@@ -76,18 +76,24 @@ module Gumdrop
76
76
  end
77
77
  context.set_content self, locals
78
78
  content= render_all(context)
79
- return content if ignore_layout
80
- layout= context.get_template()
81
- while !layout.nil?
82
- content = layout.template.render(context, content:content) { content }
79
+ return relativize content, context if ignore_layout
80
+ begin
83
81
  layout= context.get_template()
82
+ while !layout.nil? and !layout.template.nil?
83
+ content = layout.template.render(context, content:content) { content }
84
+ layout= context.get_template()
85
+ end
86
+ rescue => ex
87
+ raise StandardError, "Layout: #{ex.to_s}", ex.backtrace
84
88
  end
85
89
  relativize content, context
90
+ rescue => ex
91
+ raise StandardError, "Rendering exception: #{ex.to_s}", ex.backtrace
86
92
  end
87
93
 
88
94
  def renderTo(context, output_path, filters=[], opts={})
89
95
  return copyTo(output_path, opts) unless useLayout?
90
- site.report " rendering: #{uri}", :warning
96
+ site.report " rendering: #{uri}"
91
97
  output= render(context)
92
98
  filters.each {|f| output= f.call(output, self) }
93
99
  File.open output_path, 'w' do |f|
@@ -103,10 +109,10 @@ module Gumdrop
103
109
  true
104
110
  end
105
111
  if do_copy
106
- site.report " copying: #{uri}", :warning
112
+ site.report " copying: #{uri}"
107
113
  FileUtils.cp_r @full_path, output, opts
108
114
  else
109
- site.report " (same): #{uri}", :info
115
+ site.report " (same): #{uri}"
110
116
  end
111
117
  end
112
118
 
@@ -1,6 +1,11 @@
1
1
  module Gumdrop
2
2
 
3
3
  class Generator
4
+
5
+ include Support::Stitch
6
+ include Support::Sprockets
7
+
8
+
4
9
  attr_reader :filename, :base_path, :params, :pages
5
10
 
6
11
  def initialize(content, site, opts={})
@@ -41,6 +46,12 @@ module Gumdrop
41
46
  def set(var_name, value)
42
47
  params[var_name]= value
43
48
  end
49
+
50
+ def unload
51
+ @pages.each do |content|
52
+ @site.content_hash.delete content.uri
53
+ end
54
+ end
44
55
 
45
56
  def page(name, opts={}, &block)
46
57
  name= name[1..-1] if name.starts_with?('/')
@@ -50,7 +61,7 @@ module Gumdrop
50
61
  else
51
62
  File.join @site.src_path, @base_path, @name
52
63
  end
53
- content= GeneratedContent.new(filepath, block, @site, opts)
64
+ content= GeneratedContent.new(filepath, block, @site, self, opts)
54
65
  if opts.has_key? :template and !opts[:template].nil?
55
66
  content.template = if @site.layouts.has_key?( opts[:template] )
56
67
  @site.layouts[ opts[:template] ]
@@ -64,6 +75,8 @@ module Gumdrop
64
75
  end
65
76
  @site.report " generated: #{content.uri}", :info
66
77
  @site.content_hash[content.uri]= content
78
+ @pages << content
79
+ content
67
80
  end
68
81
 
69
82
  # FIXME: Does redirect require abs-paths?
@@ -82,98 +95,16 @@ module Gumdrop
82
95
  end
83
96
  end
84
97
 
85
- def sprockets(name, opts)
86
- require 'gumdrop/sprockets_support'
87
- # require 'pp'
88
- env = Sprockets::Environment.new @site.root_path
89
- env.append_path @site.src_path
90
- opts[:paths].each do |path|
91
- env.append_path(path)
92
- end
93
-
94
- content= env[ opts[:src] ].to_s
95
- page name do
96
- compress_output(content, opts)
97
- end
98
- keep_src(name, content, opts)
99
- prune_src(name, opts)
100
- end
101
-
102
- def stitch(name, opts)
103
- require 'gumdrop/stitch_support'
104
- content= Stitch::Package.new(opts).compile
105
- page name do
106
- compress_output(content, opts)
107
- end
108
- keep_src(name, content, opts)
109
- prune_src(name, opts)
110
- end
111
-
112
-
113
- private
114
-
115
- def compress_output(content, opts)
116
- case opts[:compress]
117
-
118
- when true, :jsmin
119
- require 'jsmin'
120
- JSMin.minify content
121
-
122
- when :yuic
123
- require "yui/compressor"
124
- compressor = YUI::JavaScriptCompressor.new(:munge => opts[:obfuscate])
125
- compressor.compress(content)
126
-
127
- when :uglify
128
- require "uglifier"
129
- Uglifier.compile( content, :mangle=>opts[:obfuscate])
130
-
131
- when :packr
132
- require 'packr'
133
- Packr.pack(content, :shrink_vars => true, :base62 => false, :private=>false)
134
-
135
- when false
136
- content
137
-
138
- else
139
- # UNKNOWN Compressor type!
140
- @site.report "Unknown javascript compressor type! (#{ opts[:compressor] })", :warning
141
- content
142
- end
143
- end
144
-
145
- def keep_src(name, content, opts)
146
- if opts[:keep_src] or opts[:keep_source]
147
- ext= File.extname name
148
- page name.gsub(ext, "#{opts.fetch(:source_postfix, '-src')}#{ext}") do
149
- content
150
- end
151
- end
152
- end
153
-
154
- def prune_src(name, opts)
155
- if opts[:prune] and opts[:root]
156
- sp = File.expand_path( @site.config.source_dir )
157
- rp = File.expand_path(opts[:root])
158
- relative_root = rp.gsub(sp, '')[1..-1]
159
- rrlen= relative_root.length - 1
160
- @site.content_hash.keys.each do |path|
161
- if path[0..rrlen] == relative_root and name != path
162
- @site.content_hash.delete path
163
- end
164
- end
165
- end
166
- end
167
-
168
98
  end
169
99
 
170
100
  class GeneratedContent < Content
171
101
  # Nothing special, per se...
172
102
 
173
- def initialize(path, block, site, params={})
103
+ def initialize(path, block, site, generator, params={})
174
104
  super(path, site, params)
175
105
  @content_block= block
176
106
  @generated= true
107
+ @generator= generator
177
108
  end
178
109
 
179
110
  def render(context=nil, ignore_layout=false, reset_context=true, locals={})