net-ftp-list 3.2.11 → 3.3.0

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