jekyll-app-engine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +24 -0
  3. data/.simplecov +3 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +6 -0
  6. data/History.markdown +7 -0
  7. data/LICENSE +21 -0
  8. data/README.md +97 -0
  9. data/Rakefile +6 -0
  10. data/jekyll-app-engine.gemspec +22 -0
  11. data/lib/app.yaml +1 -0
  12. data/lib/google-yaml.rb +42 -0
  13. data/lib/jekyll-app-engine.rb +171 -0
  14. data/script/bootstrap +3 -0
  15. data/script/cibuild +4 -0
  16. data/script/console +34 -0
  17. data/script/release +7 -0
  18. data/spec/fixtures/_app.yaml +11 -0
  19. data/spec/fixtures/_config.yml +9 -0
  20. data/spec/fixtures/_layouts/some_default.html +4 -0
  21. data/spec/fixtures/_my_collection/custom_permalink.md +5 -0
  22. data/spec/fixtures/_my_collection/custom_permalink_2.md +5 -0
  23. data/spec/fixtures/_my_collection/test.html +4 -0
  24. data/spec/fixtures/_my_collection/this-has-non-standard-chars.md +5 -0
  25. data/spec/fixtures/_other_things/test2.html +4 -0
  26. data/spec/fixtures/_posts/2013-12-12-dec-the-second.md +4 -0
  27. data/spec/fixtures/_posts/2014-03-02-march-the-second.md +4 -0
  28. data/spec/fixtures/_posts/2014-03-04-march-the-fourth.md +4 -0
  29. data/spec/fixtures/_posts/2015-01-18-jekyll-last-modified-at.md +4 -0
  30. data/spec/fixtures/feeds/atom.xml +6 -0
  31. data/spec/fixtures/images/hubot.png +0 -0
  32. data/spec/fixtures/index.html +7 -0
  33. data/spec/fixtures/jekyll-last-modified-at/page.html +4 -0
  34. data/spec/fixtures/some-subfolder/htm.htm +1 -0
  35. data/spec/fixtures/some-subfolder/test_index.html +4 -0
  36. data/spec/fixtures/some-subfolder/this-is-a-subfile.html +0 -0
  37. data/spec/fixtures/some-subfolder/this-is-a-subpage.html +4 -0
  38. data/spec/fixtures/some-subfolder/xhtml.xhtml +1 -0
  39. data/spec/jekyll-app-engine_spec.rb +131 -0
  40. data/spec/spec_helper.rb +28 -0
  41. metadata +175 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTA0NWU4YTkxMDBlODhlOGE1YzRlMzNmZTg4MjE3MTM3ZTJlMDcyZA==
5
+ data.tar.gz: !binary |-
6
+ YTRlNjQwYzAxNzRmYTNjN2RmNWIzN2M0MTNjMzExZWMyM2RlOTlkMg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZDQ5N2M2OTZkMzVhMDcxMzk0MDhiOWZiMjE0NWM3NmVkNTUwOTliNDZhM2Ji
10
+ ZTFiOWI4ZmU5ZTBlNmM1MDcyNGFhM2JkN2U0ZTZjYjBiZDdlOTBiMDNkYTM2
11
+ ZDNkNTE4Y2ZlZTA5OWVlNjc3OWYwZTQxOTRmZWI1OWRkMTNlZGM=
12
+ data.tar.gz: !binary |-
13
+ ZjU5OThlMTU2MjU2NDQzNjdmMDhlYzU2MTI3MTM4NDlmZDM1Yzg3MjhjM2Yw
14
+ Y2JmMDQyNGZlNzI0ZjM2MTAzOGJiOTJhYjBjNDU0NmJhZjRhM2Q1N2M4YWQ4
15
+ MDg1ODdhZGUwMzJhZGY5ZmZjMWUwNjU5MGMzNzA2YzMzM2I3YTI=
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/dest/
9
+ /spec/examples.txt
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+
14
+ ## Environment normalization:
15
+ /.bundle/
16
+ /vendor/bundle
17
+ /lib/bundler/man/
18
+
19
+ # for a library or gem, you might want to ignore these files since the code is
20
+ # intended to run in multiple environments; otherwise, check them in:
21
+ Gemfile.lock
22
+
23
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
24
+ .rvmrc
@@ -0,0 +1,3 @@
1
+ SimpleCov.start do
2
+ add_filter "/lib/google-yaml.rb"
3
+ end
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ script:
5
+ - rake
6
+ deploy:
7
+ provider: rubygems
8
+ gemspec: jekyll-app-engine.gemspec
9
+ api_key:
10
+ secure: gEbhxtKjKEz7JIez+hljl1IJMq8fyUOGKIXJWTWJnF4U3NZPHTq+Wv1AQKsgI80NpqTpCDTOfbiCPJ0Iti8XObkNjtfa7k9CNs/2MvQYcIWaDWP6ibgHTKZptiLh3IP+lkK3z2ZRvl4vaP/v2qKC16oaazqoli7Um0gj9dbX2A2PjxN9BZGMfgV1C3U1Igri7OWu37vVapuPvQ8NgeXOO8wWjP5tlJ2oOl0yHVXOVkw5Dwv8jpiFF0srz+lH+2FRG7yAZ95850okpNsyka+AOA1dJzBGZpyAwN3WCPQU0bsirijjDBdWpI0sxtSQFPA7z4up0PUv4/x34k9EtYjs31Xm4rtpItUiE7bgC8MVc4Li0gxhKuSQmAXozJHErM5GQZzeUUaaZffVbtKZsZUS2BX0zuRUO+22Jjfeh/nUkNiDPKVIIp5n7e2UPuGSruBy9t6GlR17KmLJ1uFV+a6WxTPlAUwS82WIuVdTzn2XrWc0WNLAHHfO3wJqFhwtGlowgmS7c7RTvc7MNkNk25e6P/p8TrEhameOxEjl6x7+lHXNZY6ssPwazGPagy2T39kSS/alCNYLuAIEkcFArM/c7tXPoajbYxpDdRJzmQm0ipKZ/xUp/Ij2GG3hF+Oq/9vBBF6/7oCLrC6Gynq7rXUlTaZURTkY3AzZQXlvmmYK4Ww=
11
+ on:
12
+ tags: true
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+
4
+ if ENV["JEKYLL_VERSION"]
5
+ gem "jekyll", "~> #{ENV["JEKYLL_VERSION"]}"
6
+ end
@@ -0,0 +1,7 @@
1
+ ## 0.1.0 / 2016-03-06
2
+
3
+ * Birthday!
4
+
5
+ ## 0.0.0 / 2016-02-24
6
+
7
+ * Initial alpha and experimentation
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 James Ramsay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # Jekyll App Engine: easy deployments to Google App Engine
2
+
3
+ [![Build Status](https://img.shields.io/travis/jamesramsay/jekyll-app-engine/master.svg)](https://travis-ci.org/jamesramsay/jekyll-app-engine)
4
+ [![Version](https://img.shields.io/gem/v/jekyll-app-engine.svg)](https://rubygems.org/gems/jekyll-app-engine)
5
+ [![Coverage Status](https://img.shields.io/codecov/c/github/jamesramsay/jekyll-app-engine/master.svg)](https://codecov.io/github/jamesramsay/jekyll-app-engine)
6
+
7
+ Jekyll App Engine (`jekyll-app-engine`) makes it easy to deploy your [Jekyll](http://jekyll.com) static site to [Google App Engine](https://appengine.google.com) by generating your `app.yaml` handlers.
8
+
9
+ Hosting your static site on Google App Engine gives you greater flexibility than using Github Pages and may potentially be cheaper and more configurable than Amazon AWS.
10
+ Using Google App Engine allows:
11
+
12
+ - fine grained HTTP cache control for pages and assets,
13
+ - HTTP/2 support including server push `Link: "</assets/style.css>; rel=preload; as=style,"`, and
14
+ - custom jekyll plugins not permitted by Github Pages, such as [`jekyll-assets`](http://github.com/jekyll/jekyll-assets)
15
+
16
+ Using Google App Engine has some challenges:
17
+
18
+ - Customising handling of 404 errors can only be done by running an application instance, which may be costly.
19
+
20
+ ## Get Started
21
+
22
+ These instructions assume you already have a [Google App Engine account](https://console.cloud.google.com/).
23
+
24
+ ### 1. Install jekyll-app-engine
25
+
26
+ Add `gem jekyll-app-engine` to your `Gemfile`.
27
+
28
+ ```
29
+ source 'https://rubygems.org'
30
+ gem 'github-pages'
31
+ gem 'jekyll-app-engine'
32
+ ```
33
+
34
+ Add to your `config.yml`.
35
+
36
+ ```yaml
37
+ gems:
38
+ - jekyll-app-engine
39
+ ```
40
+
41
+ ### 2. Basic configuration
42
+
43
+ Specify a basic configuration in the file `_app.yaml` or using the `app_engine` option configurations to your Jekyll `_config.yml`.
44
+
45
+ ```yaml
46
+ app_engine:
47
+ # Insert your configuration here or within _app.yaml
48
+ # You need to specify a runtime for App Engine
49
+ runtime: go
50
+ api_version: go1
51
+ default_expiration: 300s
52
+ ```
53
+
54
+ ### 3. Create an empty 'app'
55
+
56
+ App Engine expects all apps to have some sort of application.
57
+ Create a file called `init.go`.
58
+
59
+ ```go
60
+ // Included to enable deployment to Google App Engine
61
+ package hello
62
+
63
+ import (
64
+ )
65
+
66
+ func init() {
67
+ }
68
+ ```
69
+
70
+ You can put this anywhere, for example in a folder `_app/init.go` to keep your root tidy.
71
+
72
+ ### 4. Test and Deploy
73
+
74
+ Build your jekyll site, and you should notice the file `app.yaml` in the output directory.
75
+ Before deploying you will need to move this file to the projects root directory, where your `config.yml` file is located.
76
+
77
+ Automatic deployment using Travis: https://docs.travis-ci.com/user/deployment/google-app-engine
78
+
79
+ Manual deployment using the Google App Engine tools: todo
80
+
81
+ ## Documentation
82
+
83
+ ### Basic Configuration
84
+
85
+ jekyll-app-engine can be configured by creating a file `_app.yaml` in the source directory or by providing the configuration in the Jekyll config `_config.yml`.
86
+ The `handlers` option allows you to specify custom http headers and other feature supported by Google App Engine by Jekyll content type. The supported content types are:
87
+
88
+ - `posts`
89
+ - `pages`
90
+ - `collections`
91
+ - `static`
92
+
93
+ If you provide an Array or a `url` option, the configuration for the content type will be inserted directly as a handler, instead of generating a handler per item within the content type.
94
+
95
+ ### Document Specific Overrides
96
+
97
+ Each document can specify overrides within the document's YAML frontmatter.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "jekyll-app-engine"
5
+ spec.summary = "Generator for Google App Engine Handlers."
6
+ spec.version = "0.1.0"
7
+ spec.authors = ["James Ramsay"]
8
+ spec.email = "git@jwr.vc"
9
+ spec.homepage = "http://github.com/jamesramsay/jekyll-app-engine"
10
+ spec.licenses = ["MIT"]
11
+
12
+ spec.files = `git ls-files -z`.split("\x0")
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_development_dependency "jekyll", ">= 2.0"
18
+ spec.add_development_dependency "rspec", "~> 3.0"
19
+ spec.add_development_dependency "rake"
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "codecov"
22
+ end
@@ -0,0 +1 @@
1
+ {{ content }}
@@ -0,0 +1,42 @@
1
+ # Google App Engine doesn't support achors and alias feature of YAML
2
+ # Psych doesn't provide an option to disable achors/alias YAML features
3
+ #
4
+ # HACK: subclass the native YAMLTree, and bypass logic which checks for aliases
5
+ # ../psych/vistors/yaml_tree.rb
6
+ class GoogleYAMLTree < Psych::Visitors::YAMLTree
7
+ def accept target
8
+ # HACK: disabled alias lookup
9
+ # return any aliases we find
10
+ # if @st.key? target
11
+ # oid = @st.id_for target
12
+ # node = @st.node_for target
13
+ # anchor = oid.to_s
14
+ # node.anchor = anchor
15
+ # return @emitter.alias anchor
16
+ # end
17
+
18
+ if target.respond_to?(:to_yaml)
19
+ begin
20
+ loc = target.method(:to_yaml).source_location.first
21
+ if loc !~ /(syck\/rubytypes.rb|psych\/core_ext.rb)/
22
+ unless target.respond_to?(:encode_with)
23
+ if $VERBOSE
24
+ warn "implementing to_yaml is deprecated, please implement \"encode_with\""
25
+ end
26
+
27
+ target.to_yaml(:nodump => true)
28
+ end
29
+ end
30
+ rescue
31
+ # public_method or source_location might be overridden,
32
+ # and it's OK to skip it since it's only to emit a warning
33
+ end
34
+ end
35
+
36
+ if target.respond_to?(:encode_with)
37
+ dump_coder target
38
+ else
39
+ send(@dispatch_cache[target.class], target)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,171 @@
1
+ require 'fileutils'
2
+ require 'google-yaml'
3
+
4
+ module Jekyll
5
+
6
+ class PageWithoutAFile < Page
7
+ def read_yaml(*)
8
+ @data ||= {}
9
+ end
10
+ end
11
+
12
+ class JekyllAppEngine < Jekyll::Generator
13
+ safe true
14
+ priority :lowest
15
+
16
+ # Main plugin action, called by Jekyll-core
17
+ def generate(site)
18
+ @site = site
19
+ @app_engine = source_config
20
+
21
+ unless app_yaml_exists?
22
+ unless @app_engine
23
+ raise "App engine base configration not found"
24
+ end
25
+
26
+ @app_engine["handlers"] ||= {}
27
+
28
+ write
29
+ @site.keep_files ||= []
30
+ @site.keep_files << "app.yaml"
31
+ end
32
+ end
33
+
34
+ def source_config
35
+ if @site.config.has_key?("app_engine")
36
+ @site.config["app_engine"]
37
+ elsif source_partial_exists?
38
+ YAML.load_file(source_path)
39
+ end
40
+ end
41
+
42
+ # Checks if a optional _app.yaml partial already exists
43
+ def source_partial_exists?
44
+ if @site.respond_to?(:in_source_dir)
45
+ File.exists? @site.in_source_dir("_app.yaml")
46
+ else
47
+ File.exists? Jekyll.sanitized_path(@site.source, "_app.yaml")
48
+ end
49
+ end
50
+
51
+ # Path to optional _app.yaml partial
52
+ def source_path
53
+ if @site.respond_to?(:in_source_dir)
54
+ @site.in_source_dir("_app.yaml")
55
+ else
56
+ Jekyll.sanitized_path(@site.source, "_app.yaml")
57
+ end
58
+ end
59
+
60
+ # Destination for app.yaml file within the site source directory
61
+ def destination_path
62
+ if @site.respond_to?(:in_dest_dir)
63
+ @site.in_dest_dir("app.yaml")
64
+ else
65
+ Jekyll.sanitized_path(@site.dest, "app.yaml")
66
+ end
67
+ end
68
+
69
+ def write
70
+ FileUtils.mkdir_p File.dirname(destination_path)
71
+ File.open(destination_path, 'w') { |f| f.write(app_yaml_content) }
72
+ end
73
+
74
+ def app_yaml_content
75
+ # HACK: use sub-classed YAML implementation which disables anchors and aliases
76
+ builder = GoogleYAMLTree.create
77
+ builder << generate_app_engine_yaml
78
+
79
+ app_yaml = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", "app.yaml")
80
+ app_yaml.content = builder.tree.yaml
81
+ app_yaml.data["layout"] = nil
82
+ app_yaml.render({}, @site.site_payload)
83
+ return app_yaml.output
84
+ end
85
+
86
+ def output_collection?(label)
87
+ @site.config["collections"]["#{label}"]["output"]
88
+ end
89
+
90
+ def page_types
91
+ page_types_array = [
92
+ {
93
+ "content_type" => "posts",
94
+ "content_collection" => @site.posts.docs
95
+ },
96
+ {
97
+ "content_type" => "pages",
98
+ "content_collection" => @site.pages
99
+ },
100
+ {
101
+ "content_type" => "static",
102
+ "content_collection" => @site.static_files
103
+ },
104
+ ]
105
+
106
+ @site.collections.each_pair do |label, collection|
107
+ if label != "posts" and output_collection?(label)
108
+ page_types_array << {
109
+ "content_type" => "collections",
110
+ "content_collection" => collection.docs
111
+ }
112
+ end
113
+ end
114
+
115
+ return page_types_array
116
+ end
117
+
118
+ def generate_app_engine_yaml
119
+ app_yaml = @app_engine.dup
120
+ generated_handlers = []
121
+
122
+ page_types.each do |content|
123
+ generate_handlers(content).each { |handler| generated_handlers << handler }
124
+ end
125
+
126
+ app_yaml["handlers"] = generated_handlers
127
+
128
+ return app_yaml
129
+ end
130
+
131
+ def generate_handlers(content)
132
+ content_type = content["content_type"]
133
+ content_collection = content["content_collection"]
134
+ handlers = []
135
+
136
+ handler_template = @app_engine["handlers"][content_type] || {}
137
+ if handler_template.kind_of?(Array) or handler_template.has_key?("url")
138
+ handlers << handler_template
139
+ else
140
+ content_collection.each do |doc|
141
+ handler = {
142
+ "url" => doc.url,
143
+ "static_files" => doc.destination("").sub("#{Dir.pwd}/", ""),
144
+ "upload" => doc.destination("").sub("#{Dir.pwd}/", "")
145
+ }
146
+ handlers << handler.merge!(handler_template.dup).merge!(document_overrides(doc))
147
+ end
148
+ end
149
+
150
+ return handlers
151
+ end
152
+
153
+ # Document specific app.yaml configuration provided in yaml frontmatter
154
+ def document_overrides(document)
155
+ if document.respond_to?(:data) and document.data.has_key?("app_engine")
156
+ document.data.fetch("app_engine")
157
+ else
158
+ {}
159
+ end
160
+ end
161
+
162
+ # Checks if a app.yaml already exists in the site source
163
+ def app_yaml_exists?
164
+ if @site.respond_to?(:in_source_dir)
165
+ File.exists? @site.in_source_dir("app.yaml")
166
+ else
167
+ File.exists? Jekyll.sanitized_path(@site.source, "app.yaml")
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ bundle install
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ bundle exec rspec
@@ -0,0 +1,34 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ def relative_to_root(path)
4
+ File.expand_path(path, File.dirname(File.dirname(__FILE__)))
5
+ end
6
+
7
+ require 'jekyll'
8
+ require relative_to_root('lib/jekyll-app-engine.rb')
9
+ require 'pry-debugger'
10
+
11
+ SOURCE_DIR = relative_to_root('spec/fixtures')
12
+ DEST_DIR = relative_to_root('spec/dest')
13
+
14
+ def source_dir(*files)
15
+ File.join(SOURCE_DIR, *files)
16
+ end
17
+
18
+ def dest_dir(*files)
19
+ File.join(DEST_DIR, *files)
20
+ end
21
+
22
+ def config(overrides = {})
23
+ Jekyll.configuration({
24
+ "source" => source_dir,
25
+ "destination" => dest_dir,
26
+ "url" => "http://example.org"
27
+ }).merge(overrides)
28
+ end
29
+
30
+ def site(configuration = config)
31
+ Jekyll::Site.new(configuration)
32
+ end
33
+
34
+ binding.pry
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+ # Tag and push a release.
3
+
4
+ set -e
5
+
6
+ script/cibuild
7
+ bundle exec rake release
@@ -0,0 +1,11 @@
1
+ runtime: go
2
+ api_version: go1
3
+ default_expiration: 300s
4
+
5
+ handlers:
6
+ posts:
7
+ http_headers:
8
+ Link: "</static/css/style.css>; rel=preload; as=style"
9
+ post-static:
10
+ url: /images/
11
+ static_dir: spec/dest/images
@@ -0,0 +1,9 @@
1
+ timezone: UTC
2
+
3
+ defaults:
4
+ -
5
+ scope:
6
+ path: ""
7
+ type: page
8
+ values:
9
+ layout: some_default
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+ THIS IS MY LAYOUT
4
+ {{ content }}
@@ -0,0 +1,5 @@
1
+ ---
2
+ permalink: /permalink/
3
+ ---
4
+
5
+ # Custom permalink
@@ -0,0 +1,5 @@
1
+ ---
2
+ permalink: /permalink/unique_name.html
3
+ ---
4
+
5
+ # Unique html name
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ This is just a test.
@@ -0,0 +1,5 @@
1
+ ---
2
+ permalink: this url has an ümlaut
3
+ ---
4
+
5
+ # URL contains characters that need to be URI encoded
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ This file shouldn't show up in the app.yaml.
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ December the twelfth, actually.
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ March the second!
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ March the fourth!
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ Please don't modify this file. It's modified time is important.
@@ -0,0 +1,6 @@
1
+ ---
2
+ ---
3
+
4
+ <?xml version="1.0" encoding="utf-8"?>
5
+ <feed xmlns="http://www.w3.org/2005/Atom">
6
+ </feed>
@@ -0,0 +1,7 @@
1
+ ---
2
+ app_engine:
3
+ http_headers:
4
+ Cache-Control: "max-age=3600"
5
+ ---
6
+
7
+ HERE IS MY SITE I AM SO EXCITED TO BE USING GITHUB PAGES
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ This is a page with a modified time.
@@ -0,0 +1 @@
1
+ This file has an .htm extension, and should be included in the app.yaml
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ The permalink of this page does not end with a '/', but with a filename
@@ -0,0 +1,4 @@
1
+ ---
2
+ ---
3
+
4
+ This is a subpage!
@@ -0,0 +1 @@
1
+ This file has an .xhtml extension, and should be included in the app.yaml
@@ -0,0 +1,131 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe(Jekyll::JekyllAppEngine) do
6
+ let(:overrides) do
7
+ {
8
+ "source" => source_dir,
9
+ "destination" => dest_dir,
10
+ "url" => "http://example.org",
11
+ "collections" => {
12
+ "my_collection" => { "output" => true },
13
+ "other_things" => { "output" => false }
14
+ }
15
+ }
16
+ end
17
+ let(:config) do
18
+ Jekyll.configuration(overrides)
19
+ end
20
+ let(:site) { Jekyll::Site.new(config) }
21
+ let(:contents) { File.read(dest_dir("app.yaml")) }
22
+ let(:app_yaml) { YAML.load_file(dest_dir("app.yaml")) }
23
+ let(:handlers) { app_yaml["handlers"] }
24
+ before(:each) do
25
+ site.process
26
+ end
27
+
28
+ it "has no layout" do
29
+ expect(contents).not_to match(/\ATHIS IS MY LAYOUT/)
30
+ end
31
+
32
+ it "creates an app.yaml file" do
33
+ expect(File.exist?(dest_dir("app.yaml"))).to be_truthy
34
+ end
35
+
36
+ it "doesn't have multiple new lines or trailing whitespace" do
37
+ expect(contents).to_not match /\s+\n/
38
+ expect(contents).to_not match /\n{2,}/
39
+ end
40
+
41
+ it "puts all the pages in the app.yaml file" do
42
+ expect(handlers).to include({
43
+ "url" => "/",
44
+ "static_files" => "spec/dest/index.html",
45
+ "upload" => "spec/dest/index.html",
46
+ "http_headers" => {
47
+ "Cache-Control" => "max-age=3600"
48
+ }
49
+ })
50
+ expect(handlers).to include({
51
+ "url" => "/some-subfolder/this-is-a-subpage.html",
52
+ "static_files" => "spec/dest/some-subfolder/this-is-a-subpage.html",
53
+ "upload" => "spec/dest/some-subfolder/this-is-a-subpage.html"
54
+ })
55
+ end
56
+
57
+ it "only strips 'index.html' from end of permalink" do
58
+ expect(handlers).to include({
59
+ "url" => "/some-subfolder/test_index.html",
60
+ "static_files" => "spec/dest/some-subfolder/test_index.html",
61
+ "upload" => "spec/dest/some-subfolder/test_index.html"
62
+ })
63
+ end
64
+
65
+ it "puts all the posts in the app.yaml file" do
66
+ expect(handlers).to include({
67
+ "url" => "/2013/12/12/dec-the-second.html",
68
+ "static_files" => "spec/dest/2013/12/12/dec-the-second.html",
69
+ "upload" => "spec/dest/2013/12/12/dec-the-second.html",
70
+ "http_headers" => {
71
+ "Link" => "</static/css/style.css>; rel=preload; as=style"
72
+ }
73
+ })
74
+ expect(handlers).to include({
75
+ "url" => "/2014/03/02/march-the-second.html",
76
+ "static_files" => "spec/dest/2014/03/02/march-the-second.html",
77
+ "upload" => "spec/dest/2014/03/02/march-the-second.html",
78
+ "http_headers" => {
79
+ "Link" => "</static/css/style.css>; rel=preload; as=style"
80
+ }
81
+ })
82
+ expect(handlers).to include({
83
+ "url" => "/2014/03/04/march-the-fourth.html",
84
+ "static_files" => "spec/dest/2014/03/04/march-the-fourth.html",
85
+ "upload" => "spec/dest/2014/03/04/march-the-fourth.html",
86
+ "http_headers" => {
87
+ "Link" => "</static/css/style.css>; rel=preload; as=style"
88
+ }
89
+ })
90
+ end
91
+
92
+ describe "collections" do
93
+ it "puts all the `output:true` into app.yaml" do
94
+ expect(handlers).to include({
95
+ "url" => "/my_collection/test.html",
96
+ "static_files" => "spec/dest/my_collection/test.html",
97
+ "upload" => "spec/dest/my_collection/test.html"
98
+ })
99
+ end
100
+
101
+ it "doesn't put all the `output:false` into app.yaml" do
102
+ expect(contents).to_not match /\/other_things\/test2\.html/
103
+ end
104
+ end
105
+
106
+ it "puts all the static HTML files in the app.yaml file" do
107
+ expect(handlers).to include({
108
+ "url" => "/some-subfolder/this-is-a-subfile.html",
109
+ "static_files" => "spec/dest/some-subfolder/this-is-a-subfile.html",
110
+ "upload" => "spec/dest/some-subfolder/this-is-a-subfile.html"
111
+ })
112
+ end
113
+
114
+ it "includes the correct number of items" do
115
+ expect(handlers.length).to eql 17
116
+ end
117
+
118
+ context "with a base in _config.yml" do
119
+ let(:config) do
120
+ config_override = { "app_engine" => {
121
+ "runtime" => "python27",
122
+ "api_version" => 1
123
+ } }
124
+ Jekyll.configuration(Jekyll::Utils.deep_merge_hashes(overrides, config_override))
125
+ end
126
+
127
+ it "correctly uses _config.yml runtime" do
128
+ expect(app_yaml["runtime"]).to eql "python27"
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,28 @@
1
+ require 'simplecov'
2
+
3
+ if ENV['CI'] == 'true'
4
+ require 'codecov'
5
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
6
+ end
7
+
8
+ require 'jekyll'
9
+ require File.expand_path('../lib/jekyll-app-engine', File.dirname(__FILE__))
10
+
11
+ Jekyll.logger.log_level = :error
12
+
13
+ RSpec.configure do |config|
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ config.order = 'random'
17
+
18
+ SOURCE_DIR = File.expand_path("../fixtures", __FILE__)
19
+ DEST_DIR = File.expand_path("../dest", __FILE__)
20
+
21
+ def source_dir(*files)
22
+ File.join(SOURCE_DIR, *files)
23
+ end
24
+
25
+ def dest_dir(*files)
26
+ File.join(DEST_DIR, *files)
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-app-engine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Ramsay
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email: git@jwr.vc
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .gitignore
90
+ - .simplecov
91
+ - .travis.yml
92
+ - Gemfile
93
+ - History.markdown
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - jekyll-app-engine.gemspec
98
+ - lib/app.yaml
99
+ - lib/google-yaml.rb
100
+ - lib/jekyll-app-engine.rb
101
+ - script/bootstrap
102
+ - script/cibuild
103
+ - script/console
104
+ - script/release
105
+ - spec/fixtures/_app.yaml
106
+ - spec/fixtures/_config.yml
107
+ - spec/fixtures/_layouts/some_default.html
108
+ - spec/fixtures/_my_collection/custom_permalink.md
109
+ - spec/fixtures/_my_collection/custom_permalink_2.md
110
+ - spec/fixtures/_my_collection/test.html
111
+ - spec/fixtures/_my_collection/this-has-non-standard-chars.md
112
+ - spec/fixtures/_other_things/test2.html
113
+ - spec/fixtures/_posts/2013-12-12-dec-the-second.md
114
+ - spec/fixtures/_posts/2014-03-02-march-the-second.md
115
+ - spec/fixtures/_posts/2014-03-04-march-the-fourth.md
116
+ - spec/fixtures/_posts/2015-01-18-jekyll-last-modified-at.md
117
+ - spec/fixtures/feeds/atom.xml
118
+ - spec/fixtures/images/hubot.png
119
+ - spec/fixtures/index.html
120
+ - spec/fixtures/jekyll-last-modified-at/page.html
121
+ - spec/fixtures/some-subfolder/htm.htm
122
+ - spec/fixtures/some-subfolder/test_index.html
123
+ - spec/fixtures/some-subfolder/this-is-a-subfile.html
124
+ - spec/fixtures/some-subfolder/this-is-a-subpage.html
125
+ - spec/fixtures/some-subfolder/xhtml.xhtml
126
+ - spec/jekyll-app-engine_spec.rb
127
+ - spec/spec_helper.rb
128
+ homepage: http://github.com/jamesramsay/jekyll-app-engine
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.4.5
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Generator for Google App Engine Handlers.
152
+ test_files:
153
+ - spec/fixtures/_app.yaml
154
+ - spec/fixtures/_config.yml
155
+ - spec/fixtures/_layouts/some_default.html
156
+ - spec/fixtures/_my_collection/custom_permalink.md
157
+ - spec/fixtures/_my_collection/custom_permalink_2.md
158
+ - spec/fixtures/_my_collection/test.html
159
+ - spec/fixtures/_my_collection/this-has-non-standard-chars.md
160
+ - spec/fixtures/_other_things/test2.html
161
+ - spec/fixtures/_posts/2013-12-12-dec-the-second.md
162
+ - spec/fixtures/_posts/2014-03-02-march-the-second.md
163
+ - spec/fixtures/_posts/2014-03-04-march-the-fourth.md
164
+ - spec/fixtures/_posts/2015-01-18-jekyll-last-modified-at.md
165
+ - spec/fixtures/feeds/atom.xml
166
+ - spec/fixtures/images/hubot.png
167
+ - spec/fixtures/index.html
168
+ - spec/fixtures/jekyll-last-modified-at/page.html
169
+ - spec/fixtures/some-subfolder/htm.htm
170
+ - spec/fixtures/some-subfolder/test_index.html
171
+ - spec/fixtures/some-subfolder/this-is-a-subfile.html
172
+ - spec/fixtures/some-subfolder/this-is-a-subpage.html
173
+ - spec/fixtures/some-subfolder/xhtml.xhtml
174
+ - spec/jekyll-app-engine_spec.rb
175
+ - spec/spec_helper.rb