smeagol 0.5.9 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/smeagol/cli.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
module Smeagol
|
2
|
+
|
3
|
+
# Smeagol::CLI module is a function module that provide
|
4
|
+
# all command line interfaces.
|
5
|
+
#
|
6
|
+
module CLI
|
7
|
+
|
8
|
+
extend self
|
9
|
+
|
10
|
+
#
|
11
|
+
# Initialize Gollum wiki site for use with Smeagol.
|
12
|
+
#
|
13
|
+
def init(argv)
|
14
|
+
parser.banner = "usage: smeagol-init [OPTIONS] [WIKI-URI]\n"
|
15
|
+
|
16
|
+
parser.on('-t', '--title [TITLE]') do |title|
|
17
|
+
options[:title] = title
|
18
|
+
end
|
19
|
+
|
20
|
+
parser.on('-i', '--index [PAGE]') do |page_name|
|
21
|
+
options[:index] = page_name
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO: support more settings options for creating setup
|
25
|
+
|
26
|
+
Console.init(*parse(argv))
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Preview current Gollum wiki.
|
31
|
+
#
|
32
|
+
def preview(argv)
|
33
|
+
parser.banner = "Usage: smeagol-preview [OPTIONS]\n"
|
34
|
+
|
35
|
+
parser.on('--port [PORT]', 'Bind port (default 4567).') do |port|
|
36
|
+
options[:port] = port.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.on('--[no-]cache', 'Enables page caching.') do |flag|
|
40
|
+
options[:cache] = flag
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on('--mount-path', 'Serve website from this base path.') do |path|
|
44
|
+
options[:mount_path] = path
|
45
|
+
end
|
46
|
+
|
47
|
+
#parser.on('--auto-update', 'Updates the repository on a daily basis.') do |flag|
|
48
|
+
# options[:auto_update] = flag
|
49
|
+
#end
|
50
|
+
|
51
|
+
#parser.on('--secret [KEY]', 'Specifies the secret key used to update.') do |str|
|
52
|
+
# options[:secret] = str
|
53
|
+
#end
|
54
|
+
|
55
|
+
$stderr.puts "Starting preview..."
|
56
|
+
|
57
|
+
Console.preview(*parse(argv))
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Serve all Gollum repositories as setup in Deagol config file.
|
62
|
+
# This can be used to serve sites in production. It makes use
|
63
|
+
# of cnames to serve multiple sites via a single service.
|
64
|
+
#
|
65
|
+
def serve(argv)
|
66
|
+
config_file = nil
|
67
|
+
|
68
|
+
parser.banner = "usage: smeagol-serve [OPTIONS]\n"
|
69
|
+
|
70
|
+
parser.on('-c', '--config [PATH]', 'Load config file instead of default.') do |path|
|
71
|
+
options[:config_file] = path
|
72
|
+
end
|
73
|
+
|
74
|
+
parser.on('--port [PORT]', 'Bind port (default 4567).') do |port|
|
75
|
+
options[:port] = port.to_i
|
76
|
+
end
|
77
|
+
|
78
|
+
parser.on('--[no-]cache', 'Enables page caching.') do |flag|
|
79
|
+
options[:cache] = flag
|
80
|
+
end
|
81
|
+
|
82
|
+
parser.on('--mount-path', 'Serve website from this base path.') do |path|
|
83
|
+
options[:mount_path] = path
|
84
|
+
end
|
85
|
+
|
86
|
+
parser.on('--auto-update', 'Updates the repository on a daily basis.') do |flag|
|
87
|
+
options[:auto_update] = flag
|
88
|
+
end
|
89
|
+
|
90
|
+
parser.on('--secret [KEY]', 'Specifies the secret key, if needed to update.') do |str|
|
91
|
+
options[:secret] = str
|
92
|
+
end
|
93
|
+
|
94
|
+
Console.serve(*parse(argv))
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Update wiki repo and update/clone site repo, if designated
|
99
|
+
# in settings.
|
100
|
+
#
|
101
|
+
def update(argv)
|
102
|
+
parser.banner = "Usage: smeagol-update [OPTIONS] [WIKI-DIR]\n"
|
103
|
+
|
104
|
+
#parser.on('-s', '--site', 'Also update site directories, if applicable.') do
|
105
|
+
# options[:site] = true
|
106
|
+
#end
|
107
|
+
|
108
|
+
Console.update(*parse(argv))
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
#
|
114
|
+
# Command line options.
|
115
|
+
#
|
116
|
+
# Returns the command line options. [Hash]
|
117
|
+
#
|
118
|
+
def options
|
119
|
+
@options ||= {}
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Read command line options into `options` hash.
|
124
|
+
#
|
125
|
+
# Returns arguments and options. [Array]
|
126
|
+
#
|
127
|
+
def parse(argv)
|
128
|
+
begin
|
129
|
+
parser.parse!(argv)
|
130
|
+
rescue ::OptionParser::InvalidOption
|
131
|
+
puts "smeagol: #{$!.message}"
|
132
|
+
puts "smeagol: try 'smeagol --help' for more information"
|
133
|
+
exit 1
|
134
|
+
end
|
135
|
+
return *(argv + [options])
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Create and cache option parser.
|
140
|
+
#
|
141
|
+
# Returns option parser instance. [OptionParser]
|
142
|
+
#
|
143
|
+
def parser
|
144
|
+
@parser ||= (
|
145
|
+
parser = ::OptionParser.new
|
146
|
+
parser.on_tail('--quiet', 'Turn on $QUIET mode.') do
|
147
|
+
$QUIET = true
|
148
|
+
end
|
149
|
+
parser.on_tail('--debug', 'Turn on $DEBUG mode.') do
|
150
|
+
$DEBUG = true
|
151
|
+
end
|
152
|
+
parser.on_tail('-v', '--version', 'Display current version.') do
|
153
|
+
puts "Smeagol #{Smeagol::VERSION}"
|
154
|
+
exit 0
|
155
|
+
end
|
156
|
+
parser.on_tail('-h', '-?', '--help', 'Display this help screen.') do
|
157
|
+
puts parser
|
158
|
+
exit 0
|
159
|
+
end
|
160
|
+
parser
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module Smeagol
|
2
|
+
|
3
|
+
# Server configuration is used to store the options for the Smeagol
|
4
|
+
# server for serving sites.
|
5
|
+
#
|
6
|
+
# Configuration can be loaded from configuration files located
|
7
|
+
# at `/etc/smaegol/config.yml` and `~/.config/smaegol/config.yml`
|
8
|
+
# or `~/.smaegol/config.yml`. Here is an example configuration:
|
9
|
+
#
|
10
|
+
# Examples
|
11
|
+
#
|
12
|
+
# ---
|
13
|
+
# port: 3000
|
14
|
+
# auto_update: true
|
15
|
+
# cache_enabled: true
|
16
|
+
# repositories:
|
17
|
+
# - path: /path/to/wiki/repo
|
18
|
+
# cname: 'domain.name'
|
19
|
+
# origin: 'git@github.com:foo/foo.github.com.wiki.git'
|
20
|
+
# ref: master
|
21
|
+
# bare: false
|
22
|
+
# secret: 'pass123'
|
23
|
+
#
|
24
|
+
class Config
|
25
|
+
|
26
|
+
# Directory which contains user configuration.
|
27
|
+
CONFIG_HOME = ENV['XDG_CONFIG_HOME'] || '~/.config'
|
28
|
+
|
29
|
+
# Public: Load Smeagol server configuration.
|
30
|
+
#
|
31
|
+
# Returns [Config]
|
32
|
+
def self.load(file=nil)
|
33
|
+
config = {}
|
34
|
+
|
35
|
+
if file
|
36
|
+
config.update(load_config(file))
|
37
|
+
else
|
38
|
+
config.update(load_config('/etc/smeagol'))
|
39
|
+
config.update(load_config("#{CONFIG_HOME}/smeagol", '~/.smeagol'))
|
40
|
+
end
|
41
|
+
|
42
|
+
new(config)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Internal: Searches through the given directories looking for
|
46
|
+
# `settings.yml` file. Loads and returns the result of
|
47
|
+
# the first file found.
|
48
|
+
#
|
49
|
+
# dirs - List of directories to search for config file. [Array<String>]
|
50
|
+
#
|
51
|
+
# Returns configuration settings or empty Hash if none found. [Hash]
|
52
|
+
def self.load_config(*dirs)
|
53
|
+
dirs.each do |dir|
|
54
|
+
file = File.join(dir, 'config.yml')
|
55
|
+
file = File.expand_path(file)
|
56
|
+
if File.exist?(file)
|
57
|
+
return YAML.load_file(file)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
return {}
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Initialize new Config instance.
|
65
|
+
#
|
66
|
+
def initialize(settings={})
|
67
|
+
@port = 4567
|
68
|
+
@auto_update = false
|
69
|
+
@cache_enabled = true
|
70
|
+
@base_path = ''
|
71
|
+
@repositories = []
|
72
|
+
|
73
|
+
assign(settings)
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Given a Hash of settings, assign via writer methods.
|
78
|
+
#
|
79
|
+
def assign(settings={})
|
80
|
+
settings.each do |k,v|
|
81
|
+
__send__("#{k}=", v)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# A T T R I B U T E S
|
86
|
+
|
87
|
+
# Port to use for server. Default is 4567.
|
88
|
+
attr_accessor :port
|
89
|
+
|
90
|
+
# While running server, auto-update wiki every day.
|
91
|
+
attr_accessor :auto_update
|
92
|
+
alias :update :auto_update
|
93
|
+
alias :update= :auto_update=
|
94
|
+
|
95
|
+
# Use page cache to speed up page requests.
|
96
|
+
attr_accessor :cache
|
97
|
+
alias :cache_enabled :cache
|
98
|
+
alias :cache_enabled= :cache=
|
99
|
+
|
100
|
+
# Serve website via a given base path.
|
101
|
+
attr_accessor :base_path
|
102
|
+
alias :mount_path :base_path
|
103
|
+
alias :mount_path= :base_path=
|
104
|
+
|
105
|
+
# Wiki repository list.
|
106
|
+
#
|
107
|
+
# Examples
|
108
|
+
#
|
109
|
+
# repositories:
|
110
|
+
# - path: ~/wikis/banana-blog
|
111
|
+
# - cname: blog.bananas.org
|
112
|
+
# - secret: abc123
|
113
|
+
#
|
114
|
+
attr_reader :repositories
|
115
|
+
|
116
|
+
#
|
117
|
+
# Set list of repositories.
|
118
|
+
#
|
119
|
+
def repositories=(repos)
|
120
|
+
@repositories = (
|
121
|
+
repos.map do |repo|
|
122
|
+
case repo
|
123
|
+
when Repository then repo
|
124
|
+
else Repository.new(repo)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Deprecated: Ability to access config like hash.
|
132
|
+
#
|
133
|
+
def [](name)
|
134
|
+
instance_variable_get("@#{name}")
|
135
|
+
end
|
136
|
+
|
137
|
+
# Lookup git executable.
|
138
|
+
#def git
|
139
|
+
# ENV['git'] || ENV['GIT'] || 'git'
|
140
|
+
#end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Set secret for all repositories.
|
144
|
+
#
|
145
|
+
def secret=(secret)
|
146
|
+
return if secret.nil?
|
147
|
+
repositories.each do |repo|
|
148
|
+
repo.secret = secret
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
@@ -0,0 +1,369 @@
|
|
1
|
+
module Smeagol
|
2
|
+
|
3
|
+
# Console encapsulates all the public methods
|
4
|
+
# smeagol is likely to need, generally it maps
|
5
|
+
# to all the CLI commands.
|
6
|
+
#
|
7
|
+
module Console
|
8
|
+
extend self
|
9
|
+
|
10
|
+
#
|
11
|
+
def report(msg)
|
12
|
+
$stderr.puts msg unless $QUIET
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Initialize Gollum wiki for use with Smeagol.
|
17
|
+
# This will clone the wiki repo, if given and it
|
18
|
+
# doesn't already exist and create `_settings.yml`,
|
19
|
+
# `_layouts/` and `assets/smeagol/`.
|
20
|
+
#
|
21
|
+
# TODO: Perhaps use a supporting "managed copy" gem in future?
|
22
|
+
#
|
23
|
+
# TODO: Add --force option to override skips?
|
24
|
+
#
|
25
|
+
# Returns nothing.
|
26
|
+
#
|
27
|
+
def init(*args)
|
28
|
+
options = (Hash === args.last ? args.pop : {})
|
29
|
+
|
30
|
+
abort "Too many arguments." if args.size > 2
|
31
|
+
|
32
|
+
@wiki_url = args.shift
|
33
|
+
@wiki_dir = args.shift
|
34
|
+
|
35
|
+
if @wiki_url
|
36
|
+
unless @wiki_dir
|
37
|
+
@wiki_dir = File.basename(@wiki_url).chomp('.git')
|
38
|
+
end
|
39
|
+
@clone = true
|
40
|
+
else
|
41
|
+
@wiki_dir = Dir.pwd
|
42
|
+
if File.exist?(File.join(@wiki_dir, '.git'))
|
43
|
+
@wiki_url = wiki.repo.config['remote.origin.url'].to_s
|
44
|
+
else
|
45
|
+
abort "smeagol: not a git repo."
|
46
|
+
end
|
47
|
+
@clone = false
|
48
|
+
end
|
49
|
+
|
50
|
+
clone_wiki if @clone
|
51
|
+
|
52
|
+
save_settings(options)
|
53
|
+
save_gitignore
|
54
|
+
|
55
|
+
copy_layouts unless options[:no_layouts]
|
56
|
+
copy_assets unless options[:no_assets]
|
57
|
+
end
|
58
|
+
|
59
|
+
# The wiki git url.
|
60
|
+
attr_accessor :wiki_url
|
61
|
+
|
62
|
+
# Local directory to house wiki repo.
|
63
|
+
attr_accessor :wiki_dir
|
64
|
+
|
65
|
+
#
|
66
|
+
# If a wiki git URI is given, the clone the wiki.
|
67
|
+
#
|
68
|
+
# @todo Use grit instead of shelling out.
|
69
|
+
#
|
70
|
+
def clone_wiki
|
71
|
+
system "git clone #{wiki_url} #{wiki_dir}"
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Copy layout templates to `_layouts` directory and
|
76
|
+
# partial templates to `_partials`.
|
77
|
+
#
|
78
|
+
def copy_layouts
|
79
|
+
dst_dir = File.join(wiki_dir, '_layouts')
|
80
|
+
src_dir = LIBDIR + '/templates/layouts'
|
81
|
+
copy_dir(src_dir, dst_dir)
|
82
|
+
|
83
|
+
dst_dir = File.join(wiki_dir, '_partials')
|
84
|
+
src_dir = LIBDIR + '/templates/partials'
|
85
|
+
copy_dir(src_dir, dst_dir)
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Copy assets to `assets` directory.
|
90
|
+
#
|
91
|
+
def copy_assets
|
92
|
+
dst_dir = File.join(wiki_dir, 'assets')
|
93
|
+
src_dir = LIBDIR + '/public/assets'
|
94
|
+
copy_dir(src_dir, dst_dir)
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
def copy_dir(src_dir, dst_dir)
|
99
|
+
FileUtils.mkdir_p(dst_dir)
|
100
|
+
|
101
|
+
Dir[File.join(src_dir, '**/*')].each do |src|
|
102
|
+
next if File.directory?(src)
|
103
|
+
dst = File.join(dst_dir, src.sub(src_dir, ''))
|
104
|
+
copy_file(src, dst)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def copy_file(src, dst)
|
110
|
+
if File.exist?(dst)
|
111
|
+
report " skip: #{dst.sub(Dir.pwd,'')}"
|
112
|
+
else
|
113
|
+
FileUtils.mkdir_p(File.dirname(dst))
|
114
|
+
FileUtils.cp(src, dst)
|
115
|
+
report " copy: #{dst.sub(Dir.pwd,'')}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# Create or append `_site` to .gitignore file.
|
121
|
+
#
|
122
|
+
def save_gitignore
|
123
|
+
file = File.join(wiki_dir, '.gitignore')
|
124
|
+
if File.exist?(file)
|
125
|
+
File.open(file, 'a') do |f|
|
126
|
+
f.write("_site")
|
127
|
+
end
|
128
|
+
else
|
129
|
+
File.open(file, 'w') do |f|
|
130
|
+
f.write("_site")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Save settings.
|
137
|
+
#
|
138
|
+
def save_settings(options)
|
139
|
+
file = File.join(wiki_dir, "_settings.yml")
|
140
|
+
if File.exist?(file)
|
141
|
+
$stderr.puts " skip: #{file}"
|
142
|
+
else
|
143
|
+
text = Mustache.render(settings_template, initial_settings(options))
|
144
|
+
File.open(file, 'w') do |f|
|
145
|
+
f.write(text)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# When using #init, this provided the initial settings.
|
152
|
+
#
|
153
|
+
# @returns [Settings]
|
154
|
+
#
|
155
|
+
def initial_settings(options={})
|
156
|
+
options[:wiki_origin] = wiki_url
|
157
|
+
options[:site_origin] = wiki_url.sub('.wiki', '')
|
158
|
+
|
159
|
+
@settings = Settings.new(options)
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Read in the settings mustache template.
|
164
|
+
#
|
165
|
+
def settings_template
|
166
|
+
file = LIBDIR + '/templates/settings.yml'
|
167
|
+
IO.read(file)
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Preview current wiki (from working directory).
|
172
|
+
#
|
173
|
+
def preview(options)
|
174
|
+
repository = {}
|
175
|
+
repository[:path] = Dir.pwd
|
176
|
+
#repository[:cname] = options[:cname] if options[:cname]
|
177
|
+
repository[:secret] = options.delete(:secret) if options.key?(:secret)
|
178
|
+
|
179
|
+
options[:repositories] = [repository]
|
180
|
+
|
181
|
+
config = Smeagol::Config.new(options)
|
182
|
+
|
183
|
+
catch_signals
|
184
|
+
show_repository(config)
|
185
|
+
|
186
|
+
run_server(config)
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# Serve up sites defined in smeagol config file.
|
191
|
+
#
|
192
|
+
def serve(options)
|
193
|
+
config_file = options[:config_file]
|
194
|
+
config = Config.load(config_file)
|
195
|
+
config.assign(options)
|
196
|
+
abort "No repositories configured." if config.repositories.empty?
|
197
|
+
|
198
|
+
# Set secret on all repositories if passed in by command line option
|
199
|
+
# We can only assume they are all the same, in this case.
|
200
|
+
#
|
201
|
+
# TODO: Maybe only apply if no secret is given in config file?
|
202
|
+
if options[:secret]
|
203
|
+
config.repositories.each{ |r| r['secret'] = options['secret'] }
|
204
|
+
end
|
205
|
+
|
206
|
+
catch_signals
|
207
|
+
|
208
|
+
show_repository(config)
|
209
|
+
auto_update(config)
|
210
|
+
clear_caches(config)
|
211
|
+
|
212
|
+
run_server(config)
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# Setup trap signals.
|
217
|
+
#
|
218
|
+
def catch_signals
|
219
|
+
Signal.trap('TERM') do
|
220
|
+
Process.kill('KILL', 0)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
#
|
225
|
+
# Show repositories being served
|
226
|
+
#
|
227
|
+
def show_repository(server_config)
|
228
|
+
$stderr.puts "\n Now serving on port #{server_config.port} at /#{server_config.base_path}:"
|
229
|
+
server_config.repositories.each do |repository|
|
230
|
+
$stderr.puts " * #{repository.path} (#{repository.cname})"
|
231
|
+
end
|
232
|
+
$stderr.puts "\n"
|
233
|
+
end
|
234
|
+
|
235
|
+
#
|
236
|
+
# Run the auto update process.
|
237
|
+
#
|
238
|
+
def auto_update(server_config)
|
239
|
+
return unless server_config.auto_update
|
240
|
+
Thread.new do
|
241
|
+
while true do
|
242
|
+
sleep 86400
|
243
|
+
server_config.repositories.each do |repository|
|
244
|
+
next unless repository.auto_update?
|
245
|
+
out = repository.update
|
246
|
+
out = out[1] if Array === out
|
247
|
+
if out.index('Already up-to-date').nil?
|
248
|
+
$stderr.puts "== Repository updated at #{Time.new()} : #{repository.path} =="
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
#
|
256
|
+
# Clear the caches.
|
257
|
+
#
|
258
|
+
def clear_caches(server_config)
|
259
|
+
server_config.repositories.each do |repository|
|
260
|
+
Smeagol::Cache.new(Gollum::Wiki.new(repository.path)).clear()
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
#
|
265
|
+
# Run the web server.
|
266
|
+
#
|
267
|
+
def run_server(server_config)
|
268
|
+
#Smeagol::App.set(:git, server_config.git)
|
269
|
+
Smeagol::App.set(:repositories, server_config.repositories)
|
270
|
+
Smeagol::App.set(:cache_enabled, server_config.cache_enabled)
|
271
|
+
Smeagol::App.set(:mount_path, server_config.mount_path)
|
272
|
+
Smeagol::App.run!(:port => server_config.port)
|
273
|
+
end
|
274
|
+
|
275
|
+
#
|
276
|
+
# Update wiki repo(s).
|
277
|
+
#
|
278
|
+
def update(*args)
|
279
|
+
options = (Hash === args.last ? args.pop : {})
|
280
|
+
wiki_dir = args.first
|
281
|
+
|
282
|
+
if wiki_dir
|
283
|
+
dir = File.expand_path(wiki_dir)
|
284
|
+
repo = Repository.new(:path=>dir)
|
285
|
+
out = repo.update
|
286
|
+
out = out[1] if Array === out
|
287
|
+
report out
|
288
|
+
else
|
289
|
+
file = options[:config_file]
|
290
|
+
config = Config.load(file)
|
291
|
+
abort "No repositories configured." if config.repositories.empty?
|
292
|
+
|
293
|
+
config.secret = options[:secret]
|
294
|
+
config.repositories.each do |repository|
|
295
|
+
report "Updating: #{repository.path}"
|
296
|
+
out = repository.update
|
297
|
+
out = out[1] if Array === out
|
298
|
+
report out
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
#if settings.site
|
304
|
+
# if Dir.exist?(site_path)
|
305
|
+
# $stderr.puts "Pulling `#{repo.branch}' from `origin' in `#{repo.path}'..."
|
306
|
+
# repo.pull
|
307
|
+
# else
|
308
|
+
# $stderr.puts "Cloning `#{repo.origin}' in `#{repo.path}'..."
|
309
|
+
# repo.clone
|
310
|
+
# end
|
311
|
+
#end
|
312
|
+
|
313
|
+
#
|
314
|
+
# Site directory path.
|
315
|
+
#
|
316
|
+
# Returns expanded site path. [String]
|
317
|
+
#
|
318
|
+
def site_path
|
319
|
+
settings.site_path
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Site repository.
|
324
|
+
#
|
325
|
+
# Returns repository. [Repository]
|
326
|
+
#
|
327
|
+
def site_repo
|
328
|
+
settings.site_repo
|
329
|
+
end
|
330
|
+
|
331
|
+
#
|
332
|
+
# Current wiki directory.
|
333
|
+
#
|
334
|
+
# Returns wiki directory. [String]
|
335
|
+
#
|
336
|
+
def wiki_dir
|
337
|
+
@wiki_dir || Dir.pwd
|
338
|
+
end
|
339
|
+
|
340
|
+
#
|
341
|
+
# Get and cache Wiki object.
|
342
|
+
#
|
343
|
+
# Returns wiki. [Wiki]
|
344
|
+
#
|
345
|
+
def wiki
|
346
|
+
@wiki ||= Smeagol::Wiki.new(wiki_dir)
|
347
|
+
end
|
348
|
+
|
349
|
+
#
|
350
|
+
# Local wiki settings.
|
351
|
+
#
|
352
|
+
# Returns wiki settings. [Settings]
|
353
|
+
#
|
354
|
+
def settings
|
355
|
+
@settings ||= Settings.load(wiki_dir)
|
356
|
+
end
|
357
|
+
|
358
|
+
#
|
359
|
+
# Git executable.
|
360
|
+
#
|
361
|
+
# Returns git command path. [String]
|
362
|
+
#
|
363
|
+
def git
|
364
|
+
Smeagol.git
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|