fbtok 0.4.1 → 0.5.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: a133154bf34937e2961a05a9f3768e92cd2e4d633e64f2a52977e7eb3a7d4ae3
4
- data.tar.gz: 382ba42bb20a0038f9efeec721481d70efc41c6241a209da5ea9e2a1fb177ac1
3
+ metadata.gz: a1df323dd41b041e34646d3df3fb90ded24707020ff8cddc90af689f2f3d33d8
4
+ data.tar.gz: c023d5844a069b4c829390e80ea2b69503809d361357df27a0e87d4ee80e336a
5
5
  SHA512:
6
- metadata.gz: 800048bae44e60c94fc87073a029075d3e8d88c620ecbc3b2b4217939b4a42b40d57f855e50b60f8fe52c37593a8fe30ce786ed98169bdf87b3f64e7d1987016
7
- data.tar.gz: '0921aa61b66e4ca43c1a9643dbe951ad9fcb0bba493bc9d93c2c5ce9ef099629694323b003be701970364d2b05008826a52699d1a7759be301da48ae463db76a'
6
+ metadata.gz: 7d7759e09847da4650bc008c12a5a9c52702eb30567495a2e7667a324388203db4f2a7bba6a4ed0eea8a72a2ab211b01ca70b12e6a421026dfcf09fc024b64b2
7
+ data.tar.gz: fb1673e6b654fa8fa781844534de93c5ff913b0fd7c1c828c12319cf7b22de038b5e5f3a97a9b33a6a9d3a72fd8505c6c906e4a409aff23c140589f753f80123
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.4.1
1
+ ### 0.5.0
2
2
  ### 0.0.1 / 2025-01-02
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -12,4 +12,6 @@ lib/fbtok/fbquick.rb
12
12
  lib/fbtok/fbtok.rb
13
13
  lib/fbtok/fbtree.rb
14
14
  lib/fbtok/fbx.rb
15
+ lib/fbtok/filepack.rb
15
16
  lib/fbtok/pathspec.rb
17
+ lib/fbtok/pathspec_report.rb
data/README.md CHANGED
@@ -25,23 +25,25 @@ $ gem install fbtok
25
25
  - depends on sportdb-parser
26
26
 
27
27
  get help
28
+
28
29
  ```
29
30
  $ fbtok -h
30
31
  $ fbtree -h
31
32
  ```
32
33
 
33
34
  run on single / individual (data)files
34
- ````
35
+
36
+ ```
35
37
  $ fbtok england/2025-26/1-permierleague.txt
36
38
  $ fbtok worldcup/min/2022.txt
37
39
 
38
40
  $ fbtree england/2025-26/1-permierleague.txt
39
41
  $ fbtree worldcup/min/2022.txt
40
-
41
42
  ```
42
43
 
43
44
  or on directories (auto-collecting all datafiles)
44
45
 
46
+ ```
45
47
  $ fbtok england
46
48
  $ fbtok worldcup
47
49
 
@@ -50,19 +52,20 @@ $ fbtree worldcup
50
52
  ```
51
53
 
52
54
 
53
-
54
55
  ### fbquick/fbquik & fbx - use quick match reader & dump match schedule
55
56
 
56
57
  - depends on sportdb-quick (& sportdb-parser)
57
58
 
58
59
  get help
60
+
59
61
  ```
60
62
  $ fbquik -h
61
63
  $ fbx -h
62
64
  ```
63
65
 
64
66
  run on single / individual (data)files
65
- ````
67
+
68
+ ```
66
69
  $ fbquik england/2025-26/1-permierleague.txt
67
70
  $ fbquik worldcup/min/2022.txt
68
71
 
@@ -72,6 +75,7 @@ $ fbx worldcup/min/2022.txt
72
75
 
73
76
  or on directories (auto-collecting all datafiles)
74
77
 
78
+ ```
75
79
  $ fbquik england
76
80
  $ fbquik worldcup
77
81
  ```
@@ -81,8 +85,6 @@ note: `fbx` only works with single / individual (data)files
81
85
 
82
86
 
83
87
 
84
-
85
-
86
88
  ## Questions? Comments?
87
89
 
88
90
  Yes, you can. More than welcome.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'hoe'
2
2
 
3
3
 
4
4
  Hoe.spec 'fbtok' do
5
- self.version = '0.4.1'
5
+ self.version = '0.5.0'
6
6
 
7
7
  self.summary = "fbtok - football.txt lint tools incl. tokenizer, parser & more"
8
8
  self.description = summary
@@ -19,7 +19,7 @@ Hoe.spec 'fbtok' do
19
19
  self.licenses = ['Public Domain']
20
20
 
21
21
  self.extra_deps = [
22
- ['sportdb-parser', '>= 0.7.1'],
22
+ ['sportdb-parser', '>= 0.7.2'],
23
23
  ['sportdb-quick', '>= 0.7.0'],
24
24
  ]
25
25
 
data/bin/fbquick CHANGED
@@ -8,6 +8,13 @@
8
8
  ## $ ruby -I ../parser/lib -I ../quick/lib -I ./lib bin/fbquick
9
9
 
10
10
 
11
+ ## quick hack
12
+ ## if available always use latest (local) source version
13
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
14
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
15
+
16
+
17
+
11
18
  ## our own code
12
19
  require 'fbtok'
13
20
 
data/bin/fbquik CHANGED
@@ -3,6 +3,11 @@
3
3
  ## tip: to test run:
4
4
  ## $ ruby -I ./lib bin/fbquik
5
5
 
6
+ ## quick hack
7
+ ## if available always use latest (local) source version
8
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
10
+
6
11
 
7
12
  ## our own code
8
13
  require 'fbtok'
data/bin/fbtok CHANGED
@@ -3,6 +3,11 @@
3
3
  ## tip: to test run:
4
4
  ## $ ruby -I ./lib bin/fbtok
5
5
 
6
+ ## quick hack
7
+ ## if available always use latest (local) source version
8
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
9
+
10
+
6
11
  require 'fbtok'
7
12
 
8
13
 
data/bin/fbtree CHANGED
@@ -3,6 +3,11 @@
3
3
  ## tip: to test run:
4
4
  ## $ ruby -I ./lib bin/fbtree
5
5
 
6
+
7
+ ## quick hack
8
+ ## if available always use latest (local) source version
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
10
+
6
11
  require 'fbtok'
7
12
 
8
13
  Fbtree.main
data/bin/fbx CHANGED
@@ -4,6 +4,13 @@
4
4
  ## $ ruby -I ./lib bin/fbx
5
5
 
6
6
 
7
+ ## quick hack
8
+ ## if available always use latest (local) source version
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
10
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
11
+
12
+
13
+
7
14
  ## our own code
8
15
  require 'fbtok'
9
16
 
data/lib/fbtok/fbquick.rb CHANGED
@@ -54,10 +54,20 @@ end
54
54
  specs = if opts[:file]
55
55
  read_pathspecs( opts[:file] )
56
56
  else
57
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
58
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
59
-
60
- build_pathspecs( args )
57
+ ## check for filepack
58
+ ##
59
+ ## fix-fix-fix
60
+ ## add tool specific filepack
61
+ ## e.g. filepack.quik|quick.txt or such
62
+ ## to match first??
63
+ ## check a list of names!!
64
+ filepack = if File.file?( './filepack.txt')
65
+ read_filepack( './filepack.txt' )
66
+ else
67
+ nil
68
+ end
69
+
70
+ build_pathspecs( args, filepack: filepack )
61
71
  end
62
72
 
63
73
  pp specs
data/lib/fbtok/fbtok.rb CHANGED
@@ -58,10 +58,14 @@ end
58
58
  specs = if opts[:file]
59
59
  read_pathspecs( opts[:file] )
60
60
  else
61
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
62
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
63
-
64
- build_pathspecs( args )
61
+ ## check for filepack
62
+ filepack = if File.file?( './filepack.txt')
63
+ read_filepack( './filepack.txt' )
64
+ else
65
+ nil
66
+ end
67
+
68
+ build_pathspecs( args, filepack: filepack )
65
69
  end
66
70
 
67
71
 
@@ -82,11 +86,20 @@ specs.each_with_index do |rec,i|
82
86
  tokens, more_errors = lexer.tokenize_with_errors
83
87
 
84
88
  ####
85
- ## todo - report error on empty file (no tokens!!!)
89
+ ## todo - report error on empty file (no tokens!!!) - why? why not?
86
90
 
87
91
  puts " #{tokens.size} token(s)"
88
92
 
89
- errors += more_errors if more_errors.size > 0
93
+ if more_errors.size > 0
94
+ ## note - auto-add filename to errors
95
+ more_errors.each do |msg|
96
+ ###
97
+ ### errors << [ path, *msg ] # note: use splat (*) to add extra values (starting with msg)
98
+ errors << [path, msg]
99
+ end
100
+ end
101
+
102
+
90
103
  end
91
104
 
92
105
  if errors.size > 0
data/lib/fbtok/fbtree.rb CHANGED
@@ -58,10 +58,14 @@ end
58
58
  specs = if opts[:file]
59
59
  read_pathspecs( opts[:file] )
60
60
  else
61
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
62
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
63
-
64
- build_pathspecs( args )
61
+ ## check for filepack
62
+ filepack = if File.file?( './filepack.txt')
63
+ read_filepack( './filepack.txt' )
64
+ else
65
+ nil
66
+ end
67
+
68
+ build_pathspecs( args, filepack: filepack )
65
69
  end
66
70
 
67
71
 
@@ -81,7 +85,14 @@ specs.each_with_index do |rec,i|
81
85
 
82
86
  dump_tree_stats( tree )
83
87
 
84
- errors += parser.errors if parser.errors?
88
+ if parser.errors?
89
+ ## note - auto-add filename to errors
90
+ parser.errors.each do |msg|
91
+ ###
92
+ ### errors << [ path, *msg ] # note: use splat (*) to add extra values (starting with msg)
93
+ errors << [path, msg]
94
+ end
95
+ end
85
96
  end
86
97
 
87
98
 
data/lib/fbtok/fbx.rb CHANGED
@@ -54,8 +54,8 @@ end
54
54
 
55
55
 
56
56
  args = [
57
- '../../../openfootball/euro/2021--europe/euro.txt',
58
- '../../../openfootball/euro/2024--germany/euro.txt',
57
+ '/sports/openfootball/euro/2021--europe/euro.txt',
58
+ '/sports/openfootball/euro/2024--germany/euro.txt',
59
59
  ] if args.empty?
60
60
 
61
61
  pp args
@@ -0,0 +1,63 @@
1
+ ###################
2
+ ##
3
+ ## quick and dirty format for filepacks
4
+ ## that is, named list of files
5
+ ##
6
+ ## note - space indent(ation) does NOT matter
7
+ ##
8
+
9
+
10
+
11
+ ## PACK eng|en
12
+ ## add NAME eng|en - why? why not?
13
+ ##
14
+ ## change to FILEPACK_NAME - why? why not?
15
+ FILEPACK_HEADER_RE = %r{\A
16
+ (?: PACK ) [ ]+
17
+ (?<header> .+?) ## note - use non-greedy
18
+ \z}x
19
+
20
+ ## DIR /sports/openfootball
21
+ ## CD /sports/openfootball -- keep - why? why not?
22
+ FILEPACK_DIR_RE = %r{\A
23
+ (?: DIR|CD ) [ ]+
24
+ (?<dir> .+? ) ## note - use non-greedy
25
+
26
+ \z}x
27
+
28
+
29
+
30
+ def parse_filepack( txt )
31
+ h={}
32
+ recs = nil
33
+ basedir = nil
34
+
35
+ txt.each_line do |line|
36
+ line = line.strip
37
+
38
+ next if line.start_with?('#') || line.empty?
39
+
40
+ break if line == '__END__'
41
+
42
+
43
+ if m=FILEPACK_HEADER_RE.match(line)
44
+ keys = m[:header].strip.split( /[ ]*\|[ ]*/ )
45
+ basedir = nil
46
+ recs = []
47
+ ## note - normalize keys for now (always downcase)
48
+ keys.each {|key| h[key.downcase] = recs }
49
+ elsif m=FILEPACK_DIR_RE.match(line)
50
+ basedir = m[:dir].strip
51
+ else
52
+ file = basedir ? File.join( basedir, line ) : line
53
+ recs << file
54
+ end
55
+ end
56
+
57
+ h
58
+ end
59
+
60
+
61
+ def read_filepack( path )
62
+ parse_filepack( read_text( path ))
63
+ end
@@ -1,13 +1,13 @@
1
1
 
2
2
 
3
3
  module SportDb
4
-
5
4
  class Pathspec
6
5
 
7
6
  def self.debug=(value) @@debug = value; end
8
7
  def self.debug?() @@debug ||= false; end ## note: default is FALSE
9
8
 
10
9
 
10
+
11
11
  SEASON_RE = %r{ (?:
12
12
  (?<season>\d{4}-\d{2})
13
13
  | (?<season>\d{4})
@@ -20,6 +20,9 @@ class Pathspec
20
20
  ## BUT NOT as first character!!! (e.g. exclude .confg.txt !!!)
21
21
  ## e.g. 2024-25/at.1.txt
22
22
  ## change to at_1 or uefa_cl or such - why? why not?
23
+ ##
24
+ ## note - support case-insensitive flag (e.g. 2025-26/namur/2_Prov_A.txt)
25
+
23
26
  MATCH_RE = %r{
24
27
  ## "classic" variant i) with season folder
25
28
  ## e.g. /1930/cup.txt
@@ -30,6 +33,13 @@ class Pathspec
30
33
  (?: --[a-z0-9_-]+
31
34
  )?
32
35
  /
36
+
37
+ ### note - allow optional directories
38
+ (?:
39
+ [a-z0-9][a-z0-9_-]*
40
+ /
41
+ )*
42
+
33
43
  [a-z0-9][a-z0-9._-]* \.txt ## e.g /1-premierleague.txt
34
44
  $
35
45
  )
@@ -46,35 +56,46 @@ class Pathspec
46
56
  \.txt
47
57
  $
48
58
  )
49
- }x
59
+ }xi
50
60
 
51
61
  ### add support for matchdatafile with season NOT in directory
52
62
  ## but starting filename e.g. 2024_friendlies.txt or 2024-25_bundesliga.txt
53
63
 
54
64
 
55
- def self._norm_seasons( seasons )
56
- seasons.map {|season| Season(season) }
57
- end
58
65
 
59
66
 
60
67
  ## todo/check - rename to glob or expand or such - why? why not?
68
+
69
+ ##
70
+ ## todo - add a strict: true|false or all: true|false or such option
71
+ ## that will use generic **/*.txt and only use ignore filter!!!
72
+
73
+
61
74
  def self._find( path, seasons: nil )
75
+ ##
76
+ ## note - only if seasons filter is turn on
77
+ ## MATCH_RE gets used!!!
78
+ ## otherwise generic **/*.txt
79
+ ##
80
+ ## note - the ignore/exlude filter always gets used/applied for now
81
+
82
+
62
83
  ## check - rename dir
63
84
  ## use root_dir or work_dir or cd or such - why? why not?
64
85
 
65
-
66
86
  ## note: normalize path - use File.expand_path ??
67
87
  ## change all backslash to slash for now
68
88
  ## path = path.gsub( "\\", '/' )
69
- path = File.expand_path( path )
89
+ fullpath = File.expand_path( path )
70
90
 
71
91
  ####
72
92
  ## note - make sure path exists; raise error if not
73
- raise Errno::ENOENT, "No such directory - #{path})" unless Dir.exist?( path )
93
+ raise Errno::ENOENT, "No such directory - #{path})" unless Dir.exist?( fullpath )
74
94
 
75
95
 
76
96
  if seasons && seasons.size > 0
77
- seasons = _norm_seasons( seasons ) ## norm seasons (string, integer => Season obj)
97
+ ## norm seasons (string, integer => Season obj)
98
+ seasons = seasons.map {|season| Season(season) }
78
99
  end
79
100
 
80
101
 
@@ -83,33 +104,45 @@ def self._find( path, seasons: nil )
83
104
  ## (normally excluded with just *)
84
105
  ## was: Dir.glob( "#{path}/**/{*,.*}.txt" )
85
106
 
86
- candidates = Dir.glob( "#{path}/**/*.txt" )
107
+ candidates = Dir.glob( "#{fullpath}/**/*.txt" )
87
108
  ## pp candidates
88
109
 
89
110
 
90
111
  datafiles = []
91
112
  candidates.each do |candidate|
92
- if m = MATCH_RE.match( candidate )
93
113
 
94
- ## check for seasons filter
95
- next if seasons && seasons.size > 0 &&
96
- !seasons.include?( Season.parse( m[:season] ))
114
+ ## (i) check for (optional) seasons filter
115
+ if seasons && seasons.size > 0
116
+ if m=MATCH_RE.match( candidate )
117
+ next unless seasons.include?( Season.parse( m[:season] ))
118
+ else
119
+ next ## note - no season found in filename; skip too
120
+ end
121
+ end
97
122
 
98
- ### exclude squad
99
- ## and .v2 or .v2603
123
+
124
+ ## (ii) check for (default/built-in) ignore/excludes
125
+ basename = File.basename( candidate, File.extname( candidate ))
126
+ dirname = File.dirname( candidate )
127
+
128
+ ### exclude basenames with:
129
+ ## - squad
130
+ ## - .v2 or .v2603
100
131
  ##
101
132
  ## - worldcup/more/1930_squads.txt => squads
102
- ## - 2014--brazil/cup.v2.txt",
103
- ## - 2014--brazil/cup.v260318_164934.txt",
133
+ ## - 2014--brazil/cup.v2.txt
134
+ ## - 2014--brazil/cup.v260318_164934.txt
104
135
 
105
- basename = File.basename( candidate, File.extname( candidate ))
136
+ next if /squad/i.match?( basename )
137
+ next if /\.v[0-9][0-9_]*/i.match?( basename )
106
138
 
107
- next if /squad/i.match( basename )
108
- next if /\.v[0-9][0-9_]*/i.match( basename )
139
+ #####
140
+ ### exclude dirs with:
141
+ ## - squad or wiki
142
+ next if /squad|wiki/i.match?( dirname )
109
143
 
110
144
 
111
145
  datafiles << candidate
112
- end
113
146
  end
114
147
 
115
148
  ## pp datafiles
@@ -119,13 +152,19 @@ end
119
152
 
120
153
 
121
154
 
122
-
155
+ ##
156
+ ## rename/change to read_csv - why? why not?
123
157
  def self.read( src )
124
- recs = read_csv( src )
158
+ ## note: normalize scr - use File.expand_path ??
159
+ ## change all backslash to slash for now
160
+ ## scr = scr.gsub( "\\", '/' )
161
+ fullsrc = File.expand_path( scr )
162
+
163
+ recs = read_csv( fullsrc )
125
164
  pp recs if debug?
126
165
 
127
166
  ## note - make pathspecs relative to passed in file arg!!!
128
- basedir = File.dirname( src )
167
+ basedir = File.dirname( fullsrc )
129
168
 
130
169
  recs.each do |rec|
131
170
  path = rec['path']
@@ -141,90 +180,69 @@ end
141
180
 
142
181
 
143
182
 
183
+ def self.build( args, filepack: nil )
184
+ recs = []
144
185
 
145
- end # class Pathspec
146
-
147
-
148
-
149
- ##
150
- # PathspecReport (aka/formerly BatchReport)
186
+ ## check fo no args case (and filepack present with default)
187
+ if args.empty?
188
+ if filepack && filepack.has_key?('default')
189
+ recs << { 'path' => '<default>',
190
+ 'datafiles' => filepack['default'] }
191
+ end
192
+ else
193
+
194
+ ## note - collect all "loose/standalone" files (NOT directories)
195
+ ## in single default pathspec node
196
+ more = []
197
+
198
+
199
+ args.each do |arg|
200
+ if filepack && filepack.has_key?( arg.downcase )
201
+ recs << { 'path' => "<#{arg.downcase}>",
202
+ 'datafiles' => filepack[arg.downcase] }
203
+ ## check if directory
204
+ elsif Dir.exist?( arg )
205
+ recs << { 'path' => arg,
206
+ 'datafiles' => _find( arg ) }
207
+ elsif File.file?( arg ) ## assume it's a file
208
+ ## make sure path exists; raise error if not
209
+ ## (auto-)expand path to normalize - yes why? why not?
210
+ more << File.expand_path( arg )
211
+ else
212
+ raise Errno::ENOENT, "No such file or directory - #{arg}"
213
+ end
214
+ end
151
215
 
152
- class PathspecReport
153
- def initialize( specs, title: )
154
- @specs = specs
155
- @title = title
216
+ if more.size > 0
217
+ recs << { 'path' => '<input>',
218
+ 'datafiles' => more }
219
+ end
156
220
  end
157
221
 
158
- def build
159
- buf = String.new
160
- buf << "# #{@title} - #{@specs.size} dataset(s)\n\n"
161
-
162
- @specs.each_with_index do |rec,i|
163
- datafiles = rec['datafiles']
164
- errors = rec['errors']
165
-
166
- if errors.size > 0
167
- buf << "!! #{errors.size} ERROR(S) "
168
- else
169
- buf << " OK "
170
- end
171
- buf << "%-20s" % rec['path']
172
- buf << " - #{datafiles.size} datafile(s)"
173
- buf << "\n"
174
-
175
- if errors.size > 0
176
- buf << errors.pretty_inspect
177
- buf << "\n"
178
- end
179
- end
180
-
181
- buf
182
- end # method build
183
- end # class BatchReport
184
-
185
- BatchReport = PathspecReport
222
+ recs
223
+ end
186
224
 
225
+ end # class Pathspec
187
226
  end # module Sportdb
188
227
 
189
228
 
190
229
 
230
+
191
231
  ##
192
232
  ## keep helpers as global functions - why? why not?
193
233
 
194
234
 
195
-
196
- def build_pathspecs( args ) ### note: was expand_args
197
- specs = []
198
-
199
- ## note - collect all "loose/standalone" files (NOT directories)
200
- ## in single default pathspec node
201
- more = []
202
-
203
- args.each do |arg|
204
- ## check if directory
205
- if Dir.exist?( arg )
206
- datafiles = SportDb::Pathspec._find( arg )
207
- specs << { 'path' => arg,
208
- 'datafiles' => datafiles }
209
- elsif File.file?( arg ) ## assume it's a file
210
- ## make sure path exists; raise error if not
211
- ## (auto-)expand path to normalize - why? why not?
212
- more << arg
213
- else
214
- raise Errno::ENOENT, "No such file or directory - #{arg}"
215
- end
216
- end
217
-
218
- if more.size > 0
219
- specs << { 'path' => '<input>',
220
- 'datafiles' => more }
221
- end
222
-
223
- specs
235
+ ## build pathspecs via arguments
236
+ ## - (i) every dir is a pathspec entry/record
237
+ ## - (ii) all files get bundled together into <input> pathspec entry/record
238
+ ##
239
+ ## note: was formerly known as expand_args
240
+ def build_pathspecs( args, filepack: nil )
241
+ SportDb::Pathspec.build( args, filepack: filepack )
224
242
  end
225
243
 
226
-
227
-
244
+ ####
245
+ ## read pathspecs via csv file (using path column)
228
246
  def read_pathspecs( src )
229
247
  SportDb::Pathspec.read( src )
230
248
  end
@@ -0,0 +1,42 @@
1
+ module SportDb
2
+
3
+ ##
4
+ # PathspecReport (aka/formerly BatchReport)
5
+
6
+ class PathspecReport
7
+ def initialize( specs, title: )
8
+ @specs = specs
9
+ @title = title
10
+ end
11
+
12
+ def build
13
+ buf = String.new
14
+ buf << "# #{@title} - #{@specs.size} dataset(s)\n\n"
15
+
16
+ @specs.each_with_index do |rec,i|
17
+ datafiles = rec['datafiles']
18
+ errors = rec['errors']
19
+
20
+ if errors.size > 0
21
+ buf << "!! #{errors.size} ERROR(S) "
22
+ else
23
+ buf << " OK "
24
+ end
25
+ buf << "%-20s" % rec['path']
26
+ buf << " - #{datafiles.size} datafile(s)"
27
+ buf << "\n"
28
+
29
+ if errors.size > 0
30
+ buf << errors.pretty_inspect
31
+ buf << "\n"
32
+ end
33
+ end
34
+
35
+ buf
36
+ end # method build
37
+ end # class BatchReport
38
+
39
+ BatchReport = PathspecReport
40
+
41
+
42
+ end # module Sportdb
data/lib/fbtok.rb CHANGED
@@ -3,8 +3,9 @@ require 'sportdb/quick'
3
3
 
4
4
 
5
5
  ## our own code
6
+ require_relative 'fbtok/filepack'
6
7
  require_relative 'fbtok/pathspec'
7
-
8
+ require_relative 'fbtok/pathspec_report'
8
9
 
9
10
  require_relative 'fbtok/fbtok'
10
11
  require_relative 'fbtok/fbtree'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fbtok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-26 00:00:00.000000000 Z
11
+ date: 2026-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.1
19
+ version: 0.7.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.7.1
26
+ version: 0.7.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sportdb-quick
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,7 +100,9 @@ files:
100
100
  - lib/fbtok/fbtok.rb
101
101
  - lib/fbtok/fbtree.rb
102
102
  - lib/fbtok/fbx.rb
103
+ - lib/fbtok/filepack.rb
103
104
  - lib/fbtok/pathspec.rb
105
+ - lib/fbtok/pathspec_report.rb
104
106
  homepage: https://github.com/sportdb/footty
105
107
  licenses:
106
108
  - Public Domain