sdoc_all 0.1.0 → 0.2.0.1

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Boba Fat
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest CHANGED
@@ -1,17 +1,27 @@
1
1
  bin/sdoc-all
2
2
  lib/sdoc_all/base.rb
3
+ lib/sdoc_all/config_error.rb
3
4
  lib/sdoc_all/gems.rb
4
5
  lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb
6
+ lib/sdoc_all/generator/sdoc_all/templates/config.yml
5
7
  lib/sdoc_all/generator/sdoc_all/templates/Rakefile
6
- lib/sdoc_all/generator/sdoc_all/templates/sdoc.config.yml.erb
8
+ lib/sdoc_all/paths.rb
7
9
  lib/sdoc_all/plugins.rb
8
10
  lib/sdoc_all/rails.rb
9
- lib/sdoc_all/rdoc_task.rb
10
- lib/sdoc_all/rdoc_tasks.rb
11
11
  lib/sdoc_all/ruby.rb
12
+ lib/sdoc_all/task.rb
12
13
  lib/sdoc_all.rb
13
- lib/tasks/sdoc_all.rb
14
+ lib/tasks/sdoc_all_rake.rb
15
+ LICENSE
14
16
  Manifest
15
17
  Rakefile
16
18
  README.rdoc
19
+ spec/sdoc_all/gems_spec.rb
20
+ spec/sdoc_all/paths_spec.rb
21
+ spec/sdoc_all/plugins_spec.rb
22
+ spec/sdoc_all/rails_spec.rb
23
+ spec/sdoc_all/ruby_spec.rb
24
+ spec/sdoc_all_spec.rb
25
+ spec/spec.opts
26
+ spec/spec_helper.rb
17
27
  VERSION.yml
data/README.rdoc CHANGED
@@ -1,23 +1,134 @@
1
1
  = sdoc-all
2
- Command line tool to get documentation for ruby, rails, gems and plugins in one place
2
+ Command line tool to get documentation for ruby, rails, gems, plugins and other ruby code in one place
3
3
 
4
4
  == Getting Started
5
- sudo gem install sdoc sdoc_all
5
+ sudo gem install voloko-sdoc sdoc_all
6
6
  sdoc-all <place for your documentation>; cd <place for your documentation>
7
- rake update
8
-
9
- == Configure
10
- in <tt>sdoc.config.yml</tt> you can define:
11
- - preferred version of ruby
12
- - preferred version of rails
13
- - plugins directory
14
- - what to exclude
15
-
16
- == How it works
17
- sdoc-all generates folder with config and rakefile
18
- running <tt>rake update</tt> (or simply <tt>rake</tt> as it is default task) in that folder:
19
- - downloads ruby sources from ftp.ruby-lang.org
20
- - builds dummy rails applications and freezes gems there
21
- - builds documentation for ruby, rails, gems and plugins
22
- - merges documentation
23
- rerunning rake rebuilds only changed files if not asked to rebuild everything (force in config)
7
+ <your favorite editor> config.yml
8
+ rake run
9
+
10
+ == config.yml
11
+
12
+ === example
13
+ ---
14
+ min_update_interval: 1 hour
15
+ sdoc:
16
+ - ruby: 1.8.7
17
+ - rails
18
+ - gems:
19
+ exclude:
20
+ - mysql
21
+ - rails
22
+ - actionmailer
23
+ - actionpack
24
+ - activerecord
25
+ - activeresource
26
+ - activesupport
27
+ - plugins: ~/.plugins
28
+ - path: ~/some/path
29
+
30
+ === options
31
+ time to skip updates (for now ruby and plugins are updated)
32
+ days, hours, minutes, seconds accepted
33
+ min_update_interval: 1 hour
34
+
35
+ list of things you want to document
36
+ carefully watch indent - 4 spaces for options
37
+ sdoc:
38
+
39
+ === ruby
40
+ ruby 1.8.6 source will be downloaded for you from ftp.ruby-lang.org and placed in folder sources
41
+ - ruby: 1.8.6
42
+
43
+ if you don't want updates use this
44
+ - ruby:
45
+ version: 1.8.6
46
+ update: false
47
+
48
+ === rails
49
+ choose rails version
50
+ - rails: 2.3.2
51
+
52
+ latest installed version will be used
53
+ - rails
54
+
55
+ === gems
56
+ document all gems
57
+ - gems
58
+
59
+ document nokogiri and hpricot gems
60
+ - gems: [nokogiri, hpricot]
61
+
62
+ document nokogiri gem (gem is just an alias to gems)
63
+ - gem: nokogiri
64
+
65
+ document all installed versions of nokogiri and hpricot gems (not latest)
66
+ - gems:
67
+ only: [nokogiri, hpricot]
68
+ versions: all
69
+
70
+ document all gems except mysql and gems related to rails
71
+ - gems:
72
+ exclude:
73
+ - mysql
74
+ - rails
75
+ - actionmailer
76
+ - actionpack
77
+ - activerecord
78
+ - activeresource
79
+ - activesupport
80
+
81
+ === plugins
82
+ document plugins in folder ~/.plugins (they will also be updated if they are under git)
83
+ - plugins: ~/.plugins
84
+
85
+ document plugins in folder sources/plugins
86
+ - plugins
87
+
88
+ document only dump plugin
89
+ - plugin:
90
+ path: ~/.plugins
91
+ only: dump
92
+
93
+ document dump, access and data_columns plugins
94
+ - plugins:
95
+ path: ~/.plugins
96
+ only: [dump, access, data_columns]
97
+
98
+ don't update plugins under git
99
+ - plugins:
100
+ path: ~/.plugins
101
+ update: false
102
+
103
+ document all plugins except acts_as_fu and acts_as_bar
104
+ - plugins:
105
+ path: ~/.plugins
106
+ exclude: [acts_as_fu, acts_as_bar]
107
+
108
+ === paths
109
+ document file or directory (you can create .document file in directory to tell rdoc what to document)
110
+ - path: ~/lib/bin
111
+
112
+ it can be a glob (each entry will be documented separately)
113
+ - paths: ~/lib/*
114
+
115
+ or array (note that name of documentation for each will be relative path from common ancestor)
116
+ - paths: [~/lib/*, ~/scripts/**, /test.rb, /rm-rf.rb]
117
+
118
+ if you want to specify more options (roots are not globed in this form)
119
+ - paths:
120
+ root: ~/lib/app
121
+ main: README
122
+ paths: [+*, +lib/*.rb, +tasks/*.rake, -*.sw*, -OLD_README]
123
+
124
+ or array form (mixed type)
125
+ - paths:
126
+ - root: ~/lib/app
127
+ main: SUPAREADME
128
+ paths: [+*, +lib/*.rb, +tasks/*.rake, -*.sw*, -OLD_README]
129
+ - ~/lib/app2
130
+ - root: ~/lib/app3
131
+ main: SUPAREADME
132
+ - root: ~/lib/app3
133
+ paths: *.rb
134
+ - ~/lib/old/app*
data/Rakefile CHANGED
@@ -9,8 +9,13 @@ version = YAML.load_file(File.join(File.dirname(__FILE__), 'VERSION.yml')).join(
9
9
 
10
10
  Echoe.new('sdoc_all', version) do |p|
11
11
  p.author = "toy"
12
- p.summary = "Command line tool to get documentation for ruby, rails, gems and plugins in one place"
12
+ p.summary = "documentation for everything"
13
+ p.description = "Command line tool to get documentation for ruby, rails, gems and plugins in one place"
14
+ p.email = "ivan@workisfun.ru"
13
15
  p.url = "http://github.com/toy/sdoc_all"
14
- p.runtime_dependencies = %w(sdoc activesupport rake progress)
16
+ p.runtime_dependencies << 'activesupport'
17
+ p.runtime_dependencies << 'rake'
18
+ p.runtime_dependencies << 'progress >= 0.0.8'
19
+ # TODO: sdoc or voloko-sdoc
15
20
  p.project = 'toytoy'
16
21
  end
data/VERSION.yml CHANGED
@@ -1 +1 @@
1
- [0, 1, 0]
1
+ [0, 2, 0, 1]
data/bin/sdoc-all CHANGED
@@ -5,7 +5,7 @@ require 'rubigen'
5
5
 
6
6
  if %w(-v --version).include? ARGV.first
7
7
  version = YAML.load_file(File.join(File.dirname(__FILE__), '../VERSION.yml'))
8
- puts "#{File.basename($0)} #{version[:major]}.#{version[:minor]}.#{version[:patch]}"
8
+ puts "#{File.basename($0)} #{version.join('.')}"
9
9
  exit(0)
10
10
  end
11
11
 
data/lib/sdoc_all/base.rb CHANGED
@@ -1,80 +1,123 @@
1
1
  class SdocAll
2
2
  class Base
3
- def self.inherited(subclass)
4
- (@subclasses ||= []) << subclass
3
+ attr_reader :config
4
+
5
+ protected
6
+
7
+ def raise_unknown_options_if_not_blank!(config)
8
+ unless config.blank?
9
+ raise ConfigError.new("unknown options for \"#{self.class.short_name}\": #{config.inspect}")
10
+ end
5
11
  end
6
12
 
7
- def self.update_all_sources(options = {})
8
- options[:sources_path].mkpath
9
- Dir.chdir(options[:sources_path]) do
10
- @subclasses.each do |subclass|
11
- subclass.update_sources(options)
12
- end
13
+ def config_only_option(config)
14
+ if only = config.delete(:only)
15
+ [only].flatten.map(&:to_s).map(&:downcase)
13
16
  end
14
17
  end
15
18
 
16
- def self.rdoc_tasks(options = {})
17
- Dir.chdir(options[:sources_path]) do
18
- @@tasks = RdocTasks.new
19
+ def config_exclude_option(config)
20
+ if exclude = config.delete(:exclude)
21
+ [exclude].flatten.map(&:to_s).map(&:downcase)
22
+ else
23
+ []
24
+ end
25
+ end
19
26
 
20
- @subclasses.each do |subclass|
21
- subclass.add_rdoc_tasks(options)
22
- end
27
+ def sources_path
28
+ self.class.sources_path
29
+ end
30
+
31
+ module ClassMethods
32
+ BASE_PATH = Pathname.new(Dir.pwd).expand_path
33
+ DOCS_PATH = BASE_PATH + 'docs'
34
+ PUBLIC_PATH = BASE_PATH + 'public'
23
35
 
24
- to_clear = Dir.glob(options[:docs_path] + '*/*')
25
- @@tasks.each do |task|
26
- doc_path = options[:docs_path] + task.doc_path
27
- to_clear.delete_if{ |path| path.starts_with?(doc_path) }
36
+ def base_path
37
+ BASE_PATH
38
+ end
39
+
40
+ def docs_path
41
+ DOCS_PATH.tap(&:mkpath)
42
+ end
43
+
44
+ def public_path
45
+ PUBLIC_PATH
46
+ end
47
+
48
+ def subclasses
49
+ @subclasses ||= {}
50
+ end
51
+
52
+ def short_name
53
+ name.demodulize.underscore
54
+ end
55
+
56
+ def sources_path
57
+ Pathname.new("sources/#{short_name}").tap do |path|
58
+ path.mkpath
28
59
  end
29
- to_clear.each do |path|
30
- remove_if_present(path)
60
+ end
61
+
62
+ def inherited(subclass)
63
+ name = subclass.short_name
64
+ [name, name.singularize, name.pluralize].uniq.each do |name_form|
65
+ subclasses[name_form] = subclass
31
66
  end
67
+ end
32
68
 
33
- @@tasks.each do |task|
34
- doc_path = options[:docs_path] + task.doc_path
35
-
36
- begin
37
- raise 'force' if options[:force]
38
- if File.exist?(doc_path)
39
- unless File.directory?(doc_path)
40
- raise 'not a dir'
41
- else
42
- created = Time.parse(File.read(doc_path + 'created.rid'))
43
- Find.find(options[:sources_path] + task.src_path) do |path|
44
- Find.prune if File.directory?(path) && File.basename(path)[0] == ?.
45
- raise "changed #{path}" if File.ctime(path) > created || File.mtime(path) > created
46
- end
47
- end
48
- end
49
- rescue => e
50
- puts e
51
- remove_if_present(doc_path)
52
- end
69
+ def entries
70
+ @entries ||= []
71
+ end
72
+
73
+ def clear
74
+ entries.clear
75
+ end
76
+
77
+ def to_document(type, config)
78
+ type = type.to_s
79
+ config.symbolize_keys! if config.is_a?(Hash)
80
+ if subclasses[type]
81
+ entries << subclasses[type].new(config)
82
+ else
83
+ raise ConfigError.new("don't know how to build \"#{type}\" => #{config.inspect}")
53
84
  end
85
+ end
54
86
 
87
+ def tasks(options = {})
88
+ @@tasks = []
89
+ entries.each do |entry|
90
+ entry.add_tasks(options)
91
+ end
55
92
  @@tasks
56
93
  end
57
- end
58
94
 
59
- protected
95
+ def add_task(options = {})
96
+ options[:paths] ||= []
97
+ [/^readme$/i, /^readme\.(?:txt|rdoc|markdown)$/i, /^readme\./i].each do |readme_r|
98
+ options[:main] ||= options[:paths].grep(readme_r).first
99
+ end
100
+ @@tasks << Task.new(options)
101
+ end
60
102
 
61
- def self.add_rdoc_task(options = {})
62
- options[:pathes] ||= []
63
- [/^readme$/i, /^readme\.(?:txt|rdoc|markdown)$/i, /^readme\./i].each do |readme_r|
64
- options[:main] ||= options[:pathes].grep(readme_r).first
103
+ def system(*args)
104
+ escaped_args = args.map(&:to_s).map{ |arg| arg[/[^a-z0-9\/\-.]/i] ? arg.inspect : arg }
105
+ command = escaped_args.join(' ')
106
+ puts "Executing #{command.length > 250 ? "#{command[0, 247]}..." : command}"
107
+ Kernel.system(*args)
65
108
  end
66
- @@tasks.add(self, options)
67
- end
68
109
 
69
- def self.with_env(key, value)
70
- old_value, ENV[key] = ENV[key], value
71
- yield
72
- ensure
73
- ENV[key] = old_value
74
- end
110
+ def remove_if_present(path)
111
+ FileUtils.remove_entry(path) if File.exist?(path)
112
+ end
75
113
 
76
- def self.remove_if_present(path)
77
- FileUtils.remove_entry(path) if File.exist?(path)
114
+ def with_env(key, value)
115
+ old_value, ENV[key] = ENV[key], value
116
+ yield
117
+ ensure
118
+ ENV[key] = old_value
119
+ end
78
120
  end
121
+ extend ClassMethods
79
122
  end
80
123
  end
@@ -0,0 +1,4 @@
1
+ class SdocAll
2
+ class ConfigError < Exception
3
+ end
4
+ end
data/lib/sdoc_all/gems.rb CHANGED
@@ -1,28 +1,54 @@
1
- require 'enumerator'
2
-
3
1
  class SdocAll
4
2
  class Gems < Base
5
- def self.each(&block)
6
- Gem.source_index.each(&block)
7
- end
3
+ def initialize(config)
4
+ config ||= {}
5
+ config = {:only => config} unless config.is_a?(Hash)
6
+
7
+ @config = {
8
+ :versions => config.delete(:versions).to_s.downcase,
9
+ :only => config_only_option(config),
10
+ :exclude => config_exclude_option(config),
11
+ }
8
12
 
9
- def self.update_sources(options = {})
13
+ raise_unknown_options_if_not_blank!(config)
10
14
  end
11
15
 
12
- def self.add_rdoc_tasks(options = {})
13
- each do |gem_name, spec|
16
+ def add_tasks(options = {})
17
+ specs = config[:versions] == 'all' ? self.class.all_specs : self.class.latest_specs
18
+
19
+ specs.sort_by!{ |spec| [spec.name.downcase, spec.sort_obj] }
20
+
21
+ specs.delete_if{ |spec| !config[:only].include?(spec.name.downcase) } if config[:only]
22
+ specs.delete_if{ |spec| config[:exclude].include?(spec.name.downcase) }
23
+
24
+ specs.each do |spec|
14
25
  main = nil
15
26
  spec.rdoc_options.each_cons(2) do |options|
16
27
  main = options[1] if %w(--main -m).include?(options[0])
17
28
  end
18
- add_rdoc_task(
19
- :name_parts => [spec.name, spec.version],
29
+ Base.add_task(
20
30
  :src_path => spec.full_gem_path,
21
- :doc_path => "gems/#{gem_name}",
22
- :pathes => spec.require_paths + spec.extra_rdoc_files,
23
- :main => main
31
+ :doc_path => "gems.#{spec.full_name}",
32
+ :paths => spec.require_paths + spec.extra_rdoc_files,
33
+ :main => main,
34
+ :title => "gems: #{spec.full_name}"
24
35
  )
25
36
  end
26
37
  end
38
+
39
+ module ClassMethods
40
+ def latest_specs
41
+ Gem.source_index.latest_specs
42
+ end
43
+
44
+ def all_specs
45
+ specs = []
46
+ Gem.source_index.each do |_, spec|
47
+ specs << spec
48
+ end
49
+ specs
50
+ end
51
+ end
52
+ extend ClassMethods
27
53
  end
28
54
  end
@@ -16,12 +16,7 @@ class SdocAllGenerator < RubiGen::Base
16
16
  BASEDIRS.each { |path| m.directory path }
17
17
 
18
18
  m.file_copy_each %w(Rakefile)
19
- m.template_copy_each %w(sdoc.config.yml.erb), nil, :assigns => {:sdoc_options => {
20
- 'ruby' => options[:ruby],
21
- 'rails' => options[:rails],
22
- 'exclude' => options[:exclude],
23
- 'plugins_path' => options[:plugins_path],
24
- }}
19
+ m.file_copy_each %w(config.yml)
25
20
  end
26
21
  end
27
22
 
@@ -46,11 +41,6 @@ EOS
46
41
  opts.separator ''
47
42
  opts.separator 'Options:'
48
43
 
49
- opts.on("-r", "--ruby=\"version\"", String, "version of ruby you want to be documented like 1.8 or 1.8.6", "Default: latest") { |o| options[:ruby] = o }
50
- opts.on("-a", "--rails=\"version\"", String, "version of rails you want to be documented like 2. or 2.3.2", "Default: latest") { |o| options[:rails] = o }
51
- opts.on("-e", "--exclude=\"pathes\"", Array, "what to exclude separated with comma like gems/actionmailer or gems/actionpack,gems/rails", "Default: gems related to rails") { |o| options[:exclude] = o }
52
- opts.on("-p", "--plugins_path=\"path\"", Array, "directory in which you store plugins you use are stored", "Default: ~/.plugins") { |o| options[:plugins_path] = o }
53
-
54
44
  opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
55
45
  end
56
46
 
@@ -1,4 +1,6 @@
1
1
  require 'rubygems'
2
+ require 'rake'
2
3
  require 'sdoc'
4
+ require 'sdoc_all'
3
5
 
4
- require 'tasks/sdoc_all'
6
+ require 'tasks/sdoc_all_rake'
@@ -0,0 +1,16 @@
1
+ ---
2
+ min_update_interval: 1 hour
3
+ sdoc: # watch indent in this section - it must be 4 spaces
4
+ - ruby: 1.8.7
5
+ - rails
6
+ - gems:
7
+ exclude:
8
+ - mysql
9
+ - rails
10
+ - actionmailer
11
+ - actionpack
12
+ - activerecord
13
+ - activeresource
14
+ - activesupport
15
+ - plugins: ~/.plugins
16
+ # - path: ~/some/path
@@ -0,0 +1,100 @@
1
+ class SdocAll
2
+ class Paths < Base
3
+ def initialize(config)
4
+ config = [config] unless config.is_a?(Array)
5
+
6
+ config.each do |entry|
7
+ case entry
8
+ when Hash
9
+ entry.symbolize_keys!
10
+
11
+ unless entry[:root].present?
12
+ raise ConfigError.new("specify what to document")
13
+ end
14
+
15
+ root = Pathname.new(entry.delete(:root)).expand_path
16
+
17
+ unless root.exist?
18
+ raise ConfigError.new("path #{root} does not exist")
19
+ end
20
+
21
+ paths = entry.delete(:paths)
22
+ paths = [paths] if paths && !paths.is_a?(Array)
23
+
24
+ entries << {
25
+ :root => root,
26
+ :main => entry.delete(:main),
27
+ :paths => paths,
28
+ }
29
+ raise_unknown_options_if_not_blank!(entry)
30
+ when String
31
+ Dir[File.expand_path(entry)].each do |path|
32
+ config << {:root => path}
33
+ end
34
+ else
35
+ raise_unknown_options_if_not_blank!(entry)
36
+ end
37
+ end
38
+ end
39
+
40
+ def add_tasks(options = {})
41
+ common_path = self.class.common_path(entries.map{ |entry| entry[:root] })
42
+
43
+ entries.each do |entry|
44
+ path = entry[:root]
45
+
46
+ task_options = {
47
+ :src_path => path,
48
+ :doc_path => "paths.#{path.relative_path_from(common_path).to_s.gsub('/', '.')}",
49
+ }
50
+ task_options[:title] = task_options[:doc_path].sub('.', ': ')
51
+ task_options[:main] = entry[:main] if entry[:main]
52
+
53
+ if entry[:paths]
54
+ paths = Rake::FileList.new
55
+ Dir.chdir(path) do
56
+ entry[:paths].each do |glob|
57
+ m = /^([+-]?)(.*)$/.match(glob)
58
+ if m[1] == '-'
59
+ paths.exclude(m[2])
60
+ else
61
+ paths.include(m[2])
62
+ end
63
+ end
64
+ paths.resolve
65
+ end
66
+
67
+ task_options[:paths] = paths.to_a
68
+ end
69
+
70
+ Base.add_task(task_options)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def entries
77
+ @entries ||= []
78
+ end
79
+
80
+ module ClassMethods
81
+ def common_path(paths)
82
+ common = nil
83
+ paths.each do |path|
84
+ if common ||= path
85
+ unless path.to_s.starts_with?(common.to_s)
86
+ path.ascend do |path_part|
87
+ if common.to_s.starts_with?(path_part)
88
+ common = path_part
89
+ break
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ common = common.parent if common
96
+ end
97
+ end
98
+ extend ClassMethods
99
+ end
100
+ end