fbtok 0.4.2 → 0.5.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 +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +2 -0
- data/Rakefile +2 -2
- data/lib/fbtok/fbquick.rb +22 -4
- data/lib/fbtok/fbtok.rb +31 -11
- data/lib/fbtok/fbtree.rb +42 -13
- data/lib/fbtok/fbx.rb +2 -2
- data/lib/fbtok/filepack.rb +63 -0
- data/lib/fbtok/pathspec.rb +129 -107
- data/lib/fbtok/pathspec_report.rb +42 -0
- data/lib/fbtok.rb +2 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6bb0384d86033771326222bc9284264b9bfc44c55210261e6b598fffb3ddf925
|
|
4
|
+
data.tar.gz: a7692e7b0f394373c364234ec7b7c57933d6bd1344b58d4139beb41381a59921
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 854430fe426e69eb27651930db928cb24bf7f4b489503a222f7ff67178fb087b465718e71cc4a9421a591ab87c784e35f2a26514c99de9151ddb9a1a13c4ec53
|
|
7
|
+
data.tar.gz: e602fe075cfbd20eeed1e744f4bdfa35314f2e42db69537cb8ff14ccc87b8fed50400d5f3aa53974e342a0b09c00b7110e0614e0d06ede5595c19e6e652de63d
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
|
@@ -2,7 +2,7 @@ require 'hoe'
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
Hoe.spec 'fbtok' do
|
|
5
|
-
self.version = '0.
|
|
5
|
+
self.version = '0.5.1'
|
|
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.
|
|
22
|
+
['sportdb-parser', '>= 0.7.2'],
|
|
23
23
|
['sportdb-quick', '>= 0.7.0'],
|
|
24
24
|
]
|
|
25
25
|
|
data/lib/fbtok/fbquick.rb
CHANGED
|
@@ -54,10 +54,27 @@ end
|
|
|
54
54
|
specs = if opts[:file]
|
|
55
55
|
read_pathspecs( opts[:file] )
|
|
56
56
|
else
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
+
path = SportDb::Pathspec.path(
|
|
71
|
+
['/sports/sportdb/sport.db.v2/parser/fbtxt-specs',
|
|
72
|
+
'/sports/sportdb/sport.db.v2/parser/fbtxt-samples',
|
|
73
|
+
'/sports/openfootball'])
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
build_pathspecs( args, path: path,
|
|
77
|
+
filepack: filepack )
|
|
61
78
|
end
|
|
62
79
|
|
|
63
80
|
pp specs
|
|
@@ -91,6 +108,7 @@ pp specs
|
|
|
91
108
|
pp errors
|
|
92
109
|
else
|
|
93
110
|
puts
|
|
111
|
+
pp datafiles
|
|
94
112
|
puts " OK - no parse errors in #{datafiles.size} datafile(s)"
|
|
95
113
|
end
|
|
96
114
|
|
data/lib/fbtok/fbtok.rb
CHANGED
|
@@ -6,8 +6,8 @@ def self.main( args=ARGV )
|
|
|
6
6
|
|
|
7
7
|
opts = {
|
|
8
8
|
debug: true,
|
|
9
|
-
warn: false,
|
|
10
9
|
file: nil,
|
|
10
|
+
# warn: false,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
|
|
@@ -23,10 +23,10 @@ parser = OptionParser.new do |parser|
|
|
|
23
23
|
"turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
|
|
24
24
|
opts[:debug] = true
|
|
25
25
|
end
|
|
26
|
-
parser.on( "-w", "--warn",
|
|
27
|
-
"turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
|
|
28
|
-
opts[:warn] = true
|
|
29
|
-
end
|
|
26
|
+
# parser.on( "-w", "--warn",
|
|
27
|
+
# "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
|
|
28
|
+
# opts[:warn] = true
|
|
29
|
+
# end
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
parser.on( "-f FILE", "--file FILE",
|
|
@@ -58,10 +58,20 @@ end
|
|
|
58
58
|
specs = if opts[:file]
|
|
59
59
|
read_pathspecs( opts[:file] )
|
|
60
60
|
else
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
## check for filepack
|
|
62
|
+
filepack = if File.file?( './filepack.txt')
|
|
63
|
+
read_filepack( './filepack.txt' )
|
|
64
|
+
else
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
path = SportDb::Pathspec.path(
|
|
69
|
+
['/sports/sportdb/sport.db.v2/parser/fbtxt-specs',
|
|
70
|
+
'/sports/sportdb/sport.db.v2/parser/fbtxt-samples',
|
|
71
|
+
'/sports/openfootball'])
|
|
72
|
+
|
|
73
|
+
build_pathspecs( args, path: path,
|
|
74
|
+
filepack: filepack )
|
|
65
75
|
end
|
|
66
76
|
|
|
67
77
|
|
|
@@ -82,11 +92,20 @@ specs.each_with_index do |rec,i|
|
|
|
82
92
|
tokens, more_errors = lexer.tokenize_with_errors
|
|
83
93
|
|
|
84
94
|
####
|
|
85
|
-
## todo - report error on empty file (no tokens!!!)
|
|
95
|
+
## todo - report error on empty file (no tokens!!!) - why? why not?
|
|
86
96
|
|
|
87
97
|
puts " #{tokens.size} token(s)"
|
|
88
98
|
|
|
89
|
-
|
|
99
|
+
if more_errors.size > 0
|
|
100
|
+
## note - auto-add filename to errors
|
|
101
|
+
more_errors.each do |msg|
|
|
102
|
+
###
|
|
103
|
+
### errors << [ path, *msg ] # note: use splat (*) to add extra values (starting with msg)
|
|
104
|
+
errors << [path, msg]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
|
|
90
109
|
end
|
|
91
110
|
|
|
92
111
|
if errors.size > 0
|
|
@@ -96,6 +115,7 @@ specs.each_with_index do |rec,i|
|
|
|
96
115
|
puts "!! #{errors.size} tokenize error(s) in #{datafiles.size} datafiles(s)"
|
|
97
116
|
else
|
|
98
117
|
puts
|
|
118
|
+
pp datafiles
|
|
99
119
|
puts "OK no tokenize errors found in #{datafiles.size} datafile(s)"
|
|
100
120
|
end
|
|
101
121
|
|
data/lib/fbtok/fbtree.rb
CHANGED
|
@@ -6,8 +6,8 @@ def self.main( args=ARGV )
|
|
|
6
6
|
|
|
7
7
|
opts = {
|
|
8
8
|
debug: true,
|
|
9
|
-
warn: false,
|
|
10
9
|
file: nil,
|
|
10
|
+
## warn: false,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
parser = OptionParser.new do |parser|
|
|
@@ -22,10 +22,10 @@ parser = OptionParser.new do |parser|
|
|
|
22
22
|
"turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
|
|
23
23
|
opts[:debug] = true
|
|
24
24
|
end
|
|
25
|
-
parser.on( "-w", "--warn",
|
|
26
|
-
"turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
|
|
27
|
-
opts[:warn] = true
|
|
28
|
-
end
|
|
25
|
+
# parser.on( "-w", "--warn",
|
|
26
|
+
# "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
|
|
27
|
+
# opts[:warn] = true
|
|
28
|
+
# end
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
parser.on( "-f FILE", "--file FILE",
|
|
@@ -38,7 +38,6 @@ parser = OptionParser.new do |parser|
|
|
|
38
38
|
end
|
|
39
39
|
parser.parse!( args )
|
|
40
40
|
|
|
41
|
-
|
|
42
41
|
if opts[:debug]
|
|
43
42
|
puts "OPTS:"
|
|
44
43
|
p opts
|
|
@@ -47,8 +46,6 @@ if opts[:debug]
|
|
|
47
46
|
end
|
|
48
47
|
|
|
49
48
|
|
|
50
|
-
# SportDb::Parser::Linter.debug = opts[:debug]
|
|
51
|
-
# SportDb::Parser::Linter.warn = opts[:warn]
|
|
52
49
|
|
|
53
50
|
|
|
54
51
|
|
|
@@ -58,13 +55,37 @@ end
|
|
|
58
55
|
specs = if opts[:file]
|
|
59
56
|
read_pathspecs( opts[:file] )
|
|
60
57
|
else
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
## check for filepack
|
|
59
|
+
filepack = if File.file?( './filepack.txt')
|
|
60
|
+
read_filepack( './filepack.txt' )
|
|
61
|
+
else
|
|
62
|
+
nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
path = SportDb::Pathspec.path(
|
|
66
|
+
['/sports/sportdb/sport.db.v2/parser/fbtxt-specs',
|
|
67
|
+
'/sports/sportdb/sport.db.v2/parser/fbtxt-samples',
|
|
68
|
+
'/sports/openfootball'])
|
|
69
|
+
|
|
70
|
+
build_pathspecs( args, path: path,
|
|
71
|
+
filepack: filepack )
|
|
65
72
|
end
|
|
66
73
|
|
|
67
74
|
|
|
75
|
+
pp specs
|
|
76
|
+
|
|
77
|
+
## if more than single datafile
|
|
78
|
+
## auto-switch into quite mode for now
|
|
79
|
+
## if specs.size > 0 && specs[0]['datafiles'].size > 1
|
|
80
|
+
## opts[:debug] = false
|
|
81
|
+
## end
|
|
82
|
+
|
|
83
|
+
# SportDb::Parser::Linter.debug = opts[:debug]
|
|
84
|
+
# SportDb::Parser::Linter.warn = opts[:warn]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
68
89
|
|
|
69
90
|
|
|
70
91
|
specs.each_with_index do |rec,i|
|
|
@@ -81,7 +102,14 @@ specs.each_with_index do |rec,i|
|
|
|
81
102
|
|
|
82
103
|
dump_tree_stats( tree )
|
|
83
104
|
|
|
84
|
-
|
|
105
|
+
if parser.errors?
|
|
106
|
+
## note - auto-add filename to errors
|
|
107
|
+
parser.errors.each do |msg|
|
|
108
|
+
###
|
|
109
|
+
### errors << [ path, *msg ] # note: use splat (*) to add extra values (starting with msg)
|
|
110
|
+
errors << [path, msg]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
85
113
|
end
|
|
86
114
|
|
|
87
115
|
|
|
@@ -92,6 +120,7 @@ specs.each_with_index do |rec,i|
|
|
|
92
120
|
puts "!! #{errors.size} parse error(s) in #{datafiles.size} datafiles(s)"
|
|
93
121
|
else
|
|
94
122
|
puts
|
|
123
|
+
pp datafiles
|
|
95
124
|
puts "OK no parse errors found in #{datafiles.size} datafile(s)"
|
|
96
125
|
end
|
|
97
126
|
|
data/lib/fbtok/fbx.rb
CHANGED
|
@@ -54,8 +54,8 @@ end
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
args = [
|
|
57
|
-
'
|
|
58
|
-
'
|
|
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
|
data/lib/fbtok/pathspec.rb
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
module SportDb
|
|
4
|
-
|
|
5
4
|
class Pathspec
|
|
6
5
|
|
|
7
|
-
def self.debug=(value) @@debug = value; end
|
|
8
|
-
def self.debug?() @@debug ||= false; end ## note: default is FALSE
|
|
9
|
-
|
|
10
|
-
|
|
11
6
|
SEASON_RE = %r{ (?:
|
|
12
7
|
(?<season>\d{4}-\d{2})
|
|
13
8
|
| (?<season>\d{4})
|
|
@@ -62,9 +57,6 @@ class Pathspec
|
|
|
62
57
|
## but starting filename e.g. 2024_friendlies.txt or 2024-25_bundesliga.txt
|
|
63
58
|
|
|
64
59
|
|
|
65
|
-
def self._norm_seasons( seasons )
|
|
66
|
-
seasons.map {|season| Season(season) }
|
|
67
|
-
end
|
|
68
60
|
|
|
69
61
|
|
|
70
62
|
## todo/check - rename to glob or expand or such - why? why not?
|
|
@@ -74,23 +66,31 @@ end
|
|
|
74
66
|
## that will use generic **/*.txt and only use ignore filter!!!
|
|
75
67
|
|
|
76
68
|
|
|
77
|
-
def self.
|
|
69
|
+
def self.find( path, seasons: nil )
|
|
70
|
+
##
|
|
71
|
+
## note - only if seasons filter is turn on
|
|
72
|
+
## MATCH_RE gets used!!!
|
|
73
|
+
## otherwise generic **/*.txt
|
|
74
|
+
##
|
|
75
|
+
## note - the ignore/exlude filter always gets used/applied for now
|
|
76
|
+
|
|
77
|
+
|
|
78
78
|
## check - rename dir
|
|
79
79
|
## use root_dir or work_dir or cd or such - why? why not?
|
|
80
80
|
|
|
81
|
-
|
|
82
81
|
## note: normalize path - use File.expand_path ??
|
|
83
82
|
## change all backslash to slash for now
|
|
84
|
-
|
|
85
|
-
path = File.expand_path( path )
|
|
83
|
+
fullpath = File.expand_path( path )
|
|
86
84
|
|
|
87
85
|
####
|
|
88
86
|
## note - make sure path exists; raise error if not
|
|
89
|
-
|
|
87
|
+
## ENOENT => Error No Entity
|
|
88
|
+
raise Errno::ENOENT, "No such directory - #{path})" unless Dir.exist?( fullpath )
|
|
90
89
|
|
|
91
90
|
|
|
92
91
|
if seasons && seasons.size > 0
|
|
93
|
-
|
|
92
|
+
## norm seasons (string, integer => Season obj)
|
|
93
|
+
seasons = seasons.map {|season| Season(season) }
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
|
|
@@ -99,41 +99,45 @@ def self._find( path, seasons: nil )
|
|
|
99
99
|
## (normally excluded with just *)
|
|
100
100
|
## was: Dir.glob( "#{path}/**/{*,.*}.txt" )
|
|
101
101
|
|
|
102
|
-
candidates = Dir.glob( "#{
|
|
102
|
+
candidates = Dir.glob( "#{fullpath}/**/*.txt" )
|
|
103
103
|
## pp candidates
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
datafiles = []
|
|
107
107
|
candidates.each do |candidate|
|
|
108
|
-
if m = MATCH_RE.match( candidate )
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
## (i) check for (optional) seasons filter
|
|
110
|
+
if seasons && seasons.size > 0
|
|
111
|
+
if m=MATCH_RE.match( candidate )
|
|
112
|
+
next unless seasons.include?( Season.parse( m[:season] ))
|
|
113
|
+
else
|
|
114
|
+
next ## note - no season found in filename; skip too
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
113
118
|
|
|
119
|
+
## (ii) check for (default/built-in) ignore/excludes
|
|
120
|
+
basename = File.basename( candidate, File.extname( candidate ))
|
|
121
|
+
dirname = File.dirname( candidate )
|
|
114
122
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
##
|
|
123
|
+
### exclude basenames with:
|
|
124
|
+
## - squad
|
|
125
|
+
## - .v2 or .v2603
|
|
118
126
|
##
|
|
119
127
|
## - worldcup/more/1930_squads.txt => squads
|
|
120
|
-
## - 2014--brazil/cup.v2.txt
|
|
121
|
-
## - 2014--brazil/cup.v260318_164934.txt
|
|
122
|
-
|
|
123
|
-
basename = File.basename( candidate, File.extname( candidate ))
|
|
128
|
+
## - 2014--brazil/cup.v2.txt
|
|
129
|
+
## - 2014--brazil/cup.v260318_164934.txt
|
|
124
130
|
|
|
125
|
-
next if /squad/i.match( basename )
|
|
126
|
-
next if /\.v[0-9][0-9_]*/i.match( basename )
|
|
131
|
+
next if /squad/i.match?( basename )
|
|
132
|
+
next if /\.v[0-9][0-9_]*/i.match?( basename )
|
|
127
133
|
|
|
128
134
|
#####
|
|
129
|
-
### exclude dirs
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
next if /squad|wiki/i.match( dirname )
|
|
135
|
+
### exclude dirs with:
|
|
136
|
+
## - squad or wiki
|
|
137
|
+
next if /squad|wiki/i.match?( dirname )
|
|
133
138
|
|
|
134
139
|
|
|
135
140
|
datafiles << candidate
|
|
136
|
-
end
|
|
137
141
|
end
|
|
138
142
|
|
|
139
143
|
## pp datafiles
|
|
@@ -141,22 +145,48 @@ def self._find( path, seasons: nil )
|
|
|
141
145
|
end
|
|
142
146
|
|
|
143
147
|
|
|
148
|
+
def self.path( default=[])
|
|
149
|
+
## check for FBPATH
|
|
150
|
+
## or FBTXT_PATH
|
|
151
|
+
path = ENV['FBPATH'] || ENV['FBTXT_PATH']
|
|
152
|
+
if path
|
|
153
|
+
path.split( /[:;]/)
|
|
154
|
+
else
|
|
155
|
+
default
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end # class Pathspec
|
|
159
|
+
|
|
160
|
+
|
|
144
161
|
|
|
145
162
|
|
|
146
163
|
|
|
164
|
+
class Pathspecs ## change to a module - why? why not?
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def self.debug=(value) @@debug = value; end
|
|
168
|
+
def self.debug?() @@debug ||= false; end ## note: default is FALSE
|
|
169
|
+
|
|
170
|
+
|
|
147
171
|
def self.read( src )
|
|
148
|
-
|
|
172
|
+
## note: normalize src - use File.expand_path ??
|
|
173
|
+
## change all backslash to slash for now (\ to /)
|
|
174
|
+
fullsrc = File.expand_path( src )
|
|
175
|
+
|
|
176
|
+
recs = read_csv( fullsrc )
|
|
149
177
|
pp recs if debug?
|
|
150
178
|
|
|
151
179
|
## note - make pathspecs relative to passed in file arg!!!
|
|
152
|
-
basedir = File.dirname(
|
|
180
|
+
basedir = File.dirname( fullsrc )
|
|
153
181
|
|
|
154
182
|
recs.each do |rec|
|
|
183
|
+
##
|
|
184
|
+
## todo/check - check for season/seasons column - why? why not?
|
|
155
185
|
path = rec['path']
|
|
156
186
|
fullpath = File.expand_path( path, basedir )
|
|
157
|
-
datafiles =
|
|
187
|
+
datafiles = Pathspec.find( fullpath )
|
|
158
188
|
|
|
159
|
-
## add (new) datafiles column (from expanded pathspec)
|
|
189
|
+
## auto-add (new) datafiles column (from expanded pathspec)
|
|
160
190
|
rec['datafiles'] = datafiles
|
|
161
191
|
end
|
|
162
192
|
|
|
@@ -165,90 +195,82 @@ end
|
|
|
165
195
|
|
|
166
196
|
|
|
167
197
|
|
|
198
|
+
def self.build( args, path: [],
|
|
199
|
+
filepack: nil )
|
|
200
|
+
recs = []
|
|
168
201
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
## check fo no args case (and filepack present with default)
|
|
203
|
+
if args.empty?
|
|
204
|
+
if filepack && filepack.has_key?('default')
|
|
205
|
+
recs << { 'path' => '<default>',
|
|
206
|
+
'datafiles' => filepack['default'] }
|
|
207
|
+
end
|
|
208
|
+
else
|
|
209
|
+
|
|
210
|
+
## note - collect all "loose/standalone" files (NOT directories)
|
|
211
|
+
## in single default pathspec node
|
|
212
|
+
more = []
|
|
213
|
+
|
|
214
|
+
args.each do |arg|
|
|
215
|
+
## note - ALWAYS give priority to existing directory matches (over filepack)
|
|
216
|
+
## e.g. euro or such - why? why not?
|
|
217
|
+
##
|
|
218
|
+
## todo/check if euro/ works too?
|
|
219
|
+
## check if directory
|
|
220
|
+
if Dir.exist?( arg )
|
|
221
|
+
recs << { 'path' => arg,
|
|
222
|
+
'datafiles' => Pathspec.find( arg ) }
|
|
223
|
+
elsif filepack && filepack.has_key?( arg.downcase )
|
|
224
|
+
recs << { 'path' => "<#{arg.downcase}>",
|
|
225
|
+
'datafiles' => filepack[arg.downcase] }
|
|
226
|
+
else ## assume it's a file
|
|
227
|
+
file = find_file( arg, path: path )
|
|
228
|
+
## check if file (exists) in any path lookup
|
|
229
|
+
if file
|
|
230
|
+
## todo/fix:
|
|
231
|
+
## add File.expand_path upstream in find_file !!!
|
|
232
|
+
## and remove later here
|
|
233
|
+
## also fix upstream Errorno::ENOENT to Errno::ENOENT !!!
|
|
234
|
+
##
|
|
235
|
+
## make sure path exists; raise error if not
|
|
236
|
+
## (auto-)expand path to normalize - yes why? why not?
|
|
237
|
+
more << File.expand_path(file)
|
|
238
|
+
else
|
|
239
|
+
raise Errno::ENOENT, "No such file or directory - #{arg}"
|
|
240
|
+
end
|
|
202
241
|
end
|
|
203
|
-
|
|
242
|
+
end
|
|
204
243
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
244
|
+
if more.size > 0
|
|
245
|
+
recs << { 'path' => '<input>',
|
|
246
|
+
'datafiles' => more }
|
|
247
|
+
end
|
|
248
|
+
end
|
|
208
249
|
|
|
209
|
-
|
|
250
|
+
recs
|
|
251
|
+
end
|
|
210
252
|
|
|
253
|
+
end # class Pathspecs
|
|
211
254
|
end # module Sportdb
|
|
212
255
|
|
|
213
256
|
|
|
214
257
|
|
|
258
|
+
|
|
215
259
|
##
|
|
216
260
|
## keep helpers as global functions - why? why not?
|
|
217
261
|
|
|
218
262
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
args.each do |arg|
|
|
228
|
-
## check if directory
|
|
229
|
-
if Dir.exist?( arg )
|
|
230
|
-
datafiles = SportDb::Pathspec._find( arg )
|
|
231
|
-
specs << { 'path' => arg,
|
|
232
|
-
'datafiles' => datafiles }
|
|
233
|
-
elsif File.file?( arg ) ## assume it's a file
|
|
234
|
-
## make sure path exists; raise error if not
|
|
235
|
-
## (auto-)expand path to normalize - why? why not?
|
|
236
|
-
more << arg
|
|
237
|
-
else
|
|
238
|
-
raise Errno::ENOENT, "No such file or directory - #{arg}"
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
if more.size > 0
|
|
243
|
-
specs << { 'path' => '<input>',
|
|
244
|
-
'datafiles' => more }
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
specs
|
|
263
|
+
## build pathspecs via arguments
|
|
264
|
+
## - (i) every dir is a pathspec entry/record
|
|
265
|
+
## - (ii) all files get bundled together into <input> pathspec entry/record
|
|
266
|
+
##
|
|
267
|
+
## note: was formerly known as expand_args
|
|
268
|
+
def build_pathspecs( args, path: [], filepack: nil )
|
|
269
|
+
SportDb::Pathspecs.build( args, path: path, filepack: filepack )
|
|
248
270
|
end
|
|
249
271
|
|
|
250
|
-
|
|
251
|
-
|
|
272
|
+
####
|
|
273
|
+
## read pathspecs via csv file (using path column)
|
|
252
274
|
def read_pathspecs( src )
|
|
253
|
-
SportDb::
|
|
275
|
+
SportDb::Pathspecs.read( src )
|
|
254
276
|
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
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
|
+
version: 0.5.1
|
|
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-
|
|
11
|
+
date: 2026-06-10 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.
|
|
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.
|
|
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
|