cvelist 0.1.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.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +10 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +82 -0
- data/Rakefile +13 -0
- data/benchmark.rb +38 -0
- data/cvelist.gemspec +61 -0
- data/gemspec.yml +21 -0
- data/lib/cvelist.rb +2 -0
- data/lib/cvelist/cve.rb +83 -0
- data/lib/cvelist/directory.rb +80 -0
- data/lib/cvelist/exceptions.rb +31 -0
- data/lib/cvelist/malformed_cve.rb +42 -0
- data/lib/cvelist/range_dir.rb +121 -0
- data/lib/cvelist/repository.rb +240 -0
- data/lib/cvelist/version.rb +4 -0
- data/lib/cvelist/year_dir.rb +178 -0
- data/spec/cve_methods_examples.rb +130 -0
- data/spec/cve_spec.rb +51 -0
- data/spec/cvelist_spec.rb +8 -0
- data/spec/directory_spec.rb +83 -0
- data/spec/fixtures/CVE-2020-1994.json +140 -0
- data/spec/fixtures/cvelist/.gitkeep +0 -0
- data/spec/fixtures/cvelist/1999/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2000/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2001/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2002/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2003/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2004/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2005/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2006/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2007/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2008/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2009/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2010/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2011/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2012/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2013/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2014/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2015/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2016/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2017/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2018/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2019/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2020/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/0xxx/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/1xxx/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/20xxx/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/21xxx/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/2xxx/.gitkeep +0 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2000.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2001.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2002.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2003.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2004.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2005.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2006.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2007.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2008.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2009.json +18 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2998.json +3 -0
- data/spec/fixtures/cvelist/2021/2xxx/CVE-2021-2999.json +2 -0
- data/spec/range_dir_spec.rb +55 -0
- data/spec/repository_spec.rb +248 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/year_dir_spec.rb +96 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d5f0ca46bdd362287b4845fed77c588ef591bb86e11219f3b248b70470d5e1b0
|
4
|
+
data.tar.gz: 1507b6e252a6b4c4f721e842a23ae8d20d65c08b6644a4fce8fe31eb388fa8b4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ccc4c2da9456bc2708bb7f30d59042d4e77d32fc12bc0524e81b23f93dcfd87c4c7bfa315f66a0840fe4c66d761daf780823486ded35fda482968b462804dbf5
|
7
|
+
data.tar.gz: ad330548abb01672b25493a0c0bd84d319b172c175f7cdd7156efed1e150eeb3e4a6bb2556adaf3be9b0c21b402539e0c3476220235ec246d4790b43eddba747
|
data/.document
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [ push, pull_request ]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
tests:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby:
|
12
|
+
# - 2.4
|
13
|
+
# - 2.5
|
14
|
+
# - 2.6
|
15
|
+
- 2.7
|
16
|
+
- 3.0
|
17
|
+
# TODO: uncomment when jruby supports ruby >= 2.7
|
18
|
+
# - jruby
|
19
|
+
name: Ruby ${{ matrix.ruby }}
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v2
|
22
|
+
- name: Set up Ruby
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
- name: Install dependencies
|
27
|
+
run: bundle install --jobs 4 --retry 3
|
28
|
+
- name: Run tests
|
29
|
+
run: bundle exec rake test
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "CVEList Documentation" --protected
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2020-2021 Hal Brodigan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# cvelist.rb
|
2
|
+
|
3
|
+
* [Homepage](https://github.com/postmodern/cvelist.rb#readme)
|
4
|
+
* [Issues](https://github.com/postmodern/cvelist.rb/issues)
|
5
|
+
* [Documentation](http://rubydoc.info/gems/cvelist/frames)
|
6
|
+
* [Email](mailto:postmodern.mod3 at gmail.com)
|
7
|
+
|
8
|
+
## Description
|
9
|
+
|
10
|
+
A Ruby library for parsing the CVE JSON in the [cvelist] git repository.
|
11
|
+
|
12
|
+
## Features
|
13
|
+
|
14
|
+
* Supports downloading/updating [cvelist] Git repository.
|
15
|
+
* Supports [CVE JSON Schema v4.0][1]
|
16
|
+
|
17
|
+
## Examples
|
18
|
+
|
19
|
+
require 'cvelist'
|
20
|
+
|
21
|
+
Cloning the [cvelist] repository:
|
22
|
+
|
23
|
+
repo = CVEList::Repository.clone('path/to/cvelist')
|
24
|
+
|
25
|
+
Using an existing [cvelist] repository:
|
26
|
+
|
27
|
+
repo = CVEList::Repository.new('path/to/cvelist')
|
28
|
+
|
29
|
+
Updating an existing [cvelist] repository:
|
30
|
+
|
31
|
+
repo.pull!
|
32
|
+
|
33
|
+
Get the total number of CVEs in the repository:
|
34
|
+
|
35
|
+
repo.size
|
36
|
+
|
37
|
+
Access an individual [CVE] in the repository:
|
38
|
+
|
39
|
+
repo['CVE-2020-0001']
|
40
|
+
|
41
|
+
Enumerating over every [CVE] in the repository:
|
42
|
+
|
43
|
+
repo.each do |cve|
|
44
|
+
puts cve.id
|
45
|
+
end
|
46
|
+
|
47
|
+
Enumerating over every [CVE] in a certain year:
|
48
|
+
|
49
|
+
repo.year(2020).each do |cve|
|
50
|
+
puts cve.id
|
51
|
+
end
|
52
|
+
|
53
|
+
## Requirements
|
54
|
+
|
55
|
+
* [multi_json] ~> 1.0
|
56
|
+
* [cve_schema] ~> 0.1
|
57
|
+
|
58
|
+
## Install
|
59
|
+
|
60
|
+
$ gem install cvelist
|
61
|
+
|
62
|
+
## Benchmark
|
63
|
+
|
64
|
+
Warming up the disk cache with a first run. This may take a while ...
|
65
|
+
Parsing all 192879 CVE .json files ...
|
66
|
+
|
67
|
+
Total: 18.285097 1.651155 19.936252 ( 20.144566)
|
68
|
+
Avg: 0.000095 0.000009 0.000103 ( 0.000104)
|
69
|
+
|
70
|
+
## Copyright
|
71
|
+
|
72
|
+
Copyright (c) 2020-2021 Hal Brodigan
|
73
|
+
|
74
|
+
See {file:LICENSE.txt} for details.
|
75
|
+
|
76
|
+
[cvelist]: https://github.com/CVEProject/cvelist
|
77
|
+
[1]: https://github.com/CVEProject/cve-schema/blob/master/schema/v4.0/DRAFT-JSON-file-format-v4.md
|
78
|
+
|
79
|
+
[multi_json]: https://github.com/intridea/multi_json#readme
|
80
|
+
[cve_schema]: https://github.com/postmodern/cve_schema.rb#readme
|
81
|
+
|
82
|
+
[CVE]: https://rubydoc.info/gems/cve_schema/CVESchema/CVE/frames
|
data/Rakefile
ADDED
data/benchmark.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'cvelist/repository'
|
5
|
+
require 'json'
|
6
|
+
require 'benchmark'
|
7
|
+
|
8
|
+
CVELIST = ENV.fetch('CVELIST',File.join(Gem.user_home,'src','cvelist'))
|
9
|
+
|
10
|
+
repo = if File.directory?(CVELIST)
|
11
|
+
CVEList::Repository.new(CVELIST)
|
12
|
+
else
|
13
|
+
puts "Cloning #{CVEList::Repository::URL} into #{CVELIST} ..."
|
14
|
+
CVEList::Repository.clone(CVELIST)
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
n = repo.total_cves
|
19
|
+
|
20
|
+
puts "Warming up the disk cache with a first run. This may take a while ..."
|
21
|
+
repo.each do |cve|
|
22
|
+
# no-op
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Parsing all #{n} CVE .json files ..."
|
26
|
+
|
27
|
+
results = Benchmark.measure do
|
28
|
+
repo.each do |cve|
|
29
|
+
# no-op
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
puts
|
34
|
+
puts "Total:\t#{results}"
|
35
|
+
puts "Avg:\t#{results / n}"
|
36
|
+
rescue Interrupt
|
37
|
+
exit 130
|
38
|
+
end
|
data/cvelist.gemspec
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
7
|
+
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
require 'cvelist/version'
|
14
|
+
CVEList::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
24
|
+
|
25
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
26
|
+
|
27
|
+
gem.files = `git ls-files`.split($/)
|
28
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
29
|
+
|
30
|
+
gem.executables = gemspec.fetch('executables') do
|
31
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
32
|
+
end
|
33
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
34
|
+
|
35
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
36
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
37
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
38
|
+
|
39
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
40
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
41
|
+
})
|
42
|
+
|
43
|
+
gem.requirements = Array(gemspec['requirements'])
|
44
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
45
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
46
|
+
gem.post_install_message = gemspec['post_install_message']
|
47
|
+
|
48
|
+
split = lambda { |string| string.split(/,\s*/) }
|
49
|
+
|
50
|
+
if gemspec['dependencies']
|
51
|
+
gemspec['dependencies'].each do |name,versions|
|
52
|
+
gem.add_dependency(name,split[versions])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if gemspec['development_dependencies']
|
57
|
+
gemspec['development_dependencies'].each do |name,versions|
|
58
|
+
gem.add_development_dependency(name,split[versions])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/gemspec.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
name: cvelist
|
2
|
+
summary: Parses cvelist JSON
|
3
|
+
description: |
|
4
|
+
A Ruby library for parsing the CVE JSON in the cvelist git repository.
|
5
|
+
license: MIT
|
6
|
+
authors: Postmodern
|
7
|
+
email: postmodern.mod3@gmail.com
|
8
|
+
homepage: https://github.com/postmodern/cvelist.rb#readme
|
9
|
+
|
10
|
+
metadata:
|
11
|
+
documentation_uri: https://rubydoc.info/gems/cvelist
|
12
|
+
source_code_uri: https://github.com/postmodern/cvelist.rb
|
13
|
+
bug_tracker_uri: https://github.com/postmodern/cvelist.rb/issues
|
14
|
+
changelog_uri: https://github.com/postmodern/cvelist.rb/blob/main/ChangeLog.md
|
15
|
+
|
16
|
+
dependencies:
|
17
|
+
multi_json: ~> 1.0
|
18
|
+
cve_schema: ~> 0.1
|
19
|
+
|
20
|
+
development_dependencies:
|
21
|
+
bundler: ~> 2.0
|
data/lib/cvelist.rb
ADDED
data/lib/cvelist/cve.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'cvelist/exceptions'
|
2
|
+
require 'cve_schema/cve'
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module CVEList
|
6
|
+
#
|
7
|
+
# @see https://rubydoc.info/gems/cve_schema/CVESchema/CVE/frames
|
8
|
+
#
|
9
|
+
class CVE < CVESchema::CVE
|
10
|
+
|
11
|
+
# The path to the CVE JSON.
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
attr_reader :path
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initializes the CVE.
|
18
|
+
#
|
19
|
+
# @param [String] path
|
20
|
+
# The path to the CVE JSON.
|
21
|
+
#
|
22
|
+
def initialize(path, **kwargs)
|
23
|
+
super(**kwargs)
|
24
|
+
|
25
|
+
@path = path
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Parses the given JSON.
|
30
|
+
#
|
31
|
+
# @param [String] json
|
32
|
+
# The raw JSON.
|
33
|
+
#
|
34
|
+
# @return [Hash{String => Object}]
|
35
|
+
# The parsed JSON.
|
36
|
+
#
|
37
|
+
# @raise [InvalidJSON]
|
38
|
+
# Could not parse the JSON in the given file.
|
39
|
+
#
|
40
|
+
# @api semipublic
|
41
|
+
#
|
42
|
+
def self.parse(json)
|
43
|
+
MultiJson.load(json)
|
44
|
+
rescue MultiJson::ParseError => error
|
45
|
+
raise(InvalidJSON,error.message)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Parses the JSON in the given file.
|
50
|
+
#
|
51
|
+
# @param [String] file
|
52
|
+
# The path to the file.
|
53
|
+
#
|
54
|
+
# @return [Hash{String => Object}]
|
55
|
+
# The parsed JSON.
|
56
|
+
#
|
57
|
+
# @raise [InvalidJSON]
|
58
|
+
# Could not parse the JSON in the given file.
|
59
|
+
#
|
60
|
+
# @api semipublic
|
61
|
+
#
|
62
|
+
def self.read(file)
|
63
|
+
parse(File.read(file))
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Loads the CVE JSON from the given file.
|
68
|
+
#
|
69
|
+
# @param [String] file
|
70
|
+
# The path to the file.
|
71
|
+
#
|
72
|
+
# @return [CVE]
|
73
|
+
# The loaded CVE object.
|
74
|
+
#
|
75
|
+
# @raise [InvalidJSON, MissingJSONKey, UnknownJSONValue]
|
76
|
+
# Failed to load the CVE JSON.
|
77
|
+
#
|
78
|
+
def self.load(file)
|
79
|
+
new(file, **from_json(read(file)))
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module CVEList
|
2
|
+
#
|
3
|
+
# Represents a directory within the {Repository}.
|
4
|
+
#
|
5
|
+
class Directory
|
6
|
+
|
7
|
+
# The path to the directory.
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
#
|
13
|
+
# Initializes the directory.
|
14
|
+
#
|
15
|
+
# @param [String] path
|
16
|
+
# The path to the directory.
|
17
|
+
#
|
18
|
+
def initialize(path)
|
19
|
+
@path = File.expand_path(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Joins the file/directory name(s) with the directory path.
|
24
|
+
#
|
25
|
+
# @param [Array<String>] names
|
26
|
+
# The file/directory name(s).
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
def join(*names)
|
31
|
+
File.join(@path,*names)
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Determines whether the directory has the givne file.
|
36
|
+
#
|
37
|
+
# @param [String] name
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
def file?(name)
|
42
|
+
File.file?(join(name))
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Determines whether the directory has the given directory.
|
47
|
+
#
|
48
|
+
# @param [String] name
|
49
|
+
#
|
50
|
+
# @return [Boolean]
|
51
|
+
#
|
52
|
+
def directory?(name)
|
53
|
+
File.directory?(join(name))
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Finds all files and directories matching the pattern.
|
58
|
+
#
|
59
|
+
# @param [String] pattern
|
60
|
+
# The glob pattern.
|
61
|
+
#
|
62
|
+
# @return [Array<String>]
|
63
|
+
# The matching file and directory paths.
|
64
|
+
#
|
65
|
+
def glob(pattern)
|
66
|
+
Dir[join(pattern)]
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Converts the directory to a String.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
# The path to the directory.
|
74
|
+
#
|
75
|
+
def to_s
|
76
|
+
@path
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|