smeagol 0.5.9 → 0.6.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.
- data/.ruby +80 -0
- data/.yardopts +9 -0
- data/HISTORY.md +147 -0
- data/LICENSE.txt +30 -0
- data/README.md +132 -26
- data/bin/smeagol +9 -39
- data/bin/smeagol-init +3 -0
- data/bin/smeagol-preview +4 -0
- data/bin/smeagol-serve +4 -0
- data/bin/smeagol-update +4 -0
- data/bin/smeagold +1 -4
- data/lib/smeagol.rb +77 -6
- data/lib/smeagol/app.rb +121 -75
- data/lib/smeagol/cache.rb +43 -24
- data/lib/smeagol/cli.rb +166 -0
- data/lib/smeagol/config.rb +154 -0
- data/lib/smeagol/console.rb +369 -0
- data/lib/smeagol/controller.rb +275 -0
- data/lib/smeagol/core_ext.rb +12 -0
- data/lib/smeagol/gollum/blob_entry.rb +17 -0
- data/lib/smeagol/gollum/file.rb +44 -0
- data/lib/smeagol/gollum/page.rb +47 -0
- data/lib/smeagol/gollum/wiki.rb +31 -0
- data/lib/smeagol/helpers/rss.rb +96 -0
- data/lib/smeagol/helpers/toc.rb +69 -0
- data/lib/smeagol/public/assets/smeagol/gollum.css +716 -0
- data/lib/smeagol/public/{smeagol → assets/smeagol}/html5.js +0 -0
- data/lib/smeagol/public/{smeagol → assets/smeagol}/pygment.css +0 -0
- data/lib/smeagol/public/assets/smeagol/template.css +631 -0
- data/lib/smeagol/repository.rb +85 -0
- data/lib/smeagol/settings.rb +302 -0
- data/lib/smeagol/templates/layouts/page.mustache +19 -0
- data/lib/smeagol/templates/layouts/versions.mustache +16 -0
- data/lib/smeagol/templates/partials/footer.mustache +17 -0
- data/lib/smeagol/templates/partials/header.mustache +47 -0
- data/lib/smeagol/templates/settings.yml +64 -0
- data/lib/smeagol/version.rb +1 -1
- data/lib/smeagol/views/base.rb +188 -27
- data/lib/smeagol/views/form.rb +56 -0
- data/lib/smeagol/views/page.rb +126 -25
- data/lib/smeagol/views/post.rb +51 -0
- data/lib/smeagol/views/versions.rb +20 -6
- data/lib/smeagol/wiki.rb +25 -45
- data/test/helper.rb +72 -8
- data/test/test_app.rb +57 -0
- data/test/test_cache.rb +10 -11
- data/test/test_init.rb +27 -0
- data/test/test_update.rb +20 -0
- data/test/test_wiki.rb +13 -10
- metadata +142 -216
- data/bin/smeagol-static +0 -115
- data/lib/file.rb +0 -10
- data/lib/smeagol/hash.rb +0 -13
- data/lib/smeagol/option_parser.rb +0 -138
- data/lib/smeagol/public/smeagol/main.css +0 -234
- data/lib/smeagol/templates/page.mustache +0 -58
- data/lib/smeagol/templates/versions.mustache +0 -50
- data/test/test_file.rb +0 -12
- data/test/test_hash.rb +0 -18
@@ -0,0 +1,85 @@
|
|
1
|
+
module Smeagol
|
2
|
+
|
3
|
+
# Repostiory encapsulation. This class serves two needs,
|
4
|
+
# as a wiki repo (for Config) and as a site repo (for Settings).
|
5
|
+
# Which fields are actually used depends on which of these
|
6
|
+
# two use cases is at play.
|
7
|
+
#
|
8
|
+
class Repository
|
9
|
+
|
10
|
+
#
|
11
|
+
def initialize(opts={})
|
12
|
+
opts = OpenStruct.new(opts)
|
13
|
+
@path = opts.path
|
14
|
+
@origin = opts.origin
|
15
|
+
@ref = opts.ref || opts.tag || opts.branch || 'master'
|
16
|
+
@bare = opts.bare
|
17
|
+
@secret = opts.secret
|
18
|
+
@cname = opts.cname
|
19
|
+
@update = opts.update
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
attr_accessor :path
|
24
|
+
|
25
|
+
# Site's git repo uri.
|
26
|
+
# e.g. `git@github.com:trans/trans.github.com.git`
|
27
|
+
attr_accessor :origin
|
28
|
+
|
29
|
+
# For deployment site, if the repo is using detached branch approach,
|
30
|
+
# then specify the branch name here. This will typically be used
|
31
|
+
# for GitHub projects using `gh-pages`. Default is `master`.
|
32
|
+
attr_accessor :ref
|
33
|
+
|
34
|
+
# Alias for #ref.
|
35
|
+
alias tag ref
|
36
|
+
alias tag= ref=
|
37
|
+
|
38
|
+
# Alias for #ref.
|
39
|
+
alias branch ref
|
40
|
+
alias branch= ref=
|
41
|
+
|
42
|
+
# Passcode, if needed to interact with repo.
|
43
|
+
attr_accessor :secret
|
44
|
+
|
45
|
+
# Is the repository bare?
|
46
|
+
attr_accessor :bare
|
47
|
+
|
48
|
+
#
|
49
|
+
attr_accessor :cname
|
50
|
+
|
51
|
+
#
|
52
|
+
def auto_update?
|
53
|
+
@update
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
def repo
|
58
|
+
@repo ||= Grit::Repo.new(path, :is_bare=>bare)
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Pull down any changes.
|
63
|
+
#
|
64
|
+
def pull
|
65
|
+
repo.git.pull({}, 'origin', branch)
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# The old name for #pull.
|
70
|
+
#
|
71
|
+
alias :update :pull
|
72
|
+
|
73
|
+
#
|
74
|
+
# Clone repo to path.
|
75
|
+
#
|
76
|
+
def clone
|
77
|
+
# dummy location
|
78
|
+
tmp = ::File.join(::Dir.tmpdir, 'smeagol', Time.to_i)
|
79
|
+
git = Grit::Git.new(tmp)
|
80
|
+
git.clone({:quiet=>false, :verbose=>true, :progress=>true, :branch=>branch}, origin, path)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,302 @@
|
|
1
|
+
module Smeagol
|
2
|
+
|
3
|
+
# Wiki settings.
|
4
|
+
#
|
5
|
+
# TODO: Would it be possible/prudent to move all this into controller?
|
6
|
+
class Settings
|
7
|
+
|
8
|
+
# The name of the settings file.
|
9
|
+
# TODO: Rename to `_smeagol.yml` ?
|
10
|
+
FILE = "_settings.yml"
|
11
|
+
|
12
|
+
# Default template includes directory.
|
13
|
+
PARTIALS = '_partials'
|
14
|
+
|
15
|
+
# Default site stage directory.
|
16
|
+
SITE_PATH = '_site'
|
17
|
+
|
18
|
+
# Default sync command.
|
19
|
+
SYNC_SCRIPT = "rsync -arv --del --exclude .git* '%s/' '%s/'"
|
20
|
+
|
21
|
+
#
|
22
|
+
# Load settings.
|
23
|
+
#
|
24
|
+
# wiki_dir - Local file system location of wiki repo. [String]
|
25
|
+
#
|
26
|
+
# Returns settings instance. [Settings]
|
27
|
+
#
|
28
|
+
def self.load(wiki_dir=nil)
|
29
|
+
wiki_dir = Dir.pwd unless wiki_dir
|
30
|
+
file = File.join(wiki_dir, FILE)
|
31
|
+
file = File.expand_path(file)
|
32
|
+
if File.exist?(file)
|
33
|
+
settings = YAML.load_file(file)
|
34
|
+
else
|
35
|
+
settings = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
settings[:wiki_dir] = wiki_dir
|
39
|
+
|
40
|
+
new(settings)
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Initialize Settings.
|
45
|
+
#
|
46
|
+
# settings - Settings hash. [Hash]
|
47
|
+
#
|
48
|
+
def initialize(settings={})
|
49
|
+
@partials = PARTIALS
|
50
|
+
@index = 'Home'
|
51
|
+
@rss = true
|
52
|
+
@exclude = []
|
53
|
+
@include = []
|
54
|
+
@site = nil
|
55
|
+
@date_format = "%B %d, %Y"
|
56
|
+
@site_stage = nil
|
57
|
+
@site_sync = SYNC_SCRIPT
|
58
|
+
#@static = false
|
59
|
+
@mathjax = true
|
60
|
+
@future = false
|
61
|
+
|
62
|
+
# TODO: Raise error if no wiki_dir ?
|
63
|
+
@wiki_dir = settings[:wiki_dir]
|
64
|
+
|
65
|
+
assign(settings)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Deprecated: Access settings like a Hash.
|
69
|
+
def [](key)
|
70
|
+
__send__(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Assign settings hash via writer methods.
|
74
|
+
#
|
75
|
+
# Returns nothing.
|
76
|
+
def assign(settings={})
|
77
|
+
settings.each do |k,v|
|
78
|
+
__send__("#{k}=", v) if respond_to?("#{k}=")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Deprecated: Alias for #assign.
|
83
|
+
alias update assign
|
84
|
+
|
85
|
+
# Internal: Do not set this settings.yml!
|
86
|
+
attr_accessor :wiki_dir
|
87
|
+
|
88
|
+
# Gollum wiki's repo uri.
|
89
|
+
# e.g. `git@github.com:trans/trans.github.com.wiki.git`
|
90
|
+
attr_accessor :wiki_origin
|
91
|
+
|
92
|
+
# The particular tag or reference id to serve. Default is 'master'.
|
93
|
+
attr_accessor :wiki_ref
|
94
|
+
|
95
|
+
# Site's URL. If someone wanted to visit your website, this
|
96
|
+
# is the link they would follow, e.g. `http://trans.github.com`
|
97
|
+
attr_accessor :url
|
98
|
+
|
99
|
+
# If a site is intended for static deployment, `static` should be set to `true`.
|
100
|
+
#attr_accessor :static
|
101
|
+
|
102
|
+
#
|
103
|
+
def site
|
104
|
+
{'stage'=>site_stage, 'origin'=>site_origin, 'branch'=>site_branch}
|
105
|
+
end
|
106
|
+
|
107
|
+
# If deployment of a site is done via git or via a staging directory,
|
108
|
+
# then `site` can be used to set these.
|
109
|
+
#
|
110
|
+
# Examples
|
111
|
+
#
|
112
|
+
# site:
|
113
|
+
# origin: git@github.com:trans/trans.github.com.git
|
114
|
+
# branch: gh-pages
|
115
|
+
# path: _site
|
116
|
+
#
|
117
|
+
def site=(entry)
|
118
|
+
case entry
|
119
|
+
when Hash
|
120
|
+
self.site_origin = site['origin']
|
121
|
+
self.site_branch = site['branch']
|
122
|
+
self.site_stage = site['stage']
|
123
|
+
self.site_sync = site['sync'] if site['sync']
|
124
|
+
else
|
125
|
+
raise ArgumentError, 'site must be a mapping'
|
126
|
+
# TODO: maybe make this smarter in future to guess if single entry is origin or stage.
|
127
|
+
#self.site_stage = entry
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# If deployment of a site is done via git, then `site_origin` can be used to
|
132
|
+
# setup a Repository instance that can handle pulls and pushes automatically.
|
133
|
+
#
|
134
|
+
# Examples
|
135
|
+
#
|
136
|
+
# site_origin: git@github.com:trans/trans.github.com.git
|
137
|
+
#
|
138
|
+
attr_accessor :site_origin
|
139
|
+
|
140
|
+
# Special branch if using silly branch style, e.g. `gh-pages`.
|
141
|
+
attr_accessor :site_branch
|
142
|
+
|
143
|
+
# Set `site_stage` if the site needs to be staged for deployment.
|
144
|
+
# In other words, if the servable files in the wiki need to be
|
145
|
+
# copied into a separate directory. This can be set to `true`
|
146
|
+
# in which case the default `_site` path will be used, otherwise
|
147
|
+
# set it to the path desired.
|
148
|
+
#
|
149
|
+
# Non-absolute paths are relative to the wiki's location.
|
150
|
+
# Be sure to add this to the wiki's .gitignore file, if it is, and
|
151
|
+
# if not prefixed by and underscore, be sure to add it to `exclude`
|
152
|
+
# setting as well.
|
153
|
+
attr_accessor :site_stage
|
154
|
+
|
155
|
+
# Smeagol uses `rsync` to copy files from the repository to
|
156
|
+
# the staging location if given by `site_path`. By default this
|
157
|
+
# command is:
|
158
|
+
#
|
159
|
+
# "rsync -arv --del --exclude .git* %s/ %s/"
|
160
|
+
#
|
161
|
+
# Where the first %s is the repository location and the second is the location
|
162
|
+
# specified by the `site_path` setting. If this needs to be different it can
|
163
|
+
# be change here. Just be sure to honor the `%s` slots.
|
164
|
+
#
|
165
|
+
# If set to `~` (ie. `nil`) then the files will be copied directly
|
166
|
+
# to the site_path directory without using rsync.
|
167
|
+
attr_accessor :site_sync
|
168
|
+
|
169
|
+
# Where to find template partials. This is the location that Mustache uses
|
170
|
+
# when looking for partials. The default is `_partials`.
|
171
|
+
attr_accessor :partials
|
172
|
+
|
173
|
+
# Page to use as site index. The default is `Home`. A non-wiki
|
174
|
+
# page can be used as well, such as `index.html` (well, duh!).
|
175
|
+
attr_accessor :index
|
176
|
+
|
177
|
+
# Boolean flag to produce an rss.xml feed file for blog posts.
|
178
|
+
attr_accessor :rss
|
179
|
+
|
180
|
+
# Files to include that would not otherwise be included. A good example
|
181
|
+
# is `.htaccess` becuase dot files are excluded by default.
|
182
|
+
attr_accessor :include
|
183
|
+
|
184
|
+
# Files to exclude that would otherwise be included.
|
185
|
+
attr_accessor :exclude
|
186
|
+
|
187
|
+
# Include posts with future dates? By default all posts dated in the
|
188
|
+
# future are omitted.
|
189
|
+
attr_accessor :future
|
190
|
+
|
191
|
+
# Support the use of mathjax? Default is `true`.
|
192
|
+
attr_accessor :mathjax
|
193
|
+
|
194
|
+
# Do not load plugins. (TODO?)
|
195
|
+
#attr_accessor :safe
|
196
|
+
|
197
|
+
# TODO: I hate this. Make's me want to switch to Liquid templates.
|
198
|
+
# Hurry up with Mustache 2.0 already!
|
199
|
+
attr_accessor :date_format
|
200
|
+
|
201
|
+
# Title of site.
|
202
|
+
attr_accessor :title
|
203
|
+
|
204
|
+
# Single line description of site.
|
205
|
+
attr_accessor :tagline
|
206
|
+
|
207
|
+
# Detailed description of site.
|
208
|
+
attr_accessor :description
|
209
|
+
|
210
|
+
# Primary author/maintainer of site.
|
211
|
+
attr_accessor :author
|
212
|
+
|
213
|
+
# Menu that can be used in site template.
|
214
|
+
#
|
215
|
+
# Note this will probably be deprecated as it is easy
|
216
|
+
# enough to add a menu to your site's custom page template.
|
217
|
+
#
|
218
|
+
# Examples
|
219
|
+
#
|
220
|
+
# menu:
|
221
|
+
# - title: Blog
|
222
|
+
# href: /
|
223
|
+
# - title: Projects
|
224
|
+
# href: /Projects/
|
225
|
+
# - title: Tools
|
226
|
+
# href: /Tools/
|
227
|
+
# - title: Reads
|
228
|
+
# href: /Reads/
|
229
|
+
#
|
230
|
+
attr_accessor :menu
|
231
|
+
|
232
|
+
# Google analytics tracking id. Could be used for other such
|
233
|
+
# services if custom template is used.
|
234
|
+
#
|
235
|
+
# Note this will probably be deprecates because you can add
|
236
|
+
# the code snippet easily enough to your custom page template.
|
237
|
+
attr_accessor :tracking_id
|
238
|
+
|
239
|
+
# Include a GitHub "Fork Me" ribbon in corner of page. Entry
|
240
|
+
# should give color and position separated by a space.
|
241
|
+
# The resulting ribbon will have a link to `source_url`.
|
242
|
+
#
|
243
|
+
# TODO: Rename this `github_forkme` or something like that.
|
244
|
+
#
|
245
|
+
# Examples
|
246
|
+
#
|
247
|
+
# ribbon: red right
|
248
|
+
#
|
249
|
+
# Note this might be deprecated as one can add it by
|
250
|
+
# hand to custom page template.
|
251
|
+
attr_accessor :ribbon
|
252
|
+
|
253
|
+
# Project's development site, if applicable.
|
254
|
+
# e.g. `http://github.com/trans`
|
255
|
+
#
|
256
|
+
# TODO: Rename this field.
|
257
|
+
attr_accessor :source_url
|
258
|
+
|
259
|
+
# Expanded site directory.
|
260
|
+
#
|
261
|
+
# If `site_path` is an absolute path it will returned as given,
|
262
|
+
# otherwise this will be relative to the location of the wiki.
|
263
|
+
#
|
264
|
+
# Returns String of site path.
|
265
|
+
def site_path
|
266
|
+
site_path = (TrueClass === site_stage ? SITE_PATH : site_stage || SITE_PATH)
|
267
|
+
|
268
|
+
path = relative?(site_path) ? ::File.join(wiki_dir, site_path) : site_path
|
269
|
+
path.chomp('/') # ensure no trailing path separator
|
270
|
+
path
|
271
|
+
end
|
272
|
+
|
273
|
+
# Deprecated: Original name for #site_path.
|
274
|
+
alias :full_site_path :site_path
|
275
|
+
|
276
|
+
#
|
277
|
+
# Returns Repository object for git-based deployment site.
|
278
|
+
#
|
279
|
+
def site_repo
|
280
|
+
@site_repo ||= (
|
281
|
+
opts = (site || {}).dup
|
282
|
+
opts[:path] = site_path
|
283
|
+
Repository.new(opts)
|
284
|
+
)
|
285
|
+
end
|
286
|
+
|
287
|
+
# P R I V A T E M E T H O D S
|
288
|
+
|
289
|
+
private
|
290
|
+
|
291
|
+
#
|
292
|
+
def relative?(path)
|
293
|
+
return false if path =~ /^[A-Z]\:/
|
294
|
+
return false if path.start_with?(::File::SEPARATOR)
|
295
|
+
return false if path.start_with?('/')
|
296
|
+
#return false if path.start_with?('.')
|
297
|
+
return true
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{{> header}}
|
2
|
+
|
3
|
+
<!-- CONTENT -->
|
4
|
+
<div id="wiki-content">
|
5
|
+
<div class="wrap">
|
6
|
+
<div id="wiki-body" class="gollum-markdown-content">
|
7
|
+
<div id="template" class="markdown-body">
|
8
|
+
{{#not_home?}}
|
9
|
+
<h1>{{page_title}}</h1>
|
10
|
+
{{/not_home?}}
|
11
|
+
{{{content}}}
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<!-- END CONTENT -->
|
17
|
+
|
18
|
+
{{> footer}}
|
19
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!-- FOOTER -->
|
2
|
+
<div id="footer">
|
3
|
+
{{#author}}
|
4
|
+
<small style="float:left;">Last edited by <b>{{author}}</b> on {{date}}.</small>
|
5
|
+
{{/author}}
|
6
|
+
|
7
|
+
<small style="float:right;">
|
8
|
+
This site is a <a href="https://github.com/blog/699-making-github-more-open-git-backed-wikis">GitHub Wiki</a>
|
9
|
+
mirror powered by <a href="http://smeagolrb.info">Smeagol</a>.
|
10
|
+
</small>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
</div>
|
14
|
+
|
15
|
+
</body>
|
16
|
+
</html>
|
17
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>{{wiki_title}} - {{page_title}}</title>
|
5
|
+
|
6
|
+
<meta http-equiv="Content-type" content="text/html;charset=utf-8">
|
7
|
+
|
8
|
+
<link rel="stylesheet" href="{{base_path}}assets/smeagol/gollum.css" type="text/css"/>
|
9
|
+
<link rel="stylesheet" href="{{base_path}}assets/smeagol/pygment.css" type="text/css"/>
|
10
|
+
<link rel="stylesheet" href="{{base_path}}assets/smeagol/template.css" type="text/css"/>
|
11
|
+
|
12
|
+
<!--[if lt IE 9]>
|
13
|
+
<script src="{{base_path}}assets/smeagol/html5.js"></script>
|
14
|
+
<![endif]-->
|
15
|
+
|
16
|
+
<script type="text/javascript" src="/javascript/editor/gollum.editor.js"></script>
|
17
|
+
{{#mathjax}}
|
18
|
+
<script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
19
|
+
{{/mathjax}}
|
20
|
+
|
21
|
+
{{#tracking_id}}
|
22
|
+
<script type="text/javascript">
|
23
|
+
var _gaq = _gaq || [];
|
24
|
+
_gaq.push(['_setAccount', '{{{tracking_id}}}']);
|
25
|
+
_gaq.push(['_trackPageview']);
|
26
|
+
|
27
|
+
(function() {
|
28
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
29
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
30
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
31
|
+
})();
|
32
|
+
</script>
|
33
|
+
{{/tracking_id}}
|
34
|
+
</head>
|
35
|
+
|
36
|
+
<body>
|
37
|
+
{{{ribbon_html}}}
|
38
|
+
|
39
|
+
<div id="wiki-wrapper" class="page">
|
40
|
+
<div id="head">
|
41
|
+
<h1>{{wiki_title}}</h1>
|
42
|
+
|
43
|
+
<ul class="actions">
|
44
|
+
{{{menu_html}}}
|
45
|
+
</ul>
|
46
|
+
</div>
|
47
|
+
|