epitools 0.2.1 → 0.3.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/Rakefile CHANGED
@@ -1,38 +1,48 @@
1
- #!/usr/bin/ruby
2
1
  require 'rubygems'
2
+
3
+ #require 'bundler'
4
+ #begin
5
+ # Bundler.setup(:default, :development)
6
+ #rescue Bundler::BundlerError => e
7
+ # $stderr.puts e.message
8
+ # $stderr.puts "Run `bundle install` to install missing gems"
9
+ # exit e.status_code
10
+ #end
11
+
3
12
  require 'rake'
4
13
 
5
- begin
6
- require 'jeweler'
7
- Jeweler::Tasks.new do |gem|
8
- gem.name = "epitools"
9
- gem.summary = %Q{NOT UTILS... METILS!}
10
- gem.description = %Q{Miscellaneous utility libraries to make my life easier.}
11
- gem.email = "chris@ill-logic.com"
12
- gem.homepage = "http://github.com/epitron/epitools"
13
- gem.authors = ["epitron"]
14
- gem.add_development_dependency "rspec", ">= 1.2.9"
15
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
- end
17
- Jeweler::GemcutterTasks.new
18
- rescue LoadError
19
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "epitools"
18
+ gem.summary = %Q{NOT UTILS... METILS!}
19
+ gem.description = %Q{Miscellaneous utility libraries to make my life easier.}
20
+ gem.email = "chris@ill-logic.com"
21
+ gem.homepage = "http://github.com/epitron/epitools"
22
+ gem.authors = ["epitron"]
23
+ gem.license = "WTFPL"
24
+
25
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
26
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
27
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
28
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
29
+ gem.add_development_dependency "rspec", "~> 2.2.0"
30
+ gem.add_development_dependency "mechanize", "~> 1.0.0"
31
+ gem.add_development_dependency "sqlite3-ruby"
20
32
  end
33
+ Jeweler::RubygemsDotOrgTasks.new
21
34
 
22
- require 'spec/rake/spectask'
23
- Spec::Rake::SpecTask.new(:spec) do |spec|
24
- spec.libs << 'lib' << 'spec'
25
- spec.spec_files = FileList['spec/**/*_spec.rb']
35
+ require 'rspec/core'
36
+ require 'rspec/core/rake_task'
37
+ RSpec::Core::RakeTask.new(:spec) do |spec|
38
+ spec.pattern = FileList['spec/**/*_spec.rb']
26
39
  end
27
40
 
28
- Spec::Rake::SpecTask.new(:rcov) do |spec|
29
- spec.libs << 'lib' << 'spec'
41
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
30
42
  spec.pattern = 'spec/**/*_spec.rb'
31
43
  spec.rcov = true
32
44
  end
33
45
 
34
- task :spec => :check_dependencies
35
-
36
46
  task :default => :spec
37
47
 
38
48
  require 'rake/rdoctask'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -1,76 +1,78 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{epitools}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["epitron"]
12
- s.date = %q{2010-10-19}
12
+ s.date = %q{2010-12-02}
13
13
  s.description = %q{Miscellaneous utility libraries to make my life easier.}
14
14
  s.email = %q{chris@ill-logic.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "epitools.gemspec",
27
- "lib/epitools.rb",
28
- "lib/epitools/basetypes.rb",
29
- "lib/epitools/browser.rb",
30
- "lib/epitools/browser/browser_cache.rb",
31
- "lib/epitools/browser/mechanize_progressbar.rb",
32
- "lib/epitools/hexdump.rb",
33
- "lib/epitools/http.rb",
34
- "lib/epitools/lcs.rb",
35
- "lib/epitools/metaclass.rb",
36
- "lib/epitools/niceprint.rb",
37
- "lib/epitools/permutations.rb",
38
- "lib/epitools/pretty_backtrace.rb",
39
- "lib/epitools/progressbar.rb",
40
- "lib/epitools/rails.rb",
41
- "lib/epitools/rash.rb",
42
- "lib/epitools/ratio.rb",
43
- "lib/epitools/string_to_proc.rb",
44
- "lib/epitools/sys.rb",
45
- "lib/epitools/zopen.rb",
46
- "spec/basetypes_spec.rb",
47
- "spec/browser_spec.rb",
48
- "spec/lcs_spec.rb",
49
- "spec/metaclass_spec.rb",
50
- "spec/permutations_spec.rb",
51
- "spec/rash_spec.rb",
52
- "spec/ratio_spec.rb",
53
- "spec/spec.opts",
54
- "spec/spec_helper.rb",
55
- "spec/sys_spec.rb",
56
- "spec/zopen_spec.rb"
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "epitools.gemspec",
26
+ "lib/epitools.rb",
27
+ "lib/epitools/basetypes.rb",
28
+ "lib/epitools/browser.rb",
29
+ "lib/epitools/browser/browser_cache.rb",
30
+ "lib/epitools/browser/mechanize_progressbar.rb",
31
+ "lib/epitools/hexdump.rb",
32
+ "lib/epitools/highlight.rb",
33
+ "lib/epitools/http.rb",
34
+ "lib/epitools/lcs.rb",
35
+ "lib/epitools/metaclass.rb",
36
+ "lib/epitools/niceprint.rb",
37
+ "lib/epitools/permutations.rb",
38
+ "lib/epitools/pretty_backtrace.rb",
39
+ "lib/epitools/progressbar.rb",
40
+ "lib/epitools/rails.rb",
41
+ "lib/epitools/rash.rb",
42
+ "lib/epitools/ratio.rb",
43
+ "lib/epitools/string_to_proc.rb",
44
+ "lib/epitools/sys.rb",
45
+ "lib/epitools/zopen.rb",
46
+ "spec/basetypes_spec.rb",
47
+ "spec/browser_spec.rb",
48
+ "spec/highlight_spec.rb",
49
+ "spec/lcs_spec.rb",
50
+ "spec/metaclass_spec.rb",
51
+ "spec/permutations_spec.rb",
52
+ "spec/rash_spec.rb",
53
+ "spec/ratio_spec.rb",
54
+ "spec/spec.opts",
55
+ "spec/spec_helper.rb",
56
+ "spec/sys_spec.rb",
57
+ "spec/zopen_spec.rb"
57
58
  ]
58
59
  s.homepage = %q{http://github.com/epitron/epitools}
59
- s.rdoc_options = ["--charset=UTF-8"]
60
+ s.licenses = ["WTFPL"]
60
61
  s.require_paths = ["lib"]
61
62
  s.rubygems_version = %q{1.3.7}
62
63
  s.summary = %q{NOT UTILS... METILS!}
63
64
  s.test_files = [
64
65
  "spec/basetypes_spec.rb",
65
- "spec/browser_spec.rb",
66
- "spec/lcs_spec.rb",
67
- "spec/metaclass_spec.rb",
68
- "spec/permutations_spec.rb",
69
- "spec/rash_spec.rb",
70
- "spec/ratio_spec.rb",
71
- "spec/spec_helper.rb",
72
- "spec/sys_spec.rb",
73
- "spec/zopen_spec.rb"
66
+ "spec/browser_spec.rb",
67
+ "spec/highlight_spec.rb",
68
+ "spec/lcs_spec.rb",
69
+ "spec/metaclass_spec.rb",
70
+ "spec/permutations_spec.rb",
71
+ "spec/rash_spec.rb",
72
+ "spec/ratio_spec.rb",
73
+ "spec/spec_helper.rb",
74
+ "spec/sys_spec.rb",
75
+ "spec/zopen_spec.rb"
74
76
  ]
75
77
 
76
78
  if s.respond_to? :specification_version then
@@ -78,12 +80,18 @@ Gem::Specification.new do |s|
78
80
  s.specification_version = 3
79
81
 
80
82
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
81
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
83
+ s.add_development_dependency(%q<rspec>, ["~> 2.2.0"])
84
+ s.add_development_dependency(%q<mechanize>, ["~> 1.0.0"])
85
+ s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
82
86
  else
83
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
87
+ s.add_dependency(%q<rspec>, ["~> 2.2.0"])
88
+ s.add_dependency(%q<mechanize>, ["~> 1.0.0"])
89
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
84
90
  end
85
91
  else
86
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
92
+ s.add_dependency(%q<rspec>, ["~> 2.2.0"])
93
+ s.add_dependency(%q<mechanize>, ["~> 1.0.0"])
94
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
87
95
  end
88
96
  end
89
97
 
@@ -1,6 +1,15 @@
1
1
  __DIR__ = File.dirname(__FILE__)
2
2
 
3
+ require_wrapper = proc do |mod|
4
+ begin
5
+ require File.join(__DIR__, "epitools", mod)
6
+ rescue LoadError => e
7
+ puts "* Error loading epitools/#{mod}: #{e}"
8
+ end
9
+ end
10
+
3
11
  %w[
12
+
4
13
  basetypes
5
14
  metaclass
6
15
  niceprint
@@ -8,6 +17,9 @@ __DIR__ = File.dirname(__FILE__)
8
17
  permutations
9
18
  ratio
10
19
  zopen
20
+ colored
21
+ highlight
22
+
11
23
  ].each do |mod|
12
- require File.join(__DIR__, "epitools", mod)
24
+ require_wrapper.call mod
13
25
  end
@@ -442,6 +442,13 @@ class Hash
442
442
  end
443
443
 
444
444
 
445
+ if defined?(BasicObject)
446
+ BlankSlate = BasicObject
447
+ else
448
+ class BlankSlate
449
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
450
+ end
451
+ end
445
452
 
446
453
  module Kernel
447
454
 
@@ -460,16 +467,17 @@ protected
460
467
  # Magic "its" way:
461
468
  # User.find(:all).map &its.contacts.map(&its.last_name.capitalize)
462
469
  #
463
- def it()
464
- It.new
470
+ def it()
471
+ It.new
465
472
  end
466
-
473
+
467
474
  alias its it
468
-
475
+
469
476
  end
470
477
 
471
- class It
472
- undef_method( *(instance_methods - ["__id__", "__send__"]) )
478
+
479
+ class It < BlankSlate
480
+ #undef_method( *(instance_methods - ["__id__", "__send__"]) )
473
481
 
474
482
  def initialize
475
483
  @methods = []
@@ -489,11 +497,6 @@ class It
489
497
  end
490
498
  end
491
499
 
492
-
493
- class BlankSlate
494
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
495
- end
496
-
497
500
  class NotWrapper < BlankSlate
498
501
  def initialize(orig)
499
502
  @orig = orig
@@ -505,7 +508,7 @@ class NotWrapper < BlankSlate
505
508
 
506
509
  def method_missing(meth, *args, &block)
507
510
  result = @orig.send(meth, *args, &block)
508
- if result.is_a? TrueClass or result.is_a? FalseClass
511
+ if result.is_a? ::TrueClass or result.is_a? ::FalseClass
509
512
  !result
510
513
  else
511
514
  raise "Sorry, I don't know how to invert #{result.inspect}"
@@ -0,0 +1,17 @@
1
+ require 'epitools/colored'
2
+
3
+ class String
4
+
5
+ #
6
+ # Find all occurrences of "pattern" in the string and highlight them
7
+ # with the specified color. (defaults to light_yellow)
8
+ #
9
+ # The pattern can be a string or a regular expression.
10
+ #
11
+ def highlight(pattern, color=:light_yellow)
12
+ pattern = Regexp.new(Regexp.escape(pattern)) if pattern.is_a? String
13
+ gsub(pattern) { |match| match.send(color) }
14
+ end
15
+
16
+ end
17
+
@@ -3,10 +3,17 @@ require 'epitools/basetypes'
3
3
  class Array
4
4
 
5
5
  alias_method :"original_*_for_cartesian_*", :*
6
+
7
+ #
8
+ # Overloaded * operator.
9
+ #
10
+ # Original behaviour:
11
+ # array * number == <number> copies of array
12
+ # Extra behaviour:
13
+ # array * array = Cartesian product of the two arrays
14
+ #
6
15
  def *(other)
7
16
  case other
8
- when Integer
9
- send(:"original_*_for_cartesian_*", other)
10
17
  when Array
11
18
  # cross-product
12
19
  result = []
@@ -15,24 +22,45 @@ class Array
15
22
  result << [self[a], other[b]]
16
23
  end
17
24
  end
18
- result
25
+ result
26
+ else
27
+ send(:"original_*_for_cartesian_*", other)
19
28
  end
20
29
  end
21
30
 
31
+ #
32
+ # Multiply the array by itself 'exponent'-times.
33
+ #
22
34
  def **(exponent)
23
35
  ([self] * exponent).foldl(:*)
24
36
  end
25
37
 
26
38
  end
27
39
 
28
- def perms(total, n=0, stack=[], &block)
40
+
41
+ #
42
+ # Returns all the `size`-sized selections of the elements from an array.
43
+ #
44
+ # I can't remember why I wrote it like this, but the array you want to
45
+ # permute is passed in as a block. For example:
46
+ #
47
+ # >> perms(1) { [1,2,3,4] }
48
+ # => [[1], [2], [3], [4]]
49
+ # >> perms(2) { [1,2,3,4] }
50
+ # => [[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4],
51
+ # [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]]
52
+ #
53
+ # The block also gets passed a parameter: the depth of the recursion.
54
+ # I can't remember why I did that either! :D
55
+ #
56
+ def perms(size, n=0, stack=[], &block)
29
57
  ps = yield(n)
30
58
  results = []
31
- if n >= total
59
+ if n >= size
32
60
  results << stack
33
61
  else
34
62
  ps.each do |p|
35
- results += perms(total, n+1, stack + [p], &block)
63
+ results += perms(size, n+1, stack + [p], &block)
36
64
  end
37
65
  end
38
66
  results
File without changes
@@ -2,14 +2,17 @@ require 'zlib'
2
2
 
3
3
  #
4
4
  # A mutation of "open" that lets you read/write gzip files, as well as
5
- # regular files. (NOTE: gzip detection is purely based on filename.)
5
+ # regular files.
6
6
  #
7
- # It accepts a block just like open().
7
+ # (NOTE: gzip detection is purely based on the filename.)
8
+ #
9
+ # It accepts a block just like open()!
8
10
  #
9
11
  # Example:
10
- # zopen("test.txt") #=> #<File:test.txt>
11
- # zopen("test.txt.gz") #=> #<Zlib::GzipReader:0xb6c79424>
12
- # zopen("otherfile.gz", "w") #=> #<Zlib::GzipReader:0xb6c79424>
12
+ # zopen("test.txt") #=> #<File:test.txt>
13
+ # zopen("test.txt.gz") #=> #<Zlib::GzipReader:0xb6c79424>
14
+ # zopen("otherfile.gz", "w") #=> #<Zlib::GzipWriter:0x7fe30448>>
15
+ # zopen("test.txt.gz") { |f| f.read } # reads the contents of the .gz file, then closes the file automatically.
13
16
  #
14
17
  def zopen(filename, mode="r")
15
18
 
@@ -112,7 +112,7 @@ describe Enumerable do
112
112
  [1,2,3,4,5].split_after {|e| e == 3}.should == [ [1,2,3], [4,5] ]
113
113
  [1,2,3,4,5].split_before {|e| e == 3}.should == [ [1,2], [3,4,5] ]
114
114
 
115
- "a\nb\n---\nc\nd\n".split_at(/---/).map_recursively(&:strip).should == [ %w[a b], %w[c d] ]
115
+ "a\nb\n---\nc\nd\n".lines.split_at(/---/).map_recursively(&:strip).should == [ %w[a b], %w[c d] ]
116
116
  end
117
117
 
118
118
  it "handles nested things" do
@@ -0,0 +1,15 @@
1
+ require 'epitools/highlight'
2
+
3
+ describe String do
4
+
5
+ it "highlights" do
6
+ color = :light_yellow
7
+ highlighted = "xxx#{"match".send(color)}zzz"
8
+
9
+ "xxxmatchzzz".highlight(/match/, color).should == highlighted
10
+ "xxxmatchzzz".highlight("match", color).should == highlighted
11
+ "xxxmatchzzz".highlight(/m.+h/, color).should == highlighted
12
+ "xxxmatchzzz".highlight(/MATCH/i, color).should == highlighted
13
+ end
14
+
15
+ end
@@ -1,9 +1,11 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
 
4
- #require 'epitools'
5
- require 'spec'
6
- require 'spec/autorun'
4
+ p $:
7
5
 
8
- Spec::Runner.configure do |config|
6
+ require 'rspec'
7
+ require 'epitools'
8
+
9
+ Rspec.configure do |c|
10
+ c.mock_with :rspec
9
11
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epitools
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - epitron
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-19 00:00:00 -04:00
17
+ date: 2010-12-02 00:00:00 -05:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -24,16 +23,43 @@ dependencies:
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
- - - ">="
26
+ - - ~>
28
27
  - !ruby/object:Gem::Version
29
- hash: 13
30
28
  segments:
31
- - 1
32
29
  - 2
33
- - 9
34
- version: 1.2.9
30
+ - 2
31
+ - 0
32
+ version: 2.2.0
35
33
  type: :development
36
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mechanize
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 0
46
+ - 0
47
+ version: 1.0.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: sqlite3-ruby
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
37
63
  description: Miscellaneous utility libraries to make my life easier.
38
64
  email: chris@ill-logic.com
39
65
  executables: []
@@ -45,7 +71,6 @@ extra_rdoc_files:
45
71
  - README.rdoc
46
72
  files:
47
73
  - .document
48
- - .gitignore
49
74
  - LICENSE
50
75
  - README.rdoc
51
76
  - Rakefile
@@ -57,6 +82,7 @@ files:
57
82
  - lib/epitools/browser/browser_cache.rb
58
83
  - lib/epitools/browser/mechanize_progressbar.rb
59
84
  - lib/epitools/hexdump.rb
85
+ - lib/epitools/highlight.rb
60
86
  - lib/epitools/http.rb
61
87
  - lib/epitools/lcs.rb
62
88
  - lib/epitools/metaclass.rb
@@ -72,6 +98,7 @@ files:
72
98
  - lib/epitools/zopen.rb
73
99
  - spec/basetypes_spec.rb
74
100
  - spec/browser_spec.rb
101
+ - spec/highlight_spec.rb
75
102
  - spec/lcs_spec.rb
76
103
  - spec/metaclass_spec.rb
77
104
  - spec/permutations_spec.rb
@@ -83,11 +110,11 @@ files:
83
110
  - spec/zopen_spec.rb
84
111
  has_rdoc: true
85
112
  homepage: http://github.com/epitron/epitools
86
- licenses: []
87
-
113
+ licenses:
114
+ - WTFPL
88
115
  post_install_message:
89
- rdoc_options:
90
- - --charset=UTF-8
116
+ rdoc_options: []
117
+
91
118
  require_paths:
92
119
  - lib
93
120
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -95,7 +122,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
122
  requirements:
96
123
  - - ">="
97
124
  - !ruby/object:Gem::Version
98
- hash: 3
99
125
  segments:
100
126
  - 0
101
127
  version: "0"
@@ -104,7 +130,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
130
  requirements:
105
131
  - - ">="
106
132
  - !ruby/object:Gem::Version
107
- hash: 3
108
133
  segments:
109
134
  - 0
110
135
  version: "0"
@@ -118,6 +143,7 @@ summary: NOT UTILS... METILS!
118
143
  test_files:
119
144
  - spec/basetypes_spec.rb
120
145
  - spec/browser_spec.rb
146
+ - spec/highlight_spec.rb
121
147
  - spec/lcs_spec.rb
122
148
  - spec/metaclass_spec.rb
123
149
  - spec/permutations_spec.rb
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC