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
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
|