OILS / build / dynamic-deps.sh View on Github | oilshell.org

234 lines, 92 significant
1#!/usr/bin/env bash
2#
3# Calculate and filter deps of Python apps.
4#
5# Usage:
6# build/dynamic-deps.sh <function name>
7
8set -o nounset
9set -o pipefail
10set -o errexit
11
12# Note on the cd option, "-P": Resolve symlinks in the current working
13# directory. This is needed to make `grep $REPO_ROOT...` in `repo-filter
14# (build/dynamic-deps.sh)` work. Later, `repo-filter` and related parts may be
15# rewritten using AWK to handle it better.
16REPO_ROOT=$(cd -P "$(dirname $0)/.."; pwd)
17
18readonly PY_PATH='.:vendor/'
19
20# Temporary
21readonly DIR=_build/NINJA
22
23# In git
24readonly FILTER_DIR='prebuilt/dynamic-deps'
25
26make-egrep() {
27 # match chars until # or space, and line must be non-empty
28 gawk '
29 match($0, /([^# ]*)/, m) {
30 contents = m[0]
31 if (contents) { # skip empty lines
32 print(contents)
33 }
34 }
35 '
36}
37
38write-filters() {
39 ### Write filename filters in the egrep -f format
40
41 # For ./NINJA-config.sh to use.
42 # This style lets us add comments.
43
44 # For asdl.asdl_main and other tools
45 make-egrep >$FILTER_DIR/filter-py-tool.txt <<'EOF'
46__init__.py
47typing.py # vendor/typing.py isn't imported normally
48EOF
49
50 # Don't typecheck these files.
51
52 make-egrep >$FILTER_DIR/filter-typecheck.txt <<'EOF'
53__init__.py
54typing.py
55
56# OrderedDict is polymorphic
57pylib/collections_.py
58
59# lots of polymorphic stuff etc.
60mycpp/mylib.py
61
62# TODO: move or remove these
63tools/deps.py
64tools/readlink.py
65EOF
66
67 # On top of the typecheck filter, exclude these from translation. They are
68 # not inputs to mycpp.
69
70 make-egrep >$FILTER_DIR/filter-translate.txt <<'EOF'
71# generated code shouldn't be translated
72_devbuild/
73_gen/
74
75# definitions that are used by */*_gen.py
76.*_def\.py
77.*_spec\.py
78
79asdl/py.* # pybase.py ported by hand to C++
80
81core/py.* # pyos.py, pyutil.py ported by hand to C++
82core/optview\.py # core/optview_gen.py
83
84data_lang/py.* # pyj8.py
85
86frontend/py.*\.py # py_readline.py ported by hand to C++
87frontend/consts.py # frontend/consts_gen.py
88frontend/match.py # frontend/lexer_gen.py
89
90mycpp/iolib.py # Implemented in gc_iolib.{h,cC}
91mycpp/mops.py # Implemented in gc_mops.{h,cC}
92
93pgen2/grammar.py # These files are re-done in C++
94pgen2/pnode.py
95pgen2/token.py
96
97# should be py_path_stat.py, because it's ported by hand to C++
98pylib/path_stat.py
99
100# should be py_bool_stat.py, because it's ported by hand to C++
101osh/bool_stat.py
102EOF
103
104 wc -l $FILTER_DIR/filter-*
105}
106
107repo-filter() {
108 ### Select files from the dynamic_deps.py output
109
110 # select what's in the repo; eliminating stdlib stuff
111 # eliminate _cache for mycpp running under Python-3.10
112 grep -F -v "$REPO_ROOT/_cache" | grep -F "$REPO_ROOT" | awk '{ print $2 }'
113}
114
115exclude-filter() {
116 ### Exclude repo-relative paths
117
118 local filter_name=$1
119
120 grep -E -v -f $FILTER_DIR/filter-$filter_name.txt
121}
122
123mysort() {
124 LC_ALL=C sort
125}
126
127#
128# Programs
129#
130
131py-tool() {
132 local py_module=$1
133
134 local dir=$DIR/$py_module
135 mkdir -p $dir
136
137 PYTHONPATH=$PY_PATH /usr/bin/env python2 \
138 build/dynamic_deps.py py-manifest $py_module \
139 > $dir/all-pairs.txt
140
141 cat $dir/all-pairs.txt | repo-filter | exclude-filter py-tool | mysort \
142 > $dir/deps.txt
143
144 echo "DEPS $dir/deps.txt"
145}
146
147# Code generators
148list-gen() {
149 ls */*_gen.py
150}
151
152# mycpp and pea deps are committed to git instead of in _build/NINJA/ because
153# users might not have Python 3.10
154
155write-pea() {
156 local module='pea.pea_main'
157 local dir=prebuilt/ninja/$module
158 mkdir -p $dir
159
160 source build/dev-shell.sh # python3
161
162 # Can't use vendor/typing.py
163 python3 \
164 build/dynamic_deps.py py-manifest $module \
165 > $dir/all-pairs.txt
166
167 cat $dir/all-pairs.txt | repo-filter | mysort | tee $dir/deps.txt
168
169 echo
170 echo $dir/*
171}
172
173write-mycpp() {
174 local module='mycpp.mycpp_main'
175 local dir=prebuilt/ninja/$module
176 mkdir -p $dir
177
178 if false; then
179 ( source $MYCPP_VENV/bin/activate
180 PYTHONPATH=$REPO_ROOT:$REPO_ROOT/mycpp:$MYPY_REPO maybe-our-python3 \
181 build/dynamic_deps.py py-manifest $module > $dir/all-pairs.txt
182 )
183 fi
184
185 # TODO: it would be nicer to put this at the top of the file, but we get
186 # READONLY errors.
187 source build/dev-shell.sh
188
189 python3 build/dynamic_deps.py py-manifest $module > $dir/all-pairs.txt
190
191 local deps=$dir/deps.txt
192 cat $dir/all-pairs.txt \
193 | grep -v oilshell/oil_DEPS \
194 | repo-filter \
195 | exclude-filter py-tool \
196 | mysort \
197 | tee $deps
198
199 echo
200 echo $dir/*
201}
202
203mycpp-example-parse() {
204 ### Manifests for mycpp/examples/parse are committed to git
205
206 local dir=$DIR/parse
207 mkdir -p $dir
208
209 PYTHONPATH=$PY_PATH /usr/bin/env python2 \
210 build/dynamic_deps.py py-manifest mycpp.examples.parse \
211 > $dir/all-pairs.txt
212
213 local ty=mycpp/examples/parse.typecheck.txt
214 local tr=mycpp/examples/parse.translate.txt
215
216 cat $dir/all-pairs.txt | repo-filter | exclude-filter typecheck | mysort > $ty
217
218 cat $ty | exclude-filter translate > $tr
219
220 wc -l $ty $tr
221
222 #head $ty $tr
223}
224
225pea-hack() {
226 # Leave out help_.py for Soil
227 grep -v '_devbuild/gen/help_meta.py' $DIR/bin.oils_for_unix/typecheck.txt \
228 > pea/oils-typecheck.txt
229}
230
231# Sourced by NINJA-config.sh
232if test $(basename $0) = 'dynamic-deps.sh'; then
233 "$@"
234fi