sdoc_all 0.2.1.0 → 1.0.0

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/Manifest CHANGED
@@ -1,14 +1,15 @@
1
1
  bin/sdoc-all
2
2
  lib/sdoc_all/base.rb
3
3
  lib/sdoc_all/config_error.rb
4
- lib/sdoc_all/gems.rb
4
+ lib/sdoc_all/file_list.rb
5
5
  lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb
6
6
  lib/sdoc_all/generator/sdoc_all/templates/config.yml
7
7
  lib/sdoc_all/generator/sdoc_all/templates/Rakefile
8
- lib/sdoc_all/paths.rb
9
- lib/sdoc_all/plugins.rb
10
- lib/sdoc_all/rails.rb
11
- lib/sdoc_all/ruby.rb
8
+ lib/sdoc_all/parts/gems.rb
9
+ lib/sdoc_all/parts/paths.rb
10
+ lib/sdoc_all/parts/plugins.rb
11
+ lib/sdoc_all/parts/rails.rb
12
+ lib/sdoc_all/parts/ruby.rb
12
13
  lib/sdoc_all/task.rb
13
14
  lib/sdoc_all.rb
14
15
  lib/tasks/sdoc_all_rake.rb
@@ -16,6 +17,7 @@ LICENSE
16
17
  Manifest
17
18
  Rakefile
18
19
  README.rdoc
20
+ spec/sdoc_all/file_list_spec.rb
19
21
  spec/sdoc_all/gems_spec.rb
20
22
  spec/sdoc_all/paths_spec.rb
21
23
  spec/sdoc_all/plugins_spec.rb
data/README.rdoc CHANGED
@@ -53,6 +53,11 @@ also as ruby has no index page, you can create folder with index.html in it (als
53
53
  version: 1.8.6
54
54
  index: ruby_quick_ref
55
55
 
56
+ to build stdlib documentation for every group not fully present in ruby documentation (based on http://stdlib-doc.rubyforge.org)
57
+ - ruby:
58
+ version: 1.8.6
59
+ stdlib: true
60
+
56
61
  === rails
57
62
  choose rails version
58
63
  - rails: 2.3.2
data/VERSION.yml CHANGED
@@ -1 +1 @@
1
- [0, 2, 1, 0]
1
+ [1, 0, 0]
data/lib/sdoc_all/base.rb CHANGED
@@ -107,13 +107,13 @@ class SdocAll
107
107
  end
108
108
 
109
109
  def add_task(options = {})
110
- options[:paths] ||= []
111
- [/^readme$/i, /^readme\.(?:txt|rdoc|markdown)$/i, /^readme\./i].each do |readme_r|
112
- options[:main] ||= options[:paths].grep(readme_r).first
113
- end
114
110
  @@tasks << Task.new(options)
115
111
  end
116
112
 
113
+ def add_merge_task(options = {})
114
+ @@tasks << MergeTask.new(options)
115
+ end
116
+
117
117
  def system(*args)
118
118
  escaped_args = args.map(&:to_s).map{ |arg| arg[/[^a-z0-9\/\-.]/i] ? arg.inspect : arg }
119
119
  command = escaped_args.join(' ')
@@ -0,0 +1,11 @@
1
+ class SdocAll
2
+ class FileList < Rake::FileList
3
+ def resolve
4
+ if @pending
5
+ super
6
+ @items.replace(@items.uniq.reject{ |path| !File.exist?(path) })
7
+ end
8
+ self
9
+ end
10
+ end
11
+ end
@@ -1,7 +1,10 @@
1
1
  ---
2
2
  min_update_interval: 1 hour
3
+ title: "ruby, rails, gems"
3
4
  sdoc: # watch indent in this section - it must be 4 spaces
4
- - ruby: 1.8.7
5
+ - ruby:
6
+ version: 1.8.7
7
+ stdlib: true
5
8
  - rails
6
9
  - gems:
7
10
  exclude:
@@ -12,5 +15,5 @@ sdoc: # watch indent in this section - it must be 4 spaces
12
15
  - activerecord
13
16
  - activeresource
14
17
  - activesupport
15
- - plugins: ~/.plugins
18
+ # - plugins: ~/.plugins
16
19
  # - path: ~/some/path
@@ -0,0 +1,83 @@
1
+ class SdocAll
2
+ class Gems < Base
3
+ def initialize(raw_config)
4
+ raw_config ||= {}
5
+ raw_config = {:only => raw_config} unless raw_config.is_a?(Hash)
6
+
7
+ @config = {
8
+ :versions => raw_config.delete(:versions).to_s.downcase,
9
+ :only => config_only_option(raw_config),
10
+ :exclude => config_exclude_option(raw_config),
11
+ }
12
+
13
+ errors = []
14
+ gem_names = unfiltered_specs.map{ |spec| spec.name.downcase }
15
+ [:only, :exclude].each do |option|
16
+ if config[option]
17
+ config[option].each do |gem_name|
18
+ errors << "#{option} #{gem_name} does not match any gem" unless gem_names.include?(gem_name)
19
+ end
20
+ end
21
+ end
22
+ unless errors.empty?
23
+ raise ConfigError.new(errors.join("\n"))
24
+ end
25
+
26
+ if filtered_specs.empty?
27
+ options = config.map do |option, values|
28
+ "#{option} => #{Array(values).join(',')}" if values.present?
29
+ end.compact.join(', ')
30
+ raise ConfigError.new("no gems matches #{options}")
31
+ end
32
+
33
+ raise_unknown_options_if_not_blank!(raw_config)
34
+ end
35
+
36
+ def add_tasks(options = {})
37
+ specs = filtered_specs.sort_by{ |spec| [spec.name.downcase, spec.sort_obj] }
38
+ specs.each do |spec|
39
+ main = nil
40
+ spec.rdoc_options.each_cons(2) do |options|
41
+ main = options[1] if %w(--main -m).include?(options[0])
42
+ end
43
+ Base.add_task(
44
+ :src_path => spec.full_gem_path,
45
+ :doc_path => "gems.#{spec.full_name}",
46
+ :paths => spec.require_paths + spec.extra_rdoc_files,
47
+ :main => main,
48
+ :title => "gems: #{spec.full_name}"
49
+ )
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def unfiltered_specs
56
+ config[:versions] == 'all' ? self.class.all_specs : self.class.latest_specs
57
+ end
58
+
59
+ def filtered_specs
60
+ specs = unfiltered_specs
61
+
62
+ specs.delete_if{ |spec| !config[:only].include?(spec.name.downcase) } if config[:only]
63
+ specs.delete_if{ |spec| config[:exclude].include?(spec.name.downcase) }
64
+
65
+ specs
66
+ end
67
+
68
+ module ClassMethods
69
+ def latest_specs
70
+ Gem.source_index.latest_specs
71
+ end
72
+
73
+ def all_specs
74
+ specs = []
75
+ Gem.source_index.each do |_, spec|
76
+ specs << spec
77
+ end
78
+ specs
79
+ end
80
+ end
81
+ extend ClassMethods
82
+ end
83
+ end
@@ -1,40 +1,54 @@
1
1
  class SdocAll
2
2
  class Paths < Base
3
- def initialize(config)
4
- config = [config] unless config.is_a?(Array)
3
+ def initialize(raw_config)
4
+ raw_config = [raw_config] unless raw_config.is_a?(Array)
5
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")
6
+ errors = []
7
+ raw_config.each do |raw_entry|
8
+ begin
9
+ raw_entries = case raw_entry
10
+ when Hash
11
+ [raw_entry]
12
+ when String
13
+ Dir[File.expand_path(raw_entry)].map{ |path| {:root => path} }
14
+ else
15
+ raise_unknown_options_if_not_blank!(raw_entry)
13
16
  end
14
17
 
15
- root = Pathname.new(entry.delete(:root)).expand_path
18
+ raw_entries.each do |entry|
19
+ begin
20
+ entry.symbolize_keys!
16
21
 
17
- unless root.exist?
18
- raise ConfigError.new("path #{root} does not exist")
19
- end
22
+ unless entry[:root].present?
23
+ raise ConfigError.new("specify what to document")
24
+ end
20
25
 
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}
26
+ root = Pathname.new(entry.delete(:root)).expand_path
27
+
28
+ unless root.exist?
29
+ raise ConfigError.new("path #{root} does not exist")
30
+ end
31
+
32
+ paths = entry.delete(:paths)
33
+ paths = [paths] if paths && !paths.is_a?(Array)
34
+
35
+ entries << {
36
+ :root => root,
37
+ :main => entry.delete(:main),
38
+ :paths => paths,
39
+ }
40
+ raise_unknown_options_if_not_blank!(entry)
41
+ rescue ConfigError => e
42
+ errors << e
43
+ end
33
44
  end
34
- else
35
- raise_unknown_options_if_not_blank!(entry)
45
+ rescue ConfigError => e
46
+ errors << e
36
47
  end
37
48
  end
49
+ unless errors.empty?
50
+ raise ConfigError.new(errors.join("\n"))
51
+ end
38
52
  end
39
53
 
40
54
  def add_tasks(options = {})
@@ -1,27 +1,27 @@
1
1
  class SdocAll
2
2
  class Plugins < Base
3
- def initialize(config)
4
- config ||= {}
5
- config = {:path => config} unless config.is_a?(Hash)
3
+ def initialize(raw_config)
4
+ raw_config ||= {}
5
+ raw_config = {:path => raw_config} unless raw_config.is_a?(Hash)
6
6
 
7
- config[:path] ||= sources_path
7
+ raw_config[:path] ||= sources_path
8
8
 
9
9
  @config = {
10
- :update => config.delete(:update) != false,
11
- :path => Pathname.new(config.delete(:path)).expand_path,
12
- :only => config_only_option(config),
13
- :exclude => config_exclude_option(config),
10
+ :update => raw_config.delete(:update) != false,
11
+ :path => Pathname.new(raw_config.delete(:path)).expand_path,
12
+ :only => config_only_option(raw_config),
13
+ :exclude => config_exclude_option(raw_config),
14
14
  }
15
15
 
16
- unless @config[:path].directory?
17
- raise ConfigError.new("path #{@config[:path]} is not a directory")
16
+ unless config[:path].directory?
17
+ raise ConfigError.new("path #{config[:path]} is not a directory")
18
18
  end
19
19
 
20
- raise_unknown_options_if_not_blank!(config)
20
+ raise_unknown_options_if_not_blank!(raw_config)
21
21
  end
22
22
 
23
23
  def add_tasks(options = {})
24
- plugins = @config[:path].children.map do |path|
24
+ plugins = config[:path].children.map do |path|
25
25
  path if path.directory?
26
26
  end.compact
27
27
 
@@ -1,12 +1,12 @@
1
1
  class SdocAll
2
2
  class Rails < Base
3
- def initialize(config)
4
- config ||= {}
5
- config = {:version => config} unless config.is_a?(Hash)
3
+ def initialize(raw_config)
4
+ raw_config ||= {}
5
+ raw_config = {:version => raw_config} unless raw_config.is_a?(Hash)
6
6
 
7
- if config[:version]
8
- unless self.class.versions.include?(config[:version])
9
- raise ConfigError.new("you don't have rails #{config[:version]} installed")
7
+ if raw_config[:version]
8
+ unless self.class.versions.include?(raw_config[:version])
9
+ raise ConfigError.new("you don't have rails #{raw_config[:version]} installed")
10
10
  end
11
11
  else
12
12
  if self.class.versions.empty?
@@ -15,14 +15,14 @@ class SdocAll
15
15
  end
16
16
 
17
17
  @config = {
18
- :version => config.delete(:version) || self.class.versions.last,
18
+ :version => raw_config.delete(:version) || self.class.versions.last,
19
19
  }
20
20
 
21
- raise_unknown_options_if_not_blank!(config)
21
+ raise_unknown_options_if_not_blank!(raw_config)
22
22
  end
23
23
 
24
24
  def add_tasks(options = {})
25
- version = @config[:version]
25
+ version = config[:version]
26
26
  path = sources_path + version
27
27
 
28
28
  unless path.directory?
@@ -0,0 +1,203 @@
1
+ require 'net/ftp'
2
+ require 'net/http'
3
+
4
+ class SdocAll
5
+ class Ruby < Base
6
+ def initialize(raw_config)
7
+ raw_config ||= {}
8
+ raw_config = {:version => raw_config} unless raw_config.is_a?(Hash)
9
+
10
+ @config = {
11
+ :update => raw_config.delete(:update) != false,
12
+ :version => raw_config.delete(:version),
13
+ :index => raw_config.delete(:index),
14
+ :stdlib => raw_config.delete(:stdlib),
15
+ }
16
+
17
+ version = config[:version]
18
+ unless version.present?
19
+ raise ConfigError.new("specify version of ruby (place archive to 'sources' directory or it will be download from ftp://ftp.ruby-lang.org/)")
20
+ end
21
+ self.class.find_or_download_matching_archive(version)
22
+
23
+ if config[:index]
24
+ index = Pathname(config[:index])
25
+ unless index.directory? && (index + 'index.html').file?
26
+ raise ConfigError.new("index should be a directory with index.html inside and all related files should be with relative links")
27
+ end
28
+ end
29
+
30
+ if config[:stdlib]
31
+ download_and_get_stdlib_config
32
+ end
33
+
34
+ raise_unknown_options_if_not_blank!(raw_config)
35
+ end
36
+
37
+ def add_tasks(options = {})
38
+ archive = self.class.find_or_download_matching_archive(config[:version], :update => config[:update] && options[:update])
39
+ version = archive.full_version
40
+ src_path = sources_path + version
41
+
42
+ unless src_path.directory?
43
+ Base.remove_if_present(src_path)
44
+ case archive.extension
45
+ when 'tar.bz2'
46
+ Base.system('tar', '-xjf', archive.path, '-C', sources_path)
47
+ when 'tar.gz'
48
+ Base.system('tar', '-xzf', archive.path, '-C', sources_path)
49
+ when 'zip'
50
+ Base.system('unzip', '-q', archive.path, '-d', sources_path)
51
+ end
52
+ File.rename(sources_path + "ruby-#{version}", src_path)
53
+ end
54
+ self.class.used_sources << src_path
55
+
56
+ task_options = {
57
+ :src_path => src_path,
58
+ :doc_path => "ruby-#{version}",
59
+ :title => "ruby-#{version}"
60
+ }
61
+ task_options[:index] = config[:index] if config[:index]
62
+ Base.add_task(task_options)
63
+
64
+ if config[:stdlib]
65
+ stdlib_config = download_and_get_stdlib_config(:update => config[:update] && options[:update])
66
+
67
+ stdlib_tasks = []
68
+ Dir.chdir(src_path) do
69
+ main_files_to_document = get_files_to_document
70
+ stdlib_config['targets'].each do |target|
71
+ name = target['target']
72
+
73
+ paths = FileList.new
74
+ paths.include("{lib,ext}/#{name}/**/README*")
75
+ paths.include("{lib,ext}/#{name}.{c,rb}")
76
+ paths.include("{lib,ext}/#{name}/**/*.{c,rb}")
77
+ paths.resolve
78
+ paths.reject! do |path|
79
+ [%r{/extconf.rb\Z}, %r{/test/(?!unit)}, %r{/tests/}, %r{/sample}, %r{/demo/}].any?{ |pat| pat.match path }
80
+ end
81
+
82
+ if paths.present? && (paths - main_files_to_document).present?
83
+ stdlib_tasks << {
84
+ :src_path => src_path,
85
+ :doc_path => name.gsub(/[^a-z0-9\-_]/i, '-'),
86
+ :paths => paths.to_a,
87
+ :main => target['mainpage'],
88
+ :title => name
89
+ }
90
+ end
91
+ end
92
+ end
93
+ Base.add_merge_task(
94
+ :doc_path => "ruby-stdlib-#{version}",
95
+ :title => "ruby-stdlib-#{version}",
96
+ :tasks_options => stdlib_tasks.sort_by{ |task| task[:title].downcase }
97
+ )
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def get_files_to_document(dir = nil)
104
+ files = []
105
+
106
+ dot_document_name = '.document'
107
+ dot_document_path = dir ? dir + dot_document_name : Pathname(dot_document_name)
108
+ if dot_document_path.exist?
109
+ dot_document_path.readlines.map(&:strip).reject(&:blank?).reject{ |line| line[/^\s*#/] }
110
+ else
111
+ ['*']
112
+ end.each do |glob|
113
+ Pathname.glob(dir ? dir + glob : glob) do |path|
114
+ if path.directory?
115
+ files.concat(get_files_to_document(path))
116
+ else
117
+ files << path.to_s
118
+ end
119
+ end
120
+ end
121
+
122
+ files
123
+ end
124
+
125
+ def download_and_get_stdlib_config(options = {})
126
+ stdlib_config_url = 'http://stdlib-doc.rubyforge.org/svn/trunk/data/gendoc.yaml'
127
+ if options[:update] || (config = get_stdlib_config).nil?
128
+ data = Net::HTTP.get(URI.parse(stdlib_config_url))
129
+ stdlib_config_path.write(data)
130
+ if (config = get_stdlib_config).nil?
131
+ raise ConfigError.new("could not get stdlib config from #{stdlib_config_url}")
132
+ end
133
+ end
134
+ config
135
+ end
136
+
137
+ def get_stdlib_config
138
+ YAML.load_file stdlib_config_path if stdlib_config_path.readable?
139
+ end
140
+
141
+ def stdlib_config_path
142
+ sources_path.parent + 'stdlib-gendoc.yaml'
143
+ end
144
+
145
+ ArchiveInfo = Struct.new(:path, :name, :full_version, :extension, :version)
146
+ module ClassMethods
147
+ def match_ruby_archive(path)
148
+ name = File.basename(path)
149
+ if match = /^ruby-((\d+\.\d+\.\d+)-p(\d+))(?:\.(tar\.(?:gz|bz2)|zip))$/.match(name)
150
+ ArchiveInfo.new.tap do |i|
151
+ i.path = path
152
+ i.name = name
153
+ i.full_version = match[1]
154
+ i.extension = match[4]
155
+ i.version = match[2].split('.').map(&:to_i) << match[3].to_i
156
+ end
157
+ end
158
+ end
159
+
160
+ def last_matching_ruby_archive(version, paths)
161
+ paths.map do |path|
162
+ match_ruby_archive(path)
163
+ end.compact.sort_by(&:version).reverse.find do |tar_info|
164
+ tar_info.full_version.starts_with?(version)
165
+ end
166
+ end
167
+
168
+ def find_matching_archive(version)
169
+ paths = sources_path.parent.children.select(&:file?)
170
+ last_matching_ruby_archive(version, paths)
171
+ end
172
+
173
+ def download_matching_archive(version)
174
+ Net::FTP.open('ftp.ruby-lang.org') do |ftp|
175
+ remote_path = '/pub/ruby'
176
+ ftp.debug_mode = true
177
+ ftp.passive = true
178
+ ftp.login
179
+ ftp.chdir(remote_path)
180
+ paths = ftp.list('ruby-*.tar.bz2').map{ |line| "#{remote_path}/#{line.split.last}" }
181
+
182
+ if tar = last_matching_ruby_archive(version, paths)
183
+ dest = sources_path.parent + tar.name
184
+ unless File.exist?(dest) && File.size(dest) == ftp.size(tar.path)
185
+ ftp.getbinaryfile(tar.path, dest)
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ def find_or_download_matching_archive(version, options = {})
192
+ if options[:update] || (archive = find_matching_archive(version)).nil?
193
+ download_matching_archive(version)
194
+ if (archive = find_matching_archive(version)).nil?
195
+ raise ConfigError.new("could not find version of ruby matching #{version.inspect}")
196
+ end
197
+ end
198
+ archive
199
+ end
200
+ end
201
+ extend ClassMethods
202
+ end
203
+ end
data/lib/sdoc_all/task.rb CHANGED
@@ -1,9 +1,40 @@
1
1
  require 'digest'
2
2
 
3
3
  class SdocAll
4
- class Task
4
+ class BaseTask
5
+ def config_hash
6
+ Digest::SHA1.hexdigest(for_hash.inspect)
7
+ end
8
+
9
+ def config_hash_path
10
+ Base.docs_path + doc_path + 'config.hash'
11
+ end
12
+
13
+ def created_rid_path
14
+ Base.docs_path + doc_path + 'created.rid'
15
+ end
16
+
17
+ def last_build_time
18
+ Time.parse(created_rid_path.read) rescue nil
19
+ end
20
+
21
+ def clobber?
22
+ full_doc_path = Base.docs_path + doc_path
23
+ return true unless full_doc_path.exist?
24
+
25
+ created_hash = config_hash_path.read rescue nil
26
+ return true if created_hash != config_hash
27
+ end
28
+ end
29
+
30
+ class Task < BaseTask
5
31
  attr_reader :src_path, :doc_path, :paths, :main, :title, :index
6
32
  def initialize(options = {})
33
+ options[:paths] ||= []
34
+ [/^readme$/i, /^readme\.(?:txt|rdoc|markdown)$/i, /^readme\./i].each do |readme_r|
35
+ options[:main] ||= options[:paths].grep(readme_r).first
36
+ end
37
+
7
38
  @src_path = Pathname.new(options[:src_path]).expand_path
8
39
  @doc_path = options[:doc_path]
9
40
  @paths = options[:paths]
@@ -40,36 +71,20 @@ class SdocAll
40
71
 
41
72
  if (Base.docs_path + doc_path).directory?
42
73
  config_hash_path.open('w') do |f|
43
- f.write(hash)
74
+ f.write(config_hash)
44
75
  end
45
76
  end
46
77
  end
47
78
  end
48
79
 
49
- def hash
80
+ def for_hash
50
81
  for_hash = [src_path.to_s, doc_path.to_s, paths, main, title, last_build_time]
51
82
  for_hash << index if index
52
- Digest::SHA1.hexdigest(for_hash.inspect)
53
- end
54
-
55
- def config_hash_path
56
- Base.docs_path + doc_path + 'config.hash'
57
- end
58
-
59
- def created_rid_path
60
- Base.docs_path + doc_path + 'created.rid'
61
- end
62
-
63
- def last_build_time
64
- Time.parse(created_rid_path.read) rescue nil
83
+ for_hash
65
84
  end
66
85
 
67
86
  def clobber?
68
- full_doc_path = Base.docs_path + doc_path
69
- return true unless full_doc_path.exist?
70
-
71
- created_hash = config_hash_path.read rescue nil
72
- return true if created_hash != hash
87
+ return true if super
73
88
 
74
89
  latest = [src_path.mtime, src_path.ctime].max
75
90
  created = last_build_time
@@ -82,5 +97,64 @@ class SdocAll
82
97
  end
83
98
  created.nil? || latest >= created
84
99
  end
100
+
101
+ def occupied_doc_pathes
102
+ [doc_path]
103
+ end
104
+ end
105
+
106
+ class MergeTask < BaseTask
107
+ attr_reader :doc_path, :title, :tasks, :titles
108
+ def initialize(options = {})
109
+ @doc_path = options[:doc_path]
110
+ @title = options[:title]
111
+ @tasks = options[:tasks_options].map do |task_options|
112
+ Task.new(task_options.merge(
113
+ :doc_path => "#{parts_path}/#{task_options[:doc_path]}",
114
+ :title => "#{title}: #{task_options[:title]}"
115
+ ))
116
+ end
117
+ @titles = options[:tasks_options].map do |task_options|
118
+ task_options[:title]
119
+ end
120
+ end
121
+
122
+ def parts_path
123
+ "#{doc_path}_parts"
124
+ end
125
+
126
+ def run(options = {})
127
+ p clobber?
128
+ if clobber?
129
+ Base.remove_if_present(Base.docs_path + doc_path)
130
+
131
+ tasks.each do |task|
132
+ task.run(options)
133
+ end
134
+
135
+ Dir.chdir(Base.docs_path) do
136
+ cmd = %w(sdoc-merge)
137
+ cmd << '-o' << Base.docs_path + doc_path
138
+ cmd << '-t' << title
139
+ cmd << '-n' << titles.join(',')
140
+ cmd << '-u' << tasks.map{ |task| "../#{task.doc_path}" }.join(' ')
141
+ Base.system(*cmd + tasks.map(&:doc_path))
142
+ end
143
+ end
144
+ end
145
+
146
+ def for_hash
147
+ [doc_path.to_s, title, tasks.map(&:config_hash).join(' ')]
148
+ end
149
+
150
+ def clobber?
151
+ return true if super
152
+
153
+ tasks.any?(&:clobber?)
154
+ end
155
+
156
+ def occupied_doc_pathes
157
+ [doc_path, parts_path]
158
+ end
85
159
  end
86
160
  end
data/lib/sdoc_all.rb CHANGED
@@ -64,7 +64,7 @@ class SdocAll
64
64
  Dir.chdir(Base.docs_path) do
65
65
  to_delete = Dir.glob('*')
66
66
  tasks.each do |task|
67
- to_delete.delete(task.doc_path)
67
+ to_delete -= task.occupied_doc_pathes
68
68
  end
69
69
  to_delete.each do |path|
70
70
  Base.remove_if_present(path)
@@ -76,10 +76,10 @@ class SdocAll
76
76
  task.run(options)
77
77
  end
78
78
 
79
- hash = Digest::SHA1.hexdigest(tasks.map(&:hash).inspect + title.to_s)
79
+ config_hash = Digest::SHA1.hexdigest(tasks.map(&:config_hash).inspect + title.to_s)
80
80
  created_hash = config_hash_path.read rescue nil
81
81
 
82
- if hash != created_hash
82
+ if config_hash != created_hash
83
83
  Dir.chdir(Base.docs_path) do
84
84
  paths = []
85
85
  titles = []
@@ -106,7 +106,7 @@ class SdocAll
106
106
  if Base.public_path.directory?
107
107
  File.symlink(Base.docs_path, Base.public_path + 'docs')
108
108
  config_hash_path.open('w') do |f|
109
- f.write(hash)
109
+ f.write(config_hash)
110
110
  end
111
111
  last_build_sdoc_version_path.open('w') do |f|
112
112
  f.write(current_sdoc_version)
@@ -116,7 +116,7 @@ class SdocAll
116
116
  end
117
117
  end
118
118
  rescue ConfigError => e
119
- STDERR.puts e.to_s
119
+ STDERR.puts "\e[1;31m#{e.to_s}\e[0m"
120
120
  end
121
121
  end
122
122
 
@@ -125,17 +125,7 @@ class SdocAll
125
125
  config = YAML.load_file('config.yml').symbolize_keys rescue {}
126
126
 
127
127
  min_update_interval = if config[:min_update_interval].to_s[/(\d+)\s*(.*)/]
128
- value = $1.to_i
129
- case $2
130
- when /^d/
131
- value.days
132
- when /^h/
133
- value.hours
134
- when /^m/
135
- value.minutes
136
- else
137
- value.seconds
138
- end
128
+ $1.to_i.send({'d' => :days, 'h' => :hours, 'm' => :minutes}[$2[0, 1].downcase] || :seconds)
139
129
  else
140
130
  1.hour
141
131
  end
@@ -163,7 +153,7 @@ class SdocAll
163
153
  end
164
154
  end
165
155
  if errors.present?
166
- raise ConfigError.new(errors)
156
+ raise ConfigError.new(errors.join("\n"))
167
157
  end
168
158
  else
169
159
  raise ConfigError.new("config did not specify what to document")
@@ -173,10 +163,11 @@ class SdocAll
173
163
  extend ClassMethods
174
164
  end
175
165
 
176
- require 'sdoc_all/base.rb'
177
- require 'sdoc_all/task.rb'
178
- require 'sdoc_all/config_error.rb'
166
+ require 'sdoc_all/base'
167
+ require 'sdoc_all/task'
168
+ require 'sdoc_all/config_error'
169
+ require 'sdoc_all/file_list'
179
170
 
180
- Dir.entries("#{__DIR__}/sdoc_all").grep(/\.rb$/).each do |file|
181
- require "sdoc_all/#{file}"
171
+ Dir.entries("#{__DIR__}/sdoc_all/parts").grep(/\.rb$/).each do |file|
172
+ require "sdoc_all/parts/#{file}"
182
173
  end
data/sdoc_all.gemspec CHANGED
@@ -2,22 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{sdoc_all}
5
- s.version = "0.2.1.0"
5
+ s.version = "1.0.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["toy"]
9
- s.date = %q{2009-06-26}
9
+ s.date = %q{2009-08-15}
10
10
  s.default_executable = %q{sdoc-all}
11
11
  s.description = %q{Command line tool to get documentation for ruby, rails, gems and plugins in one place}
12
12
  s.email = %q{ivan@workisfun.ru}
13
13
  s.executables = ["sdoc-all"]
14
- s.extra_rdoc_files = ["bin/sdoc-all", "lib/sdoc_all/base.rb", "lib/sdoc_all/config_error.rb", "lib/sdoc_all/gems.rb", "lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb", "lib/sdoc_all/generator/sdoc_all/templates/config.yml", "lib/sdoc_all/generator/sdoc_all/templates/Rakefile", "lib/sdoc_all/paths.rb", "lib/sdoc_all/plugins.rb", "lib/sdoc_all/rails.rb", "lib/sdoc_all/ruby.rb", "lib/sdoc_all/task.rb", "lib/sdoc_all.rb", "lib/tasks/sdoc_all_rake.rb", "LICENSE", "README.rdoc"]
15
- s.files = ["bin/sdoc-all", "lib/sdoc_all/base.rb", "lib/sdoc_all/config_error.rb", "lib/sdoc_all/gems.rb", "lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb", "lib/sdoc_all/generator/sdoc_all/templates/config.yml", "lib/sdoc_all/generator/sdoc_all/templates/Rakefile", "lib/sdoc_all/paths.rb", "lib/sdoc_all/plugins.rb", "lib/sdoc_all/rails.rb", "lib/sdoc_all/ruby.rb", "lib/sdoc_all/task.rb", "lib/sdoc_all.rb", "lib/tasks/sdoc_all_rake.rb", "LICENSE", "Manifest", "Rakefile", "README.rdoc", "spec/sdoc_all/gems_spec.rb", "spec/sdoc_all/paths_spec.rb", "spec/sdoc_all/plugins_spec.rb", "spec/sdoc_all/rails_spec.rb", "spec/sdoc_all/ruby_spec.rb", "spec/sdoc_all_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "VERSION.yml", "sdoc_all.gemspec"]
14
+ s.extra_rdoc_files = ["bin/sdoc-all", "lib/sdoc_all/base.rb", "lib/sdoc_all/config_error.rb", "lib/sdoc_all/file_list.rb", "lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb", "lib/sdoc_all/generator/sdoc_all/templates/config.yml", "lib/sdoc_all/generator/sdoc_all/templates/Rakefile", "lib/sdoc_all/parts/gems.rb", "lib/sdoc_all/parts/paths.rb", "lib/sdoc_all/parts/plugins.rb", "lib/sdoc_all/parts/rails.rb", "lib/sdoc_all/parts/ruby.rb", "lib/sdoc_all/task.rb", "lib/sdoc_all.rb", "lib/tasks/sdoc_all_rake.rb", "LICENSE", "README.rdoc"]
15
+ s.files = ["bin/sdoc-all", "lib/sdoc_all/base.rb", "lib/sdoc_all/config_error.rb", "lib/sdoc_all/file_list.rb", "lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb", "lib/sdoc_all/generator/sdoc_all/templates/config.yml", "lib/sdoc_all/generator/sdoc_all/templates/Rakefile", "lib/sdoc_all/parts/gems.rb", "lib/sdoc_all/parts/paths.rb", "lib/sdoc_all/parts/plugins.rb", "lib/sdoc_all/parts/rails.rb", "lib/sdoc_all/parts/ruby.rb", "lib/sdoc_all/task.rb", "lib/sdoc_all.rb", "lib/tasks/sdoc_all_rake.rb", "LICENSE", "Manifest", "Rakefile", "README.rdoc", "spec/sdoc_all/file_list_spec.rb", "spec/sdoc_all/gems_spec.rb", "spec/sdoc_all/paths_spec.rb", "spec/sdoc_all/plugins_spec.rb", "spec/sdoc_all/rails_spec.rb", "spec/sdoc_all/ruby_spec.rb", "spec/sdoc_all_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "VERSION.yml", "sdoc_all.gemspec"]
16
16
  s.homepage = %q{http://github.com/toy/sdoc_all}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sdoc_all", "--main", "README.rdoc"]
18
18
  s.require_paths = ["lib"]
19
19
  s.rubyforge_project = %q{toytoy}
20
- s.rubygems_version = %q{1.3.4}
20
+ s.rubygems_version = %q{1.3.5}
21
21
  s.summary = %q{documentation for everything}
22
22
 
23
23
  if s.respond_to? :specification_version then
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ class SdocAll
4
+ describe FileList do
5
+ before do
6
+ @list = FileList.new
7
+ end
8
+
9
+ it "should include well" do
10
+ @list.include('R*')
11
+ @list.should == %w(Rakefile README.rdoc)
12
+ end
13
+
14
+ it "should exclude well" do
15
+ @list.include('R*')
16
+ @list.exclude('Rake*')
17
+ @list.should == %w(README.rdoc)
18
+ end
19
+
20
+ it "should exclude non existing files from list" do
21
+ @list.include('R*')
22
+ @list.include('non existing')
23
+ @list.should == %w(Rakefile README.rdoc)
24
+ end
25
+
26
+ it "should exclude duplicates" do
27
+ @list.include('R*')
28
+ @list.include('R*')
29
+ @list.should == %w(Rakefile README.rdoc)
30
+ end
31
+
32
+ it "should not fail if directory changes after resolve" do
33
+ @list.include('R*')
34
+ @list.resolve
35
+ Dir.original_chdir('lib') do
36
+ @list.should == %w(Rakefile README.rdoc)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -14,7 +14,7 @@ class SdocAll
14
14
  Pathname.should_receive(:new).with("#{sym}").and_return(@roots[sym])
15
15
  Base.should_receive(:add_task).with(:doc_path => "paths.lala.#{sym}_exp", :src_path => @roots[sym].expand_path, :title => "paths: lala/#{sym}_exp")
16
16
  end
17
- Paths.should_receive(:common_path).with([@roots[:a], @roots[:b], @roots[:c]].map(&:expand_path)).and_return('/common')
17
+ Paths.should_receive(:common_path).with(@roots.values_at(:a, :b, :c).map(&:expand_path)).and_return('/common')
18
18
 
19
19
  File.should_receive(:expand_path).with('*').and_return('/common/lala/*')
20
20
  Dir.should_receive(:[]).with('/common/lala/*').and_return(['a', 'b', 'c'])
@@ -28,7 +28,7 @@ class SdocAll
28
28
  Pathname.should_receive(:new).with("#{sym}").and_return(@roots[sym])
29
29
  Base.should_receive(:add_task).with(:doc_path => "paths.lala.#{sym}_exp", :src_path => @roots[sym].expand_path, :title => "paths: lala/#{sym}_exp")
30
30
  end
31
- Paths.should_receive(:common_path).with([@roots[:a], @roots[:b], @roots[:d], @roots[:e]].map(&:expand_path)).and_return('/common')
31
+ Paths.should_receive(:common_path).with(@roots.values_at(:a, :b, :d, :e).map(&:expand_path)).and_return('/common')
32
32
 
33
33
  File.should_receive(:expand_path).with('*').and_return('/common/lala/*')
34
34
  File.should_receive(:expand_path).with('**').and_return('/common/common/lala/*')
@@ -97,5 +97,21 @@ class SdocAll
97
97
  Paths.new([{:root => '/lalala/lala/root'}, {:root => '/lalala/lolo/other'}]).add_tasks
98
98
  end
99
99
  end
100
+
101
+ it "should add task for mixed config" do
102
+ @roots = {}
103
+ [:a, :b, :c, :d, :e, :f, :g].each do |sym|
104
+ @roots[sym] = mock(sym, :expand_path => mock("#{sym}_exp".to_sym, :exist? => true, :relative_path_from => "lala/#{sym}_exp"))
105
+ Pathname.should_receive(:new).with("#{sym}").and_return(@roots[sym])
106
+ Base.should_receive(:add_task).with(:doc_path => "paths.lala.#{sym}_exp", :src_path => @roots[sym].expand_path, :title => "paths: lala/#{sym}_exp")
107
+ end
108
+ Paths.should_receive(:common_path).with(@roots.values_at(:a, :b, :c, :d, :e, :f, :g).map(&:expand_path)).and_return('/common')
109
+
110
+ File.should_receive(:expand_path).with('*').and_return('/common/lala/*')
111
+ Dir.should_receive(:[]).with('/common/lala/*').and_return(['b', 'c'])
112
+ File.should_receive(:expand_path).with('**').and_return('/common/lala/**')
113
+ Dir.should_receive(:[]).with('/common/lala/**').and_return(['e', 'f'])
114
+ Paths.new([{:root => 'a'}, '*', {:root => 'd'}, '**', {:root => 'g'}]).add_tasks
115
+ end
100
116
  end
101
117
  end
@@ -24,7 +24,7 @@ describe SdocAll do
24
24
  @tasks = []
25
25
  @each = @tasks.should_receive(:each_with_progress)
26
26
  %w(a b c).each do |c|
27
- task = mock(c, :doc_path => "#{c}", :src_path => "/sources/#{c}", :title => "<#{c}>")
27
+ task = mock(c, :doc_path => "#{c}", :src_path => "/sources/#{c}", :title => "<#{c}>", :config_hash => 'abc')
28
28
  task.should_receive(:run)
29
29
  File.should_receive(:file?).with(Pathname.new("/docs/#{c}/index.html")).and_return(true)
30
30
  @each.and_yield(task)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdoc_all
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - toy
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-26 00:00:00 +04:00
12
+ date: 2009-08-15 00:00:00 +04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,14 +52,15 @@ extra_rdoc_files:
52
52
  - bin/sdoc-all
53
53
  - lib/sdoc_all/base.rb
54
54
  - lib/sdoc_all/config_error.rb
55
- - lib/sdoc_all/gems.rb
55
+ - lib/sdoc_all/file_list.rb
56
56
  - lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb
57
57
  - lib/sdoc_all/generator/sdoc_all/templates/config.yml
58
58
  - lib/sdoc_all/generator/sdoc_all/templates/Rakefile
59
- - lib/sdoc_all/paths.rb
60
- - lib/sdoc_all/plugins.rb
61
- - lib/sdoc_all/rails.rb
62
- - lib/sdoc_all/ruby.rb
59
+ - lib/sdoc_all/parts/gems.rb
60
+ - lib/sdoc_all/parts/paths.rb
61
+ - lib/sdoc_all/parts/plugins.rb
62
+ - lib/sdoc_all/parts/rails.rb
63
+ - lib/sdoc_all/parts/ruby.rb
63
64
  - lib/sdoc_all/task.rb
64
65
  - lib/sdoc_all.rb
65
66
  - lib/tasks/sdoc_all_rake.rb
@@ -69,14 +70,15 @@ files:
69
70
  - bin/sdoc-all
70
71
  - lib/sdoc_all/base.rb
71
72
  - lib/sdoc_all/config_error.rb
72
- - lib/sdoc_all/gems.rb
73
+ - lib/sdoc_all/file_list.rb
73
74
  - lib/sdoc_all/generator/sdoc_all/sdoc_all_generator.rb
74
75
  - lib/sdoc_all/generator/sdoc_all/templates/config.yml
75
76
  - lib/sdoc_all/generator/sdoc_all/templates/Rakefile
76
- - lib/sdoc_all/paths.rb
77
- - lib/sdoc_all/plugins.rb
78
- - lib/sdoc_all/rails.rb
79
- - lib/sdoc_all/ruby.rb
77
+ - lib/sdoc_all/parts/gems.rb
78
+ - lib/sdoc_all/parts/paths.rb
79
+ - lib/sdoc_all/parts/plugins.rb
80
+ - lib/sdoc_all/parts/rails.rb
81
+ - lib/sdoc_all/parts/ruby.rb
80
82
  - lib/sdoc_all/task.rb
81
83
  - lib/sdoc_all.rb
82
84
  - lib/tasks/sdoc_all_rake.rb
@@ -84,6 +86,7 @@ files:
84
86
  - Manifest
85
87
  - Rakefile
86
88
  - README.rdoc
89
+ - spec/sdoc_all/file_list_spec.rb
87
90
  - spec/sdoc_all/gems_spec.rb
88
91
  - spec/sdoc_all/paths_spec.rb
89
92
  - spec/sdoc_all/plugins_spec.rb
@@ -123,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
126
  requirements: []
124
127
 
125
128
  rubyforge_project: toytoy
126
- rubygems_version: 1.3.4
129
+ rubygems_version: 1.3.5
127
130
  signing_key:
128
131
  specification_version: 3
129
132
  summary: documentation for everything
data/lib/sdoc_all/gems.rb DELETED
@@ -1,54 +0,0 @@
1
- class SdocAll
2
- class Gems < Base
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
- }
12
-
13
- raise_unknown_options_if_not_blank!(config)
14
- end
15
-
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|
25
- main = nil
26
- spec.rdoc_options.each_cons(2) do |options|
27
- main = options[1] if %w(--main -m).include?(options[0])
28
- end
29
- Base.add_task(
30
- :src_path => spec.full_gem_path,
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}"
35
- )
36
- end
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
53
- end
54
- end
data/lib/sdoc_all/ruby.rb DELETED
@@ -1,119 +0,0 @@
1
- require 'net/ftp'
2
-
3
- class SdocAll
4
- class Ruby < Base
5
- def initialize(config)
6
- config ||= {}
7
- config = {:version => config} unless config.is_a?(Hash)
8
-
9
- @config = {
10
- :update => config.delete(:update) != false,
11
- :version => config.delete(:version),
12
- :index => config.delete(:index),
13
- }
14
-
15
- version = @config[:version]
16
- unless version.present?
17
- raise ConfigError.new("specify version of ruby (place archive to 'sources' directory or it will be download from ftp://ftp.ruby-lang.org/)")
18
- end
19
- self.class.find_or_download_matching_archive(version)
20
-
21
- if @config[:index]
22
- index = Pathname(@config[:index])
23
- unless index.directory? && (index + 'index.html').file?
24
- raise ConfigError.new("index should be a directory with index.html inside and all related files should be with relative links")
25
- end
26
- end
27
-
28
- raise_unknown_options_if_not_blank!(config)
29
- end
30
-
31
- def add_tasks(options = {})
32
- archive = self.class.find_or_download_matching_archive(config[:version], :update => config[:update] && options[:update])
33
- version = archive.full_version
34
- path = sources_path + version
35
-
36
- unless path.directory?
37
- Base.remove_if_present(path)
38
- case archive.extension
39
- when 'tar.bz2'
40
- Base.system('tar', '-xjf', archive.path, '-C', sources_path)
41
- when 'tar.gz'
42
- Base.system('tar', '-xzf', archive.path, '-C', sources_path)
43
- when 'zip'
44
- Base.system('unzip', '-q', archive.path, '-d', sources_path)
45
- end
46
- File.rename(sources_path + "ruby-#{version}", path)
47
- end
48
- self.class.used_sources << path
49
-
50
- task_options = {
51
- :src_path => path,
52
- :doc_path => "ruby-#{version}",
53
- :title => "ruby-#{version}"
54
- }
55
- task_options[:index] = config[:index] if config[:index]
56
- Base.add_task(task_options)
57
- end
58
-
59
- private
60
-
61
- ArchiveInfo = Struct.new(:path, :name, :full_version, :extension, :version)
62
- module ClassMethods
63
- def match_ruby_archive(path)
64
- name = File.basename(path)
65
- if match = /^ruby-((\d+\.\d+\.\d+)-p(\d+))(?:\.(tar\.(?:gz|bz2)|zip))$/.match(name)
66
- ArchiveInfo.new.tap do |i|
67
- i.path = path
68
- i.name = name
69
- i.full_version = match[1]
70
- i.extension = match[4]
71
- i.version = match[2].split('.').map(&:to_i) << match[3].to_i
72
- end
73
- end
74
- end
75
-
76
- def last_matching_ruby_archive(version, paths)
77
- paths.map do |path|
78
- match_ruby_archive(path)
79
- end.compact.sort_by(&:version).reverse.find do |tar_info|
80
- tar_info.full_version.starts_with?(version)
81
- end
82
- end
83
-
84
- def find_matching_archive(version)
85
- paths = sources_path.parent.children.select(&:file?)
86
- last_matching_ruby_archive(version, paths)
87
- end
88
-
89
- def download_matching_archive(version)
90
- Net::FTP.open('ftp.ruby-lang.org') do |ftp|
91
- remote_path = '/pub/ruby'
92
- ftp.debug_mode = true
93
- ftp.passive = true
94
- ftp.login
95
- ftp.chdir(remote_path)
96
- paths = ftp.list('ruby-*.tar.bz2').map{ |line| "#{remote_path}/#{line.split.last}" }
97
-
98
- if tar = last_matching_ruby_archive(version, paths)
99
- dest = sources_path.parent + tar.name
100
- unless File.exist?(dest) && File.size(dest) == ftp.size(tar.path)
101
- ftp.getbinaryfile(tar.path, dest)
102
- end
103
- end
104
- end
105
- end
106
-
107
- def find_or_download_matching_archive(version, options = {})
108
- if options[:update] || (archive = find_matching_archive(version)).nil?
109
- download_matching_archive(version)
110
- if (archive = find_matching_archive(version)).nil?
111
- raise ConfigError.new("could not find version of ruby matching #{version.inspect}")
112
- end
113
- end
114
- archive
115
- end
116
- end
117
- extend ClassMethods
118
- end
119
- end