spontaneous 0.2.0.beta5 → 0.2.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile +2 -0
- data/Readme.markdown +4 -4
- data/application/css/core.css.scss +144 -43
- data/application/css/definitions.css.scss +50 -16
- data/application/css/dialogue.css.scss +5 -2
- data/application/css/editing.css.scss +7 -7
- data/application/css/font.css.scss +1 -1
- data/application/css/meta.css.scss +6 -6
- data/application/css/popover.css.scss +6 -6
- data/application/css/top.css.scss +8 -1
- data/application/js/add_alias_dialogue.js +137 -36
- data/application/js/add_home_dialogue.js +10 -10
- data/application/js/ajax.js +26 -26
- data/application/js/authentication.js +2 -2
- data/application/js/box.js +21 -10
- data/application/js/box_container.js +13 -7
- data/application/js/compatibility.js +19 -17
- data/application/js/conflicted_field_dialogue.js +5 -5
- data/application/js/content.js +22 -16
- data/application/js/content_area.js +62 -33
- data/application/js/dialogue.js +16 -16
- data/application/js/dom.js +9 -10
- data/application/js/edit_panel.js +25 -20
- data/application/js/editing.js +21 -8
- data/application/js/entry.js +1 -1
- data/application/js/extensions.js +11 -11
- data/application/js/field/boolean.js +6 -6
- data/application/js/field/date.js +1 -1
- data/application/js/field/file.js +17 -17
- data/application/js/field/image.js +27 -27
- data/application/js/field/markdown.js +72 -71
- data/application/js/field/select.js +9 -9
- data/application/js/field/string.js +3 -3
- data/application/js/field/webvideo.js +2 -2
- data/application/js/field_preview.js +3 -0
- data/application/js/init.js +3 -2
- data/application/js/jquery-selection-position.js +13 -13
- data/application/js/location.js +17 -12
- data/application/js/login.js +2 -2
- data/application/js/meta_view/user_admin.js +101 -101
- data/application/js/metadata.js +1 -1
- data/application/js/page.js +2 -2
- data/application/js/page_browser.js +13 -13
- data/application/js/page_entry.js +1 -1
- data/application/js/panel/root_menu.js +10 -10
- data/application/js/popover.js +6 -5
- data/application/js/popover_view.js +5 -5
- data/application/js/preview.js +10 -4
- data/application/js/progress.js +6 -6
- data/application/js/properties.js +35 -6
- data/application/js/publish.js +43 -43
- data/application/js/require.js +14 -14
- data/application/js/services.js +3 -3
- data/application/js/sharded_upload.js +9 -8
- data/application/js/side_bar.js +5 -5
- data/application/js/state.js +2 -2
- data/application/js/status_bar.js +6 -6
- data/application/js/top_bar.js +97 -65
- data/application/js/types.js +9 -6
- data/application/js/upload.js +4 -4
- data/application/js/upload_manager.js +21 -21
- data/application/js/user.js +1 -1
- data/application/js/vendor/jquery.velocity.min.js +7 -0
- data/application/js/views.js +32 -8
- data/application/js/views/box_view.js +51 -31
- data/application/js/views/page_piece_view.js +17 -15
- data/application/js/views/page_view.js +54 -43
- data/application/js/views/piece_view.js +44 -37
- data/application/static/font/fontawesome-webfont-4f0022f25672c7f501c339cbf98d9117.ttf +0 -0
- data/application/views/index.erb +1 -0
- data/db/migrations/20130114120000_create_revision_tables.rb +2 -1
- data/db/migrations/20130813111009_increase_path_length.rb +11 -2
- data/db/migrations/20140506171823_add_index_to_target_id.rb +11 -0
- data/db/migrations/20140514090204_add_content_hash.rb +59 -0
- data/db/migrations/20140519150253_add_content_hash_timestamp.rb +20 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/asset/environment.rb +77 -15
- data/lib/spontaneous/box.rb +21 -0
- data/lib/spontaneous/capistrano/deploy.rb +1 -1
- data/lib/spontaneous/capistrano/sync.rb +8 -7
- data/lib/spontaneous/change.rb +4 -2
- data/lib/spontaneous/cli/fields.rb +7 -3
- data/lib/spontaneous/cli/generate.rb +2 -0
- data/lib/spontaneous/cli/init.rb +24 -93
- data/lib/spontaneous/cli/init/db.rb +94 -0
- data/lib/spontaneous/cli/init/mysql.rb +17 -0
- data/lib/spontaneous/cli/init/postgresql.rb +33 -0
- data/lib/spontaneous/cli/init/sqlite.rb +14 -0
- data/lib/spontaneous/cli/site.rb +45 -20
- data/lib/spontaneous/collections/box_set.rb +3 -0
- data/lib/spontaneous/collections/entry_set.rb +43 -4
- data/lib/spontaneous/collections/field_set.rb +14 -2
- data/lib/spontaneous/data_mapper.rb +40 -7
- data/lib/spontaneous/data_mapper/content_model.rb +1 -1
- data/lib/spontaneous/data_mapper/content_model/associations.rb +63 -12
- data/lib/spontaneous/data_mapper/content_model/timestamps.rb +9 -14
- data/lib/spontaneous/data_mapper/content_table.rb +4 -2
- data/lib/spontaneous/data_mapper/dataset.rb +31 -2
- data/lib/spontaneous/data_mapper/scope.rb +37 -20
- data/lib/spontaneous/errors.rb +6 -0
- data/lib/spontaneous/facet.rb +20 -10
- data/lib/spontaneous/field/base.rb +8 -1
- data/lib/spontaneous/field/file.rb +28 -3
- data/lib/spontaneous/field/image.rb +2 -0
- data/lib/spontaneous/field/update.rb +6 -0
- data/lib/spontaneous/field/webvideo/vimeo.rb +6 -1
- data/lib/spontaneous/field/webvideo/vine.rb +1 -1
- data/lib/spontaneous/field/webvideo/youtube.rb +1 -1
- data/lib/spontaneous/generators/site.rb +6 -4
- data/lib/spontaneous/generators/site/.gitignore +1 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +3 -3
- data/lib/spontaneous/generators/site/config/{indexes.rb.tt → initializers/indexes.rb.tt} +0 -0
- data/lib/spontaneous/generators/site/config/initializers/publishing.rb.tt +78 -0
- data/lib/spontaneous/generators/site/{config/database.yml.tt → db/mysql2.yml.tt} +7 -6
- data/lib/spontaneous/generators/site/db/postgres.yml.tt +25 -0
- data/lib/spontaneous/generators/site/db/sqlite3.yml.tt +18 -0
- data/lib/spontaneous/generators/site/public/humans.txt.tt +14 -0
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +51 -0
- data/lib/spontaneous/loader.rb +1 -1
- data/lib/spontaneous/logger.rb +1 -1
- data/lib/spontaneous/media/image/optimizer.rb +1 -1
- data/lib/spontaneous/media/image/processor.rb +11 -2
- data/lib/spontaneous/media/image/renderable.rb +2 -0
- data/lib/spontaneous/model.rb +3 -0
- data/lib/spontaneous/model/box/allowed_types.rb +17 -4
- data/lib/spontaneous/model/core.rb +36 -3
- data/lib/spontaneous/model/core/aliases.rb +5 -2
- data/lib/spontaneous/model/core/boxes.rb +6 -0
- data/lib/spontaneous/model/core/cascading_change.rb +38 -0
- data/lib/spontaneous/model/core/content_hash.rb +171 -0
- data/lib/spontaneous/model/core/entries.rb +0 -19
- data/lib/spontaneous/model/core/fields.rb +11 -0
- data/lib/spontaneous/model/core/modifications.rb +22 -21
- data/lib/spontaneous/model/core/render.rb +3 -0
- data/lib/spontaneous/model/core/serialisation.rb +18 -17
- data/lib/spontaneous/model/page.rb +35 -8
- data/lib/spontaneous/model/page/page_tree.rb +20 -8
- data/lib/spontaneous/model/page/paths.rb +79 -50
- data/lib/spontaneous/model/page/singleton.rb +71 -0
- data/lib/spontaneous/model/page/site_map.rb +2 -1
- data/lib/spontaneous/model/page/site_timestamps.rb +2 -2
- data/lib/spontaneous/model/piece.rb +10 -0
- data/lib/spontaneous/output/context.rb +13 -6
- data/lib/spontaneous/output/format.rb +30 -5
- data/lib/spontaneous/output/helpers/script_helper.rb +8 -0
- data/lib/spontaneous/output/helpers/stylesheet_helper.rb +7 -0
- data/lib/spontaneous/output/renderable.rb +16 -0
- data/lib/spontaneous/output/store.rb +1 -1
- data/lib/spontaneous/output/template/renderer.rb +2 -2
- data/lib/spontaneous/page_piece.rb +25 -1
- data/lib/spontaneous/prototypes/box_prototype.rb +13 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +7 -4
- data/lib/spontaneous/publishing.rb +10 -5
- data/lib/spontaneous/publishing/immediate.rb +32 -349
- data/lib/spontaneous/publishing/pipeline.rb +43 -0
- data/lib/spontaneous/publishing/progress.rb +186 -0
- data/lib/spontaneous/publishing/publish.rb +107 -0
- data/lib/spontaneous/publishing/rerender.rb +17 -0
- data/lib/spontaneous/publishing/revision.rb +53 -18
- data/lib/spontaneous/publishing/simultaneous.rb +1 -1
- data/lib/spontaneous/publishing/steps.rb +154 -0
- data/lib/spontaneous/publishing/steps/activate_revision.rb +45 -0
- data/lib/spontaneous/publishing/steps/archive_old_revisions.rb +22 -0
- data/lib/spontaneous/publishing/steps/base_step.rb +49 -0
- data/lib/spontaneous/publishing/steps/copy_static_files.rb +74 -0
- data/lib/spontaneous/publishing/steps/create_revision_directory.rb +24 -0
- data/lib/spontaneous/publishing/steps/generate_rackup_file.rb +51 -0
- data/lib/spontaneous/publishing/steps/generate_search_indexes.rb +24 -0
- data/lib/spontaneous/publishing/steps/render_revision.rb +69 -0
- data/lib/spontaneous/publishing/steps/write_revision_file.rb +43 -0
- data/lib/spontaneous/rack/back.rb +3 -1
- data/lib/spontaneous/rack/back/alias.rb +9 -8
- data/lib/spontaneous/rack/front.rb +1 -1
- data/lib/spontaneous/rack/middleware.rb +7 -4
- data/lib/spontaneous/rack/middleware/transaction.rb +14 -0
- data/lib/spontaneous/rack/page_controller.rb +23 -8
- data/lib/spontaneous/revision.rb +5 -10
- data/lib/spontaneous/schema.rb +5 -0
- data/lib/spontaneous/server.rb +3 -1
- data/lib/spontaneous/site.rb +17 -10
- data/lib/spontaneous/site/publishing.rb +25 -3
- data/lib/spontaneous/site/state.rb +7 -3
- data/lib/spontaneous/tasks/database.rake +5 -10
- data/lib/spontaneous/utils/database/mysql_dumper.rb +5 -1
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +4 -3
- data/test/fixtures/example_application/config/initializers/initializer1.rb +1 -0
- data/test/fixtures/example_application/config/initializers/initializer2.rb +1 -0
- data/test/fixtures/example_application/config/initializers/publishing.rb +13 -0
- data/test/fixtures/search/config/{indexes.rb → initializers/indexes.rb} +0 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -4
- data/test/functional/test_application.rb +10 -0
- data/test/functional/test_back.rb +23 -5
- data/test/functional/test_cli.rb +98 -34
- data/test/functional/test_front.rb +7 -3
- data/test/test_helper.rb +35 -28
- data/test/unit/test_alias.rb +20 -3
- data/test/unit/test_assets.rb +58 -30
- data/test/unit/test_changesets.rb +20 -12
- data/test/unit/test_content_hash.rb +496 -0
- data/test/unit/test_context.rb +28 -1
- data/test/unit/test_controllers.rb +96 -61
- data/test/unit/test_crypt.rb +1 -8
- data/test/unit/test_datamapper.rb +95 -19
- data/test/unit/test_features.rb +1 -4
- data/test/unit/test_fields.rb +61 -12
- data/test/unit/test_generators.rb +39 -2
- data/test/unit/test_images.rb +3 -1
- data/test/unit/test_modifications.rb +224 -219
- data/test/unit/test_output_store.rb +10 -0
- data/test/unit/{test_formats.rb → test_outputs.rb} +75 -6
- data/test/unit/test_page.rb +61 -15
- data/test/unit/test_plugins.rb +2 -42
- data/test/unit/test_publishing_pipeline.rb +1050 -0
- data/test/unit/test_render.rb +30 -0
- data/test/unit/test_revisions.rb +110 -2
- data/test/unit/test_schema.rb +4 -0
- data/test/unit/test_search.rb +1 -1
- data/test/unit/test_serialisation.rb +6 -1
- data/test/unit/test_singletons.rb +159 -0
- data/test/unit/test_site.rb +71 -44
- metadata +140 -86
- data/application/static/font/fontawesome-webfont-1c66a4738b40ef0f6b1abca0ba9a796d.ttf +0 -0
- data/test/unit/test_publishing.rb +0 -330
@@ -2,11 +2,16 @@
|
|
2
2
|
|
3
3
|
module Spontaneous
|
4
4
|
module Publishing
|
5
|
-
autoload :Immediate,
|
6
|
-
autoload :Threaded,
|
7
|
-
autoload :Simultaneous,
|
8
|
-
autoload :EventClient,
|
9
|
-
autoload :Revision,
|
5
|
+
autoload :Immediate, "spontaneous/publishing/immediate"
|
6
|
+
autoload :Threaded, "spontaneous/publishing/threaded"
|
7
|
+
autoload :Simultaneous, "spontaneous/publishing/simultaneous"
|
8
|
+
autoload :EventClient, "spontaneous/publishing/event_client"
|
9
|
+
autoload :Revision, "spontaneous/publishing/revision"
|
10
|
+
autoload :Steps, "spontaneous/publishing/steps"
|
11
|
+
autoload :Progress, "spontaneous/publishing/progress"
|
12
|
+
autoload :Pipeline, "spontaneous/publishing/pipeline"
|
13
|
+
autoload :Publish, "spontaneous/publishing/publish"
|
14
|
+
autoload :Rerender, "spontaneous/publishing/rerender"
|
10
15
|
end # Publishing
|
11
16
|
end # Spontaneous
|
12
17
|
|
@@ -3,352 +3,35 @@
|
|
3
3
|
require 'simultaneous'
|
4
4
|
require 'sass'
|
5
5
|
|
6
|
-
module Spontaneous
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# TODO: scheduled publishes will
|
40
|
-
# changes.each do |change|
|
41
|
-
# change.destroy
|
42
|
-
# end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def publish_all
|
48
|
-
# maybe someone will make a change while we're publishing the site
|
49
|
-
# (but after we've duplicated the tables)
|
50
|
-
# so save the current list of changes
|
51
|
-
# TODO: make sure this is robust
|
52
|
-
# changes = S::Change.all
|
53
|
-
publish(nil)
|
54
|
-
# changes.each do |change|
|
55
|
-
# change.destroy
|
56
|
-
# end
|
57
|
-
end
|
58
|
-
|
59
|
-
def rerender_revision
|
60
|
-
logger.info { "Re-rendering revision #{@revision}"}
|
61
|
-
render_revision
|
62
|
-
end
|
63
|
-
|
64
|
-
protected
|
65
|
-
|
66
|
-
def page_rendered(page, event = "rendering", format = "html")
|
67
|
-
@pages_rendered += 1
|
68
|
-
update_progress(event, percent_complete)
|
69
|
-
logger.info { "Done: #{event} page #{page.path} (#{format}) #{percent_complete.round(1)}%" }
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
def pages
|
74
|
-
@pages ||= @site.pages
|
75
|
-
end
|
76
|
-
|
77
|
-
# The number of times the publisher has to run through the site's pages
|
78
|
-
# in order to generate the search indexes.
|
79
|
-
# Returns either 0 or 1
|
80
|
-
def index_stages
|
81
|
-
[1, @site.indexes.length].min
|
82
|
-
end
|
83
|
-
|
84
|
-
def publish(modified_page_list)
|
85
|
-
logger.info { "Publishing revision #{@revision}"}
|
86
|
-
at_exit {
|
87
|
-
abort_publish_at_exit
|
88
|
-
}
|
89
|
-
before_publish
|
90
|
-
@content_model.publish(revision, modified_page_list) do
|
91
|
-
render_revision
|
92
|
-
end
|
93
|
-
after_publish
|
94
|
-
rescue ::Exception => e # Catch even interrupts because we definitely need to cleanup
|
95
|
-
abort_publish(e)
|
96
|
-
raise(e)
|
97
|
-
end
|
98
|
-
|
99
|
-
def render_revision
|
100
|
-
update_progress("rendering", 0)
|
101
|
-
@pages_rendered = 0
|
102
|
-
@content_model.scope(@revision, true) do
|
103
|
-
render_pages
|
104
|
-
index_pages unless index_stages == 0
|
105
|
-
end
|
106
|
-
copy_static_files
|
107
|
-
generate_rackup_file
|
108
|
-
end
|
109
|
-
|
110
|
-
def render_pages
|
111
|
-
template_revision = @site.output_store.revision(@revision)
|
112
|
-
@render_transaction = template_revision.transaction
|
113
|
-
delay = @site.config.publishing_delay # the delay is purely used in interface testing
|
114
|
-
pages.each do |page|
|
115
|
-
page.outputs.each do |output|
|
116
|
-
render_page(page, output, @render_transaction)
|
117
|
-
end
|
118
|
-
sleep(delay) if delay
|
119
|
-
end
|
120
|
-
@render_transaction.commit
|
121
|
-
@render_transaction = nil
|
122
|
-
end
|
123
|
-
|
124
|
-
def render_page(page, output, transaction)
|
125
|
-
logger.info { "#{page.path}" }
|
126
|
-
output.publish_page(renderer, revision, transaction)
|
127
|
-
page_rendered(page, "rendering", output.format)
|
128
|
-
end
|
129
|
-
|
130
|
-
def index_pages
|
131
|
-
@site.indexer(revision) do |indexer|
|
132
|
-
pages.each { |page|
|
133
|
-
indexer << page
|
134
|
-
page_rendered(page, 'indexing')
|
135
|
-
}
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# Used to calculate the progress percentage
|
140
|
-
# Calculated by (pages * indexes) + (pages * formats)
|
141
|
-
# where indexes = Site.indexes.length > 0 ? 1 : 0
|
142
|
-
# although not all pages are included by a format
|
143
|
-
def total_pages_to_render
|
144
|
-
@total_pages ||= \
|
145
|
-
begin
|
146
|
-
index_steps = (index_stages * pages.count)
|
147
|
-
output_steps = pages.map { |page| page.outputs.length }.inject(0, :+)
|
148
|
-
index_steps + output_steps
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def percent_complete
|
153
|
-
((@pages_rendered || 0).to_f / (total_pages_to_render).to_f) * 100.0
|
154
|
-
end
|
155
|
-
|
156
|
-
# Deprecated. It's easier to use the messaging path provided by Simultaneous
|
157
|
-
# as it's auto configuring.
|
158
|
-
def event_client
|
159
|
-
@event_client ||= Spontaneous::Publishing::EventClient.new(ENV["SPOT_SERVER"])
|
160
|
-
end
|
161
|
-
|
162
|
-
def update_progress(state, progress='*')
|
163
|
-
simultaneous_event('publish_progress', {:state => state, :progress => progress}.to_json)
|
164
|
-
end
|
165
|
-
|
166
|
-
def generate_rackup_file
|
167
|
-
# use the real path to the app rather than the symlink in order to sandbox the live site
|
168
|
-
# not sure that this is a good idea: it would force a publish for every deploy
|
169
|
-
# which is only sometimes appropriate/desirable
|
170
|
-
# UPDATE: What was I on about there? The true downside to this is that it would force a restart/HUP for
|
171
|
-
# every publish. Not sure that the comment above this one is based on truth or some mad momentary fantasy
|
172
|
-
path = Pathname.new(Spontaneous.root).realpath.to_s
|
173
|
-
rackup = 'config/front.ru'
|
174
|
-
|
175
|
-
template = (<<-RACKUP).gsub(/^ +/, '')
|
176
|
-
# This is an automatically generated file *DO NOT EDIT*
|
177
|
-
# To configure your Rack application make your changes in
|
178
|
-
# '#{path}/#{rackup}'
|
179
|
-
|
180
|
-
# Set the revision to display
|
181
|
-
ENV["#{Spontaneous::SPOT_REVISION_NUMBER}"] = '#{revision}'
|
182
|
-
ENV["#{Spontaneous::SPOT_ROOT}"] = '#{path}'
|
183
|
-
|
184
|
-
# Change to the absolute path of our application and load the Rack config
|
185
|
-
root = '#{path}'
|
186
|
-
Dir.chdir(root)
|
187
|
-
eval(::File.read('#{rackup}'), binding, ::File.join(root, '#{rackup}'), __LINE__)
|
188
|
-
RACKUP
|
189
|
-
rack_file = Spontaneous.revision_dir(revision) / 'config.ru'
|
190
|
-
File.open(rack_file, 'w') { |f| f.write(template) }
|
191
|
-
end
|
192
|
-
|
193
|
-
# Creates a revisions/REVISION file that contains the directory name of the current
|
194
|
-
# revision. This is useful in deployment because it's a real (non-symlinked) file
|
195
|
-
# that changes with each publish and can hence be used as the target for an
|
196
|
-
# `inotifywait` script that does something with every publish.
|
197
|
-
def generate_revision_file(r)
|
198
|
-
rev_file = Spontaneous.revision_root / 'REVISION'
|
199
|
-
File.open(rev_file, 'w') { |f| f.write(Spontaneous::Media.pad_revision(r)) }
|
200
|
-
end
|
201
|
-
|
202
|
-
def copy_static_files
|
203
|
-
update_progress("copying_files")
|
204
|
-
public_dest = Pathname.new(Spontaneous.revision_dir(revision) / 'public')
|
205
|
-
FileUtils.mkdir_p(public_dest) unless File.exists?(public_dest)
|
206
|
-
facets = Spontaneous.instance.facets
|
207
|
-
public_dirs = facets.map { |facet| facet.paths.expanded(:public) }.flatten
|
208
|
-
facets.each do |facet|
|
209
|
-
copy_facet_public_files(facet, public_dest)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def copy_facet_public_files(facet, public_dest)
|
214
|
-
public_dirs = facet.paths.expanded(:public).map { |dir| Pathname.new(dir) }
|
215
|
-
public_dirs.each do |public_src|
|
216
|
-
next unless public_src.exist?
|
217
|
-
public_src = public_src.realpath
|
218
|
-
Dir[public_src.to_s / "**/*"].each do |file|
|
219
|
-
copy_facet_public_dir(facet, file, public_src, public_dest)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
def copy_facet_public_dir(facet, original, public_src, public_dest)
|
225
|
-
original = Pathname.new(original)
|
226
|
-
# insert facet namespace in front of path to keep URLs consistent across
|
227
|
-
# the back & front servers
|
228
|
-
dest = File.join [facet.file_namespace, original.relative_path_from(public_src).to_s].compact
|
229
|
-
dest = public_dest + dest
|
230
|
-
if original.directory?
|
231
|
-
dest.mkpath
|
232
|
-
else
|
233
|
-
copy_public_file(original, dest)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def copy_public_file(src, dest)
|
238
|
-
# TODO: Add coffeescript compilation.
|
239
|
-
# Should be implemented using sprockets
|
240
|
-
case src.extname
|
241
|
-
when ".scss"
|
242
|
-
render_sass_template(src, dest)
|
243
|
-
else
|
244
|
-
link_file(src, dest)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def link_file(src, dest)
|
249
|
-
src_dev = File::stat(src).dev
|
250
|
-
dst_dev = File::stat(File.dirname(dest)).dev
|
251
|
-
if (src_dev == dst_dev)
|
252
|
-
FileUtils.ln(src, dest, :force => true)
|
253
|
-
else
|
254
|
-
FileUtils.cp(src, dest)
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
def render_sass_template(template, dest)
|
259
|
-
dest_css = [dest.basename('.scss'), "css"].join(".")
|
260
|
-
dest = (dest.dirname + dest_css)
|
261
|
-
|
262
|
-
dir = File.dirname(template)
|
263
|
-
load_paths = [dir, File.join(dir, "sass")]
|
264
|
-
|
265
|
-
File.open(dest, 'w') do |file|
|
266
|
-
begin
|
267
|
-
engine = Sass::Engine.for_file(template.to_s, {
|
268
|
-
:filename => template.to_s,
|
269
|
-
:load_paths => load_paths,
|
270
|
-
:cache => false,
|
271
|
-
:style => :compressed
|
272
|
-
})
|
273
|
-
file.write(engine.render)
|
274
|
-
rescue Sass::SyntaxError => e
|
275
|
-
# it's likely that the error is coming from rendering an include file that isn't designed to
|
276
|
-
# be rendered singly (i.e. it depends on another include file)
|
277
|
-
# but let's show an error anyway
|
278
|
-
logger.warn(e)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def before_publish
|
284
|
-
update_progress("initialising")
|
285
|
-
# when working with multiple instances it's possible to rollback the revision number
|
286
|
-
# leaving behind old revisions > the current published_revision.
|
287
|
-
@content_model.delete_revision(revision)
|
288
|
-
@site.send(:pending_revision=, revision)
|
289
|
-
end
|
290
|
-
|
291
|
-
def after_publish
|
292
|
-
update_progress("finalising")
|
293
|
-
begin
|
294
|
-
tmp = Spontaneous.revision_dir(revision) / "tmp"
|
295
|
-
FileUtils.mkdir_p(tmp) unless ::File.exists?(tmp)
|
296
|
-
activate_revision
|
297
|
-
@site.must_publish_all!(false)
|
298
|
-
update_progress("complete")
|
299
|
-
rescue => e
|
300
|
-
# if a post publish hook raises an exception then we want to roll everything back
|
301
|
-
deactivate_revision(e)
|
302
|
-
raise e
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
def activate_revision
|
307
|
-
S::PublishedRevision.create(:revision => revision, :published_at => now)
|
308
|
-
@site.send(:set_published_revision, revision)
|
309
|
-
write_revision(revision)
|
310
|
-
@site.trigger(:after_publish, revision)
|
311
|
-
@site.send(:pending_revision=, nil)
|
312
|
-
@content_model.cleanup_revisions(revision, keep_revisions)
|
313
|
-
end
|
314
|
-
|
315
|
-
def deactivate_revision(exception)
|
316
|
-
S::PublishedRevision.filter(:revision => revision).delete
|
317
|
-
@site.send(:set_published_revision, @previous_revision)
|
318
|
-
write_revision(@previous_revision)
|
319
|
-
abort_publish(exception)
|
320
|
-
end
|
321
|
-
|
322
|
-
# Makes the revision live on the filesystem by symlinking the revisions/current
|
323
|
-
# directory to the revision directory and writing the current revision to the
|
324
|
-
# revisions/REVISION file.
|
325
|
-
def write_revision(revision)
|
326
|
-
symlink_revision(revision)
|
327
|
-
generate_revision_file(revision)
|
328
|
-
end
|
329
|
-
|
330
|
-
def symlink_revision(rev)
|
331
|
-
system("ln -nsf #{Spontaneous.revision_dir(rev)} #{Spontaneous.revision_dir}")
|
332
|
-
end
|
333
|
-
|
334
|
-
def abort_publish_at_exit
|
335
|
-
abort_publish(nil)
|
336
|
-
end
|
337
|
-
|
338
|
-
def abort_publish(exception)
|
339
|
-
if (r = @site.pending_revision)
|
340
|
-
update_progress("aborting")
|
341
|
-
@render_transaction.rollback if @render_transaction
|
342
|
-
@site.output_store.revision(r).delete # we might have committed the transaction
|
343
|
-
@site.send(:pending_revision=, nil)
|
344
|
-
@content_model.delete_revision(revision)
|
345
|
-
puts exception.backtrace.join("\n") if exception
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
def keep_revisions
|
350
|
-
@site.config.keep_revisions || KEEP_REVISIONS
|
351
|
-
end
|
352
|
-
end # Immediate
|
353
|
-
end # Publishing
|
354
|
-
end # Spontaneous
|
6
|
+
module Spontaneous::Publishing
|
7
|
+
class Immediate
|
8
|
+
include ::Simultaneous::Task
|
9
|
+
|
10
|
+
attr_reader :revision
|
11
|
+
|
12
|
+
def initialize(site, revision, steps)
|
13
|
+
@site, @revision, @steps = site, revision, steps
|
14
|
+
end
|
15
|
+
|
16
|
+
def publish_pages(pages)
|
17
|
+
publish.publish_pages(pages)
|
18
|
+
end
|
19
|
+
|
20
|
+
def publish_all
|
21
|
+
publish.publish_all
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish
|
25
|
+
Publish.new(@site, @revision, @steps)
|
26
|
+
end
|
27
|
+
|
28
|
+
def rerender
|
29
|
+
Rerender.new(@site, @revision, @steps).rerender
|
30
|
+
end
|
31
|
+
|
32
|
+
def rerender_revision
|
33
|
+
logger.info { "Re-rendering revision #{@revision}"}
|
34
|
+
render_revision
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Spontaneous::Publishing
|
2
|
+
class Pipeline
|
3
|
+
attr_reader :steps
|
4
|
+
|
5
|
+
def initialize(steps)
|
6
|
+
@steps = Array(steps)
|
7
|
+
@completed = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(site, revision, pages, progress)
|
11
|
+
calculate_step_count(site, revision, pages, progress)
|
12
|
+
run_steps(site, revision, pages, progress)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_steps(site, revision, pages, progress)
|
16
|
+
begin
|
17
|
+
run_steps!(site, revision, pages, progress)
|
18
|
+
rescue Exception => e
|
19
|
+
rollback_steps!(site, revision, pages, progress)
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_steps!(site, revision, pages, progress)
|
25
|
+
steps.each do |step|
|
26
|
+
@completed << step.call(site, revision, pages, progress)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def rollback_steps!(site, revision, pages, progress)
|
31
|
+
@completed.each do |step|
|
32
|
+
step.rollback if step && step.respond_to?(:rollback)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def calculate_step_count(site, revision, pages, progress)
|
37
|
+
count = steps.map { |step|
|
38
|
+
step.respond_to?(:count) ? step.count(site, revision, pages, progress) : 0
|
39
|
+
}.inject(0, :+)
|
40
|
+
progress.start(count)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|