smeagol 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.ruby +80 -0
  2. data/.yardopts +9 -0
  3. data/HISTORY.md +147 -0
  4. data/LICENSE.txt +30 -0
  5. data/README.md +132 -26
  6. data/bin/smeagol +9 -39
  7. data/bin/smeagol-init +3 -0
  8. data/bin/smeagol-preview +4 -0
  9. data/bin/smeagol-serve +4 -0
  10. data/bin/smeagol-update +4 -0
  11. data/bin/smeagold +1 -4
  12. data/lib/smeagol.rb +77 -6
  13. data/lib/smeagol/app.rb +121 -75
  14. data/lib/smeagol/cache.rb +43 -24
  15. data/lib/smeagol/cli.rb +166 -0
  16. data/lib/smeagol/config.rb +154 -0
  17. data/lib/smeagol/console.rb +369 -0
  18. data/lib/smeagol/controller.rb +275 -0
  19. data/lib/smeagol/core_ext.rb +12 -0
  20. data/lib/smeagol/gollum/blob_entry.rb +17 -0
  21. data/lib/smeagol/gollum/file.rb +44 -0
  22. data/lib/smeagol/gollum/page.rb +47 -0
  23. data/lib/smeagol/gollum/wiki.rb +31 -0
  24. data/lib/smeagol/helpers/rss.rb +96 -0
  25. data/lib/smeagol/helpers/toc.rb +69 -0
  26. data/lib/smeagol/public/assets/smeagol/gollum.css +716 -0
  27. data/lib/smeagol/public/{smeagol → assets/smeagol}/html5.js +0 -0
  28. data/lib/smeagol/public/{smeagol → assets/smeagol}/pygment.css +0 -0
  29. data/lib/smeagol/public/assets/smeagol/template.css +631 -0
  30. data/lib/smeagol/repository.rb +85 -0
  31. data/lib/smeagol/settings.rb +302 -0
  32. data/lib/smeagol/templates/layouts/page.mustache +19 -0
  33. data/lib/smeagol/templates/layouts/versions.mustache +16 -0
  34. data/lib/smeagol/templates/partials/footer.mustache +17 -0
  35. data/lib/smeagol/templates/partials/header.mustache +47 -0
  36. data/lib/smeagol/templates/settings.yml +64 -0
  37. data/lib/smeagol/version.rb +1 -1
  38. data/lib/smeagol/views/base.rb +188 -27
  39. data/lib/smeagol/views/form.rb +56 -0
  40. data/lib/smeagol/views/page.rb +126 -25
  41. data/lib/smeagol/views/post.rb +51 -0
  42. data/lib/smeagol/views/versions.rb +20 -6
  43. data/lib/smeagol/wiki.rb +25 -45
  44. data/test/helper.rb +72 -8
  45. data/test/test_app.rb +57 -0
  46. data/test/test_cache.rb +10 -11
  47. data/test/test_init.rb +27 -0
  48. data/test/test_update.rb +20 -0
  49. data/test/test_wiki.rb +13 -10
  50. metadata +142 -216
  51. data/bin/smeagol-static +0 -115
  52. data/lib/file.rb +0 -10
  53. data/lib/smeagol/hash.rb +0 -13
  54. data/lib/smeagol/option_parser.rb +0 -138
  55. data/lib/smeagol/public/smeagol/main.css +0 -234
  56. data/lib/smeagol/templates/page.mustache +0 -58
  57. data/lib/smeagol/templates/versions.mustache +0 -50
  58. data/test/test_file.rb +0 -12
  59. 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,16 @@
1
+ {{> header}}
2
+
3
+ <div id="wiki-content">
4
+ <div class="wrap">
5
+
6
+ <h1>Versions</h1>
7
+
8
+ <div id="wiki-body">
9
+ {{{content}}}
10
+ </div>
11
+
12
+ </div>
13
+ </div>
14
+
15
+ {{> footer}}
16
+
@@ -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
+