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