net-ftp-list 3.2.11 → 3.4.1

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: a7055fe548d1984de166f451dfb2aa7240c8606a04c3f06b149a6b3892573027
4
+ data.tar.gz: 67ac2d02694ca97a6ab76da05b0dc75f3b06bbadd11b28c8ca82b4dd0f4053e7
5
5
  SHA512:
6
- metadata.gz: 152ab46668a0b77b896d444d1ef2d4ef1c32c9d9106f5d6e203c2864757e2e045c1663c906b35eaa599361fccda8a5c726975f1c229ed4ae479510d4825b055a
7
- data.tar.gz: e0e1b61861bd271da806f44503595b14fc4580b2166981f701446957d34af225de1da90bfa1da7fa075854055234a69bf9df80b42d8728f040537cfac4978221
6
+ metadata.gz: eda43bbfa999e5d4f1c163f842e1a87cd0fa787fd6c7b241683ad9bacf8e2d71c645a8b20ff63d96714d9edd986cd4a00da8966463646874e2aaeccc6fc2719a
7
+ data.tar.gz: 6f16a6ca4991c274356c6ff4899be14cea0ab7009960f8de6c99f0ea8696c79466bcad1963aa8a6c8c08dd1edc0ce5ce8a6b33edf5c5bbef26cd9d57244a6e49
@@ -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", "3.1", "3.2", "3.3", "3.4", "4.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,11 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ .idea/*
7
+ .idea/**/*
8
+ *.gem
9
+ .ruby-version
10
+ .tool-versions
11
+ /Gemfile.lock
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/Rakefile CHANGED
@@ -1,54 +1,19 @@
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
+
20
6
  Rake::TestTask.new(:test) do |test|
21
7
  test.libs << 'lib' << 'test'
22
8
  test.pattern = 'test/**/test_*.rb'
23
9
  test.verbose = true
24
10
  end
25
11
 
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
12
  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
13
  rdoc.rdoc_dir = 'rdoc'
51
- rdoc.title = "net-ftp-list #{version}"
14
+ rdoc.title = 'net-ftp-list'
52
15
  rdoc.rdoc_files.include('README*')
53
16
  rdoc.rdoc_files.include('lib/**/*.rb')
54
17
  end
18
+
19
+ task default: %i[test]
@@ -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:
11
- @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
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:
20
+ @raw = raw_ls_line.respond_to?(:force_encoding) ? raw_ls_line.dup.force_encoding('utf-8') : raw_ls_line
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
@@ -9,27 +9,25 @@ require 'time'
9
9
  class Net::FTP::List::Netware < Net::FTP::List::Parser
10
10
  # Stolen straight from the ASF's commons Java FTP LIST parser library.
11
11
  # http://svn.apache.org/repos/asf/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/
12
- REGEXP = %r!^
12
+ REGEXP = /^
13
13
  (d|-){1}\s+
14
14
  \[(.*?)\]\s+
15
15
  (\S+)\s+(\d+)\s+
16
16
  (\S+\s+\S+\s+((\d+:\d+)|(\d{4})))
17
17
  \s+(.*)
18
- $!x
18
+ $/x.freeze
19
19
 
20
20
  # Parse a Netware 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
-
24
- is_dir = match[1] == 'd'
23
+ type = match[1] == 'd' ? :dir : :file
25
24
 
26
25
  emit_entry(
27
26
  raw,
28
- :mtime => Time.parse(match[5]),
29
- :filesize => match[4].to_i,
30
- :dir => is_dir,
31
- :file => !is_dir,
32
- :basename => match[9]
27
+ mtime: parse_time(match[5], timezone: timezone),
28
+ filesize: match[4].to_i,
29
+ type: type,
30
+ basename: match[9],
33
31
  )
34
32
  end
35
33
  end
@@ -1,28 +1,45 @@
1
+ require 'date'
2
+
1
3
  # Abstract FTP LIST parser. It really just defines and documents the interface.
2
4
  class Net::FTP::List::Parser
5
+ class << self
6
+ # Returns registered parsers.
7
+ def parsers
8
+ @parsers ||= []
9
+ end
3
10
 
4
- @@parsers = []
11
+ # Manuall register a parser.
12
+ def register(parser)
13
+ parsers.push(parser) unless parsers.include?(parser)
14
+ end
5
15
 
6
- # Run a passed block with each parser in succession, from the most specific to the least
7
- # specific. Will return the result of the block.
8
- def self.with_each_parser(&blk) #:yields: parser
9
- @@parsers.each(&blk)
10
- end
16
+ # Automatically add an inheriting parser to the list of known parsers.
17
+ def inherited(klass)
18
+ super
19
+ register(klass)
20
+ end
11
21
 
12
- # Automatically add an inheriting parser to the list of known parsers.
13
- def self.inherited(klass) #:nodoc:
14
- @@parsers.push(klass)
15
- end
22
+ # The main parse method. Return false from it if parsing fails (this is cheaper than raising an exception)
23
+ def parse(_raw, **)
24
+ false
25
+ end
16
26
 
17
- # The main parse method. Return false from it if parsing fails (this is cheaper than raising an exception)
18
- def self.parse(raw)
19
- return false
20
- end
27
+ private
21
28
 
22
- private
29
+ # Automatically adds the name of the parser class to the server_type field
30
+ def emit_entry(raw, **extra)
31
+ Net::FTP::List::Entry.new raw, **extra, server_type: to_s.split('::').pop
32
+ end
23
33
 
24
- # Automatically adds the name of the parser class to the server_type field
25
- def self.emit_entry(raw, extra_attributes)
26
- Net::FTP::List::Entry.new raw, extra_attributes.merge(:server_type => to_s.split('::').pop)
34
+ def parse_time(str, timezone:, format: nil)
35
+ case timezone
36
+ when :utc
37
+ (format ? DateTime.strptime(str, format) : DateTime.parse(str)).to_time
38
+ when :local
39
+ format ? Time.strptime(str, format) : Time.parse(str)
40
+ else
41
+ raise ArgumentError, "invalid timezone #{timezone}, only :utc and :local are allowed"
42
+ end
43
+ end
27
44
  end
28
45
  end
@@ -6,28 +6,27 @@ require 'net/ftp/list/parser'
6
6
  # drwxr-xr-x folder 0 Nov 30 10:03 houdini
7
7
  # -rw-r--r-- 0 101426 101426 Jun 7 2008 imap with spaces.rb
8
8
  class Net::FTP::List::Rumpus < Net::FTP::List::Parser
9
-
10
- REGEXP = %r!^
11
- ([drwxr-]{10})\s+
9
+ REGEXP = /^
10
+ ([drwx-]{10})\s+
12
11
  (folder|0\s+\d+)\s+
13
12
  (\d+)\s+
14
13
  (\w+)\s+
15
14
  (\d{1,2})\s+
16
15
  (\d{2}:\d{2}|\d{4})\s+
17
16
  (.+)
18
- $!x
17
+ $/x.freeze
19
18
 
20
19
  # Parse a Rumpus FTP LIST entry.
21
- def self.parse(raw)
20
+ def self.parse(raw, timezone: :utc)
22
21
  match = REGEXP.match(raw.strip) or return false
22
+ type = match[2] == 'folder' ? :dir : :file
23
23
 
24
24
  emit_entry(
25
25
  raw,
26
- :basename => match[7],
27
- :mtime => Time.parse([match[4], match[5], match[6]].join(" ")),
28
- :file => !(match[2] == "folder"),
29
- :dir => (match[2] == "folder"),
30
- :filesize => match[3].to_i
26
+ basename: match[7],
27
+ mtime: parse_time(match[4..6].join(' '), timezone: timezone),
28
+ type: type,
29
+ filesize: match[3].to_i,
31
30
  )
32
31
  end
33
32
  end
@@ -8,83 +8,75 @@ require 'net/ftp/list/parser'
8
8
  # drwxr-xr-x 4 steve group 4096 Dec 10 20:23 etc
9
9
  # -rw-r--r-- 1 root other 531 Jan 29 03:26 README.txt
10
10
  class Net::FTP::List::Unix < Net::FTP::List::Parser
11
-
12
11
  # Stolen straight from the ASF's commons Java FTP LIST parser library.
13
12
  # http://svn.apache.org/repos/asf/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/
14
13
  REGEXP = %r{
15
- ([pbcdlfmpSs-])
14
+ ([pbcdlfmSs-])
16
15
  (((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\+?\s+
17
16
  (?:(\d+)\s+)?
18
- (\S+)?\s+
19
- (?:(\S+(?:\s\S+)*)\s+)?
17
+ (\S+)?\s+(\S+)?\s+
20
18
  (?:\d+,\s+)?
21
19
  (\d+)\s+
22
20
  ((?:\d+[-/]\d+[-/]\d+)|(?:\S+\s+\S+))\s+
23
21
  (\d+(?::\d+)?)\s+
24
22
  (\S*)(\s*.*)
25
- }x
23
+ }x.freeze
26
24
 
27
25
  ONE_YEAR = (60 * 60 * 24 * 365)
28
26
 
29
27
  # Parse a Unix like FTP LIST entries.
30
- def self.parse(raw)
28
+ def self.parse(raw, timezone: :utc)
31
29
  match = REGEXP.match(raw.strip) or return false
32
-
33
- dir, symlink, file, device = false, false, false, false
34
- case match[1]
35
- when /d/ then dir = true
36
- when /l/ then symlink = true
37
- when /[f-]/ then file = true
38
- when /[psbc]/ then device = true
39
- end
40
- return false unless dir or symlink or file or device
30
+ type = case match[1]
31
+ when /d/ then :dir
32
+ when /l/ then :symlink
33
+ when /[f-]/ then :file
34
+ when /[psbc]/ then :device
35
+ end
36
+ return false if type.nil?
41
37
 
42
38
  # Don't match on rumpus (which looks very similar to unix)
43
- return false if match[17].nil? and ((match[15].nil? and match[16].to_s == 'folder') or match[15].to_s == '0')
39
+ return false if match[17].nil? && ((match[15].nil? && (match[16].to_s == 'folder')) || (match[15].to_s == '0'))
44
40
 
45
41
  # TODO: Permissions, users, groups, date/time.
46
42
  filesize = match[18].to_i
47
-
48
43
  mtime_month_and_day = match[19]
49
44
  mtime_time_or_year = match[20]
50
45
 
51
46
  # Unix mtimes specify a 4 digit year unless the data is within the past 180
52
- # days or so. Future dates always specify a 4 digit year.
47
+ # days or so. Future dates always specify a 4 digit year.
53
48
  # If the parsed date, with today's year, could be in the future, then
54
49
  # the date must be for the previous year
55
- mtime_string = if mtime_time_or_year.match(/^[0-9]{1,2}:[0-9]{2}$/)
56
- if Time.parse("#{mtime_month_and_day} #{Time.now.year}") > Time.now
57
- "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year - 1}"
58
- else
59
- "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year}"
60
- end
61
- elsif mtime_time_or_year.match(/^[0-9]{4}$/)
62
- "#{mtime_month_and_day} #{mtime_time_or_year}"
63
- end
64
-
65
- mtime = Time.parse(mtime_string)
50
+ mtime_string = case mtime_time_or_year
51
+ when /^[0-9]{1,2}:[0-9]{2}$/
52
+ if parse_time("#{mtime_month_and_day} #{Time.now.year}", timezone: timezone) > Time.now
53
+ "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year - 1}"
54
+ else
55
+ "#{mtime_month_and_day} #{mtime_time_or_year} #{Time.now.year}"
56
+ end
57
+ when /^[0-9]{4}$/
58
+ "#{mtime_month_and_day} #{mtime_time_or_year}"
59
+ end
66
60
 
61
+ mtime = parse_time(mtime_string, timezone: timezone)
67
62
  basename = match[21].strip
68
63
 
69
64
  # filenames with spaces will end up in the last match
70
65
  basename += match[22] unless match[22].nil?
71
66
 
72
67
  # strip the symlink stuff we don't care about
73
- if symlink
74
- basename.sub!(/\s+\->(.+)$/, '')
75
- symlink_destination = $1.strip if $1
68
+ if type == :symlink
69
+ basename.sub!(/\s+->(.+)$/, '')
70
+ symlink_destination = Regexp.last_match(1).strip if Regexp.last_match(1)
76
71
  end
77
72
 
78
73
  emit_entry(
79
74
  raw,
80
- :dir => dir,
81
- :file => file,
82
- :device => device,
83
- :symlink => symlink,
84
- :filesize => filesize,
85
- :basename => basename,
86
- :symlink_destination => symlink_destination,
87
- :mtime => mtime
75
+ type: type,
76
+ filesize: filesize,
77
+ basename: basename,
78
+ symlink_destination: symlink_destination,
79
+ mtime: mtime,
88
80
  )
89
81
  end
90
82
  end
@@ -3,12 +3,9 @@ require 'net/ftp/list/parser'
3
3
  # If all other attempts to parse the entry fail this is the parser that is going to be used.
4
4
  # It might be a good idea to fail loudly.
5
5
  class Net::FTP::List::Unknown < Net::FTP::List::Parser
6
- def self.parse(raw)
7
- if Net::FTP::List.raise_on_failed_server_detection
8
- raise Net::FTP::List::ParseError, "Could not parse #{raw} since none of the parsers was up to the task"
9
- end
6
+ def self.parse(raw, **)
7
+ raise Net::FTP::List::ParseError, "Could not parse #{raw} since none of the parsers was up to the task" if Net::FTP::List.raise_on_failed_server_detection
10
8
 
11
- emit_entry(raw, {})
9
+ emit_entry(raw)
12
10
  end
13
11
  end
14
-
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
-
data/net-ftp-list.gemspec CHANGED
@@ -1,61 +1,22 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
- # stub: net-ftp-list 3.2.11 ruby lib
6
-
7
1
  Gem::Specification.new do |s|
8
- s.name = "net-ftp-list".freeze
9
- s.version = "3.2.11"
2
+ s.name = 'net-ftp-list'
3
+ s.version = '3.4.1'
4
+ s.authors = ['Stateless Systems']
5
+ s.email = 'enquiries@statelesssystems.com'
6
+ s.summary = 'Parse FTP LIST command output.'
7
+ s.homepage = 'http://github.com/stateless-systems/net-ftp-list'
8
+ s.license = 'MIT'
10
9
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib".freeze]
13
- s.authors = ["Stateless Systems".freeze]
14
- s.date = "2018-04-02"
15
- s.email = "enquiries@statelesssystems.com".freeze
16
- s.extra_rdoc_files = [
17
- "README.txt"
18
- ]
19
- s.files = [
20
- ".ruby-version",
21
- "Gemfile",
22
- "Gemfile.lock",
23
- "README.txt",
24
- "Rakefile",
25
- "VERSION.yml",
26
- "lib/net/ftp/list.rb",
27
- "lib/net/ftp/list/entry.rb",
28
- "lib/net/ftp/list/microsoft.rb",
29
- "lib/net/ftp/list/netware.rb",
30
- "lib/net/ftp/list/parser.rb",
31
- "lib/net/ftp/list/rumpus.rb",
32
- "lib/net/ftp/list/unix.rb",
33
- "lib/net/ftp/list/unknown.rb",
34
- "net-ftp-list.gemspec",
35
- "test/test_net_ftp_list.rb",
36
- "test/test_net_ftp_list_entry.rb",
37
- "test/test_net_ftp_list_microsoft.rb",
38
- "test/test_net_ftp_list_netware.rb",
39
- "test/test_net_ftp_list_rumpus.rb",
40
- "test/test_net_ftp_list_unix.rb"
41
- ]
42
- s.homepage = "http://github.com/stateless-systems/net-ftp-list".freeze
43
- s.rubygems_version = "2.7.6".freeze
44
- s.summary = "Parse FTP LIST command output.".freeze
10
+ s.files = `git ls-files -z`.split("\x0").reject {|f| f.start_with?('test/') }
11
+ s.test_files = `git ls-files -z -- test/*`.split("\x0")
12
+ s.require_paths = ['lib']
13
+ s.required_ruby_version = '>= 2.5'
45
14
 
46
- if s.respond_to? :specification_version then
47
- s.specification_version = 4
15
+ s.add_dependency 'net-ftp'
48
16
 
49
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
51
- s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
52
- else
53
- s.add_dependency(%q<jeweler>.freeze, [">= 0"])
54
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
55
- end
56
- else
57
- s.add_dependency(%q<jeweler>.freeze, [">= 0"])
58
- s.add_dependency(%q<test-unit>.freeze, [">= 0"])
59
- end
17
+ s.add_development_dependency 'bigdecimal'
18
+ s.add_development_dependency 'rake'
19
+ s.add_development_dependency 'rdoc'
20
+ s.add_development_dependency 'test-unit'
21
+ s.add_development_dependency 'timecop'
60
22
  end
61
-
@@ -2,14 +2,13 @@ require 'test/unit'
2
2
  require 'net/ftp/list'
3
3
 
4
4
  class TestNetFTPList < Test::Unit::TestCase
5
-
6
5
  def test_all
7
6
  one = Net::FTP::List.parse('drwxr-xr-x 4 user group 4096 Dec 10 20:23 etc')
8
7
  assert_kind_of Net::FTP::List::Entry, one
9
8
  assert one.dir?
10
9
  assert !one.file?
11
10
 
12
- two = Net::FTP::List.parse("++ unknown garbage +++")
11
+ two = Net::FTP::List.parse('++ unknown garbage +++')
13
12
  assert_kind_of Net::FTP::List::Entry, two
14
13
  assert two.unknown?
15
14
  assert_equal '', two.basename
@@ -18,7 +17,7 @@ class TestNetFTPList < Test::Unit::TestCase
18
17
  def test_raise_when_flag_set
19
18
  Net::FTP::List.raise_on_failed_server_detection = true
20
19
  assert_raise(Net::FTP::List::ParseError) do
21
- Net::FTP::List.parse("++ unknown garbage +++")
20
+ Net::FTP::List.parse('++ unknown garbage +++')
22
21
  end
23
22
  ensure
24
23
  Net::FTP::List.raise_on_failed_server_detection = false
@@ -1,18 +1,18 @@
1
1
  require 'test/unit'
2
2
  require 'net/ftp/list'
3
+ require 'bigdecimal'
3
4
 
4
5
  class TestNetFTPEntry < Test::Unit::TestCase
5
-
6
6
  def test_equality
7
- a = Net::FTP::List::Entry.new('foo1', {:basename => 'foo1'})
8
- b = Net::FTP::List::Entry.new('foo2', {:basename => 'foo2'})
9
- c = Net::FTP::List::Entry.new('foo1', {:basename => 'foo1'})
7
+ a = Net::FTP::List::Entry.new('foo1', basename: 'foo1')
8
+ b = Net::FTP::List::Entry.new('foo2', basename: 'foo2')
9
+ c = Net::FTP::List::Entry.new('foo1', basename: 'foo1')
10
10
 
11
- assert a.eql? c
11
+ assert a.eql?(c)
12
12
  assert a.eql? a
13
13
  assert !a.eql?(b)
14
14
  assert !a.eql?(1)
15
- assert !a.eql?(1.0)
15
+ assert !a.eql?(BigDecimal('1.0'))
16
16
  end
17
17
 
18
18
  def test_comparison
@@ -26,24 +26,24 @@ class TestNetFTPEntry < Test::Unit::TestCase
26
26
 
27
27
  assert file2 > file1
28
28
  assert file2 >= file1
29
- assert file2 == file2
29
+ assert file2 == Net::FTP::List.parse(raw2)
30
+ assert file2 <= file3
31
+ assert file2 < file3
32
+ assert file2 >= file1
33
+ assert file2 > file1
34
+ assert file2 != file1
35
+ assert file2 != file3
30
36
  assert file2 <= file3
31
37
  assert file2 < file3
32
- assert !(file2 < file1)
33
- assert !(file2 <= file1)
34
- assert !(file2 == file1)
35
- assert !(file2 == file3)
36
- assert !(file2 > file3)
37
- assert !(file2 >= file3)
38
38
 
39
- assert !(file2 < 2)
40
- assert !(file2 < 2.0)
39
+ assert file2 >= 2
40
+ assert file2 >= 2.0
41
41
  assert file2 <= 2
42
42
  assert file2 <= 2.0
43
43
  assert file2 == 2
44
- assert file2 == 2.0
45
- assert !(file2 > 2)
46
- assert !(file2 > 2.0)
44
+ assert file2 == BigDecimal('2.0')
45
+ assert file2 <= 2
46
+ assert file2 <= 2.0
47
47
  assert file2 >= 2
48
48
  assert file2 >= 2.0
49
49
 
@@ -52,7 +52,7 @@ class TestNetFTPEntry < Test::Unit::TestCase
52
52
  end
53
53
 
54
54
  def test_raise_on_unknown_options
55
- assert_raise(ArgumentError) { Net::FTP::List::Entry.new("foo", {:bar => "baz"}) }
55
+ assert_raise(ArgumentError) { Net::FTP::List::Entry.new('foo', bar: 'baz') }
56
56
  end
57
57
 
58
58
  def test_default_values
@@ -67,7 +67,6 @@ class TestNetFTPEntry < Test::Unit::TestCase
67
67
  assert !e.file?
68
68
  assert !e.symlink?
69
69
  assert_kind_of Time, e.mtime
70
- assert_equal "Unknown", e.server_type
70
+ assert_equal 'Unknown', e.server_type
71
71
  end
72
-
73
72
  end
@@ -2,15 +2,14 @@ require 'test/unit'
2
2
  require 'net/ftp/list'
3
3
 
4
4
  class TestNetFTPListMicrosoft < Test::Unit::TestCase
5
-
6
5
  def setup
7
6
  @dir = Net::FTP::List.parse('06-25-07 01:08PM <DIR> etc')
8
7
  @file = Net::FTP::List.parse('11-27-07 08:45PM 23437 README.TXT')
9
8
  end
10
9
 
11
10
  def test_parse_new
12
- assert_equal "Microsoft", @dir.server_type, 'LIST M$ directory'
13
- assert_equal "Microsoft", @file.server_type, 'LIST M$ directory'
11
+ assert_equal 'Microsoft', @dir.server_type, 'LIST M$ directory'
12
+ assert_equal 'Microsoft', @file.server_type, 'LIST M$ directory'
14
13
  end
15
14
 
16
15
  def test_parse_dd_mm_yyyy
@@ -62,12 +61,12 @@ class TestNetFTPListMicrosoft < Test::Unit::TestCase
62
61
  end
63
62
 
64
63
  def test_rubbish_lines
65
- assert_instance_of Net::FTP::List::Entry, Net::FTP::List.parse("++ bah! ++")
64
+ assert_instance_of Net::FTP::List::Entry, Net::FTP::List.parse('++ bah! ++')
66
65
  end
67
66
 
68
67
  def test_ruby_microsoft_mtime
69
- assert_equal DateTime.strptime('06-25-07 01:08PM', "%m-%d-%y %I:%M%p"), @dir.mtime
70
- assert_equal DateTime.strptime('11-27-07 08:45PM', "%m-%d-%y %I:%M%p"), @file.mtime
68
+ assert_equal Time.utc(2007, 6, 25, 13, 8), @dir.mtime
69
+ assert_equal Time.utc(2007, 11, 27, 20, 45), @file.mtime
71
70
  end
72
71
 
73
72
  def test_ruby_microsoft_like_dir
@@ -89,6 +88,6 @@ class TestNetFTPListMicrosoft < Test::Unit::TestCase
89
88
 
90
89
  def test_zero_hour
91
90
  file = Net::FTP::List.parse('10-15-09 00:34AM <DIR> aspnet_client')
92
- assert_equal 1255566840.to_s, file.mtime.strftime('%s')
91
+ assert_equal Time.utc(2009, 10, 15, 0, 34), file.mtime
93
92
  end
94
93
  end
@@ -2,20 +2,19 @@ require 'test/unit'
2
2
  require 'net/ftp/list'
3
3
 
4
4
  class TestNetFTPListNetware < Test::Unit::TestCase
5
-
6
5
  def setup
7
- @dir = Net::FTP::List.parse('d [RWCEAFMS] dpearce 512 Jun 27 23:46 public.www')
8
- @file = Net::FTP::List.parse('- [RWCEAFMS] dpearce 2767 Jun 22 06:22 about.html')
6
+ @dir = Net::FTP::List.parse('d [RWCEAFMS] dpearce 512 Jun 27 23:46 public.www')
7
+ @file = Net::FTP::List.parse('- [RWCEAFMS] dpearce 2767 Jun 22 06:22 about.html', timezone: :local)
9
8
  end
10
9
 
11
10
  def test_parse_new
12
- assert_equal "Netware", @dir.server_type, 'LIST Netware directory'
13
- assert_equal "Netware", @file.server_type, 'LIST Netware file'
11
+ assert_equal 'Netware', @dir.server_type, 'LIST Netware directory'
12
+ assert_equal 'Netware', @file.server_type, 'LIST Netware file'
14
13
  end
15
14
 
16
15
  def test_ruby_netware_mtime
17
- assert_equal @dir.mtime, Time.parse('Jun 27 23:46')
18
- assert_equal @file.mtime, Time.parse('Jun 22 06:22')
16
+ assert_equal Time.utc(Time.now.year, 6, 27, 23, 46), @dir.mtime
17
+ assert_equal Time.local(Time.now.year, 6, 22, 6, 22), @file.mtime
19
18
  end
20
19
 
21
20
  def test_ruby_netware_like_dir
@@ -34,5 +33,4 @@ class TestNetFTPListNetware < Test::Unit::TestCase
34
33
  assert_equal 512, @dir.filesize
35
34
  assert_equal 2767, @file.filesize
36
35
  end
37
-
38
36
  end
@@ -2,20 +2,19 @@ require 'test/unit'
2
2
  require 'net/ftp/list'
3
3
 
4
4
  class TestNetFTPListRumpus < Test::Unit::TestCase
5
-
6
5
  def setup
7
6
  @dir = Net::FTP::List.parse 'drwxrwxrwx folder 0 Nov 16 22:12 Alias'
8
- @file = Net::FTP::List.parse '-rw-r--r-- 0 101426 101426 Jun 7 2008 imap with spaces.rb'
7
+ @file = Net::FTP::List.parse '-rw-r--r-- 0 101426 101426 Jun 7 2008 imap with spaces.rb', timezone: :local
9
8
  end
10
9
 
11
10
  def test_parsed
12
- assert_equal "Rumpus", @dir.server_type, 'LIST Rumpus directory'
13
- assert_equal "Rumpus", @file.server_type, 'LIST Rumpus file with spaces'
11
+ assert_equal 'Rumpus', @dir.server_type, 'LIST Rumpus directory'
12
+ assert_equal 'Rumpus', @file.server_type, 'LIST Rumpus file with spaces'
14
13
  end
15
14
 
16
15
  def test_ruby_unix_like_date
17
- assert_equal Time.parse("Nov 16 22:12"), @dir.mtime
18
- assert_equal Time.parse("Jun 7 2008"), @file.mtime
16
+ assert_equal Time.utc(Time.now.year, 11, 16, 22, 12), @dir.mtime
17
+ assert_equal Time.local(2008, 6, 7), @file.mtime
19
18
  end
20
19
 
21
20
  def test_dir
@@ -1,97 +1,110 @@
1
1
  require 'test/unit'
2
2
  require 'net/ftp/list'
3
+ require 'timecop'
3
4
 
4
5
  class TestNetFTPListUnix < Test::Unit::TestCase
6
+ def parse(*args, **opts)
7
+ Net::FTP::List.parse(*args, **opts)
8
+ end
9
+
5
10
  def setup
6
- @dir = Net::FTP::List.parse 'drwxr-xr-x 4 user group 4096 Jan 1 00:00 etc' rescue nil
7
- @file = Net::FTP::List.parse '-rw-r--r-- 1 root other 531 Dec 31 23:59 README' rescue nil
8
- @other_dir = Net::FTP::List.parse 'drwxr-xr-x 8 1791 600 4096 Mar 11 07:57 forums' rescue nil
9
- @spaces = Net::FTP::List.parse 'drwxrwxr-x 2 danial danial 72 May 23 12:52 spaces suck' rescue nil
10
- @symlink = Net::FTP::List.parse 'lrwxrwxrwx 1 danial danial 4 Oct 30 15:26 bar -> /etc' rescue nil
11
- @empty_symlink = Net::FTP::List.parse 'lrwxrwxrwx 1 danial danial 4 Oct 30 15:26 foo' rescue nil
12
- @older_date = Net::FTP::List.parse '-rwxrwxrwx 1 owner group 154112 Feb 15 2008 participando.xls' rescue nil
13
- @block_dev = Net::FTP::List.parse 'brw-r----- 1 root disk 1, 0 Apr 13 2006 ram0' rescue nil
14
- @char_dev = Net::FTP::List.parse 'crw-rw-rw- 1 root root 1, 3 Apr 13 2006 null' rescue nil
15
- @socket_dev = Net::FTP::List.parse 'srw-rw-rw- 1 root root 0 Aug 20 14:15 log' rescue nil
16
- @pipe_dev = Net::FTP::List.parse 'prw-r----- 1 root adm 0 Nov 22 10:30 xconsole' rescue nil
17
- @file_no_inodes = Net::FTP::List.parse '-rw-r--r-- foo@localhost foo@localhost 6034 May 14 23:13 index.html' rescue nil
18
- @file_today = Net::FTP::List.parse 'crw-rw-rw- 1 root root 1, 3 Aug 16 14:28 today.txt' rescue nil
19
- @no_user = Net::FTP::List.parse '-rw-rw---- 2786 Jul 7 01:57 README' rescue nil
11
+ @dir = parse('drwxr-xr-x 4 user group 4096 Jan 1 00:00 etc')
12
+ @file = parse('-rw-r--r-- 1 root other 531 Dec 31 23:59 README')
13
+ @other_dir = parse('drwxr-xr-x 8 1791 600 4096 Mar 11 07:57 forums')
14
+ @spaces = parse('drwxrwxr-x 2 danial danial 72 May 23 12:52 spaces suck')
15
+ @symlink = parse('lrwxrwxrwx 1 danial danial 4 Oct 30 15:26 bar -> /etc')
16
+ @empty_symlink = parse('lrwxrwxrwx 1 danial danial 4 Oct 30 15:26 foo')
17
+ @block_dev = parse('brw-r----- 1 root disk 1, 0 Apr 13 2006 ram0', timezone: :local)
18
+ @char_dev = parse('crw-rw-rw- 1 root root 1, 3 Apr 13 2006 null')
19
+ @socket_dev = parse('srw-rw-rw- 1 root root 0 Aug 20 14:15 log')
20
+ @pipe_dev = parse('prw-r----- 1 root adm 0 Nov 22 10:30 xconsole')
21
+ @file_no_inodes = parse('-rw-r--r-- foo@utchost foo@utchost 6034 May 14 23:13 index.html')
22
+ @file_today = parse('crw-rw-rw- 1 root root 1, 3 Aug 16 14:28 today.txt')
23
+ @no_user = parse('-rw-rw---- 2786 Jul 7 01:57 README')
24
+ @older_date = parse('-rwxrwxrwx 1 owner group 154112 Feb 15 2008 participando.xls')
25
+ @file_with_date = parse('-rw-r--r-- 1 tig tig 39757835 Jan 26 2014 PSA 23 99 May-2010.pdf')
20
26
  end
21
27
 
22
28
  def test_parse_new
23
- assert_equal "Unix", @dir.server_type, 'LIST unixish directory'
24
- assert_equal "Unix", @file.server_type, 'LIST unixish file'
25
- assert_equal "Unix", @other_dir.server_type, 'LIST unixish directory'
26
- assert_equal "Unix", @spaces.server_type, 'LIST unixish directory with spaces'
27
- assert_equal "Unix", @symlink.server_type, 'LIST unixish symlink'
28
- assert_equal "Unix", @empty_symlink.server_type, 'LIST unixish symlink'
29
- assert_equal "Unix", @block_dev.server_type, 'LIST unix block device'
30
- assert_equal "Unix", @char_dev.server_type, 'LIST unix char device'
31
- assert_equal "Unix", @socket_dev.server_type, 'LIST unix socket device'
32
- assert_equal "Unix", @pipe_dev.server_type, 'LIST unix socket device'
33
- assert_equal "Unix", @file_no_inodes.server_type, 'LIST unixish file with no inodes'
34
- assert_equal "Unix", @no_user.server_type, 'LIST unixish file with no user/group'
35
- end
36
-
37
- class ::Time
38
- class << self
39
- def time_travel(time)
40
- @traveled_to_time = time
41
-
42
- begin
43
- yield
44
- ensure
45
- @traveled_to_time = nil
46
- end
47
- end
48
-
49
- alias_method :original_now, :now
50
- def now
51
- @traveled_to_time || original_now
52
- end
53
- end
29
+ assert_equal 'Unix', @dir.server_type, 'LIST unixish directory'
30
+ assert_equal 'Unix', @file.server_type, 'LIST unixish file'
31
+ assert_equal 'Unix', @other_dir.server_type, 'LIST unixish directory'
32
+ assert_equal 'Unix', @spaces.server_type, 'LIST unixish directory with spaces'
33
+ assert_equal 'Unix', @symlink.server_type, 'LIST unixish symlink'
34
+ assert_equal 'Unix', @empty_symlink.server_type, 'LIST unixish symlink'
35
+ assert_equal 'Unix', @block_dev.server_type, 'LIST unix block device'
36
+ assert_equal 'Unix', @char_dev.server_type, 'LIST unix char device'
37
+ assert_equal 'Unix', @socket_dev.server_type, 'LIST unix socket device'
38
+ assert_equal 'Unix', @pipe_dev.server_type, 'LIST unix socket device'
39
+ assert_equal 'Unix', @file_no_inodes.server_type, 'LIST unixish file with no inodes'
40
+ assert_equal 'Unix', @file_today.server_type, 'LIST unixish file'
41
+ assert_equal 'Unix', @no_user.server_type, 'LIST unixish file with no user/group'
42
+ assert_equal 'Unix', @older_date.server_type, 'LIST unixish file with older date'
43
+ assert_equal 'Unix', @file_with_date.server_type, 'LIST unix with file containing a date'
54
44
  end
55
45
 
56
46
  # mtimes in the past, same year.
57
47
  def test_ruby_unix_like_date_past_same_year
58
-
59
- Time.time_travel(Time.local(2009, 1, 1)) do
60
- assert_equal Time.local(2009, 1, 1), Net::FTP::List.parse(@dir.raw).mtime
48
+ Timecop.freeze(Time.utc(2009, 1, 1)) do
49
+ assert_equal Time.utc(2009, 1, 1), parse(@dir.raw).mtime
61
50
  end
62
- Time.time_travel(Time.local(2008, 4, 1)) do
63
- assert_equal Time.local(2008, 3, 11, 7, 57), Net::FTP::List.parse(@other_dir.raw).mtime
51
+ Timecop.freeze(Time.utc(2008, 4, 1)) do
52
+ assert_equal Time.utc(2008, 3, 11, 7, 57), parse(@other_dir.raw).mtime
64
53
  end
65
54
  end
66
55
 
67
56
  # mtimes in the past, previous year
68
57
  def test_ruby_unix_like_date_past_previous_year
69
- Time.time_travel(Time.local(2008, 2, 4)) do
70
- assert_equal Time.local(2007, 10, 30, 15, 26), Net::FTP::List.parse(@symlink.raw).mtime
58
+ Timecop.freeze(Time.utc(2008, 2, 4)) do
59
+ assert_equal Time.utc(2007, 10, 30, 15, 26), parse(@symlink.raw).mtime
71
60
  end
72
61
  end
73
62
 
74
63
  # mtime in the future.
75
64
  def test_ruby_unix_like_date_future
76
- Time.time_travel(Time.local(2006, 3, 1)) do
77
- assert_equal Time.local(2006, 4, 13), Net::FTP::List.parse(@char_dev.raw).mtime
65
+ Timecop.freeze(Time.utc(2006, 3, 1)) do
66
+ assert_equal Time.utc(2006, 4, 13), parse(@char_dev.raw).mtime
78
67
  end
79
68
  end
80
69
 
81
70
  # Parsed during a leap year.
82
71
  def test_ruby_unix_like_date_leap_year
83
- Time.time_travel(Time.local(2012, 1, 2)) do
84
- assert_equal Time.local(2011, 10, 30, 15, 26), Net::FTP::List.parse(@symlink.raw).mtime
72
+ Timecop.freeze(Time.utc(2012, 1, 2)) do
73
+ assert_equal Time.utc(2011, 10, 30, 15, 26), parse(@symlink.raw).mtime
85
74
  end
86
75
  end
87
76
 
88
77
  # mtimes today, same year.
89
78
  def test_ruby_unix_like_date_today_same_year
90
- Time.time_travel(Time.local(2013, 8, 16)) do
91
- assert_equal Time.local(2013, 8, 16, 14, 28), Net::FTP::List.parse(@file_today.raw).mtime
79
+ Timecop.freeze(Time.utc(2013, 8, 16)) do
80
+ assert_equal Time.utc(2013, 8, 16, 14, 28), parse(@file_today.raw).mtime
92
81
  end
93
82
  end
94
83
 
84
+ def test_basename
85
+ assert_equal 'etc', @dir.basename
86
+ assert_equal 'README', @file.basename
87
+ assert_equal 'forums', @other_dir.basename
88
+ assert_equal 'spaces suck', @spaces.basename
89
+ assert_equal 'bar', @symlink.basename
90
+ assert_equal 'foo', @empty_symlink.basename
91
+ assert_equal 'ram0', @block_dev.basename
92
+ assert_equal 'null', @char_dev.basename
93
+ assert_equal 'log', @socket_dev.basename
94
+ assert_equal 'xconsole', @pipe_dev.basename
95
+ assert_equal 'index.html', @file_no_inodes.basename
96
+ assert_equal 'today.txt', @file_today.basename
97
+ assert_equal 'README', @no_user.basename
98
+ assert_equal 'participando.xls', @older_date.basename
99
+ assert_equal 'PSA 23 99 May-2010.pdf', @file_with_date.basename
100
+ end
101
+
102
+ def test_mtime
103
+ assert_equal Time.utc(2008, 2, 15), @older_date.mtime
104
+ assert_equal Time.local(2006, 4, 13), @block_dev.mtime
105
+ assert_equal Time.utc(2014, 1, 26), @file_with_date.mtime
106
+ end
107
+
95
108
  def test_ruby_unix_like_dir
96
109
  assert_equal 'etc', @dir.basename
97
110
  assert @dir.dir?
@@ -104,7 +117,7 @@ class TestNetFTPListUnix < Test::Unit::TestCase
104
117
 
105
118
  def test_ruby_unix_like_symlink
106
119
  assert_equal 'bar', @symlink.basename
107
- assert_equal "/etc", @symlink.symlink_destination
120
+ assert_equal '/etc', @symlink.symlink_destination
108
121
  assert @symlink.symlink?
109
122
  assert !@symlink.dir?
110
123
  assert !@symlink.file?
@@ -152,12 +165,13 @@ class TestNetFTPListUnix < Test::Unit::TestCase
152
165
  end
153
166
 
154
167
  def test_single_digit_hour
155
- Time.time_travel(Time.local(2014, 8, 16)) do
168
+ Timecop.freeze(Time.utc(2014, 8, 16)) do
169
+ single_digit_hour = nil
156
170
  assert_nothing_raised do
157
- @single_digit_hour = Net::FTP::List.parse('-rw-r--r-- 1 root other 531 Dec 31 3:59 README')
171
+ single_digit_hour = parse('-rw-r--r-- 1 root other 531 Dec 31 3:59 README')
158
172
  end
159
173
 
160
- assert_equal Time.local(2013, 12, 31, 3, 59), @single_digit_hour.mtime
174
+ assert_equal Time.utc(2013, 12, 31, 3, 59), single_digit_hour.mtime
161
175
  end
162
176
  end
163
177
  end
metadata CHANGED
@@ -1,17 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ftp-list
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.11
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stateless Systems
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2018-04-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: jeweler
13
+ name: net-ftp
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bigdecimal
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rake
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rdoc
15
56
  requirement: !ruby/object:Gem::Requirement
16
57
  requirements:
17
58
  - - ">="
@@ -38,19 +79,30 @@ dependencies:
38
79
  - - ">="
39
80
  - !ruby/object:Gem::Version
40
81
  version: '0'
41
- description:
82
+ - !ruby/object:Gem::Dependency
83
+ name: timecop
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
42
96
  email: enquiries@statelesssystems.com
43
97
  executables: []
44
98
  extensions: []
45
- extra_rdoc_files:
46
- - README.txt
99
+ extra_rdoc_files: []
47
100
  files:
48
- - ".ruby-version"
101
+ - ".github/workflows/test.yml"
102
+ - ".gitignore"
49
103
  - Gemfile
50
- - Gemfile.lock
51
104
  - README.txt
52
105
  - Rakefile
53
- - VERSION.yml
54
106
  - lib/net/ftp/list.rb
55
107
  - lib/net/ftp/list/entry.rb
56
108
  - lib/net/ftp/list/microsoft.rb
@@ -67,9 +119,9 @@ files:
67
119
  - test/test_net_ftp_list_rumpus.rb
68
120
  - test/test_net_ftp_list_unix.rb
69
121
  homepage: http://github.com/stateless-systems/net-ftp-list
70
- licenses: []
122
+ licenses:
123
+ - MIT
71
124
  metadata: {}
72
- post_install_message:
73
125
  rdoc_options: []
74
126
  require_paths:
75
127
  - lib
@@ -77,16 +129,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
129
  requirements:
78
130
  - - ">="
79
131
  - !ruby/object:Gem::Version
80
- version: '0'
132
+ version: '2.5'
81
133
  required_rubygems_version: !ruby/object:Gem::Requirement
82
134
  requirements:
83
135
  - - ">="
84
136
  - !ruby/object:Gem::Version
85
137
  version: '0'
86
138
  requirements: []
87
- rubyforge_project:
88
- rubygems_version: 2.7.6
89
- signing_key:
139
+ rubygems_version: 4.0.10
90
140
  specification_version: 4
91
141
  summary: Parse FTP LIST command output.
92
- test_files: []
142
+ test_files:
143
+ - test/test_net_ftp_list.rb
144
+ - test/test_net_ftp_list_entry.rb
145
+ - test/test_net_ftp_list_microsoft.rb
146
+ - test/test_net_ftp_list_netware.rb
147
+ - test/test_net_ftp_list_rumpus.rb
148
+ - test/test_net_ftp_list_unix.rb
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.0.0-p451
data/Gemfile.lock DELETED
@@ -1,63 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- 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)
52
- power_assert
53
- thread_safe (0.3.6)
54
-
55
- PLATFORMS
56
- ruby
57
-
58
- DEPENDENCIES
59
- jeweler
60
- test-unit
61
-
62
- BUNDLED WITH
63
- 1.16.1
data/VERSION.yml DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 3
3
- :minor: 2
4
- :patch: 11
5
- :build: