stevenson 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +146 -0
- data/Rakefile +6 -0
- data/assets/template_aliases.yml +36 -0
- data/bin/stevenson +5 -0
- data/lib/stevenson/configurators/yaml_configurator.rb +99 -0
- data/lib/stevenson/output_filters/jekyll.rb +22 -0
- data/lib/stevenson/output_filters/zip.rb +46 -0
- data/lib/stevenson/template_loader.rb +50 -0
- data/lib/stevenson/templates/base.rb +45 -0
- data/lib/stevenson/templates/git.rb +27 -0
- data/lib/stevenson/templates/invalid_template_exception.rb +6 -0
- data/lib/stevenson/version.rb +3 -0
- data/lib/stevenson.rb +59 -0
- data/spec/configurators/yaml_configurator_spec.rb +12 -0
- data/spec/helpers.rb +14 -0
- data/spec/output_filters/jekyll_spec.rb +17 -0
- data/spec/output_filters/zip_spec.rb +17 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/template_loader_spec.rb +51 -0
- data/spec/templates/base_spec.rb +83 -0
- data/spec/templates/git_spec.rb +37 -0
- data/stevenson.gemspec +30 -0
- metadata +192 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 283a293b67a913eb19f38d5c26e28af097f7a397
|
4
|
+
data.tar.gz: b030b2e3298150ff97011f35de15d382170d3c4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9d7087c8863bb1e47c762409f3756ebabe512c93f1b1dc7276684baefe6c7bfdb438961538c8f3fc65e1d3e3098b8bc55bd633df86590d570a5eebea8f0ee771
|
7
|
+
data.tar.gz: f01181f0ee29f1cee4eb3c36a5d8da36d8142ad0d29fbd7480277f3092a4c4990c40ed3563dafb794e4f6d0e3fbcb7071b9640896125deff4e88d5ec6ca3f77d
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 RootsRated, LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# Stevenson
|
2
|
+
[](https://travis-ci.org/RootsRated/stevenson)
|
3
|
+
|
4
|
+
Stevenson is a [Jekyll](http://jekyllrb.com) microsite generator created by
|
5
|
+
RootsRated.com. Stevenson is named for Robert Louis Stevenson, author of *The
|
6
|
+
Strange Case of Dr. Jekyll and Mr. Hyde*.
|
7
|
+
[A project](https://github.com/dirk/stevenson) was previously created with this
|
8
|
+
name and a similar purpose about 2 years ago, but it hasn't been updated since.
|
9
|
+
This project is our attempt to resurrect the idea of a quick simple Jekyll site
|
10
|
+
generator.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'stevenson', :git => 'git://github.com/RootsRated/stevenson.git'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself with:
|
23
|
+
|
24
|
+
$ git clone git://github.com/RootsRated/stevenson.git
|
25
|
+
$ cd stevenson
|
26
|
+
$ rake install
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
### Basics
|
31
|
+
|
32
|
+
Use Stevenson to create a new microsite like this:
|
33
|
+
|
34
|
+
$ stevenson new hello_world
|
35
|
+
|
36
|
+
This will create a new directory in your current working directory named
|
37
|
+
`hello_world`. This directory should be a ready-to-use Jekyll
|
38
|
+
installation.
|
39
|
+
|
40
|
+
### Jekyll Compiling
|
41
|
+
|
42
|
+
Stevenson can automatically jekyll build a project and output a built directory
|
43
|
+
using the `-j` or `--jekyll`. Following the example from above, you can use the
|
44
|
+
following command:
|
45
|
+
|
46
|
+
$ stevenson new hello_world -j
|
47
|
+
|
48
|
+
This will output a directory called `hello_world` with the built assets from the
|
49
|
+
jekyll project created by the earlier command without the jekyll flag.
|
50
|
+
|
51
|
+
### Zip Output
|
52
|
+
|
53
|
+
Stevenson can also output directories as a zip archive using the `-z` or `--zip`
|
54
|
+
flags. The following command will produce the same result as the first example
|
55
|
+
as a zip archive:
|
56
|
+
|
57
|
+
$ stevenson new hello_world.zip -z
|
58
|
+
|
59
|
+
Also, the zip flag and jekyll flag can be used together to produce a built and
|
60
|
+
compress out like so:
|
61
|
+
|
62
|
+
$ stevenson new hello_world.zip -z -j
|
63
|
+
|
64
|
+
This will output a file called `hello_world.zip` with a ready-built website.
|
65
|
+
|
66
|
+
Remember that the first argument to `stevenson new` should have a `.zip` on the
|
67
|
+
end, as stevenson will not automatically add this extension.
|
68
|
+
|
69
|
+
### Templates
|
70
|
+
|
71
|
+
By default, stevenson will use RootsRated's
|
72
|
+
[Hyde](https://github.com/rootsrated/hyde) repo as the template for the new
|
73
|
+
site, but alternative templates can be used with the `--template` or `-t`
|
74
|
+
option, like so:
|
75
|
+
|
76
|
+
$ stevenson new hello_world -t https://github.com/YourUsername/YourTemplate.git
|
77
|
+
|
78
|
+
This will clone the repo at `https://github.com/YourUsername/YourTemplate.git`
|
79
|
+
to `hello_world` and begin altering the repo based on the contents of a
|
80
|
+
YAML file in your template's root directory named `_stevenson.yml`. This file
|
81
|
+
should contain config options to be set in various files of your Jekyll
|
82
|
+
installation along with information on whether these options should be secret,
|
83
|
+
validated as emails, validated as URLs, or limited to a certain length.
|
84
|
+
|
85
|
+
Here's an example of the YAML file:
|
86
|
+
|
87
|
+
#_stevenson.yml
|
88
|
+
'_config.yml':
|
89
|
+
title:
|
90
|
+
question: 'Title: '
|
91
|
+
limit: 40
|
92
|
+
email:
|
93
|
+
question: 'Email: '
|
94
|
+
email: true
|
95
|
+
description:
|
96
|
+
question: 'Description: '
|
97
|
+
url:
|
98
|
+
question: 'URL: '
|
99
|
+
url: true
|
100
|
+
|
101
|
+
This file will produce the following questions when
|
102
|
+
`stevenson new hello_world https://github.com/YourUsername/YourTemplate.git` is
|
103
|
+
used:
|
104
|
+
|
105
|
+
$ stevenson new hello_world -t https://github.com/YourUsername/YourTemplate.git
|
106
|
+
Title: My Site
|
107
|
+
Email: info@example.org
|
108
|
+
Description: Lorem Ipsum...
|
109
|
+
URL: http://www.example.org
|
110
|
+
|
111
|
+
When these questions are answered, the following will be added to
|
112
|
+
`hello_world/_config.yml`:
|
113
|
+
|
114
|
+
#_config.yml
|
115
|
+
title: RootsRated.com
|
116
|
+
email: info@rootsrated.com
|
117
|
+
description: This is a microsite created by RootsRated.com
|
118
|
+
url: http://www.rootsrated.com
|
119
|
+
|
120
|
+
**The 'question' of each option is required** and will be used to ask users for
|
121
|
+
input to replace these values.
|
122
|
+
|
123
|
+
Any values already set in the `_config.yml` will be used as defaults for these
|
124
|
+
questions.
|
125
|
+
|
126
|
+
## Similar Projects
|
127
|
+
|
128
|
+
Stevenson may not be the right tool for what you're trying to do, so here's a few
|
129
|
+
other projects with similar ideas but slight differences:
|
130
|
+
|
131
|
+
- [Octopress](http://octopress.org/) - Octopress is a build and management tool
|
132
|
+
for jekyll sites that's more targeted at blogging and personal sites than
|
133
|
+
microsites. Octopress is a much more complete solution for jekyll sites with a
|
134
|
+
much bigger community, however it definitely lacks some of the simplicity and
|
135
|
+
ease of Stevenson. If Stevenson is Sinatra, Octopress is Ruby on Rails.
|
136
|
+
- [The Original Stevenson Project](https://github.com/dirk/stevenson) - This
|
137
|
+
project was not a first. There was another project called Stevenson with a similar
|
138
|
+
idea a while back, but unfortunately it hasn't been updated in over 2 years.
|
139
|
+
|
140
|
+
## Contributing
|
141
|
+
|
142
|
+
1. Fork it ( https://github.com/RootsRated/stevenson/fork )
|
143
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
144
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
145
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
146
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
hyde-base:
|
2
|
+
git: https://github.com/RootsRated/hyde.git
|
3
|
+
subdirectory: base
|
4
|
+
templatedco-exmachina:
|
5
|
+
git: https://github.com/RootsRated/hyde.git
|
6
|
+
subdirectory: exmachina
|
7
|
+
templatedco-horizons:
|
8
|
+
git: https://github.com/RootsRated/hyde.git
|
9
|
+
subdirectory: horizons
|
10
|
+
templatedco-ion:
|
11
|
+
git: https://github.com/RootsRated/hyde.git
|
12
|
+
subdirectory: ion
|
13
|
+
templatedco-linear:
|
14
|
+
git: https://github.com/RootsRated/hyde.git
|
15
|
+
subdirectory: linear
|
16
|
+
templatedco-phaseshift:
|
17
|
+
git: https://github.com/RootsRated/hyde.git
|
18
|
+
subdirectory: phaseshift
|
19
|
+
templatedco-solarize:
|
20
|
+
git: https://github.com/RootsRated/hyde.git
|
21
|
+
subdirectory: solarize
|
22
|
+
rr-base:
|
23
|
+
git: https://github.com/RootsRated/rootsrated_hyde.git
|
24
|
+
subdirectory: base
|
25
|
+
rr-ironman:
|
26
|
+
git: https://github.com/RootsRated/rootsrated_hyde.git
|
27
|
+
subdirectory: ironman
|
28
|
+
rr-ironwood:
|
29
|
+
git: https://github.com/RootsRated/rootsrated_hyde.git
|
30
|
+
subdirectory: ironwood
|
31
|
+
rr-new-balance:
|
32
|
+
git: https://github.com/RootsRated/rootsrated_hyde.git
|
33
|
+
subdirectory: new-balance
|
34
|
+
rr-ski-seattle:
|
35
|
+
git: https://github.com/RootsRated/rootsrated_hyde.git
|
36
|
+
subdirectory: ski-seattle
|
data/bin/stevenson
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Stevenson
|
5
|
+
module Configurator
|
6
|
+
class YAMLConfigurator
|
7
|
+
def initialize(config_path)
|
8
|
+
# Save the config path for later use
|
9
|
+
@config_path = config_path
|
10
|
+
|
11
|
+
# Load options from the template
|
12
|
+
@root_options = load_yaml File.join(config_path, '_stevenson.yml')
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure(path=nil, options=nil)
|
16
|
+
# If no options are provided, use the root_options
|
17
|
+
options ||= @root_options
|
18
|
+
|
19
|
+
# If no path is provided, use the config_path
|
20
|
+
path ||= @config_path
|
21
|
+
|
22
|
+
# If the path is a directory, recursively configure that directory
|
23
|
+
if File.directory? path
|
24
|
+
# Iterate through each option provided
|
25
|
+
options.each do |key, value|
|
26
|
+
configure "#{path}/#{key}", value
|
27
|
+
end
|
28
|
+
else
|
29
|
+
# If path is a file, load the YAML from that file
|
30
|
+
config = load_yaml path
|
31
|
+
|
32
|
+
# Collect answers for the config in the file
|
33
|
+
config = collect_answers options, config
|
34
|
+
|
35
|
+
# And save the config back to YAML file.
|
36
|
+
save_yaml path, config
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def collect_answers(options, config)
|
43
|
+
if !options['question'] || options['question'].is_a?(Hash)
|
44
|
+
# If the current option is not a leaf, iterate over its values
|
45
|
+
options.each do |key, value|
|
46
|
+
# If no key is present in the config, assign one
|
47
|
+
config[key] = {} unless config[key]
|
48
|
+
|
49
|
+
# Recursively collect answers for the current key in the config and
|
50
|
+
# options
|
51
|
+
config[key] = collect_answers value, config[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the new config
|
55
|
+
config
|
56
|
+
else
|
57
|
+
# If the option is not a hash, ask the user for input set the key in
|
58
|
+
# the config to it
|
59
|
+
ask_question options, config
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_yaml(path)
|
64
|
+
# If a YAML file is present, load it
|
65
|
+
if File.file? path
|
66
|
+
YAML.load_file(path) || {}
|
67
|
+
else
|
68
|
+
# Otherwise, return an empty hash
|
69
|
+
{}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def save_yaml(path, config)
|
74
|
+
# Write config to path as YAML
|
75
|
+
File.open(path, 'w') do |f|
|
76
|
+
f.write config.to_yaml
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def ask_question(options, default_value)
|
81
|
+
# Load the question text and highline options hash
|
82
|
+
question = options['question']
|
83
|
+
options.delete 'question'
|
84
|
+
|
85
|
+
# Ask the user the question and apply all options
|
86
|
+
answer = ask(question) do |q|
|
87
|
+
q.default = default_value if default_value != {}
|
88
|
+
q.echo = false if options['secret']
|
89
|
+
q.validate = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i if options['email']
|
90
|
+
q.validate = /https?:\/\/[\S]+/ if options['url']
|
91
|
+
q.limit = options['limit'] if options['limit']
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return the user's answer
|
95
|
+
answer.to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Stevenson
|
2
|
+
module OutputFilters
|
3
|
+
module JekyllFilter
|
4
|
+
def output(directory)
|
5
|
+
# Jekyll Build the Directory
|
6
|
+
Dir.chdir(path) do
|
7
|
+
`jekyll b`
|
8
|
+
end
|
9
|
+
|
10
|
+
# Replace the repository with the compiled directory
|
11
|
+
Dir.mktmpdir do |dir|
|
12
|
+
FileUtils.cp_r File.join(path, '_site', '.'), dir
|
13
|
+
FileUtils.rm_r path
|
14
|
+
FileUtils.cp_r dir, path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Call the parent method
|
18
|
+
super directory
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'zip'
|
2
|
+
|
3
|
+
module Stevenson
|
4
|
+
module OutputFilters
|
5
|
+
module ZipFilter
|
6
|
+
def output(directory)
|
7
|
+
Dir.mktmpdir do |dir|
|
8
|
+
# Call the parent method
|
9
|
+
super dir
|
10
|
+
|
11
|
+
# Zip up the output directory
|
12
|
+
write dir, directory
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def write(inputDir, outputFile)
|
19
|
+
@inputDir = inputDir
|
20
|
+
@outputFile = outputFile
|
21
|
+
|
22
|
+
entries = Dir.entries(@inputDir)
|
23
|
+
entries.delete(".")
|
24
|
+
entries.delete("..")
|
25
|
+
io = Zip::File.open(@outputFile, Zip::File::CREATE)
|
26
|
+
|
27
|
+
writeEntries(entries, "", io)
|
28
|
+
io.close()
|
29
|
+
end
|
30
|
+
|
31
|
+
def writeEntries(entries, path, io)
|
32
|
+
entries.each { |e|
|
33
|
+
zipFilePath = path == "" ? e : File.join(path, e)
|
34
|
+
diskFilePath = File.join(@inputDir, zipFilePath)
|
35
|
+
if File.directory?(diskFilePath)
|
36
|
+
io.mkdir(zipFilePath)
|
37
|
+
subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
|
38
|
+
writeEntries(subdir, zipFilePath, io)
|
39
|
+
else
|
40
|
+
io.get_output_stream(zipFilePath) { |f| f.puts(File.open(diskFilePath, "rb").read())}
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'stevenson/templates/base'
|
2
|
+
require 'stevenson/templates/git'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Stevenson
|
6
|
+
class TemplateLoader
|
7
|
+
TEMPLATE_ALIASES_PATH = File.join('..', '..', 'assets', 'template_aliases.yml')
|
8
|
+
|
9
|
+
def self.load(template_name)
|
10
|
+
# If a template alias exists with the key template
|
11
|
+
if template_aliases[template_name]
|
12
|
+
# Load a template and return it
|
13
|
+
load_template template_aliases[template_name]
|
14
|
+
elsif template_name =~ /^.*\.git$/
|
15
|
+
# If the given string is a git url, load the git template and return it
|
16
|
+
Templates::GitTemplate.new template_name
|
17
|
+
else
|
18
|
+
# Otherwise, return a new template using the name as a path
|
19
|
+
Templates::Base.new template_name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.template_aliases
|
24
|
+
# Get the path to the template aliases file
|
25
|
+
template_aliases_path = File.join(File.dirname(__FILE__), TEMPLATE_ALIASES_PATH)
|
26
|
+
|
27
|
+
# Load the template aliases
|
28
|
+
template_aliases = YAML.load_file template_aliases_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.load_template(template_options)
|
32
|
+
# If the template options contain a git url, load the git template and return it
|
33
|
+
if template_options['git']
|
34
|
+
template = Templates::GitTemplate.new template_options['git']
|
35
|
+
|
36
|
+
# If the alias provides a branch, switch to it
|
37
|
+
template.switch_branch template_options['branch'] if template_options['branch']
|
38
|
+
|
39
|
+
# If the alias provides a subdirectory, switch to it
|
40
|
+
template.select_subdirectory template_options['subdirectory'] if template_options['subdirectory']
|
41
|
+
|
42
|
+
# Return the template
|
43
|
+
template
|
44
|
+
else
|
45
|
+
# Otherwise, return false
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'stevenson/templates/invalid_template_exception'
|
2
|
+
|
3
|
+
module Stevenson
|
4
|
+
module Templates
|
5
|
+
class Base
|
6
|
+
def initialize(path)
|
7
|
+
if !File.directory?(path)
|
8
|
+
# If the given path is not a directory, raise an invalid template exception
|
9
|
+
raise InvalidTemplateException.new('The given path is not a directory')
|
10
|
+
else
|
11
|
+
# Otherwise, copy the template to a temporary directory to work with
|
12
|
+
@path = Dir.mktmpdir
|
13
|
+
FileUtils.cp_r File.join(path, '.'), @path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def path
|
18
|
+
# Return the path to the repo
|
19
|
+
@path
|
20
|
+
end
|
21
|
+
|
22
|
+
def select_subdirectory(directory)
|
23
|
+
# Create a new temporary directory to work from
|
24
|
+
new_path = Dir.mktmpdir
|
25
|
+
|
26
|
+
# Copy files from the subdirectory to the new temp dir
|
27
|
+
FileUtils.cp_r File.join(@path, directory, '.'), new_path
|
28
|
+
|
29
|
+
# Remove the old temporary directory
|
30
|
+
FileUtils.remove_entry_secure @path
|
31
|
+
|
32
|
+
# Set the path to the new path
|
33
|
+
@path = new_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def output(directory)
|
37
|
+
# Copy the configured template to the output_directory
|
38
|
+
FileUtils.copy_entry @path, directory
|
39
|
+
|
40
|
+
# Cleanup the temporary directory
|
41
|
+
FileUtils.remove_entry_secure @path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'stevenson/templates/base'
|
3
|
+
|
4
|
+
module Stevenson
|
5
|
+
module Templates
|
6
|
+
class GitTemplate < Base
|
7
|
+
def initialize(template_url)
|
8
|
+
# Create a temporary directory to clone the repo at
|
9
|
+
Dir.mktmpdir do |dir|
|
10
|
+
# Clone the repo to a temporary directory for later use
|
11
|
+
Git.clone template_url, File.join(dir, 'repo')
|
12
|
+
|
13
|
+
# Call the super, thereby assigning the @path
|
14
|
+
super File.join(dir, 'repo')
|
15
|
+
end
|
16
|
+
rescue Git::GitExecuteError => e
|
17
|
+
# If the given URL is not valid, raise an exception and cleanup
|
18
|
+
raise InvalidTemplateException.new('Failed to clone the repository')
|
19
|
+
end
|
20
|
+
|
21
|
+
def switch_branch(branch)
|
22
|
+
repo = Git::Base.open(path)
|
23
|
+
repo.checkout(branch)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/stevenson.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'stevenson/configurators/yaml_configurator'
|
2
|
+
require 'stevenson/output_filters/jekyll'
|
3
|
+
require 'stevenson/output_filters/zip'
|
4
|
+
require 'stevenson/template_loader'
|
5
|
+
require 'stevenson/version'
|
6
|
+
require 'thor'
|
7
|
+
|
8
|
+
module Stevenson
|
9
|
+
|
10
|
+
class Application < Thor
|
11
|
+
desc 'stevenson new PROJECT_NAME', 'generates a Jekyll at PROJECT_NAME'
|
12
|
+
|
13
|
+
method_option :branch,
|
14
|
+
aliases: '-b',
|
15
|
+
desc: 'The git branch you would like to use from your template'
|
16
|
+
method_option :jekyll,
|
17
|
+
type: :boolean,
|
18
|
+
aliases: '-j',
|
19
|
+
desc: 'Jekyll compiles the output directory'
|
20
|
+
method_option :subdirectory,
|
21
|
+
aliases: '-s',
|
22
|
+
desc: 'The subdirectory to use from the template, if any'
|
23
|
+
method_option :template,
|
24
|
+
aliases: '-t',
|
25
|
+
default: 'hyde-base',
|
26
|
+
desc: 'The template repository to use'
|
27
|
+
method_option :zip,
|
28
|
+
type: :boolean,
|
29
|
+
aliases: "-z",
|
30
|
+
desc: 'Zip compresses the output directory'
|
31
|
+
|
32
|
+
def new(output_directory)
|
33
|
+
# Load the template using the template loader
|
34
|
+
template = Stevenson::TemplateLoader.load options[:template]
|
35
|
+
|
36
|
+
# If a branch is provided, switch to that branch
|
37
|
+
template.switch_branch options[:branch] if options[:branch]
|
38
|
+
|
39
|
+
# If a subdirectory is provided, switch to that directory
|
40
|
+
template.select_subdirectory options[:subdirectory] if options[:subdirectory]
|
41
|
+
|
42
|
+
# Configure the template
|
43
|
+
configurator = Stevenson::Configurator::YAMLConfigurator.new template.path
|
44
|
+
configurator.configure
|
45
|
+
|
46
|
+
# If the jekyll flag is set, compile the template output
|
47
|
+
template.extend(Stevenson::OutputFilters::JekyllFilter) if options[:jekyll]
|
48
|
+
|
49
|
+
# If the zip flag is set, zip up the template output
|
50
|
+
template.extend(Stevenson::OutputFilters::ZipFilter) if options[:zip]
|
51
|
+
|
52
|
+
# Save the repo to the output directory
|
53
|
+
template.output output_directory
|
54
|
+
|
55
|
+
rescue Templates::InvalidTemplateException => e
|
56
|
+
say e.message
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
describe Stevenson::Configurator::YAMLConfigurator do
|
2
|
+
describe '#initialize' do
|
3
|
+
let(:temporary_directory) { Dir.mktmpdir }
|
4
|
+
let(:yaml_configurator) { Stevenson::Configurator::YAMLConfigurator.new temporary_directory }
|
5
|
+
|
6
|
+
it 'creates a new configurator' do
|
7
|
+
expect(yaml_configurator).to be_an_instance_of Stevenson::Configurator::YAMLConfigurator
|
8
|
+
end
|
9
|
+
|
10
|
+
after { FileUtils.remove_entry_secure temporary_directory }
|
11
|
+
end
|
12
|
+
end
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
describe Stevenson::OutputFilters::JekyllFilter do
|
2
|
+
describe '#output' do
|
3
|
+
let(:temporary_directory) { Dir.mktmpdir }
|
4
|
+
let(:template) { Stevenson::TemplateLoader.load 'hyde-base' }
|
5
|
+
|
6
|
+
before do
|
7
|
+
template.extend(subject)
|
8
|
+
template.output temporary_directory
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'outputs a jekyll compiled directory' do
|
12
|
+
expect(File.exists? File.join(temporary_directory, '_config.yml')).to eq false
|
13
|
+
end
|
14
|
+
|
15
|
+
after { FileUtils.remove_entry_secure temporary_directory }
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe Stevenson::OutputFilters::ZipFilter do
|
2
|
+
describe '#output' do
|
3
|
+
let(:temporary_directory) { Dir.mktmpdir }
|
4
|
+
let(:template) { Stevenson::Templates::GitTemplate.new 'https://github.com/RootsRated/stevenson-base-template.git' }
|
5
|
+
|
6
|
+
before do
|
7
|
+
template.extend(subject)
|
8
|
+
template.output File.join(temporary_directory, 'archive.zip')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'outputs a zipped directory' do
|
12
|
+
expect(File.exists? File.join(temporary_directory, 'archive.zip')).to eq true
|
13
|
+
end
|
14
|
+
|
15
|
+
after { FileUtils.remove_entry_secure temporary_directory }
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
describe Stevenson::TemplateLoader do
|
2
|
+
subject { Stevenson::TemplateLoader }
|
3
|
+
|
4
|
+
describe '.load' do
|
5
|
+
context 'when given a template alias' do
|
6
|
+
let(:template_alias) { 'hyde-base' }
|
7
|
+
let(:template) { subject.load template_alias }
|
8
|
+
|
9
|
+
it 'returns the appropriate template' do
|
10
|
+
expect(template).to be_an_instance_of Stevenson::Templates::GitTemplate
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
Dir.mktmpdir do |dir|
|
15
|
+
template.output dir
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when given a git url' do
|
21
|
+
let(:url) { 'https://github.com/RootsRated/stevenson-base-template.git' }
|
22
|
+
let(:template) { subject.load url }
|
23
|
+
|
24
|
+
it 'returns the appropriate template' do
|
25
|
+
expect(template).to be_an_instance_of Stevenson::Templates::GitTemplate
|
26
|
+
end
|
27
|
+
|
28
|
+
after do
|
29
|
+
Dir.mktmpdir do |dir|
|
30
|
+
template.output dir
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when given a path' do
|
36
|
+
let(:path) { Dir.mktmpdir }
|
37
|
+
let(:template) { subject.load path }
|
38
|
+
|
39
|
+
it 'returns the appropriate template' do
|
40
|
+
expect(template).to be_an_instance_of Stevenson::Templates::Base
|
41
|
+
end
|
42
|
+
|
43
|
+
after do
|
44
|
+
FileUtils.remove_entry_secure path
|
45
|
+
Dir.mktmpdir do |dir|
|
46
|
+
template.output dir
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
describe Stevenson::Templates::Base do
|
2
|
+
subject { Stevenson::Templates::Base }
|
3
|
+
|
4
|
+
describe '#initialize' do
|
5
|
+
context 'with a valid path' do
|
6
|
+
let(:path) { Dir.mktmpdir }
|
7
|
+
|
8
|
+
before { FileUtils.touch File.join(path, '_stevenson.yml') }
|
9
|
+
|
10
|
+
it 'creates a new Template' do
|
11
|
+
expect( subject.new path ).to be_an_instance_of Stevenson::Templates::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
after { FileUtils.remove_entry_secure path }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with an invalid path' do
|
18
|
+
let(:path) { Dir.mktmpdir }
|
19
|
+
|
20
|
+
it 'raises an invalid template exception' do
|
21
|
+
expect{ subject.new File.join(path, 'not-a-path') }.to raise_exception Stevenson::Templates::InvalidTemplateException
|
22
|
+
end
|
23
|
+
|
24
|
+
after { FileUtils.remove_entry_secure path }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#path' do
|
29
|
+
let(:path) { Dir.mktmpdir }
|
30
|
+
let(:template) { subject.new path }
|
31
|
+
|
32
|
+
before do
|
33
|
+
FileUtils.touch File.join(path, '_stevenson.yml')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns the path of the template' do
|
37
|
+
expect(File.exists? File.join(template.path, '_stevenson.yml')).to eq true
|
38
|
+
end
|
39
|
+
|
40
|
+
after { FileUtils.remove_entry_secure path }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#select_subdirectory' do
|
44
|
+
let(:path) { Dir.mktmpdir }
|
45
|
+
let(:subdirectory) { 'subdirectory' }
|
46
|
+
let(:template) { subject.new path }
|
47
|
+
|
48
|
+
before do
|
49
|
+
Dir.mkdir File.join(path, subdirectory)
|
50
|
+
FileUtils.touch File.join(path, subdirectory, '_stevenson.yml')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'changes the path of the template to a given subdirectory' do
|
54
|
+
template.select_subdirectory subdirectory
|
55
|
+
expect(File.exists? File.join(template.path, '_stevenson.yml')).to eq true
|
56
|
+
end
|
57
|
+
|
58
|
+
after do
|
59
|
+
template.output path
|
60
|
+
FileUtils.remove_entry_secure path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#output' do
|
65
|
+
let(:path) { Dir.mktmpdir }
|
66
|
+
let(:template) { subject.new path }
|
67
|
+
let(:temporary_directory) { Dir.mktmpdir }
|
68
|
+
|
69
|
+
before { template.output File.join(temporary_directory, 'output') }
|
70
|
+
|
71
|
+
it 'outputs the finished template to the directory' do
|
72
|
+
expect(File.exists? File.join(temporary_directory, 'output')).to eq true
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'destroys the temporary directory' do
|
76
|
+
expect(File.exists? template.path).to eq false
|
77
|
+
end
|
78
|
+
|
79
|
+
after do
|
80
|
+
FileUtils.remove_entry_secure temporary_directory
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe Stevenson::Templates::GitTemplate do
|
2
|
+
subject { Stevenson::Templates::GitTemplate }
|
3
|
+
|
4
|
+
describe '#initialize' do
|
5
|
+
context 'with a valid URL' do
|
6
|
+
let(:template) { subject.new 'https://github.com/RootsRated/stevenson-base-template.git' }
|
7
|
+
|
8
|
+
it 'creates a new GitTemplate' do
|
9
|
+
expect(template).to be_an_instance_of Stevenson::Templates::GitTemplate
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'clones the given repository to the working template path' do
|
13
|
+
expect(File.exists? File.join(template.path, 'base', '_config.yml')).to eq true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with an invalid URL' do
|
18
|
+
let(:invalid_url) { 'https://github.com/RootsRated/not-a-repo.git' }
|
19
|
+
|
20
|
+
it 'raises an invalid template exception' do
|
21
|
+
expect{ subject.new invalid_url }.to raise_exception(Stevenson::Templates::InvalidTemplateException)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#switch_branch' do
|
27
|
+
let(:branch) { 'master' }
|
28
|
+
let(:template) { subject.new 'https://github.com/RootsRated/stevenson-base-template.git' }
|
29
|
+
|
30
|
+
before { template.switch_branch branch }
|
31
|
+
|
32
|
+
it 'checksout the repo to the given branch' do
|
33
|
+
repo = Git::Base.open(template.path)
|
34
|
+
expect(repo.current_branch).to eq branch
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/stevenson.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'stevenson/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "stevenson"
|
8
|
+
spec.version = Stevenson::VERSION
|
9
|
+
spec.authors = ["Dylan Karr"]
|
10
|
+
spec.email = ["dylan@RootsRated.com"]
|
11
|
+
spec.summary = "Stevenson is a generator for Jekyll microsites created by RootsRated.com"
|
12
|
+
spec.description = "Stevenson is a simple generator for microsites using Jekyll"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
|
25
|
+
spec.add_dependency "git"
|
26
|
+
spec.add_dependency "highline"
|
27
|
+
spec.add_dependency "jekyll"
|
28
|
+
spec.add_dependency "rubyzip", ">= 1.0.0"
|
29
|
+
spec.add_dependency "thor"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stevenson
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dylan Karr
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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: git
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: highline
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: jekyll
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubyzip
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.0.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: thor
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Stevenson is a simple generator for microsites using Jekyll
|
126
|
+
email:
|
127
|
+
- dylan@RootsRated.com
|
128
|
+
executables:
|
129
|
+
- stevenson
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- assets/template_aliases.yml
|
141
|
+
- bin/stevenson
|
142
|
+
- lib/stevenson.rb
|
143
|
+
- lib/stevenson/configurators/yaml_configurator.rb
|
144
|
+
- lib/stevenson/output_filters/jekyll.rb
|
145
|
+
- lib/stevenson/output_filters/zip.rb
|
146
|
+
- lib/stevenson/template_loader.rb
|
147
|
+
- lib/stevenson/templates/base.rb
|
148
|
+
- lib/stevenson/templates/git.rb
|
149
|
+
- lib/stevenson/templates/invalid_template_exception.rb
|
150
|
+
- lib/stevenson/version.rb
|
151
|
+
- spec/configurators/yaml_configurator_spec.rb
|
152
|
+
- spec/helpers.rb
|
153
|
+
- spec/output_filters/jekyll_spec.rb
|
154
|
+
- spec/output_filters/zip_spec.rb
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
- spec/template_loader_spec.rb
|
157
|
+
- spec/templates/base_spec.rb
|
158
|
+
- spec/templates/git_spec.rb
|
159
|
+
- stevenson.gemspec
|
160
|
+
homepage: ''
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata: {}
|
164
|
+
post_install_message:
|
165
|
+
rdoc_options: []
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.2.2
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: Stevenson is a generator for Jekyll microsites created by RootsRated.com
|
184
|
+
test_files:
|
185
|
+
- spec/configurators/yaml_configurator_spec.rb
|
186
|
+
- spec/helpers.rb
|
187
|
+
- spec/output_filters/jekyll_spec.rb
|
188
|
+
- spec/output_filters/zip_spec.rb
|
189
|
+
- spec/spec_helper.rb
|
190
|
+
- spec/template_loader_spec.rb
|
191
|
+
- spec/templates/base_spec.rb
|
192
|
+
- spec/templates/git_spec.rb
|