doc 0.0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,6 +1,85 @@
1
1
  # doc
2
2
 
3
- Successor of sdoc_all.
3
+ Get searchable documentation for ruby, rails, gems, plugins and all other ruby code in one place.
4
+
5
+ Successor of [sdoc_all](https://github.com/toy/sdoc_all).
6
+
7
+ ## Usage
8
+
9
+ sudo gem install doc
10
+ docr <place for your documentation>; cd <place for your documentation>
11
+ <your favorite editor> Rakefile
12
+ rake build
13
+ open public/index.html # that's true for mac
14
+
15
+ ## Config
16
+
17
+ doc.title 'ruby, rails, gems'
18
+ doc.min_update_interval 1.week
19
+ doc.clean_after 1.day
20
+ doc.public_dir 'pub'
21
+
22
+ doc.ruby 'ruby', 'ruby1.9', :except => %w[win32ole tk], :index => 'ruby_quick_ref'
23
+ doc.rails 2, 3, :prerelease => true
24
+ doc.gems :except => %w[
25
+ mysql
26
+ rails railties actionmailer actionpack activemodel activerecord activeresource activesupport
27
+ yard keychain_services msgpack doc
28
+ ], :prerelease => true
29
+ doc.paths '~/.plugins/*', :main => 'README*', :file_list => %w[+lib +README* +CHANGELOG*], :title => proc{ |path| "plugin #{path.basename}" }
30
+ doc.paths '~/var/ruby', :file_list => %w[+**/*.rb -_arc]
31
+
32
+ ### Global options
33
+
34
+ - `title` for documentation title, default is 'ruby documentation'
35
+ - `min_update_interval` — time between code updates, now used only for ruby source, default is 1 hour
36
+ - `clean_after` — delete old generated documentation after this period of time, by default it is not set and no cleaning is made
37
+ - `public_dir` — specify custom dir for final documentation, 'public' by default
38
+
39
+ `ruby`, `rails`, `gems`, `paths` — documentation configurators, below their options are explained, all configurators have default option which can be specified without key syntax
40
+
41
+ `gem` and `path` are just aliases to `gems` and `paths`
42
+
43
+ ### ruby
44
+
45
+ Specify what to document using:
46
+
47
+ - `source`: path to ruby source
48
+ - `archive`: path to archive with ruby source (bzipped tar, gzipped tar or zip)
49
+ - `version`: ruby version in form X.Y, X.Y.Z or X.Y.Z-pPPP. Source will be downloaded from github.com/ruby/ruby or ruby-lang.org
50
+ - `binary`: command which is asked to run code to automatically determine ruby version. Source will be downloaded as for version specifier
51
+
52
+ All those specifiers accepts multiple entries. Default option is `binary`, 'ruby' binary is used if version is not specified.
53
+
54
+ Other options:
55
+
56
+ - `format`: can be `:all` to simply document all code, `:separate` to build core documentation and stdlib documentation separately and `:integrate` to integrate all stdlib to core
57
+ - `except`: skip documenting certain parts (like `win32ole` and `tk`)
58
+ - `index`: specify folder containing index.html to replace front page. Good place for cheat sheet or quick ref like one downloaded from [zenspider](http://www.zenspider.com/Languages/Ruby/QuickRef.html).
59
+
60
+ ### rails
61
+
62
+ Specify version(s) of rails to document using `:version`. Can be any part of version: 3, '3.0', '3.0.1'. That is default option so you can skip key. If version is not specified, latest found in installed gems will be used.
63
+
64
+ Use `:prerelease => true` to document prerelease versions.
65
+
66
+ ### gems
67
+
68
+ Use `:only` to document only certain gems or use `:except` to skip them from being documented. `:only` is the default option.
69
+
70
+ Use `:versions => :all` if you want to document all installed versions.
71
+
72
+ Use `:prerelease => true` to document prerelease versions.
73
+
74
+ ### paths
75
+
76
+ Default option is `:glob`. Specify list of globs (or paths), documentation will be created for every path matched by glob.
77
+
78
+ Use `:main` to specify main file. It is a list of file names, first one found at path will be used.
79
+
80
+ Use `:file_list` to filter what to document. It can be an Array of glob string prefixed with + and - to exclude or include or a proc receiving instance of Rake::FileList.
81
+
82
+ Use `:title` to specify title, it must be a proc receiving path and returning title.
4
83
 
5
84
  ## Copyright
6
85
 
data/Rakefile CHANGED
@@ -6,11 +6,15 @@ name = 'doc'
6
6
 
7
7
  Jeweler::Tasks.new do |gem|
8
8
  gem.name = name
9
- gem.summary = %Q{Documentation for everything}
10
- gem.description = %Q{Command line tool to get searchable documentation for ruby, rails, gems, plugins and other ruby related code in one place}
9
+ gem.summary = %Q{Get all ruby documentation in one place}
10
+ gem.description = %Q{Generate `Rakefile` with `docr` and get searchable documentation for ruby, rails, gems, plugins and all other ruby code in one place}
11
11
  gem.homepage = "http://github.com/toy/#{name}"
12
12
  gem.license = 'MIT'
13
13
  gem.authors = ['Ivan Kuchin']
14
+ gem.add_runtime_dependency 'sdoc', '= 0.2.20'
15
+ gem.add_runtime_dependency 'fspath'
16
+ gem.add_runtime_dependency 'progress'
17
+ gem.add_runtime_dependency 'net-ftp-list'
14
18
  gem.add_development_dependency 'jeweler', '~> 1.5.1'
15
19
  gem.add_development_dependency 'rake-gem-ghost'
16
20
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0.0
1
+ 0.0.1
data/bin/docr ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ case
6
+ when %w[-v --version].include?(ARGV.first)
7
+ puts "#{File.basename($0)} #{(Pathname(__FILE__) + '../../VERSION').read}"
8
+ exit
9
+ when %w[-h --help].include?(ARGV.first) || ARGV.length != 1
10
+ puts "#{File.basename($0)} dir_name"
11
+ exit
12
+ else
13
+ dir = Pathname(ARGV.first)
14
+ dir.mkpath
15
+
16
+ rakefile_path = dir + 'Rakefile'
17
+ rakefile_data = <<-RUBY
18
+ require 'doc'
19
+
20
+ Doc::Tasks.new do |doc|
21
+ doc.title 'ruby, rails, gems'
22
+ doc.min_update_interval 1.week
23
+
24
+ doc.ruby
25
+ doc.rails
26
+ doc.gems :except => %w[mysql rails actionmailer actionpack activerecord activeresource activesupport]
27
+ end
28
+ RUBY
29
+
30
+ if rakefile_path.exist? && rakefile_path.read != rakefile_data
31
+ puts 'Rakefile exists, overwrite?'
32
+ abort unless %w[o y].include?(STDIN.gets.strip.downcase[0, 1])
33
+ end
34
+
35
+ (dir + 'Rakefile').open('w') do |f|
36
+ f.write rakefile_data
37
+ end
38
+
39
+ puts %{Next steps:}
40
+ puts %{ cd "#{dir}"}
41
+ puts %{ #{ENV['EDITOR'] || 'vim'} Rakefile}
42
+ puts %{ rake build}
43
+ end
data/doc.gemspec CHANGED
@@ -4,13 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{doc}
8
- s.version = "0.0.0.0"
7
+ s.name = "doc"
8
+ s.version = "0.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ivan Kuchin"]
12
- s.date = %q{2010-12-16}
13
- s.description = %q{Command line tool to get searchable documentation for ruby, rails, gems, plugins and other ruby related code in one place}
12
+ s.date = "2011-10-04"
13
+ s.description = "Generate `Rakefile` with `docr` and get searchable documentation for ruby, rails, gems, plugins and all other ruby code in one place"
14
+ s.executables = ["docr"]
14
15
  s.extra_rdoc_files = [
15
16
  "LICENSE.txt",
16
17
  "README.markdown"
@@ -21,27 +22,59 @@ Gem::Specification.new do |s|
21
22
  "README.markdown",
22
23
  "Rakefile",
23
24
  "VERSION",
25
+ "bin/docr",
24
26
  "doc.gemspec",
25
- "lib/doc.rb"
27
+ "lib/doc.rb",
28
+ "lib/doc/base_task.rb",
29
+ "lib/doc/builder.rb",
30
+ "lib/doc/command.rb",
31
+ "lib/doc/config_error.rb",
32
+ "lib/doc/config_object.rb",
33
+ "lib/doc/configurator.rb",
34
+ "lib/doc/configurator/gems.rb",
35
+ "lib/doc/configurator/paths.rb",
36
+ "lib/doc/configurator/rails.rb",
37
+ "lib/doc/configurator/ruby.rb",
38
+ "lib/doc/configurator/ruby/path_info.rb",
39
+ "lib/doc/configurator/ruby/source.rb",
40
+ "lib/doc/configurator/ruby/stdlib.rb",
41
+ "lib/doc/configurator/ruby/version_specifier.rb",
42
+ "lib/doc/core_ext.rb",
43
+ "lib/doc/documentor.rb",
44
+ "lib/doc/merger.rb",
45
+ "lib/doc/root_config.rb",
46
+ "lib/doc/root_merger.rb",
47
+ "lib/doc/tasks.rb"
26
48
  ]
27
- s.homepage = %q{http://github.com/toy/doc}
49
+ s.homepage = "http://github.com/toy/doc"
28
50
  s.licenses = ["MIT"]
29
51
  s.require_paths = ["lib"]
30
- s.rubygems_version = %q{1.3.7}
31
- s.summary = %q{Documentation for everything}
52
+ s.rubygems_version = "1.8.10"
53
+ s.summary = "Get all ruby documentation in one place"
32
54
 
33
55
  if s.respond_to? :specification_version then
34
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
35
56
  s.specification_version = 3
36
57
 
37
58
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<sdoc>, ["= 0.2.20"])
60
+ s.add_runtime_dependency(%q<fspath>, [">= 0"])
61
+ s.add_runtime_dependency(%q<progress>, [">= 0"])
62
+ s.add_runtime_dependency(%q<net-ftp-list>, [">= 0"])
38
63
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
39
64
  s.add_development_dependency(%q<rake-gem-ghost>, [">= 0"])
40
65
  else
66
+ s.add_dependency(%q<sdoc>, ["= 0.2.20"])
67
+ s.add_dependency(%q<fspath>, [">= 0"])
68
+ s.add_dependency(%q<progress>, [">= 0"])
69
+ s.add_dependency(%q<net-ftp-list>, [">= 0"])
41
70
  s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
42
71
  s.add_dependency(%q<rake-gem-ghost>, [">= 0"])
43
72
  end
44
73
  else
74
+ s.add_dependency(%q<sdoc>, ["= 0.2.20"])
75
+ s.add_dependency(%q<fspath>, [">= 0"])
76
+ s.add_dependency(%q<progress>, [">= 0"])
77
+ s.add_dependency(%q<net-ftp-list>, [">= 0"])
45
78
  s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
46
79
  s.add_dependency(%q<rake-gem-ghost>, [">= 0"])
47
80
  end
data/lib/doc.rb CHANGED
@@ -0,0 +1,11 @@
1
+ require 'doc/core_ext'
2
+
3
+ module Doc
4
+ smart_autoload :Tasks, :Documentor, :Configurator, :ConfigObject, :RootConfig, :ConfigError
5
+ smart_autoload :BaseTask, :Builder, :Merger, :RootMerger
6
+ smart_autoload :Command
7
+ end
8
+
9
+ glob_require 'doc/configurator/*.rb'
10
+
11
+ # TODO: kill sdoc_all hehe >:->
@@ -0,0 +1,76 @@
1
+ require 'digest/sha2'
2
+
3
+ module Doc
4
+ class BaseTask
5
+ attr_reader :documentor, :title, :dir_name, :config
6
+ def initialize(documentor, options)
7
+ @documentor = documentor
8
+ @title = options[:title].to_s
9
+ @dir_name = options[:dir_name].to_s
10
+ doc_dir.touch if doc_dir.exist?
11
+ end
12
+
13
+ def doc_dir
14
+ documentor.docs_dir / dir_name
15
+ end
16
+
17
+ def self.state_methods(name, data_code_for_state)
18
+ class_eval <<-RUBY, __FILE__, __LINE__
19
+ def #{name}_state
20
+ @#{name}_state ||= #{data_code_for_state}
21
+ end
22
+ def #{name}_state_path
23
+ doc_dir / '.#{name}_state'
24
+ end
25
+ def #{name}_state_changed?
26
+ !#{name}_state_path.exist? || Marshal.load(#{name}_state_path.read) != #{name}_state
27
+ rescue true
28
+ end
29
+ def write_#{name}_state
30
+ #{name}_state_path.write(Marshal.dump(#{name}_state))
31
+ end
32
+ RUBY
33
+ end
34
+
35
+ state_methods :config, <<-RUBY
36
+ @config
37
+ RUBY
38
+
39
+ def hash
40
+ config.hash
41
+ end
42
+ def eql?(other)
43
+ config.eql?(other.config)
44
+ end
45
+
46
+ def control_files_exist?
47
+ %w[created.rid index.html].all? do |name|
48
+ (doc_dir / name).exist?
49
+ end
50
+ end
51
+
52
+ def run?
53
+ config_state_changed? || !control_files_exist?
54
+ end
55
+
56
+ abstract_method :build
57
+ def run(force = false)
58
+ if force || run?
59
+ doc_dir.rmtree_verbose if doc_dir.exist?
60
+ build
61
+ write_config_state
62
+ @state = control_files_exist? ? :succeeded : :failed
63
+ end
64
+ rescue SystemExit
65
+ @state = :failed
66
+ end
67
+
68
+ def succeeded?
69
+ @state == :succeeded
70
+ end
71
+
72
+ def failed?
73
+ @state == :failed
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,101 @@
1
+ require 'find'
2
+
3
+ module Doc
4
+ class Builder < BaseTask
5
+ attr_reader :index, :main, :source_dir, :paths
6
+ def initialize(documentor, options)
7
+ super
8
+ @index = options[:index].to_s if options[:index]
9
+ @main = options[:main].to_s if options[:main]
10
+ @source_dir = FSPath(options[:source_dir]).expand_path if options[:source_dir]
11
+ @paths = Array(options[:paths]) if options[:paths]
12
+
13
+ unless @source_dir || @paths
14
+ raise 'both source_dir and paths are not set'
15
+ end
16
+
17
+ if @paths
18
+ if @source_dir && !options[:no_auto_add_paths]
19
+ children = @source_dir.children.select(&:file?).map(&:basename).map(&:to_s)
20
+ @paths = children.grep(/^((mit-)?license|change(?:s|log)|readme|history|todo|copying|faq|legal)($|\.)/i) | @paths
21
+ end
22
+
23
+ if @main
24
+ unless @paths.include?(@main)
25
+ @paths = [@main] | @paths
26
+ end
27
+ else
28
+ %w[^ /].map do |prefix|
29
+ [/#{prefix}readme(?:\.(?:txt|rdoc|markdown|md))?$/i, /#{prefix}readme\./i]
30
+ end.flatten.each do |readme_r|
31
+ break if @main = @paths.grep(readme_r).first
32
+ end
33
+ end
34
+
35
+ @paths.select! do |path|
36
+ source_dir ? (source_dir / path).readable? : File.readable?(path)
37
+ end
38
+ @paths.uniq!
39
+
40
+ unless @source_dir
41
+ if @source_dir = FSPath.common_dir(*@paths)
42
+ @paths = @paths.map{ |path| FSPath(path).relative_path_from(@source_dir).to_s }
43
+ end
44
+ end
45
+ end
46
+
47
+ chdir_source_dir do
48
+ paths_info = []
49
+ if paths
50
+ Find.find(*paths) do |path|
51
+ paths_info << [path, File.size(path), File.mtime(path).to_i]
52
+ end
53
+ end
54
+
55
+ @config = {
56
+ :title => title,
57
+ :dir_name => dir_name,
58
+ :index => index,
59
+ :main => main,
60
+ :source_dir => source_dir.to_s,
61
+ :paths => paths_info,
62
+ }
63
+ end
64
+ end
65
+
66
+ def build
67
+ cmd = Command.new('sdoc')
68
+ cmd.add '--format=shtml'
69
+ cmd.add '--template=direct'
70
+ cmd.add '--line-numbers'
71
+ cmd.add '--all'
72
+ cmd.add '--charset=utf-8'
73
+ cmd.add '--tab-width=2'
74
+ cmd.add "--title=#{title}"
75
+ cmd.add "--output=#{doc_dir}"
76
+ cmd.add "--main=#{main}" if main
77
+ cmd.add *paths if paths
78
+
79
+ chdir_source_dir do
80
+ cmd.run
81
+ end
82
+
83
+ if control_files_exist? && index
84
+ index_dir_name = 'custom_index'
85
+ FileUtils.cp_r(index, doc_dir / index_dir_name)
86
+ index_html = doc_dir / 'index.html'
87
+ index_html.write(index_html.read.sub(/(<frame src=")[^"]+(" name="docwin" \/>)/, "\\1#{index_dir_name}/index.html\\2"))
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def chdir_source_dir(&block)
94
+ if source_dir
95
+ Dir.chdir(source_dir, &block)
96
+ else
97
+ block.call
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,40 @@
1
+ require 'shellwords'
2
+
3
+ module Doc
4
+ class Command
5
+ def self.run(*command)
6
+ new(*command).run
7
+ end
8
+
9
+ attr_reader :command, :status
10
+ def initialize(*command)
11
+ @command = command
12
+ end
13
+
14
+ def add(*arguments)
15
+ @command.concat(arguments)
16
+ end
17
+
18
+ def run
19
+ command_string = command.length == 1 ? command.first : command.map(&:to_s).shelljoin
20
+ puts "cd #{Dir.pwd.shellescape}; #{command_string}"
21
+ output = IO.popen("#{command_string} 2>&1", &:read)
22
+ @status = $?
23
+ status.success? || begin
24
+ print output
25
+ case
26
+ when status.signaled?
27
+ if status.termsig == 2
28
+ raise Interrupt.new
29
+ else
30
+ raise SignalException.new(status.termsig)
31
+ end
32
+ when status.exited?
33
+ raise SystemExit.new(status.exitstatus)
34
+ else
35
+ raise status.inspect
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end