fbtok 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (10) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/Rakefile +1 -1
  4. data/bin/fbchk +42 -62
  5. data/bin/fbt +37 -59
  6. data/bin/fbtok +30 -55
  7. data/bin/fbtree +65 -17
  8. data/bin/fbx +11 -12
  9. data/lib/fbtok/opts.rb +102 -23
  10. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0cf5b4c14ed4e4466a769b2389e9aaf2add0fe631034010778cfc9a7671d088
4
- data.tar.gz: 311e35505a4ec9b729784e4adf415888e64a855fda4a2bed3ab971a51c8ebb40
3
+ metadata.gz: db7e5c105200820cbce7e9701ed2b8ce0506e366f4215a013288b66b625528ff
4
+ data.tar.gz: 3f02e52b461d14d014a3a4c3283dd452f0ca6316048969b5cf0af1cd4bd457b8
5
5
  SHA512:
6
- metadata.gz: d9d1a0b0b736368613f2cae07c69ecc9fec2ca41e3b40a77471e3790ce585a4a4fb5a4559c8005deb59dee2e56fa3f489c2025033b8281910ffec8e77ad94356
7
- data.tar.gz: 692715563a64d828eea4bbef1528721773dea1b7c7f4a2103079a804991fcc683ae6afff9aa76dfbf116b5050a77771c85c2ae11f5c950b402391f2eec077d5b
6
+ metadata.gz: e8c77935b70909ac04697276af902f0597f6eed411b8bddee77248a0145c1fb704eb58a59cd49744ac7e93da97fa5410ca5a35825ea3ec4ca0ea4f834d30543f
7
+ data.tar.gz: 35ef329be9dddaaf94658252e9e2684b4f3f63a89da8484db3507ab36f8afefc319d2ab4f3154389539a7ad6545779dd39e710f0eb7e82990988690cea107458
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.2.3
1
+ ### 0.3.0
2
2
  ### 0.0.1 / 2025-01-02
3
3
 
4
4
  * Everything is new. First release.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'hoe'
2
2
 
3
3
 
4
4
  Hoe.spec 'fbtok' do
5
- self.version = '0.2.3'
5
+ self.version = '0.3.0'
6
6
 
7
7
  self.summary = "fbtok - football.txt lint tools incl. tokenizer, parser & more"
8
8
  self.description = summary
data/bin/fbchk CHANGED
@@ -59,52 +59,51 @@ end
59
59
  parser.parse!( args )
60
60
 
61
61
 
62
- puts "OPTS:"
63
- p opts
64
- puts "ARGV:"
65
- p args
66
-
67
-
68
- ## todo/check - use packs or projects or such
69
- ## instead of specs - why? why not?
70
- specs = []
71
- if opts[:file]
72
- recs = read_csv( opts[:file] )
73
- pp recs
74
- ## note - make pathspecs relative to passed in file arg!!!
75
- basedir = File.dirname( opts[:file] )
76
- recs.each do |rec|
77
- paths = SportDb::Parser::Opts.find( rec['path'], dir: basedir )
78
- specs << [paths, rec]
79
- end
80
- else
81
- paths = if args.empty?
82
- []
83
- else
84
- ## check for directories
85
- ## and auto-expand
86
- SportDb::Parser::Opts.expand_args( args )
87
- end
88
- specs << [paths, {}]
89
- end
90
-
91
-
92
62
  if opts[:debug]
93
- SportDb::QuickMatchLinter.debug = true
94
- SportDb::QuickMatchReader.debug = true
95
- SportDb::MatchParser.debug = true
63
+ puts "OPTS:"
64
+ p opts
65
+ puts "ARGV:"
66
+ p args
67
+
68
+ SportDb::QuickMatchLinter.debug = true
69
+ SportDb::QuickMatchReader.debug = true
70
+ SportDb::MatchParser.debug = true
96
71
  else
97
- SportDb::QuickMatchLinter.debug = false
98
- SportDb::QuickMatchReader.debug = false
99
- SportDb::MatchParser.debug = false
100
- LogUtils::Logger.root.level = :info
72
+ SportDb::QuickMatchLinter.debug = false
73
+ SportDb::QuickMatchReader.debug = false
74
+ SportDb::MatchParser.debug = false
75
+ LogUtils::Logger.root.level = :info
101
76
  end
102
77
 
103
78
 
104
- specs.each_with_index do |(paths, rec),i|
79
+
80
+
81
+ ## todo/check - use packs or projects or such
82
+ ## instead of specs - why? why not?
83
+ specs = if opts[:file]
84
+ SportDb::Parser::Opts.read_pathspecs( opts[:file] )
85
+ else
86
+ paths = if args.empty?
87
+ []
88
+ else
89
+ ## check for directories
90
+ ## and auto-expand
91
+ SportDb::Parser::Opts.expand_args( args )
92
+ end
93
+ ## always return array of specs
94
+ [SportDb::Parser::Opts.build_pathspec( paths: paths)]
95
+ end
96
+
97
+
98
+
99
+
100
+ specs.each_with_index do |spec,i|
101
+ paths = spec.paths
102
+ rec = spec.rec
103
+
105
104
  errors = []
106
105
  paths.each_with_index do |path,j|
107
- puts "==> [#{j+1}/#{paths.size}] reading >#{path}<..."
106
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{paths.size}] reading >#{path}<..."
108
107
  quick = SportDb::QuickMatchLinter.new( read_text( path ),
109
108
  check_teams: opts[:teams] )
110
109
  matches = quick.parse
@@ -140,28 +139,9 @@ end
140
139
  ###
141
140
  ## generate a report if --file option used
142
141
  if opts[:file]
143
-
144
- buf = String.new
145
-
146
- buf << "# fbchk summary report - #{specs.size} dataset(s)\n\n"
147
-
148
- specs.each_with_index do |(paths, rec),i|
149
- errors = rec['errors']
150
-
151
- if errors.size > 0
152
- buf << "!! #{errors.size} ERROR(S) "
153
- else
154
- buf << " OK "
155
- end
156
- buf << "%-20s" % rec['path']
157
- buf << " - #{paths.size} datafile(s)"
158
- buf << "\n"
159
-
160
- if errors.size > 0
161
- buf << errors.pretty_inspect
162
- buf << "\n"
163
- end
164
- end
142
+ buf = SportDb::Parser::BatchReport.new(
143
+ specs,
144
+ title: 'fbchk summary report' ).build
165
145
 
166
146
  puts
167
147
  puts "SUMMARY:"
@@ -169,7 +149,7 @@ if opts[:file]
169
149
 
170
150
  basedir = File.dirname( opts[:file] )
171
151
  basename = File.basename( opts[:file], File.extname( opts[:file] ))
172
- outpath = "#{basedir}/fbcheck.#{basename}.txt"
152
+ outpath = "#{basedir}/fbchk.#{basename}.txt"
173
153
  write_text( outpath, buf )
174
154
  end
175
155
 
data/bin/fbt CHANGED
@@ -50,51 +50,47 @@ require 'fbtok'
50
50
  end
51
51
  parser.parse!( args )
52
52
 
53
- puts "OPTS:"
54
- p opts
55
- puts "ARGV:"
56
- p args
57
-
58
-
59
- ## todo/check - use packs or projects or such
60
- ## instead of specs - why? why not?
61
- specs = []
62
- if opts[:file]
63
- recs = read_csv( opts[:file] )
64
- pp recs
65
- ## note - make pathspecs relative to passed in file arg!!!
66
- basedir = File.dirname( opts[:file] )
67
- recs.each do |rec|
68
- paths = SportDb::Parser::Opts.find( rec['path'], dir: basedir )
69
- specs << [paths, rec]
70
- end
71
- else
72
- paths = if args.empty?
73
- [
74
- '../../../openfootball/euro/2021--europe/euro.txt',
75
- '../../../openfootball/euro/2024--germany/euro.txt',
76
- ]
77
- else
78
- ## check for directories
79
- ## and auto-expand
80
- SportDb::Parser::Opts.expand_args( args )
81
- end
82
- specs << [paths, {}]
83
- end
84
53
 
85
54
 
86
55
  if opts[:debug]
87
- SportDb::QuickMatchReader.debug = true
88
- SportDb::MatchParser.debug = true
56
+ puts "OPTS:"
57
+ p opts
58
+ puts "ARGV:"
59
+ p args
60
+
61
+ SportDb::QuickMatchReader.debug = true
62
+ SportDb::MatchParser.debug = true
89
63
  else
90
- SportDb::QuickMatchReader.debug = false
91
- SportDb::MatchParser.debug = false
92
- LogUtils::Logger.root.level = :info
64
+ SportDb::QuickMatchReader.debug = false
65
+ SportDb::MatchParser.debug = false
66
+ LogUtils::Logger.root.level = :info
93
67
  end
94
68
 
95
69
 
96
- specs.each_with_index do |(paths, rec),i|
70
+ ## todo/check - use packs or projects or such
71
+ ## instead of specs - why? why not?
72
+ specs = if opts[:file]
73
+ SportDb::Parser::Opts.read_pathspecs( opts[:file] )
74
+ else
75
+ paths = if args.empty?
76
+ ['/sports/openfootball/euro/2021--europe/euro.txt',
77
+ '/sports/openfootball/euro/2024--germany/euro.txt']
78
+ else
79
+ ## check for directories
80
+ ## and auto-expand
81
+ SportDb::Parser::Opts.expand_args( args )
82
+ end
83
+ ## always return array of specs
84
+ [SportDb::Parser::Opts.build_pathspec( paths: paths)]
85
+ end
86
+
87
+
88
+
89
+ specs.each_with_index do |spec,i|
90
+ paths = spec.paths
91
+ rec = spec.rec
97
92
  errors = []
93
+
98
94
  paths.each_with_index do |path,j|
99
95
  puts "==> [#{j+1}/#{paths.size}] reading >#{path}<..."
100
96
  quick = SportDb::QuickMatchReader.new( read_text( path ) )
@@ -130,28 +126,9 @@ end
130
126
  ###
131
127
  ## generate a report if --file option used
132
128
  if opts[:file]
133
-
134
- buf = String.new
135
-
136
- buf << "# fbt summary report - #{specs.size} dataset(s)\n\n"
137
-
138
- specs.each_with_index do |(paths, rec),i|
139
- errors = rec['errors']
140
-
141
- if errors.size > 0
142
- buf << "!! #{errors.size} ERROR(S) "
143
- else
144
- buf << " OK "
145
- end
146
- buf << "%-20s" % rec['path']
147
- buf << " - #{paths.size} datafile(s)"
148
- buf << "\n"
149
-
150
- if errors.size > 0
151
- buf << errors.pretty_inspect
152
- buf << "\n"
153
- end
154
- end
129
+ buf = SportDb::Parser::BatchReport.new(
130
+ specs,
131
+ title: 'fbt summary report' ).build
155
132
 
156
133
  puts
157
134
  puts "SUMMARY:"
@@ -163,5 +140,6 @@ if opts[:file]
163
140
  end
164
141
 
165
142
 
143
+
166
144
  puts "bye"
167
145
 
data/bin/fbtok CHANGED
@@ -57,43 +57,36 @@ if opts[:debug]
57
57
  end
58
58
 
59
59
 
60
+
60
61
  ## todo/check - use packs or projects or such
61
62
  ## instead of specs - why? why not?
62
- specs = []
63
- if opts[:file]
64
- recs = read_csv( opts[:file] )
65
- pp recs if opts[:debug]
66
-
67
- ## note - make pathspecs relative to passed in file arg!!!
68
- basedir = File.dirname( opts[:file] )
69
- recs.each do |rec|
70
- paths = SportDb::Parser::Opts.find( rec['path'], dir: basedir )
71
- specs << [paths, rec]
72
- end
73
- else
74
- paths = if args.empty?
75
- [
76
- '/sports/openfootball/euro/2021--europe/euro.txt',
77
- '/sports/openfootball/euro/2024--germany/euro.txt',
78
- ]
79
- else
80
- ## check for directories
81
- ## and auto-expand
82
- SportDb::Parser::Opts.expand_args( args )
83
- end
84
- specs << [paths, {}]
85
- end
86
-
63
+ specs = if opts[:file]
64
+ SportDb::Parser::Opts.read_pathspecs( opts[:file] )
65
+ else
66
+ paths = if args.empty?
67
+ ['/sports/openfootball/euro/2021--europe/euro.txt',
68
+ '/sports/openfootball/euro/2024--germany/euro.txt']
69
+ else
70
+ ## check for directories
71
+ ## and auto-expand
72
+ SportDb::Parser::Opts.expand_args( args )
73
+ end
74
+ ## always return array of specs
75
+ [SportDb::Parser::Opts.build_pathspec( paths: paths)]
76
+ end
87
77
 
88
78
 
89
79
  linter = SportDb::Parser::Linter.new
90
80
 
91
81
 
92
- specs.each_with_index do |(paths, rec),i|
93
- errors = []
82
+ specs.each_with_index do |spec,i|
83
+ paths = spec.paths
84
+ rec = spec.rec
85
+
86
+ errors = []
94
87
 
95
88
  paths.each_with_index do |path,j|
96
- puts "==> [#{j+1}/#{paths.size}] reading >#{path}<..."
89
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{paths.size}] reading >#{path}<..."
97
90
  linter.read( path, parse: false ) ## only tokenize (do NOT parse)
98
91
 
99
92
  errors += linter.errors if linter.errors?
@@ -119,35 +112,17 @@ end
119
112
  ## generate a report if --file option used
120
113
  if opts[:file]
121
114
 
122
- buf = String.new
123
-
124
- buf << "# fbtok summary report - #{specs.size} dataset(s)\n\n"
125
-
126
- specs.each_with_index do |(paths, rec),i|
127
- errors = rec['errors']
128
-
129
- if errors.size > 0
130
- buf << "!! #{errors.size} ERROR(S) "
131
- else
132
- buf << " OK "
133
- end
134
- buf << "%-20s" % rec['path']
135
- buf << " - #{paths.size} datafile(s)"
136
- buf << "\n"
137
-
138
- if errors.size > 0
139
- buf << errors.pretty_inspect
140
- buf << "\n"
141
- end
142
- end
115
+ buf = SportDb::Parser::BatchReport.new(
116
+ specs,
117
+ title: 'fbtok summary report' ).build
143
118
 
144
- puts
145
- puts "SUMMARY:"
146
- puts buf
119
+ puts
120
+ puts "SUMMARY:"
121
+ puts buf
147
122
 
148
- # maybe write out in the future?
149
- # basedir = File.dirname( opts[:file] )
150
- # basename = File.basename( opts[:file], File.extname( opts[:file] ))
123
+ # maybe write out in the future?
124
+ # basedir = File.dirname( opts[:file] )
125
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
151
126
  end
152
127
 
153
128
  puts "bye"
data/bin/fbtree CHANGED
@@ -10,6 +10,7 @@ args = ARGV
10
10
 
11
11
  opts = {
12
12
  debug: true,
13
+ file: nil,
13
14
  }
14
15
 
15
16
  parser = OptionParser.new do |parser|
@@ -24,6 +25,14 @@ parser = OptionParser.new do |parser|
24
25
  "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
25
26
  opts[:debug] = true
26
27
  end
28
+
29
+ parser.on( "-f FILE", "--file FILE",
30
+ "read datafiles (pathspecs) via .csv file") do |file|
31
+ opts[:file] = file
32
+ ## note: for batch (massive) processing auto-set debug (verbose output) to false (as default)
33
+ opts[:debug] = false
34
+ end
35
+
27
36
  end
28
37
  parser.parse!( args )
29
38
 
@@ -44,16 +53,20 @@ end
44
53
 
45
54
  ## todo/check - use packs or projects or such
46
55
  ## instead of specs - why? why not?
47
- paths = if args.empty?
48
- [
49
- '/sports/openfootball/euro/2021--europe/euro.txt',
50
- '/sports/openfootball/euro/2024--germany/euro.txt',
51
- ]
52
- else
53
- ## check for directories
54
- ## and auto-expand
55
- SportDb::Parser::Opts.expand_args( args )
56
- end
56
+ specs = if opts[:file]
57
+ SportDb::Parser::Opts.read_pathspecs( opts[:file] )
58
+ else
59
+ paths = if args.empty?
60
+ ['/sports/openfootball/euro/2021--europe/euro.txt',
61
+ '/sports/openfootball/euro/2024--germany/euro.txt']
62
+ else
63
+ ## check for directories
64
+ ## and auto-expand
65
+ SportDb::Parser::Opts.expand_args( args )
66
+ end
67
+ ## always return array of specs
68
+ [SportDb::Parser::Opts.build_pathspec( paths: paths)]
69
+ end
57
70
 
58
71
 
59
72
 
@@ -78,16 +91,51 @@ end
78
91
  linter = SportDb::Parser::Linter.new
79
92
 
80
93
 
81
- paths.each_with_index do |path,i|
82
-
83
- puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
94
+ specs.each_with_index do |spec,i|
95
+ paths = spec.paths
96
+ rec = spec.rec
97
+
98
+ errors = []
99
+
100
+ paths.each_with_index do |path,j|
101
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{paths.size}] reading >#{path}<..."
102
+ tree = linter.read( path, parse: true )
103
+ dump_tree_stats( tree )
104
+
105
+ errors += linter.errors if linter.errors?
106
+ end
107
+
108
+ if errors.size > 0
109
+ puts
110
+ pp errors
111
+ puts
112
+ puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
113
+ else
114
+ puts
115
+ puts "OK no parse errors found in #{paths.size} datafile(s)"
116
+ end
117
+
118
+ ## add errors to rec via rec['errors'] to allow
119
+ ## for further processing/reporting
120
+ rec['errors'] = errors
121
+ end
84
122
 
85
- tree = linter.read( path, parse: true )
86
123
 
87
- dump_tree_stats( tree )
88
- end
124
+ ###
125
+ ## generate a report if --file option used
126
+ if opts[:file]
89
127
 
128
+ buf = SportDb::Parser::BatchReport.new(
129
+ specs,
130
+ title: 'fbtree summary report' ).build
90
131
 
91
- puts "bye"
132
+ puts
133
+ puts "SUMMARY:"
134
+ puts buf
92
135
 
136
+ # maybe write out in the future?
137
+ # basedir = File.dirname( opts[:file] )
138
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
139
+ end
93
140
 
141
+ puts "bye"
data/bin/fbx CHANGED
@@ -47,13 +47,18 @@ require 'fbtok'
47
47
  end
48
48
  parser.parse!( args )
49
49
 
50
- puts "OPTS:"
51
- p opts
52
- puts "ARGV:"
53
- p args
54
-
55
-
56
50
 
51
+ if opts[:debug]
52
+ puts "OPTS:"
53
+ p opts
54
+ puts "ARGV:"
55
+ p args
56
+
57
+ SportDb::MatchParser.debug = true
58
+ else
59
+ SportDb::MatchParser.debug = false
60
+ LogUtils::Logger.root.level = :info
61
+ end
57
62
 
58
63
 
59
64
  paths = if args.empty?
@@ -70,12 +75,6 @@ paths = if args.empty?
70
75
 
71
76
 
72
77
 
73
- if opts[:debug]
74
- SportDb::MatchParser.debug = true
75
- else
76
- SportDb::MatchParser.debug = false
77
- LogUtils::Logger.root.level = :info
78
- end
79
78
 
80
79
  ## errors = []
81
80
 
data/lib/fbtok/opts.rb CHANGED
@@ -31,7 +31,9 @@ class Opts
31
31
  }x
32
32
 
33
33
 
34
- def self.find( path, dir: nil )
34
+
35
+
36
+ def self._find( path )
35
37
  ## check - rename dir
36
38
  ## use root_dir or work_dir or cd or such - why? why not?
37
39
 
@@ -40,11 +42,8 @@ def self.find( path, dir: nil )
40
42
  ## note: normalize path - use File.expand_path ??
41
43
  ## change all backslash to slash for now
42
44
  ## path = path.gsub( "\\", '/' )
43
- path = if dir
44
- File.expand_path( path, File.expand_path( dir ))
45
- else
46
- File.expand_path( path )
47
- end
45
+ path = File.expand_path( path )
46
+
48
47
 
49
48
  ## check all txt files
50
49
  ## note: incl. files starting with dot (.)) as candidates
@@ -60,29 +59,109 @@ def self.find( path, dir: nil )
60
59
  end
61
60
 
62
61
 
63
- def self.expand_args( args )
64
- paths = []
65
-
66
- args.each do |arg|
67
- ## check if directory
68
- if Dir.exist?( arg )
69
- datafiles = find( arg )
70
- if debug?
71
- puts
72
- puts " found #{datafiles.size} match txt datafiles in #{arg}"
73
- pp datafiles
74
- end
75
- paths += datafiles
76
- else
77
- ## assume it's a file
78
- paths << arg
62
+ def self._expand( arg )
63
+ ## check if directory
64
+ if Dir.exist?( arg )
65
+ datafiles = _find( arg )
66
+ if debug?
67
+ puts
68
+ puts " found #{datafiles.size} match txt datafiles in #{arg}"
69
+ pp datafiles
70
+ end
71
+ datafiles
72
+ else ## assume it's a file
73
+ ## make sure path exists; raise error if not
74
+ if File.exist?( arg )
75
+ [arg] ## note - always return an array - why? why not?
76
+ else
77
+ raise Errno::ENOENT, "No such file or directory - #{arg}"
79
78
  end
80
79
  end
80
+ end
81
+
82
+
83
+ def self.expand_args( args )
84
+ paths = []
85
+ args.each do |arg|
86
+ paths += _expand( arg )
87
+ end
88
+ paths
89
+ end
90
+
81
91
 
82
- paths
92
+
93
+ ## todo/check - find a better name
94
+ ## e.g. BatchItem or PackageDef or ???
95
+ ##
96
+ ## find a different name for rec for named value props?
97
+ ## why? why not?
98
+ PathspecNode = Struct.new( :paths, :rec )
99
+
100
+ def self.build_pathspec( paths: )
101
+ PathspecNode.new( paths: paths, rec: {} )
102
+ end
103
+
104
+ def self.read_pathspecs( src )
105
+ specs = []
106
+
107
+ recs = read_csv( src )
108
+ pp recs if debug?
109
+
110
+ ## note - make pathspecs relative to passed in file arg!!!
111
+ basedir = File.dirname( src )
112
+ recs.each do |rec|
113
+ path = rec['path']
114
+ fullpath = File.expand_path( path, basedir )
115
+ ## make sure path exists; raise error if not
116
+ paths = if Dir.exist?( fullpath )
117
+ _find( fullpath )
118
+ else
119
+ raise Errno::ENOENT, "No such directory - #{fullpath})"
120
+ end
121
+
122
+ specs << PathspecNode.new( paths: paths, rec: rec )
123
+ end
124
+ specs
83
125
  end
84
126
  end # class Opts
85
127
 
86
128
 
129
+ ##
130
+ # BatchReport (a.k.a. PathspecsReport)
131
+
132
+ class BatchReport
133
+
134
+ def initialize( specs, title: )
135
+ @specs = specs
136
+ @title = title
137
+ end
138
+
139
+ def build
140
+ buf = String.new
141
+ buf << "# #{@title} - #{@specs.size} dataset(s)\n\n"
142
+
143
+ @specs.each_with_index do |spec,i|
144
+ paths = spec.paths
145
+ rec = spec.rec
146
+ errors = rec['errors']
147
+
148
+ if errors.size > 0
149
+ buf << "!! #{errors.size} ERROR(S) "
150
+ else
151
+ buf << " OK "
152
+ end
153
+ buf << "%-20s" % rec['path']
154
+ buf << " - #{paths.size} datafile(s)"
155
+ buf << "\n"
156
+
157
+ if errors.size > 0
158
+ buf << errors.pretty_inspect
159
+ buf << "\n"
160
+ end
161
+ end
162
+
163
+ buf
164
+ end # method build
165
+ end # class BatchReport
87
166
  end # class Parser
88
167
  end # module SportDb
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.2.3
4
+ version: 0.3.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: 2025-01-22 00:00:00.000000000 Z
11
+ date: 2025-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-parser