sdoc_all 0.2.1.0 → 1.0.0

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