k_fileset 0.0.3

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.
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ # Glob entry can be used to find <PathEntries> that match a Glob
5
+ # with optional exclusion patterns and flags
6
+ class GlobEntry
7
+ include GlobProps
8
+
9
+ def initialize(working_directory, glob, flags, exclusions)
10
+ @working_directory = working_directory
11
+ @glob = glob
12
+ @flags = flags
13
+ @exclusions = exclusions
14
+ end
15
+
16
+ # Dealing with edge cases:
17
+ # https://bugs.ruby-lang.org/issues/17280
18
+
19
+ def path_entries
20
+ Dir.chdir(working_directory) do
21
+ Dir.glob(glob, flags)
22
+ .reject { |file| exclusions.any? { |pattern| pattern_match?(pattern, file) } }
23
+ .map do |file|
24
+ # pathname = Pathname.new(file)
25
+ # key = pathname.realpath.to_s
26
+ # key = File.join(key, '.') if file.ends_with?('.')
27
+ # PathEntry.new(key, pathname, Dir.pwd, file)
28
+ PathEntry.new(file)
29
+ end
30
+ end
31
+ end
32
+
33
+ def match?(absolute_file)
34
+ # match the inclusion Glob first
35
+
36
+ # Using absolute files because two sibling Globs may have different exclusion rules
37
+ # and the incoming file needs to be tested against the correct Glob and it's exclusions
38
+ absolute_glob = File.expand_path(glob, path)
39
+
40
+ return false unless File.fnmatch?(absolute_glob, absolute_file)
41
+
42
+ true
43
+ end
44
+
45
+ private
46
+
47
+ def pattern_match?(pattern, file)
48
+ return pattern.match?(file) if pattern.is_a?(Regexp)
49
+ return pattern.call(file) if pattern.respond_to?(:call)
50
+
51
+ File.fnmatch?(pattern, file) # As String
52
+ end
53
+ end
54
+ end
55
+ # File.fnmatch('?', '/', File::FNM_PATHNAME) #=> false : wildcard doesn't match '/' on FNM_PATHNAME
56
+ # File.fnmatch('*', '/', File::FNM_PATHNAME) #=> false : ditto
57
+ # File.fnmatch('[/]', '/', File::FNM_PATHNAME) #=> false : ditto
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ # GlobConfig, GlobBuilder
5
+ class GlobInfo
6
+ include GlobProps
7
+
8
+ def initialize(glob, exclude = nil, flags = File::FNM_PATHNAME | File::FNM_EXTGLOB)
9
+ @working_directory = Dir.pwd
10
+ @glob = Pathname.new(glob).cleanpath.to_s
11
+ @glob += File::SEPARATOR if glob.end_with?(File::SEPARATOR)
12
+ @flags = flags
13
+
14
+ # absolute_path_glob
15
+ @exclusions = build_exclusions(exclude)
16
+ end
17
+
18
+ def entry
19
+ GlobEntry.new(working_directory, glob, flags, exclusions)
20
+ end
21
+
22
+ class << self
23
+ # rubocop:disable Metrics/AbcSize:
24
+ def build_glob_entries(glob_infos)
25
+ glob_entries = []
26
+
27
+ glob_infos.each do |glob_info|
28
+ found = glob_entries.find_index { |entry| entry.working_directory == glob_info.working_directory && entry.glob == glob_info.glob }
29
+
30
+ if found
31
+ glob_entries[found].exclusions = (glob_entries[found].exclusions + glob_info.exclusions).uniq
32
+ else
33
+ glob_entries << GlobEntry.new(glob_info.working_directory, glob_info.glob, glob_info.flags, glob_info.exclusions)
34
+ end
35
+ end
36
+ glob_entries
37
+ end
38
+ # rubocop:enable Metrics/AbcSize:
39
+ end
40
+
41
+ private
42
+
43
+ # Handles String based Glob, Regexp pattern or lambda expression
44
+ def build_exclusions(exclude)
45
+ return [] if exclude.nil?
46
+ return [exclude] if valid_exclusion?(exclude)
47
+
48
+ exclude.select { |ex| valid_exclusion?(ex) }
49
+ end
50
+
51
+ def valid_exclusion?(exclusion)
52
+ exclusion.is_a?(String) || exclusion.is_a?(Regexp) || exclusion.respond_to?(:call)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ module GlobProps
5
+ attr_accessor :working_directory
6
+ attr_accessor :glob
7
+ attr_accessor :exclusions
8
+ attr_accessor :flags
9
+ end
10
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ # PathEntry is a (RUBY) Pathname object with some extra properties
5
+ class PathEntry < Pathname
6
+ include KLog::Logging
7
+ # unique absolute path name e.g.(/abc, /abc/.)
8
+ # attr_reader :key
9
+ # attr_reader :path_name # Pathname
10
+ attr_reader :working_directory
11
+
12
+ # attr_reader :relative_path
13
+
14
+ # _path_name,
15
+ def initialize(path)
16
+ super(path)
17
+ # @key = realpath.to_s
18
+ # @key = File.join(@key, '.') if pathname.ends_with?('.')
19
+ # puts @key
20
+ # @path_name = path_name
21
+ @working_directory = Dir.getwd
22
+ # @pathname = pathname
23
+ # debug
24
+ end
25
+
26
+ def key
27
+ return @key if defined? @key
28
+
29
+ @key = begin
30
+ key = realpath.to_s
31
+ key = File.join(key, '.') if basename.to_s == '.' # if pathname.ends_with?('.')
32
+ key
33
+ end
34
+ end
35
+
36
+ # Realpath (is the absolute path of the entry)
37
+ #
38
+ # The Realpath is based on the current directory at the time this entry was created
39
+ # def realpath
40
+ # path_name.realpath(working_directory).to_s
41
+ # end
42
+
43
+ def path
44
+ realpath.to_s
45
+ end
46
+
47
+ def debug
48
+ # puts "expand_path : #{self.expand_path.to_s}"
49
+ # puts "realdirpath : #{self.realdirpath.to_s}"
50
+ # puts "realpath : #{self.realpath.to_s}"
51
+ # puts "extname : #{self.extname.to_s}"
52
+ # puts "basename : #{self.basename.to_s}"
53
+ # puts "dirname : #{self.dirname.to_s}"
54
+ # puts "to_path : #{self.to_path.to_s}"
55
+ # puts "parent : #{self.parent.to_s}"
56
+ # log.line
57
+ log.kv 'key', key
58
+ log.kv 'working_directory', working_directory
59
+ log.kv 'pathname', path
60
+
61
+ log.kv 'to_path', to_path
62
+ log.kv 'cleanpath', cleanpath
63
+
64
+ # log.kv 'directory?', directory?
65
+ # log.kv 'root?', root?
66
+ # log.kv 'absolute?', absolute?
67
+ # log.kv 'relative?', relative?
68
+ # log.kv 'exist?', exist?
69
+ # log.kv 'file?', file?
70
+ # log.kv 'size?', size?
71
+ # log.kv 'ftype', ftype
72
+ # log.kv 'empty?', empty?
73
+ # log.kv 'readable?', readable?
74
+ # log.kv 'birthtime', birthtime
75
+ # log.kv 'expand_path', expand_path
76
+ # log.kv 'realdirpath', realdirpath
77
+ # log.kv 'realpath', realpath
78
+ # log.kv 'extname', extname
79
+ # log.kv 'basename', basename
80
+ # log.kv 'dirname', dirname
81
+ # log.kv 'to_path', to_path
82
+ # log.kv 'size', size
83
+
84
+ log.line
85
+ end
86
+ end
87
+ end
88
+
89
+ # relative_path() if its in two places
90
+
91
+ # Useful Pathname methods
92
+ #
93
+ # p.directory?
94
+ # p.root?
95
+ # p.absolute?
96
+ # p.relative?
97
+ # p.exist?
98
+ # p.file?
99
+ # p.size?
100
+ # p.zero?
101
+ # p.ftype
102
+ # p.empty?
103
+ # p.each_line
104
+ # p.read
105
+ # p.readlines
106
+
107
+ # p.readable?
108
+ # p.birthtime
109
+
110
+ # p.join
111
+ # p.mkpath
112
+ # p.find
113
+ # p.entries
114
+ # p.stat
115
+ # p.each_entry
116
+ # p.relative_path_from
117
+
118
+ # p.expand_path
119
+ # p.realdirpath
120
+ # p.realpath
121
+ # p.extname
122
+ # p.basename
123
+ # p.dirname
124
+ # p.relative_path_from
125
+ # p.to_path
126
+ # p.parent
127
+ # p.split
128
+ # p.size
129
+ # p.cleanpath
130
+ # p.children
131
+ # p.mkdir
132
+ # p.rmdir
133
+ # p.glob
134
+ # p.fnmatch
135
+ # p.fnmatch?
136
+ # p.delete
137
+ # p.each_filename
138
+ # p.each_line
139
+
140
+ # p.read
141
+ # p.readlines
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ VERSION = '0.0.3'
5
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KFileset
4
+ # Whitelist rules around including of files with optional exclusion rules
5
+ class Whitelist
6
+ def initialize
7
+ @glob_entries = nil # glob_entries
8
+ @globs = [] # glob_infos /
9
+ end
10
+
11
+ def path_entries
12
+ glob_entries.flat_map(&:path_entries)
13
+ end
14
+
15
+ def add(glob, exclude = nil, flags = nil)
16
+ flags ||= FileSet::DEF_FLAGS
17
+ @glob_entries = nil
18
+ @globs << KFileset::GlobInfo.new(glob, exclude, flags)
19
+
20
+ self
21
+ end
22
+
23
+ def clear
24
+ @glob_entries = nil
25
+ @globs = []
26
+
27
+ self
28
+ end
29
+
30
+ # Return true if file is matched against an entry in the whitelist
31
+ def match?(file)
32
+ glob_entries.any? { |entry| entry.match?(file) }
33
+ end
34
+
35
+ # Return GlobInfo entries with the directory, glob and exclusions
36
+ #
37
+ # Will denormalize the entries where matching (path and glob), whilst expanding with any new exclusions.
38
+ def glob_entries
39
+ @glob_entries ||= KFileset::GlobInfo.build_glob_entries(@globs)
40
+ end
41
+
42
+ # def glob_entries
43
+ # @glob_entries ||= begin
44
+ # glob_entries = []
45
+
46
+ # @globs.each do |glob|
47
+ # # found = glob_entries.find_index { |entry| entry.path == glob.absolute_path && entry.glob == glob.absolute_glob }
48
+ # found = glob_entries.find_index { |entry| entry.path == glob.path && entry.glob == glob.glob }
49
+
50
+ # if found
51
+ # glob_entries[found].exclusions = (glob_entries[found].exclusions + glob.exclusions).uniq
52
+ # else
53
+ # glob_entries << glob.entry
54
+ # end
55
+ # end
56
+ # glob_entries
57
+ # end
58
+
59
+ # @glob_entries
60
+ # end
61
+ end
62
+ end
data/lib/k_fileset.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'k_log'
4
+ require 'k_fileset/version'
5
+ require 'k_fileset/whitelist'
6
+ require 'k_fileset/path_entry'
7
+ require 'k_fileset/glob_props'
8
+ require 'k_fileset/glob_entry'
9
+ require 'k_fileset/glob_info'
10
+ require 'k_fileset/file_set'
11
+
12
+ module KFileset
13
+ # raise KFileset::Error, 'Sample message'
14
+ class Error < StandardError; end
15
+
16
+ # Your code goes here...
17
+ end
18
+
19
+ if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
20
+ namespace = 'KFileset::Version'
21
+ file_path = $LOADED_FEATURES.find { |f| f.include?('k_fileset/version') }
22
+ version = KFileset::VERSION.ljust(9)
23
+ puts "#{namespace.ljust(35)} : #{version.ljust(9)} : #{file_path}"
24
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: k_fileset
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - David Cruwys
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: k_log
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.0
27
+ description: " K-Fileset provides file system snapshot using GLOB inclusions and
28
+ exclusions\n"
29
+ email:
30
+ - david@ideasmen.com.au
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".github/workflows/main.yml"
36
+ - ".gitignore"
37
+ - ".rspec"
38
+ - ".rubocop.yml"
39
+ - CODE_OF_CONDUCT.md
40
+ - Gemfile
41
+ - Guardfile
42
+ - LICENSE.txt
43
+ - README.md
44
+ - Rakefile
45
+ - STORIES.md
46
+ - USAGE.md
47
+ - bin/console
48
+ - bin/k
49
+ - bin/kgitsync
50
+ - bin/khotfix
51
+ - bin/setup
52
+ - hooks/pre-commit
53
+ - hooks/update-version
54
+ - k_fileset.gemspec
55
+ - lib/k_fileset.rb
56
+ - lib/k_fileset/file_set.rb
57
+ - lib/k_fileset/file_set_examples.rb
58
+ - lib/k_fileset/glob_entry.rb
59
+ - lib/k_fileset/glob_info.rb
60
+ - lib/k_fileset/glob_props.rb
61
+ - lib/k_fileset/path_entry.rb
62
+ - lib/k_fileset/version.rb
63
+ - lib/k_fileset/whitelist.rb
64
+ homepage: http://appydave.com/gems/k-fileset
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: http://appydave.com/gems/k-fileset
69
+ source_code_uri: https://github.com/klueless-io/k_fileset
70
+ changelog_uri: https://github.com/klueless-io/k_fileset/commits/master
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '2.5'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.2.7
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: K-Fileset provides file system snapshot using GLOB inclusions and exclusions
90
+ test_files: []