-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdependency_report.sh
More file actions
executable file
·158 lines (129 loc) · 4.95 KB
/
Copy pathdependency_report.sh
File metadata and controls
executable file
·158 lines (129 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
set -euo pipefail
go_cmd="${GO:-go}"
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
workspace="${GOWORK:-$repo_root/go.work}"
out_dir="${OUTPUT_DIR:-.ci-result}/dependencies"
api_base_ref="${API_BASE_REF:-}"
mkdir -p "$out_dir"
require_counts() {
local mod_file="$1"
awk '
/^require \(/ { inblock = 1; next }
inblock && /^\)/ { inblock = 0; next }
inblock && NF >= 2 {
if ($0 ~ /\/\/ indirect/) indirect++
else direct++
next
}
/^require[ \t]+/ {
if ($0 ~ /\/\/ indirect/) indirect++
else direct++
}
END { printf "%d\t%d\n", direct, indirect }
' "$mod_file"
}
module_list() {
local dir="$1"
local module_workspace=off
if [[ "$dir" == "$repo_root" || "$dir" == "$repo_root/"* ]]; then
module_workspace="$workspace"
fi
(cd "$dir" && GOWORK="$module_workspace" "$go_cmd" list -m all) | tail -n +2 | sort
}
write_module_report() {
local name="$1"
local dir="$2"
local modules="$out_dir/$name.modules"
local counts direct_count indirect_count build_list_count
module_list "$dir" >"$modules"
counts="$(require_counts "$dir/go.mod")"
direct_count="${counts%%$'\t'*}"
indirect_count="${counts##*$'\t'}"
build_list_count="$(wc -l <"$modules" | tr -d ' ')"
printf '%s\t%s\t%s\t%s\t%s\n' "$name" "$direct_count" "$indirect_count" "$build_list_count" "$modules"
}
write_minimal_core_report() {
local packages="$out_dir/minimal-core-packages.txt"
local summary="$out_dir/minimal-core-summary.tsv"
(
cd "$repo_root"
GOWORK="$workspace" "$go_cmd" list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' \
./httpx ./binding ./middleware/maxbody ./middleware/timeout
) | sed '/^$/d' | sort -u >"$packages"
local total toolkit third_party
total="$(wc -l <"$packages" | tr -d ' ')"
toolkit="$(grep -c '^github.com/aatuh/api-toolkit/v4' "$packages" || true)"
third_party=$((total - toolkit))
{
printf 'profile\tpackage_count\ttoolkit_package_count\tthird_party_package_count\tpackage_list\n'
printf 'minimal-core\t%s\t%s\t%s\t%s\n' "$total" "$toolkit" "$third_party" "$packages"
} >"$summary"
}
write_diff_reports() {
local base_ref="$1"
local tmp_dir base_dir
tmp_dir="$(mktemp -d)"
base_dir="$tmp_dir/base"
git -C "$repo_root" worktree add --detach --quiet "$base_dir" "$base_ref"
trap 'git -C "$repo_root" worktree remove --force "$base_dir" >/dev/null 2>&1 || true; rm -rf "$tmp_dir"' RETURN
for name in root contrib; do
local current="$out_dir/$name.modules"
local base_modules="$out_dir/$name.base.modules"
local dir="."
if [ "$name" = "contrib" ]; then
dir="contrib"
fi
if [ ! -d "$base_dir/$dir" ]; then
: >"$base_modules"
else
module_list "$base_dir/$dir" >"$base_modules"
fi
comm -13 "$base_modules" "$current" >"$out_dir/$name.added.modules"
comm -23 "$base_modules" "$current" >"$out_dir/$name.removed.modules"
done
}
summary_tsv="$out_dir/summary.tsv"
{
printf 'module\tdirect_require_count\tindirect_require_count\tbuild_list_dependency_count\tmodule_list\n'
write_module_report root "$repo_root"
write_module_report contrib "$repo_root/contrib"
} >"$summary_tsv"
write_minimal_core_report
if [ -n "$api_base_ref" ]; then
write_diff_reports "$api_base_ref"
fi
root_added="$out_dir/root.added.modules"
root_removed="$out_dir/root.removed.modules"
contrib_added="$out_dir/contrib.added.modules"
contrib_removed="$out_dir/contrib.removed.modules"
root_added_count=0
root_removed_count=0
contrib_added_count=0
contrib_removed_count=0
if [ -s "$root_added" ]; then root_added_count="$(wc -l <"$root_added" | tr -d ' ')"; fi
if [ -s "$root_removed" ]; then root_removed_count="$(wc -l <"$root_removed" | tr -d ' ')"; fi
if [ -s "$contrib_added" ]; then contrib_added_count="$(wc -l <"$contrib_added" | tr -d ' ')"; fi
if [ -s "$contrib_removed" ]; then contrib_removed_count="$(wc -l <"$contrib_removed" | tr -d ' ')"; fi
cat >"$out_dir/summary.md" <<EOF_SUMMARY
## Dependency footprint summary
This report is a dependency review signal. Vulnerability status remains owned by
\`make vuln\` and \`release-check-summary.json\` \`vulnerability_evidence\`.
| Module | Direct requires | Indirect requires | Build-list dependencies |
| --- | ---: | ---: | ---: |
$(awk 'NR > 1 { printf "| `%s` | %s | %s | %s |\n", $1, $2, $3, $4 }' "$summary_tsv")
Minimal core package footprint:
$(awk 'NR > 1 { printf "- profile `%s`: %s non-stdlib packages, %s toolkit packages, %s third-party packages\n", $1, $2, $3, $4 }' "$out_dir/minimal-core-summary.tsv")
Base ref: \`${api_base_ref:-not set}\`
| Module | Added modules | Removed modules |
| --- | ---: | ---: |
| root | ${root_added_count} | ${root_removed_count} |
| contrib | ${contrib_added_count} | ${contrib_removed_count} |
Artifacts:
- \`${summary_tsv}\`
- \`${out_dir}/root.modules\`
- \`${out_dir}/contrib.modules\`
- \`${out_dir}/minimal-core-summary.tsv\`
- \`${out_dir}/minimal-core-packages.txt\`
EOF_SUMMARY
cat "$out_dir/summary.md"