diff --git a/HISTORY.md b/HISTORY.md index 7261a905..58db2e6a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,14 @@ * Major Enhancements * Optimize page write/update/delete to use Grit::Index::read_tree instead of manually recreating entire index contents. + * Added --irb option for the gollum command. + * Update working dir (if present) when edited via the API (#6) +* Minor Enhancements + * Support a `:gollum_path` Sinatra setting for `Precious::App` + * Add Wiki#size to efficiently count pages without loading them. + * Add the correct content type when serving files from the frontend. + * Wiki#pages come back sorted by Page#title. + * Add --host option and default it to 127.0.0.1. * Bug Fixes * Increase minimum Sanitize version requirement to 1.1.0. 1.0.x versions of Sanitize require Hpricot instead of Nokogiri @@ -13,6 +21,7 @@ anonymous info. * Prevent `Gollum::Wiki#write_page` from clobbering existing pages. * Handle duplicate page errors in frontend. + * Fix bugs trying to retrieve pages with invalid names. # 1.0.1 / 2010-08-12 diff --git a/README.md b/README.md index ecee5c06..5100bb18 100644 --- a/README.md +++ b/README.md @@ -326,7 +326,7 @@ Initialize the Gollum::Repo object: wiki = Gollum::Wiki.new("my-gollum-repo.git") # => -By default, internal wiki links are all absolute from the root. To specify a different base path, you can send specify the `:base_path` option: +By default, internal wiki links are all absolute from the root. To specify a different base path, you can specify the `:base_path` option: wiki = Gollum::Wiki.new("my-gollum-repo.git", :base_path => "/wiki") diff --git a/bin/gollum b/bin/gollum index 9290e6c7..86ac7622 100755 --- a/bin/gollum +++ b/bin/gollum @@ -8,18 +8,17 @@ Gollum is a multi-format Wiki Engine/API/Frontend. Basic Command Line Usage: gollum [OPTIONS] [PATH] - PATH The path to the Gollum repository. + PATH The path to the Gollum repository (default .). Options: HELP require 'optparse' - require 'rubygems' -require 'gollum/frontend/app' +require 'gollum' exec = {} -options = {} +options = { 'port' => 4567, 'bind' => '127.0.0.1' } opts = OptionParser.new do |opts| opts.banner = help @@ -27,15 +26,78 @@ opts = OptionParser.new do |opts| options['port'] = port.to_i end + opts.on("--host [HOST]", "Hostname or IP address to listen on (default 0.0.0.0).") do |host| + options['bind'] = host + end + opts.on("--version", "Display current version.") do puts "Gollum " + Gollum::VERSION exit 0 end + + opts.on("--irb", "Start an irb process with gollum loaded for the current wiki.") do + options['irb'] = true + end end # Read command line options into `options` hash -opts.parse! +begin + opts.parse! +rescue OptionParser::InvalidOption + puts "gollum: #{$!.message}" + puts "gollum: try 'gollum --help' for more information" + exit +end -$path = ARGV[0] || Dir.pwd +gollum_path = ARGV[0] || Dir.pwd -Precious::App.run!(options) +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 + wiki = Gollum::Wiki.new(gollum_path) + if !wiki.exist? then raise Grit::InvalidGitRepositoryError end + puts "Loaded Gollum wiki at #{File.expand_path(gollum_path).inspect}." + puts + 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 "Check out the Gollum README for more." + IRB.start_session(binding) + rescue Grit::InvalidGitRepositoryError, Grit::NoSuchPathError + puts "Invalid Gollum wiki at #{File.expand_path(gollum_path).inspect}" + exit 0 + end +else + require 'gollum/frontend/app' + Precious::App.set(:gollum_path, gollum_path) + Precious::App.run!(options) +end diff --git a/gollum.gemspec b/gollum.gemspec index 1e65f678..901e91f6 100644 --- a/gollum.gemspec +++ b/gollum.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.rdoc_options = ["--charset=UTF-8"] s.extra_rdoc_files = %w[README.md LICENSE] - s.add_dependency('grit', "~> 2.2") + s.add_dependency('grit', "~> 2.3") s.add_dependency('github-markup', [">= 0.4.0", "< 1.0.0"]) s.add_dependency('albino', "~> 1.0") s.add_dependency('sinatra', "~> 1.0") @@ -31,9 +31,11 @@ Gem::Specification.new do |s| s.add_dependency('sanitize', "~> 1.1") s.add_dependency('nokogiri', "~> 1.4") - s.add_development_dependency('shoulda') + s.add_development_dependency('RedCloth') s.add_development_dependency('mocha') s.add_development_dependency('org-ruby') + s.add_development_dependency('rdiscount') + s.add_development_dependency('shoulda') # = MANIFEST = s.files = %w[ diff --git a/lib/gollum.rb b/lib/gollum.rb index 21a0c8ea..68e96fff 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -12,6 +12,7 @@ require 'gollum/ruby1.8' # internal require 'gollum/pagination' +require 'gollum/blob_entry' require 'gollum/wiki' require 'gollum/page' require 'gollum/file' diff --git a/lib/gollum/blob_entry.rb b/lib/gollum/blob_entry.rb new file mode 100644 index 00000000..b224fc4a --- /dev/null +++ b/lib/gollum/blob_entry.rb @@ -0,0 +1,71 @@ +module Gollum + class BlobEntry + # Gets the String SHA for this blob. + attr_reader :sha + + # Gets the String full path for this blob. + attr_reader :path + + def initialize(sha, path) + @sha = sha + @path = path + @dir = @name = @blob = nil + end + + # Gets the normalized directory path for this blob. + def dir + @dir ||= self.class.normalize_dir(::File.dirname(@path)) + end + + # Gets the String file base name for this blob. + def name + @name ||= ::File.basename(@path) + end + + # Gets a Grit::Blob instance for this blob. + # + # repo - Grit::Repo instance for the Grit::Blob. + # + # Returns an unbaked Grit::Blob instance. + def blob(repo) + @blob ||= Grit::Blob.create(repo, :id => @sha, :name => @name) + end + + # Gets a Page instance for this blob. + # + # wiki - Gollum::Wiki instance for the Gollum::Page + # + # Returns a Gollum::Page instance. + def page(wiki, commit) + blob = self.blob(wiki.repo) + page = wiki.page_class.new(wiki).populate(blob, self.dir) + page.version = commit + page + end + + def inspect + %(#) + end + + # Normalizes a given directory name for searching through tree paths. + # Ensures that a directory begins with a slash, or + # + # normalize_dir("") # => "" + # normalize_dir(".") # => "" + # normalize_dir("foo") # => "/foo" + # normalize_dir("/foo/") # => "/foo" + # normalize_dir("/") # => "" + # + # dir - String directory name. + # + # Returns a normalized String directory name, or nil if no directory + # is given. + def self.normalize_dir(dir) + if dir + dir = ::File.expand_path(dir, '/') + dir = '' if dir == '/' + end + dir + end + end +end \ No newline at end of file diff --git a/lib/gollum/file.rb b/lib/gollum/file.rb index 20ceeec8..8e7c33d3 100644 --- a/lib/gollum/file.rb +++ b/lib/gollum/file.rb @@ -33,6 +33,11 @@ module Gollum # Public: The String path of the file. attr_reader :path + # Public: The String mime type of the file. + def mime_type + @blob.mime_type + end + ######################################################################### # # Internal Methods @@ -46,13 +51,14 @@ module Gollum # # Returns a Gollum::File or nil if the file could not be found. def find(name, version) - if commit = @wiki.repo.commit(version) - if (blob = commit.tree / name) && blob.is_a?(Grit::Blob) - @blob = blob - @path = name - @version = commit - self - end + checked = name.downcase + map = @wiki.tree_map_for(version) + sha = @wiki.ref_map[version] || version + if entry = map.detect { |entry| entry.path.downcase == checked } + @path = name + @blob = Grit::Blob.create(@wiki.repo, :id => entry.sha, :name => entry.name) + @version = Grit::Commit.create(@wiki.repo, :id => sha) + self end end end diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb index 87771827..b91e23d0 100644 --- a/lib/gollum/frontend/app.rb +++ b/lib/gollum/frontend/app.rb @@ -1,3 +1,4 @@ +require 'cgi' require 'sinatra' require 'gollum' require 'mustache/sinatra' @@ -12,6 +13,7 @@ module Precious dir = File.dirname(File.expand_path(__FILE__)) # We want to serve public assets for now + set :public, "#{dir}/public" set :static, true @@ -38,9 +40,9 @@ module Precious show_page_or_file('Home') end - get '/edit/:name' do - @name = params[:name] - wiki = Gollum::Wiki.new($path) + get '/edit/*' do + @name = params[:splat].first + wiki = Gollum::Wiki.new(settings.gollum_path) if page = wiki.page(@name) @page = page @content = page.raw_data @@ -50,27 +52,27 @@ module Precious end end - post '/edit/:name' do - name = params[:name] - wiki = Gollum::Wiki.new($path) + post '/edit/*' do + name = params[:splat].first + wiki = Gollum::Wiki.new(settings.gollum_path) page = wiki.page(name) format = params[:format].intern name = params[:rename] if params[:rename] wiki.update_page(page, name, format, params[:content], commit_message) - redirect "/#{Gollum::Page.cname name}" + redirect "/#{CGI.escape(Gollum::Page.cname(name))}" end - post '/create/:name' do + post '/create/*' do name = params[:page] - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) format = params[:format].intern begin wiki.write_page(name, format, params[:content], commit_message) - redirect "/#{name}" + redirect "/#{CGI.escape(name)}" rescue Gollum::DuplicatePageError => e @message = "Duplicate page: #{e.message}" mustache :error @@ -80,13 +82,13 @@ module Precious post '/preview' do format = params['wiki_format'] data = params['text'] - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) wiki.preview_page("Preview", data, format).formatted_data end get '/history/:name' do @name = params[:name] - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) @page = wiki.page(@name) @page_num = [params[:page].to_i, 1].max @versions = @page.versions :page => @page_num @@ -96,10 +98,10 @@ module Precious post '/compare/:name' do @versions = params[:versions] || [] if @versions.size < 2 - redirect "/history/#{params[:name]}" + redirect "/history/#{CGI.escape(params[:name])}" else redirect "/compare/%s/%s...%s" % [ - params[:name], + CGI.escape(params[:name]), @versions.last, @versions.first] end @@ -108,7 +110,7 @@ module Precious get '/compare/:name/:version_list' do @name = params[:name] @versions = params[:version_list].split(/\.{2,3}/) - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) @page = wiki.page(@name) diffs = wiki.repo.diff(@versions.first, @versions.last, @page.path) @diff = diffs.first @@ -117,7 +119,7 @@ module Precious get %r{/(.+?)/([0-9a-f]{40})} do name = params[:captures][0] - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) if page = wiki.page(name, params[:captures][1]) @page = page @name = name @@ -130,7 +132,7 @@ module Precious get '/search' do @query = params[:q] - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) @results = wiki.search @query mustache :search end @@ -140,13 +142,14 @@ module Precious end def show_page_or_file(name) - wiki = Gollum::Wiki.new($path) + wiki = Gollum::Wiki.new(settings.gollum_path) if page = wiki.page(name) @page = page @name = name @content = page.formatted_data mustache :page elsif file = wiki.file(name) + content_type file.mime_type file.raw_data else @name = name @@ -155,9 +158,7 @@ module Precious end def commit_message - { :message => params[:message], - :name => `git config --get user.name `.strip, - :email => `git config --get user.email`.strip } + { :message => params[:message] } end end end diff --git a/lib/gollum/frontend/templates/compare.mustache b/lib/gollum/frontend/templates/compare.mustache index 3a99fbd2..5f7f99ae 100644 --- a/lib/gollum/frontend/templates/compare.mustache +++ b/lib/gollum/frontend/templates/compare.mustache @@ -1,7 +1,7 @@

{{title}}: {{before}} → {{after}}

diff --git a/lib/gollum/frontend/templates/create.mustache b/lib/gollum/frontend/templates/create.mustache index 969f2512..146d43c7 100644 --- a/lib/gollum/frontend/templates/create.mustache +++ b/lib/gollum/frontend/templates/create.mustache @@ -2,7 +2,7 @@ « Home

{{title}}

-
+