sid-csv 0.0.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 +7 -0
- data/README.md +34 -0
- data/bin/sid-csv +57 -0
- data/data/sid-csv.cddl +49 -0
- data/lib/sid-csv.rb +88 -0
- data/sid-csv.gemspec +16 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0930d2fcacf9e23529f172d66f4d8d3ad22b181c6a40013999278b30b2a187d1'
|
4
|
+
data.tar.gz: 1871c2534af3fd0063bfe11c779dd5b7c7dbb376007a69f34ca3d4f26dfc16b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc3972b423d25efa128695717bcf9d8d2acb8d57a3689c1bfe84f859e37da3e2c0191e3ed7d56d3495a6f7ddf5ac9881616ea61c2234c680902ccd80733f784a
|
7
|
+
data.tar.gz: '01719d214191ab4b1426a7fd1d833b3172242637a312f2a854fad5cc2975bf85db3ffb04161eed9df47b5c25ef7ed9a3b1a9ff36d25501ee049c9ecf1869161b'
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# SID CSV conversion utility
|
2
|
+
|
3
|
+
This little tool provides for conversion between [YANG-SID][core-sid]
|
4
|
+
files as used by [YANG-CBOR][RFC9254] and corresponding human-readable
|
5
|
+
CSV files.
|
6
|
+
|
7
|
+
[](http://badge.fury.io/rb/sid-csv)
|
8
|
+
|
9
|
+
[core-sid]: https://www.ietf.org/archive/id/draft-ietf-core-sid-20.html
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
`gem install sid-csv`
|
14
|
+
|
15
|
+
## Formats
|
16
|
+
|
17
|
+
sid-csv knows the following formats:
|
18
|
+
|
19
|
+
* .sid: sid file (JSON) as defined in [draft-ietf-core-sid][core-sid]
|
20
|
+
* .csv: CSV file as defined in [RFC4180][]
|
21
|
+
|
22
|
+
[RFC9254]: http://rfc-editor.org/rfc/rfc9254
|
23
|
+
[RFC8610]: http://rfc-editor.org/rfc/rfc8610
|
24
|
+
[RFC4180]: http://rfc-editor.org/rfc/rfc4180
|
25
|
+
|
26
|
+
Sources and targets are defined by `-f csv`, `-t csv` (default: `sid`).
|
27
|
+
|
28
|
+
## Command line utilities
|
29
|
+
|
30
|
+
* `sid-csv -tcsv foo.sid > foo.csv`
|
31
|
+
* `sid-csv -fcsv foo.csv > foo.sid`
|
32
|
+
|
33
|
+
Output is to stdout, input from one or more files given as command line
|
34
|
+
arguments (use `-` for standard input).
|
data/bin/sid-csv
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/sid-csv.rb'
|
3
|
+
include CSV::SID
|
4
|
+
|
5
|
+
Encoding.default_external = Encoding::UTF_8
|
6
|
+
require 'optparse'
|
7
|
+
require 'ostruct'
|
8
|
+
|
9
|
+
$options = OpenStruct.new
|
10
|
+
begin
|
11
|
+
op = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: merge-patch orig patch"
|
13
|
+
|
14
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
15
|
+
$options.verbose = v
|
16
|
+
end
|
17
|
+
opts.on("-tFMT", "--to=FMT", [:sid, :csv], "Target format") do |v|
|
18
|
+
$options.target = v
|
19
|
+
end
|
20
|
+
opts.on("-fFMT", "--from=FMT", [:sid, :csv], "Source format") do |v|
|
21
|
+
$options.source = v
|
22
|
+
end
|
23
|
+
opts.on("-c", "--[no-]cddlcheck", "Perform CDDL check") do |v|
|
24
|
+
$options.cddlcheck = v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
op.parse!
|
28
|
+
rescue Exception => e
|
29
|
+
warn e
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
|
33
|
+
if $options.cddlcheck
|
34
|
+
warn "** Can't check cddl yet."
|
35
|
+
exit 1
|
36
|
+
end
|
37
|
+
|
38
|
+
$options.target ||= :sid
|
39
|
+
$options.source ||= :sid
|
40
|
+
|
41
|
+
input = ARGF.read
|
42
|
+
|
43
|
+
case [$options.source, $options.target]
|
44
|
+
in [:sid, :csv]
|
45
|
+
sid_data = sid_data_from_file(input)
|
46
|
+
sid_csv_data = sid_csv_from_data(sid_data)
|
47
|
+
generated_csv1 = csv_generate(sid_csv_data)
|
48
|
+
puts generated_csv1
|
49
|
+
in [:csv, :sid]
|
50
|
+
converted_csv2 = CSV.parse(input, nil_value: "", converters: :integer)
|
51
|
+
# File.write("ietf-system-csv-cddl.diag", `cddl ../data/sid-csv.cddl vp ietf-system-csv-2.json`)
|
52
|
+
sid2 = sid_file_from_csv(converted_csv2)
|
53
|
+
puts JSON.pretty_generate(sid2)
|
54
|
+
in [src, trg]
|
55
|
+
warn "** Can't translate #{src} to #{trg} yet."
|
56
|
+
exit 1
|
57
|
+
end
|
data/data/sid-csv.cddl
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
; header = absent
|
2
|
+
|
3
|
+
SID-File = [meta-record,
|
4
|
+
?description-record,
|
5
|
+
*dependency-record,
|
6
|
+
*range-record,
|
7
|
+
*item-record]
|
8
|
+
|
9
|
+
meta-record = ["ietf-sid-file",
|
10
|
+
module-name: text,
|
11
|
+
module-revision: empty / text,
|
12
|
+
sid-file-revision: empty / text,
|
13
|
+
sid-file-status: empty / "unpublished" / "published"]
|
14
|
+
|
15
|
+
description-record = ["description",
|
16
|
+
description: empty / text]
|
17
|
+
|
18
|
+
dependency-record = ["dependency",
|
19
|
+
module-name: text,
|
20
|
+
module-revision: text]
|
21
|
+
|
22
|
+
range-record = ["range",
|
23
|
+
entry-point: uint,
|
24
|
+
size: uint]
|
25
|
+
|
26
|
+
item-record = [; "item", -- useful to elide for bulk of file
|
27
|
+
sid: uint
|
28
|
+
(
|
29
|
+
namespace: "module" / "identity" / "feature"
|
30
|
+
identifier: yang-identifier
|
31
|
+
//
|
32
|
+
namespace: "data"
|
33
|
+
identifier: schema-node-path
|
34
|
+
)
|
35
|
+
status: empty / "stable" / "unstable" / "obsolete"]
|
36
|
+
|
37
|
+
yang-identifier = text .abnf ("yang-identifier" .det id-abnf)
|
38
|
+
schema-node-path = text .abnf ("schema-node-path" .det id-abnf)
|
39
|
+
id-abnf = '
|
40
|
+
schema-node-path = "/" QID *( "/" OQID)
|
41
|
+
yang-identifier = ID
|
42
|
+
QID = ID ":" ID
|
43
|
+
OQID = ID [":" ID]
|
44
|
+
ID = I *C
|
45
|
+
I = "_" / %x41-5a / %x61-7a
|
46
|
+
C = I / %x30-39 / "-" / "."
|
47
|
+
'
|
48
|
+
|
49
|
+
empty = ""
|
data/lib/sid-csv.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
module CSV::SID
|
5
|
+
|
6
|
+
def csv_line(source, *entries)
|
7
|
+
entries.map do |entry|
|
8
|
+
case entry
|
9
|
+
in String
|
10
|
+
source[entry]
|
11
|
+
in Symbol
|
12
|
+
entry.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def csv_lines(source, *entries)
|
18
|
+
if source
|
19
|
+
source.map do |row|
|
20
|
+
csv_line(row, *entries)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def sid_csv_from_data(sid_data)
|
26
|
+
[
|
27
|
+
csv_line(sid_data, :"ietf-sid-file", "module-name", "module-revision",
|
28
|
+
"sid-file-revision", "sid-file-status"),
|
29
|
+
csv_line(sid_data, :description, "description"),
|
30
|
+
*csv_lines(sid_data["dependency-revision"], :dependency,
|
31
|
+
"module-name", "module-revision"),
|
32
|
+
*csv_lines(sid_data["assignment-range"], :range, "entry-point", "size"),
|
33
|
+
*csv_lines(sid_data["item"], "sid", "namespace", "identifier", "status"),
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
def csv_hash(names, values)
|
38
|
+
Hash[names.zip(values).filter{|k, v| v != ""}]
|
39
|
+
end
|
40
|
+
|
41
|
+
def csv_store(csv, name, names, values)
|
42
|
+
csv[name] ||= []
|
43
|
+
csv[name] << csv_hash(names, values)
|
44
|
+
end
|
45
|
+
|
46
|
+
SID_FILE_TOP_LEVEL = "ietf-sid-file:sid-file"
|
47
|
+
|
48
|
+
def sid_file_from_csv(sid_csv)
|
49
|
+
{SID_FILE_TOP_LEVEL =>
|
50
|
+
sid_csv.each_with_object({}) do |line, result|
|
51
|
+
case line
|
52
|
+
in ["ietf-sid-file", *values]
|
53
|
+
result.merge!(csv_hash(["module-name", "module-revision",
|
54
|
+
"sid-file-revision", "sid-file-status"], values))
|
55
|
+
in ["description", *values]
|
56
|
+
result.merge!(csv_hash(["description"], values))
|
57
|
+
in ["dependency", *values]
|
58
|
+
csv_store(result, "dependency-revision",
|
59
|
+
["module-name", "module-revision"], values)
|
60
|
+
in ["range", entry_point, size]
|
61
|
+
csv_store(result, "assignment-range",
|
62
|
+
["entry-point", "size"], [entry_point.to_s, size.to_s])
|
63
|
+
in [sid, namespace, name, status]
|
64
|
+
csv_store(result, "item",
|
65
|
+
["namespace", "identifier", "sid", "status"],
|
66
|
+
[namespace, name, sid.to_s, status])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def csv_generate(data)
|
73
|
+
CSV.generate('') do |csv|
|
74
|
+
data.each do |row|
|
75
|
+
csv << row
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def sid_data_from_file(text)
|
81
|
+
JSON.load(text)[SID_FILE_TOP_LEVEL]
|
82
|
+
end
|
83
|
+
|
84
|
+
def json_dump(fn, value)
|
85
|
+
File.write(fn, JSON.pretty_generate(value))
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/sid-csv.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "sid-csv"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "YANG-CBOR SID file as CSV"
|
5
|
+
s.description = %q{sid-csv implements a library and a command-line interface to YANG sid files as CSV}
|
6
|
+
s.author = "Carsten Bormann"
|
7
|
+
s.email = "cabo@tzi.org"
|
8
|
+
s.license = "Apache-2.0"
|
9
|
+
s.homepage = "https://github.com/cabo/sid-csv"
|
10
|
+
s.has_rdoc = false
|
11
|
+
s.files = Dir['lib/**/*.rb'] + %w(README.md sid-csv.gemspec data/sid-csv.cddl) + Dir['bin/**/*']
|
12
|
+
s.executables = Dir['bin/**/*'].map {|x| File.basename(x)}
|
13
|
+
s.required_ruby_version = '>= 2.7.0'
|
14
|
+
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sid-csv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carsten Bormann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: sid-csv implements a library and a command-line interface to YANG sid
|
14
|
+
files as CSV
|
15
|
+
email: cabo@tzi.org
|
16
|
+
executables:
|
17
|
+
- sid-csv
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- README.md
|
22
|
+
- bin/sid-csv
|
23
|
+
- data/sid-csv.cddl
|
24
|
+
- lib/sid-csv.rb
|
25
|
+
- sid-csv.gemspec
|
26
|
+
homepage: https://github.com/cabo/sid-csv
|
27
|
+
licenses:
|
28
|
+
- Apache-2.0
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 2.7.0
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubygems_version: 3.4.10
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: YANG-CBOR SID file as CSV
|
49
|
+
test_files: []
|