#!/usr/bin/env ruby $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib]) require 'optparse' require 'rubygems' require 'gollum' require 'erb' require 'sprockets' exec = {} options = { :port => 4567, :bind => '0.0.0.0', } wiki_options = { :live_preview => false, :allow_uploads => false, :allow_editing => true, } opts = OptionParser.new do |opts| # define program name (although this defaults to the name of the file, just in case...) opts.program_name = "gollum" # set basic info for the "--help" command (options will be appended automatically from the below definitions) opts.banner = ' Gollum is a multi-format Wiki Engine/API/Frontend. Usage: gollum [options] [git-repo] Arguments: [git-repo] Path to the git repository being served. If not specified, current working directory is used. Notes: Paths for all options are relative to unless absolute. This message is only a basic description. For more information, please visit: https://github.com/gollum/gollum OPTIONS' # define gollum options opts.separator "" opts.separator " Major:" opts.on("-h", "--host [HOST]", "Specify the hostname or IP address to listen on. Default: '0.0.0.0'.") do |host| options[:bind] = host end opts.on("-p", "--port [PORT]", "Specify the port to bind Gollum with. Default: '4567'.") do |port| begin # don't use "port.to_i" here... it doesn't raise errors which might result in a nice confusion later on options[:port] = Integer(port) rescue ArgumentError puts "Error: '#{port}' is not a valid port number." exit 1 end end opts.on("-c", "--config [FILE]", "Specify path to the Gollum's configuration file.") do |file| options[:config] = file end opts.on("-r", "--ref [REF]", "Specify the branch to serve. Default: 'master'.") do |ref| wiki_options[:ref] = ref end opts.on("-a", "--adapter [ADAPTER]", "Launch Gollum using a specific git adapter. Default: 'grit'.") do |adapter| Gollum::GIT_ADAPTER = adapter end opts.on("--bare", "Declare '' to be bare. This is only necessary when using the grit adapter.") do wiki_options[:repo_is_bare] = true end opts.on("-b", "--base-path [PATH]", "Specify the leading portion of all Gollum URLs (path info). Default: '/'.", "Example: setting this to '/wiki' will make the wiki accessible under 'http://localhost:4567/wiki/'.") do |base_path| # first trim a leading slash, if any base_path.sub!(/^\/+/, '') # make a backup of the option and sanitize it base_path_original = base_path.dup base_path = ERB::Util.url_encode(base_path) base_path.gsub!('%2F', '/') # then let the user know if we changed the URL unless base_path_original == base_path puts </pages/*'.") do |path| wiki_options[:page_file_dir] = path end opts.on("--static", "Use static assets. Defaults to false in development/test, defaults to true in production/staging.") do wiki_options[:static] = true end opts.on("--no-static", "Do not use static assets (even when in production/staging).") do wiki_options[:static] = false end opts.on("--assets [PATH]", "Set the path to look for static assets. Only used if --static is set to true, or environment is production/staging. Default: ./public/assets") do |path| wiki_options[:static_assets_path] = path end opts.on("--precompile-assets [PATH]", "Precompile static assets to PATH.") do |path| options[:precompile] = path || './public/assets' end opts.on("--css", "Inject custom CSS into each page. The '/custom.css' file is used (must be committed).") do wiki_options[:css] = true end opts.on("--js", "Inject custom JavaScript into each page. The '/custom.js' file is used (must be committed).") do wiki_options[:js] = true end opts.on("--emoji", "Parse and interpret emoji tags (e.g. :heart:) except when the leading colon is backslashed (e.g. \\:heart:).") do wiki_options[:emoji] = true end opts.on("--no-edit", "Disable the feature of editing pages.") do wiki_options[:allow_editing] = false end opts.on("--follow-renames", "Follow pages across renames in the History view. Default except on jruby.") do wiki_options[:follow_renames] = true end opts.on("--no-follow-renames", "Do not follow pages across renames in the History view.") do wiki_options[:follow_renames] = false end opts.on("--allow-uploads [MODE]", [:dir, :page], "Enable file uploads.", "If set to 'dir', Gollum will store all uploads in the '/uploads/' directory.", "If set to 'page', Gollum will store each upload at the currently edited page.") do |mode| wiki_options[:allow_uploads] = true wiki_options[:per_page_uploads] = true if mode == :page end opts.on("--mathjax", "Enable MathJax (renders mathematical equations).", "By default, uses the 'TeX-AMS-MML_HTMLorMML' config with the 'autoload-all' extension.") do wiki_options[:mathjax] = true end opts.on("--irb", "Launch Gollum in 'console mode', with a predefined API.") do options[:irb] = true end opts.separator "" opts.separator " Minor:" opts.on("--h1-title", "Use the first '

' as page title.") do wiki_options[:h1_title] = true end opts.on("--no-display-metadata", "Do not render metadata tables in pages.") do wiki_options[:display_metadata] = false end opts.on("--user-icons [MODE]", [:gravatar, :identicon, :none], "Use specific user-icons for history view.", "Can be set to 'gravatar', 'identicon' or 'none'. Default: 'none'.") do |mode| wiki_options[:user_icons] = mode end opts.on("--mathjax-config [FILE]", "Specify path to a custom MathJax configuration.", "If not specified, uses the '/mathjax.config.js' file.") do |file| wiki_options[:mathjax_config] = file || 'mathjax.config.js' end opts.on("--template-dir [PATH]", "Specify custom mustache template directory.") do |path| wiki_options[:template_dir] = path end opts.on("--template-page", "Use _Template in root as a template for new pages.") do wiki_options[:template_page] = true end opts.separator "" opts.separator " Common:" opts.on("--help", "Display this message.") do puts opts exit 0 end opts.on("--version", "Display the current version of Gollum.") do puts "Gollum " + Gollum::VERSION end opts.on("--versions", "Display the current version of Gollum and auxiliary gems.") do puts "Gollum " + Gollum::VERSION puts "Running on: #{RUBY_PLATFORM} with Ruby version #{RUBY_VERSION}" puts "Using:" loaded_gemspecs = Gem.loaded_specs gollum_gems = ['gollum-lib', 'gollum-rjgit_adapter', 'rjgit', 'gollum-grit_adapter', 'grit', 'gollum-rugged_adapter', 'rugged'] puts Gem.loaded_specs.select{|name, spec| gollum_gems.include?(name)}.map {|name, spec| "#{name} #{spec.version}"} puts "With the following renderers:" renderer_gems = ['kramdown', 'RedCloth', 'org-ruby', 'creole', 'asciidoctor', 'wikicloth'] renderer_gems.each do |renderer| begin require renderer rescue LoadError end end puts Gem.loaded_specs.select{|name, spec| renderer_gems.include?(name)}.map {|name, spec| "#{name} #{spec.version}"} exit 0 end opts.separator "" end # Read command line options into `options` hash begin opts.parse! rescue OptionParser::InvalidOption puts "gollum: #{$!.message}" puts "gollum: try 'gollum --help' for more information" exit end # --gollum-path wins over ARGV[0] gollum_path = ARGV[0] || Dir.pwd if options[:irb] require 'irb' # http://jameskilton.com/2009/04/02/embedding-irb-into-your-ruby-application/ module IRB # :nodoc: def self.start_session(binding) unless @__initialized args = ARGV ARGV.replace(ARGV.dup) IRB.setup(nil) ARGV.replace(args) @__initialized = true end ws = WorkSpace.new(binding) irb = Irb.new(ws) @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] @CONF[:MAIN_CONTEXT] = irb.context catch(:IRB_EXIT) do irb.eval_input end end end begin require 'gollum-lib' wiki = Gollum::Wiki.new(gollum_path, wiki_options) if !wiki.exist? then raise Gollum::InvalidGitRepositoryError end puts puts "Loaded Gollum wiki at:" puts "#{File.expand_path(gollum_path).inspect}" puts puts "Example API calls:" puts %( page = wiki.page('page-name')) puts %( # => ) puts puts %( page.raw_data) puts %( # => "# My wiki page") puts puts %( page.formatted_data) puts %( # => "

My wiki page

") puts puts "Full API documentation at:" puts "https://github.com/gollum/gollum-lib" puts IRB.start_session(binding) rescue Gollum::InvalidGitRepositoryError, Gollum::NoSuchPathError puts "Invalid Gollum wiki at #{File.expand_path(gollum_path).inspect}" exit 0 end elsif options[:precompile] require 'gollum/app' env = Precious::Assets.sprockets manifest = Sprockets::Manifest.new(env, options[:precompile]) Sprockets::Helpers.configure do |config| config.environment = env config.prefix = "#{wiki_options[:base_path]}/#{Precious::Assets::ASSET_URL}" config.digest = true config.public_path = options[:precompile] config.manifest = manifest end puts "Precompiling assets to #{::File.expand_path(options[:precompile])}..." manifest.compile(Precious::Assets::MANIFEST) else require 'gollum/app' Precious::App.set(:gollum_path, gollum_path) Precious::App.set(:wiki_options, wiki_options) Precious::App.settings.mustache[:templates] = wiki_options[:template_dir] if wiki_options[:template_dir] if cfg = options[:config] # If the path begins with a '/' it will be considered an absolute path, # otherwise it will be relative to the CWD cfg = File.join(Dir.getwd, cfg) unless cfg.slice(0) == File::SEPARATOR require cfg end base_path = wiki_options[:base_path] if base_path.nil? Precious::App.run!(options) else require 'rack' class MapGollum def initialize(base_path) @mg = Rack::Builder.new do map "/#{base_path}" do run Precious::App end map '/' do run Proc.new { [302, { 'Location' => "/#{base_path}" }, []] } end map '/*' do run Proc.new { [302, { 'Location' => "/#{base_path}" }, []] } end end end def call(env) @mg.call(env) end end # Rack::Handler does not work with Ctrl + C. Use Rack::Server instead. Rack::Server.new(:app => MapGollum.new(base_path), :Port => options[:port], :Host => options[:bind]).start end end