net-ftp-list 3.2.11 → 3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ac7690dd10010600fa4b5d91dbd083f549361bd279381ee44194948d0d10cc2
4
- data.tar.gz: 6effa8abfb935b263038ebcf7a993bd77334f7d57c0631065b04781563a7e632
3
+ metadata.gz: 3664e5c75774117ae0ec40734948526a60d5f8b55a38629a9abe56e0d2599813
4
+ data.tar.gz: 26ebefa96b9b63150c4c63af7c7912c8346f9ae080066eac3d37a198264645a7
5
5
  SHA512:
6
- metadata.gz: 152ab46668a0b77b896d444d1ef2d4ef1c32c9d9106f5d6e203c2864757e2e045c1663c906b35eaa599361fccda8a5c726975f1c229ed4ae479510d4825b055a
7
- data.tar.gz: e0e1b61861bd271da806f44503595b14fc4580b2166981f701446957d34af225de1da90bfa1da7fa075854055234a69bf9df80b42d8728f040537cfac4978221
6
+ metadata.gz: cff6489e1af74de5c0c25b5b5461b2be0ce57f4cb52086d36f7876836db07cacd120e3e34143c63d0ea06ad7504092ff1702ff7c87513368468aee72ef2486ad
7
+ data.tar.gz: 655bee68bff7169c0ab47f6e9124c129e6339b953e635165cb7feebd82fa44a85b921d688b63b432ad0eab8c7c8a189107ab538f5ec4bfdca8df0ec22f1f3ff7
@@ -0,0 +1,21 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ ruby:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ["2.5", "2.6", "2.7", "3.0"]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby-version }}
20
+ bundler-cache: true
21
+ - run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ .idea/*
7
+ .idea/**/*
8
+ *.gem
9
+ .ruby-version
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ inherit_gem:
2
+ rubocop-bsm:
3
+ - default.yml
4
+ inherit_mode:
5
+ merge:
6
+ - Exclude
7
+
8
+ AllCops:
9
+ TargetRubyVersion: "2.5"
10
+
11
+ Metrics/ParameterLists:
12
+ Exclude:
13
+ - lib/net/ftp/list/entry.rb
14
+ Metrics/MethodLength:
15
+ Exclude:
16
+ - lib/net/ftp/list/unix.rb
17
+ - test/**/*.rb
data/Gemfile CHANGED
@@ -1,6 +1,2 @@
1
1
  source 'https://rubygems.org'
2
-
3
- group :development do
4
- gem 'jeweler'
5
- gem 'test-unit'
6
- end
2
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,63 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ net-ftp-list (3.3.0)
5
+
1
6
  GEM
2
7
  remote: https://rubygems.org/
3
8
  specs:
4
- addressable (2.4.0)
5
- builder (3.2.3)
6
- descendants_tracker (0.0.4)
7
- thread_safe (~> 0.3, >= 0.3.1)
8
- faraday (0.9.2)
9
- multipart-post (>= 1.2, < 3)
10
- git (1.3.0)
11
- github_api (0.16.0)
12
- addressable (~> 2.4.0)
13
- descendants_tracker (~> 0.0.4)
14
- faraday (~> 0.8, < 0.10)
15
- hashie (>= 3.4)
16
- mime-types (>= 1.16, < 3.0)
17
- oauth2 (~> 1.0)
18
- hashie (3.5.7)
19
- highline (1.7.10)
20
- jeweler (2.3.9)
21
- builder
22
- bundler
23
- git (>= 1.2.5)
24
- github_api (~> 0.16.0)
25
- highline (>= 1.6.15)
26
- nokogiri (>= 1.5.10)
27
- psych
28
- rake
29
- rdoc
30
- semver2
31
- jwt (1.5.6)
32
- mime-types (2.99.3)
33
- mini_portile2 (2.3.0)
34
- multi_json (1.13.1)
35
- multi_xml (0.6.0)
36
- multipart-post (2.0.0)
37
- nokogiri (1.8.2)
38
- mini_portile2 (~> 2.3.0)
39
- oauth2 (1.4.0)
40
- faraday (>= 0.8, < 0.13)
41
- jwt (~> 1.0)
42
- multi_json (~> 1.3)
43
- multi_xml (~> 0.5)
44
- rack (>= 1.2, < 3)
45
- power_assert (1.1.1)
46
- psych (3.0.2)
47
- rack (2.0.4)
48
- rake (12.3.1)
49
- rdoc (6.0.3)
50
- semver2 (3.4.2)
51
- test-unit (3.2.7)
9
+ ast (2.4.2)
10
+ parallel (1.20.1)
11
+ parser (3.0.1.1)
12
+ ast (~> 2.4.1)
13
+ power_assert (2.0.0)
14
+ rainbow (3.0.0)
15
+ rake (13.0.3)
16
+ regexp_parser (2.1.1)
17
+ rexml (3.2.5)
18
+ rubocop (1.15.0)
19
+ parallel (~> 1.10)
20
+ parser (>= 3.0.0.0)
21
+ rainbow (>= 2.2.2, < 4.0)
22
+ regexp_parser (>= 1.8, < 3.0)
23
+ rexml
24
+ rubocop-ast (>= 1.5.0, < 2.0)
25
+ ruby-progressbar (~> 1.7)
26
+ unicode-display_width (>= 1.4.0, < 3.0)
27
+ rubocop-ast (1.6.0)
28
+ parser (>= 3.0.1.1)
29
+ rubocop-bsm (0.6.0)
30
+ rubocop (~> 1.0)
31
+ rubocop-performance
32
+ rubocop-rake
33
+ rubocop-rspec
34
+ rubocop-performance (1.11.3)
35
+ rubocop (>= 1.7.0, < 2.0)
36
+ rubocop-ast (>= 0.4.0)
37
+ rubocop-rake (0.5.1)
38
+ rubocop
39
+ rubocop-rspec (2.3.0)
40
+ rubocop (~> 1.0)
41
+ rubocop-ast (>= 1.1.0)
42
+ ruby-progressbar (1.11.0)
43
+ test-unit (3.4.1)
52
44
  power_assert
53
- thread_safe (0.3.6)
45
+ timecop (0.9.4)
46
+ unicode-display_width (2.0.0)
54
47
 
55
48
  PLATFORMS
56
49
  ruby
57
50
 
58
51
  DEPENDENCIES
59
- jeweler
52
+ net-ftp-list!
53
+ rake
54
+ rubocop-bsm
60
55
  test-unit
56
+ timecop
61
57
 
62
58
  BUNDLED WITH
63
- 1.16.1
59
+ 2.2.14
data/Rakefile CHANGED
@@ -1,54 +1,22 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'yaml'
4
-
5
- begin
6
- require 'jeweler'
7
- Jeweler::Tasks.new do |gem|
8
- gem.name = "net-ftp-list"
9
- gem.summary = %Q{Parse FTP LIST command output.}
10
- gem.email = "enquiries@statelesssystems.com"
11
- gem.homepage = "http://github.com/stateless-systems/net-ftp-list"
12
- gem.authors = ["Stateless Systems"]
13
- end
14
- Jeweler::RubygemsDotOrgTasks.new
15
- rescue LoadError
16
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
- end
18
-
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
19
3
  require 'rake/testtask'
4
+ require 'rdoc/task'
5
+ require 'rubocop/rake_task'
6
+
20
7
  Rake::TestTask.new(:test) do |test|
21
8
  test.libs << 'lib' << 'test'
22
9
  test.pattern = 'test/**/test_*.rb'
23
10
  test.verbose = true
24
11
  end
25
12
 
26
- begin
27
- require 'rcov/rcovtask'
28
- Rcov::RcovTask.new do |test|
29
- test.libs << 'test'
30
- test.pattern = 'test/**/test_*.rb'
31
- test.verbose = true
32
- end
33
- rescue LoadError
34
- task :rcov do
35
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
- end
37
- end
38
-
39
- task :default => :test
40
-
41
- require 'rdoc/task'
42
13
  Rake::RDocTask.new do |rdoc|
43
- if File.exist?('VERSION.yml')
44
- config = YAML.load(File.read('VERSION.yml'))
45
- version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
46
- else
47
- version = ""
48
- end
49
-
50
14
  rdoc.rdoc_dir = 'rdoc'
51
- rdoc.title = "net-ftp-list #{version}"
15
+ rdoc.title = 'net-ftp-list'
52
16
  rdoc.rdoc_files.include('README*')
53
17
  rdoc.rdoc_files.include('lib/**/*.rb')
54
18
  end
19
+
20
+ RuboCop::RakeTask.new(:rubocop)
21
+
22
+ task default: %i[rubocop test]
data/lib/net/ftp/list.rb CHANGED
@@ -21,9 +21,9 @@ module Net::FTP::List
21
21
  end
22
22
 
23
23
  # Parse a line from FTP LIST responsesa and return a Net::FTP::List::Entry
24
- def self.parse(*args)
25
- Parser.with_each_parser do | p |
26
- entry = p.parse(*args)
24
+ def self.parse(*args, **opts)
25
+ Parser.parsers.each do |parser|
26
+ entry = parser.parse(*args, **opts)
27
27
  return entry if entry
28
28
  end
29
29
  end
@@ -32,4 +32,3 @@ module Net::FTP::List
32
32
  class ParseError < RuntimeError
33
33
  end
34
34
  end
35
-
@@ -2,17 +2,28 @@
2
2
  class Net::FTP::List::Entry
3
3
  include Comparable
4
4
 
5
- ALLOWED_ATTRIBUTES = [:raw, :basename, :dir, :file, :symlink, :mtime, :filesize, :device, :server_type, :symlink_destination] #:nodoc:
5
+ attr_reader :raw, :basename, :type, :filesize, :mtime, :server_type, :symlink_destination
6
+ alias to_s raw
7
+ alias name basename
8
+ alias size filesize
6
9
 
7
10
  # Create a new entry object. The additional argument is the list of metadata keys
8
11
  # that can be used on the object. By default just takes and set the raw list entry.
9
12
  # Net::FTP::List.parse(raw_list_string) # => Net::FTP::List::Parser instance.
10
- def initialize(raw_ls_line, optional_attributes = {}) #:nodoc:
13
+ def initialize(raw_ls_line,
14
+ basename: nil,
15
+ type: nil,
16
+ mtime: nil,
17
+ filesize: nil,
18
+ server_type: nil,
19
+ symlink_destination: nil) #:nodoc:
11
20
  @raw = raw_ls_line.respond_to?(:force_encoding) ? raw_ls_line.force_encoding('utf-8') : raw_ls_line
12
- optional_attributes.each_pair do |key, value|
13
- raise ArgumentError, "#{key} is not supported" unless ALLOWED_ATTRIBUTES.include?(key)
14
- instance_variable_set("@#{key}", value.respond_to?(:force_encoding) ? value.force_encoding('utf-8') : value)
15
- end
21
+ @basename = basename || ''
22
+ @type = type
23
+ @mtime = mtime || Time.now
24
+ @filesize = filesize || 0
25
+ @server_type = server_type || 'Unknown'
26
+ @symlink_destination = symlink_destination
16
27
  end
17
28
 
18
29
  # Tests for objects equality (value and type).
@@ -22,83 +33,52 @@ class Net::FTP::List::Entry
22
33
  # @return [true, false] true if the objects are equal and have the same type; false otherwise.
23
34
  #
24
35
  def eql?(other)
25
- return false if !other.instance_of? self.class
26
- return true if self.object_id == other.object_id
36
+ return false unless other.is_a?(::Net::FTP::List::Entry)
37
+ return true if equal?(other)
27
38
 
28
- self.raw == other.raw # if it's exactly the same line then the objects are the same
39
+ raw == other.raw # if it's exactly the same line then the objects are the same
29
40
  end
30
41
 
31
-
32
42
  # Compares the receiver against another object.
33
43
  #
34
44
  # @param (see #eql?)
35
45
  #
36
- # @return [Fixnum] -1, 0, or +1 depending on whether the receiver is less than, equal to, or greater than the other object.
46
+ # @return [Integer] -1, 0, or +1 depending on whether the receiver is less than, equal to, or greater than the other object.
37
47
  #
38
48
  def <=>(other)
39
- if other.instance_of? self.class
40
- return self.filesize <=> other.filesize
41
- elsif other.instance_of? Fixnum or other.instance_of? Integer or other.instance_of? Float
42
- return self.filesize <=> other
49
+ case other
50
+ when ::Net::FTP::List::Entry
51
+ return filesize <=> other.filesize
52
+ when Numeric
53
+ return filesize <=> other
43
54
  end
44
- raise ArgumentError.new('comparison of %s with %s failed!' % [self.class, other.class])
45
- end
46
55
 
47
- # The raw list entry string.
48
- def raw
49
- @raw ||= ''
50
- end
51
- alias_method :to_s, :raw
52
-
53
- # The items basename (filename).
54
- def basename
55
- @basename ||= ''
56
- end
57
- alias name basename
58
-
59
- # Symlink destination, the "/etc" in "bar -> /etc". May be nil.
60
- def symlink_destination
61
- @symlink_destination
56
+ raise ArgumentError, format('comparison of %<self>s with %<other>s failed!', self: self.class, other: other.class)
62
57
  end
63
58
 
64
59
  # Looks like a directory, try CWD.
65
60
  def dir?
66
- !!(@dir ||= false)
61
+ type == :dir
67
62
  end
68
63
  alias directory? dir?
69
64
 
70
65
  # Looks like a file, try RETR.
71
66
  def file?
72
- !!(@file ||= false)
67
+ type == :file
73
68
  end
74
69
 
75
70
  # Looks like a symbolic link.
76
71
  def symlink?
77
- !!(@symlink ||= false)
72
+ type == :symlink
78
73
  end
79
74
 
80
75
  # Looks like a device.
81
76
  def device?
82
- !!(@device ||= false)
83
- end
84
-
85
- # Returns the modification time of the file/directory or the current time if unknown
86
- def mtime
87
- @mtime || Time.now
88
- end
89
-
90
- # Returns the filesize of the entry or 0 for directorties
91
- def filesize
92
- @filesize || 0
93
- end
94
- alias size filesize
95
-
96
- # Returns the detected server type if this entry
97
- def server_type
98
- @server_type || "Unknown"
77
+ type == :device
99
78
  end
100
79
 
80
+ # Is the entry type unknown?
101
81
  def unknown?
102
- @dir.nil? && @file.nil? && @symlink.nil? && @device.nil?
82
+ !dir? && !file? && !symlink? && !device?
103
83
  end
104
84
  end
@@ -11,36 +11,34 @@ require 'date'
11
11
  class Net::FTP::List::Microsoft < Net::FTP::List::Parser
12
12
  REGEXP = %r!
13
13
  ^\s*
14
- ([0-9\-:\/]{5,})\s+([0-9\-:]{3,}(?:[aApP][mM])?)\s+
14
+ ([0-9\-:/]{5,})\s+([0-9\-:]{3,}(?:[aApP][mM])?)\s+
15
15
  (?:(<DIR>)|([0-9]+))\s+
16
16
  (\S.*)
17
17
  \s*$
18
- !x
18
+ !x.freeze
19
19
 
20
20
  # Parse a Microsoft(NT) like FTP LIST entries.
21
- def self.parse(raw)
21
+ def self.parse(raw, timezone: :utc)
22
22
  match = REGEXP.match(raw.strip) or return false
23
23
 
24
- date_match = %r!(\d\d).(\d\d).(\d\d(?:\d\d)?)!.match(match[1])
24
+ date_match = /(\d\d).(\d\d).(\d\d(?:\d\d)?)/.match(match[1])
25
25
  date_format = date_match[1].to_i > 12 ? '%d-%m-%y' : '%m-%d-%y'
26
- date_format.sub!(%r{%y}, '%Y') if date_match[3].length > 2
26
+ date_format.sub!(/%y/, '%Y') if date_match[3].length > 2
27
27
 
28
- if match[1] !~ /\-/
29
- date_format.gsub!(/\-/, '/') if match[1] =~ %r{/}
30
- date_format.gsub!(/\-/, ':') if match[1] =~ %r{:}
28
+ unless /-/.match?(match[1])
29
+ date_format.tr!('-', '/') if %r{/}.match?(match[1])
30
+ date_format.tr!('-', ':') if /:/.match?(match[1])
31
31
  end
32
32
 
33
- mtime = DateTime.strptime("#{match[1]} #{match[2]}", "#{date_format} %H:%M%p")
34
- is_dir = match[3] == '<DIR>'
35
- filesize = is_dir ? 0 : match[4].to_i
33
+ mtime = parse_time("#{match[1]} #{match[2]}", format: "#{date_format} %H:%M%p", timezone: timezone)
34
+ type = match[3] == '<DIR>' ? :dir : :file
36
35
 
37
36
  emit_entry(
38
37
  raw,
39
- :dir => is_dir,
40
- :file => !is_dir,
41
- :filesize => filesize,
42
- :basename => match[5],
43
- :mtime => mtime
38
+ type: type,
39
+ filesize: match[4].to_i,
40
+ basename: match[5],
41
+ mtime: mtime,
44
42
  )
45
43
  end
46
44
  end