sdoc_all 0.1.0 → 0.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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