Skip to content

Commit 5c2f21d

Browse files
committed
First cut at toolkit to do package inspection.
README.md has all the info.
1 parent c64d93f commit 5c2f21d

File tree

14 files changed

+1837
-0
lines changed

14 files changed

+1837
-0
lines changed

tools/BUILD

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright 2026 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""rules_pkg internal code.
15+
16+
All interfaces are subject to change at any time.
17+
"""
18+
19+
load("@rules_python//python:py_binary.bzl", "py_binary")
20+
21+
package(
22+
default_package_metadata = ["//:license"],
23+
default_visibility = ["//visibility:public"],
24+
)
25+
26+
filegroup(
27+
name = "standard_package",
28+
srcs = [
29+
"BUILD",
30+
] + glob([
31+
"*.py",
32+
]),
33+
visibility = [
34+
"//distro:__pkg__",
35+
"//doc_build:__pkg__",
36+
],
37+
)
38+
39+
py_binary(
40+
name = "cpio-ls",
41+
srcs = [
42+
"cpio-ls.py",
43+
],
44+
deps = [
45+
"//tools/lib:cpio",
46+
],
47+
)
48+
49+
py_binary(
50+
name = "rpm2cpio",
51+
srcs = [
52+
"rpm2cpio.py",
53+
],
54+
deps = [
55+
"//tools/lib:rpm_file",
56+
],
57+
)
58+
59+
py_binary(
60+
name = "tree_size_compare",
61+
srcs = [
62+
"tree_size_compare.py",
63+
],
64+
deps = [
65+
"//tools/lib:deb_reader",
66+
"//tools/lib:fs_reader",
67+
"//tools/lib:rpm_reader",
68+
"//tools/lib:saved_tree",
69+
"//tools/lib:tar_reader",
70+
"//tools/lib:tree_reader",
71+
],
72+
)

tools/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# package inspection and analysis tools
2+
3+
This is toolkit for building need specific tools. It consists of:
4+
5+
- A collection of readers for various kinds of packages.
6+
- Some reference implementation tools to show how the readers work.
7+
8+
Much of the code here is AI generated. The ar, deb, rpm and cpio readers
9+
were hand crafted by a human.
10+
11+
## Tools
12+
13+
### rpm2cpio - portable rpm2cpio utility
14+
- runs anywhere with python 3.12 or higher
15+
- extracts and steams out the cpio archive
16+
- can also dump rpm headers
17+
18+
### cpio-ls - read a cpio archive stream and list the files
19+
- this is just a demonstration of how you could write `cpio -i`
20+
21+
### tree_size_compare
22+
- compare 2 archives and look for differences in sizes of files.

tools/cpio-ls.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""cpio file lister.
2+
3+
This is mini-tool to ilst the paths in a cpio archive.
4+
"""
5+
6+
import sys
7+
8+
from tools.lib.cpio import CpioReader
9+
10+
11+
def lscpio(cpio):
12+
while True:
13+
info = cpio.next()
14+
if not info:
15+
break
16+
if info.is_symlink:
17+
print(f"{info.path}: {info.uid}/{info.gid}, mode:{info.mode}, {info.size} -> {info.symlink_target}")
18+
else:
19+
20+
print(f"{info.path}: {info.uid}/{info.gid}, mode:{info.mode}, {info.size}")
21+
22+
23+
def main(args):
24+
if len(args) > 1:
25+
with open(args[1], "rb") as inp:
26+
cpio = CpioReader(inp)
27+
lscpio(cpio)
28+
else:
29+
cpio = CpioReader(sys.stdin.buffer)
30+
lscpio(cpio)
31+
32+
33+
if __name__ == "__main__":
34+
main(sys.argv)

tools/lib/BUILD

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Copyright 2026 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
"""rules_pkg internal code.
15+
16+
All interfaces are subject to change at any time.
17+
"""
18+
19+
load("@rules_python//python:py_binary.bzl", "py_binary")
20+
load("@rules_python//python:py_library.bzl", "py_library")
21+
22+
package(
23+
default_package_metadata = ["//:license"],
24+
default_visibility = ["//visibility:public"],
25+
)
26+
27+
filegroup(
28+
name = "standard_package",
29+
srcs = [
30+
"BUILD",
31+
] + glob([
32+
"*.py",
33+
]),
34+
visibility = [
35+
"//distro:__pkg__",
36+
"//doc_build:__pkg__",
37+
],
38+
)
39+
40+
py_library(
41+
name = "cpio",
42+
srcs = [
43+
"cpio.py",
44+
],
45+
deps = [":tree_reader"],
46+
)
47+
48+
py_library(
49+
name = "deb_reader",
50+
srcs = [
51+
"deb_reader.py",
52+
],
53+
deps = [":tree_reader"],
54+
)
55+
56+
py_library(
57+
name = "fs_reader",
58+
srcs = [
59+
"fs_reader.py",
60+
],
61+
deps = [":tree_reader"],
62+
)
63+
64+
py_library(
65+
name = "rpm_file",
66+
srcs = [
67+
"rpm_file.py",
68+
],
69+
)
70+
71+
py_library(
72+
name = "rpm_reader",
73+
srcs = [
74+
"rpm_reader.py",
75+
],
76+
deps = [
77+
":cpio",
78+
":rpm_file",
79+
":tree_reader",
80+
],
81+
)
82+
83+
py_library(
84+
name = "saved_tree",
85+
srcs = [
86+
"saved_tree.py",
87+
],
88+
deps = [":tree_reader"],
89+
)
90+
91+
py_library(
92+
name = "tar_reader",
93+
srcs = [
94+
"tar_reader.py",
95+
],
96+
deps = [":tree_reader"],
97+
)
98+
99+
py_library(
100+
name = "tree_reader",
101+
srcs = [
102+
"tree_reader.py",
103+
],
104+
)

0 commit comments

Comments
 (0)