3
# Copyright (C) 2020, 2021 Etersoft
4
# Copyright (C) 2020, 2021 Vitaly Lipatov <lav@etersoft.ru>
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU Affero General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU Affero General Public License for more details.
16
# You should have received a copy of the GNU Affero General Public License
17
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
load_helper epm-sh-altlinux
24
__epm_restore_print_comment()
26
echo "#$2 generated by 'epm restore --dry-run' from $(basename $(dirname $(realpath "$1")))/$(basename "$1")$3"
29
# FIXME: python modules are packaged into python packages, but we have only module names and rpm package names instead of python packages
30
# enable python3dest(PEP-503 normalized name) provides
31
# https://bugzilla.altlinux.org/show_bug.cgi?id=39003
32
__epm_filter_pip_to_rpm()
34
tr "A-Z" "a-z" | sed -e "s|_|-|g" -e "s|^python[-_]||" -e "s|python$||" \
35
-e "s|bs4|beautifulsoup4|" \
36
-e "s|pillow|Pillow|" \
37
-e "s|sqlalchemy|SQLAlchemy|" \
38
-e "s|flask-SQLAlchemy|flask_sqlalchemy|" \
39
-e "s|redis|redis-py|" \
41
-e "s|pymonetdb|monetdb|" \
43
-e "s|flask-migrate|Flask-Migrate|" \
44
-e "s|twisted|twisted-core|" \
45
-e "s|pymacaroons|pymacaroons-pynacl|" \
46
-e "s|pygments|Pygments|" \
47
-e "s|memcached|memcache|" \
48
-e "s|pyinstaller||" \
49
-e "s|pyopenssl|OpenSSL|"
56
echo "$2" | grep -E -- "$sign[[:space:]]*[0-9.]+?" | sed -E -e "s|.*$sign[[:space:]]*([0-9.]+?).*|\1|"
66
[ -n "$equal" ] || equal=">="
70
for sign in "<=" "<" ">=" ">" "==" "!=" "~="; do
71
ll=$(fill_sign "$sign" "$l")
72
[ -n "$ll" ] || continue
73
[ "$sign" = "==" ] && sign="$equal"
74
[ "$sign" = "~=" ] && sign="$equal"
75
[ "$sign" = "!=" ] && sign=">="
76
[ -n "$pi" ] && pi="$pi
80
[ -n "$pi" ] || pi="$t"
86
echo "$*" | grep "=" | head -n1 | sed -e 's| *=.*||'
89
__epm_lineprint_python_array()
93
local name="$(__epm_get_array_name "$a")"
94
(echo "$a" | sed -E -e 's@(\]|\)).*@\1@' ; echo "print('\n'.join($name))" ) | ( a= python3 - || a= python - )
97
# translate pip requirement lines to rpm notation
98
# (compare signs and package names)
99
__epm_restore_convert_to_rpm_notation()
104
if echo "$l" | grep -q 'platform_python_implementation != "PyPy"' ; then
105
[ -n "$verbose" ] && warning " $t is not PyPi requirement, skipped"
108
if echo "$l" | grep -q 'sys_platform == "darwin"' ; then
109
[ -n "$verbose" ] && warning " $t is darwin only requirement, skipped"
112
if echo "$l" | grep -q 'sys_platform == "win32"' ; then
113
[ -n "$verbose" ] && warning " $t is win32 only requirement, skipped"
116
if echo "$l" | grep -q "; *python_version *< *['\"]3" ; then
117
[ -n "$verbose" ] && warning " $t is python2 only requirement, skipped"
120
if echo "$l" | grep -q "; *python_version *<= *['\"]2\." ; then
121
[ -n "$verbose" ] && warning " $t is python2 only requirement, skipped"
124
# drop various "python_version > '3.5'"
125
l="$(echo "$l" | sed -e "s| *;.*||")"
126
if echo "$l" | grep -qE "^ *#" || [ -z "$l" ] ; then
129
local t="$(echo "$l" | sed -E -e "s|[[:space:]]*[<>!=~]+.*||" -e "s| *#.*||" | __epm_filter_pip_to_rpm)"
130
[ -n "$t" ] || continue
132
if echo "$l" | grep -qE "^\[" ; then
135
# if dependency_links URLs, use egg name
136
if echo "$l" | grep -qE "://" ; then
137
if echo "$l" | grep -q "#egg=" ; then
138
t="$(echo "$l" | sed -e "s|.*#egg=||" -e "s|\[.*||" | __epm_filter_pip_to_rpm)"
140
warning " skipping URL $l ..."
145
__epm_pi_sign_to_rpm "$t" "$l" "$equal"
155
if [ -n "$dryrun" ] ; then
157
basename "$req_file" | grep -E -q "(dev|test|coverage)" && reqmacro="%py3_buildrequires"
159
__epm_restore_print_comment "$req_file"
160
cat $req_file | __epm_restore_convert_to_rpm_notation | sed -e "s|^|$reqmacro |"
163
info "Install requirements from $req_file ..."
164
ilist="$(cat $req_file | __epm_restore_convert_to_rpm_notation | cut -d' ' -f 1 | sed -e "s|^|python3-module-|")"
167
ilist="$(estrlist list $ilist)"
168
docmd epm install $ilist
171
__epm_restore_print_toml()
174
lt=$(mktemp) || fatal
177
#!//usr/bin/env python3
179
# https://realpython.com/python-toml/
184
raise Exception('Run me with a file')
186
pyproject = sys.argv[1]
188
c = toml.load(pyproject)
189
n = c["tool"]["poetry"]["dependencies"]
190
for key, value in n.items():
191
if isinstance(value, dict):
192
print('\n' + key + ' ' , value["version"])
194
print('\n' + key + ' ' + value)
199
__epm_restore_print_pyproject()
202
__epm_restore_print_toml "$req_file" | __epm_restore_convert_to_rpm_notation | sed -e 's|\*||' -e 's|\^|>= |'
205
__epm_restore_pyproject()
211
if [ -n "$dryrun" ] ; then
214
__epm_restore_print_comment "$req_file"
215
__epm_restore_print_pyproject "$req_file" | sed -e "s|^|$reqmacro |"
218
info "Install requirements from $req_file ..."
219
ilist="$(__epm_restore_print_pyproject "$req_file" | cut -d' ' -f 1 | sed -e "s|^|python3-module-|")"
222
ilist="$(estrlist list $ilist)"
223
docmd epm install $ilist
228
rhas "$1" "[[:space:]]*$2[[:space:]]*=[[:space:]]*[\[(]"
231
__epm_restore_setup_py()
234
if [ -z "$dryrun" ] ; then
235
info "Install requirements from $req_file ..."
243
if rhas "$l" "^ *#" ; then
247
if __eresection "$l" "REQUIREMENTS" ; then
251
if __eresection "$l" "install_requires" ; then
255
if __eresection "$l" "setup_requires" ; then
256
reqmacro="%py3_buildrequires"
259
if __eresection "$l" "tests_require" ; then
260
reqmacro="%py3_buildrequires"
263
if [ -n "$section" ] ; then
269
if [ -z "$section" ] || ! rhas "$l" "(\]|\)),*" ; then
273
if [ -n "$dryrun" ] ; then
275
__epm_restore_print_comment "$req_file" "" " $(__epm_get_array_name "$section")"
276
__epm_lineprint_python_array "$ar" | __epm_restore_convert_to_rpm_notation ">=" | sed -e "s|^|$reqmacro |"
278
ilist="$ilist $(__epm_lineprint_python_array "$ar" | __epm_restore_convert_to_rpm_notation ">=" | cut -d' ' -f 1 | sed -e "s|^|python3-module-|")"
284
if [ -n "$dryrun" ] ; then
288
ilist="$(estrlist list $ilist)"
289
docmd epm install $ilist
292
__epm_print_npm_list()
299
echo "$l" | grep -q '"\(.*\)": "\(.*\)"' || continue
300
local name="$(echo "$l" | sed -e 's|.*"\(.*\)": ".*|\1|')"
301
[ -z "$name" ] && continue
302
local ver="$(echo "$l" | sed -e 's|.*"\(.*\)": "\(.*\)".*|\2|')" #'
303
[ -z "$name" ] && continue
305
if [ -n "$dryrun" ] ; then
308
if echo "$ver" | grep -q "^\^" ; then
313
ll=$(echo "$ver" | sed -e 's|^[^~]||')
314
pi="$pi$reqmacro node-$name $sign $ll"
315
# [ -n "$pi" ] && pi="$pi
317
# [ -n "$pi" ] || pi="$pi$reqmacro: node-$t"
321
local pi="node-$name"
322
#echo " $l -> $name -> $pi"
324
[ -n "$name" ] || continue
328
[ -n "$dryrun" ] || echo "$ilist"
332
__epm_print_perl_list()
338
# perl(Class::ErrorHandler)>=0
339
echo "$l" | grep -q '^perl(' || continue
340
local name="$(echo "$l" | sed -e 's|>=.*||' -e 's|::|/|g' -e 's|)|.pm)|')"
341
[ "$name" = "perl(perl.pm)" ] && continue
342
[ -z "$name" ] && continue
343
local ver="$(echo "$l" | sed -e 's|.*>=||')"
344
[ -z "$name" ] && continue
346
if [ -n "$dryrun" ] ; then
349
[ "$ver" = "0" ] || sign=" >= $ver"
350
pi="$pi$reqmacro $name$sign"
355
#echo " $l -> $name -> $pi"
357
[ -n "$name" ] || continue
361
[ -n "$dryrun" ] || echo "$ilist"
364
__epm_print_perl_list_shyaml()
370
# Convert::ASN1: 0.10
371
echo "$l" | grep -q '^ *\(.*\): \(.*\)' || continue
372
local name="$(echo "$l" | sed -e 's| *\(.*\): \(.*\)|\1|' -e 's|::|/|g')".pm
373
[ "$name" = "perl.pm" ] && continue
374
[ -z "$name" ] && continue
375
local ver="$(echo "$l" | sed -e 's| *\(.*\): \(.*\)|\2|')"
376
[ -z "$name" ] && continue
378
if [ -n "$dryrun" ] ; then
381
[ "$ver" = "0" ] || sign=" >= $ver"
382
pi="$pi$reqmacro perl($name)$sign"
386
local pi="perl($name)"
387
#echo " $l -> $name -> $pi"
389
[ -n "$name" ] || continue
393
[ -n "$dryrun" ] || echo "$ilist"
397
__epm_print_nupkg_list()
399
a= dotnet list $1 package | grep "^ > " | while read n name req other; do
400
if [ -n "$dryrun" ] ; then
401
echo "BuildRequires: nupkg($name) >= $req"
411
if [ -n "$dryrun" ] ; then
412
echo "# generated via dotnet list $(basename $(dirname $(realpath "$req_file")))/$(basename "$req_file") package"
413
__epm_print_nupkg_list $req_file
417
info "Install requirements from $req_file ..."
418
ilist=$(__epm_print_nupkg_list $req_file)
419
ilist="$(estrlist list $ilist)"
420
docmd epm install $ilist
423
__epm_print_meson_list()
428
while read name sign ver other ; do
431
[ -n "$other" ] && continue
432
if [ -n "$dryrun" ] ; then
434
pi="$reqmacro pkgconfig($name)"
435
[ -n "$sign" ] && pi="$pi $sign $ver"
439
local pi="pkgconfig($name)"
441
[ -n "$name" ] || continue
445
[ -n "$dryrun" ] || echo "$ilist"
451
# gtk_dep = dependency('gtk4', version: '>= 4.6')
452
# gtk_wayland_dep = dependency('gtk4-wayland', required: false)
453
# packagekit_dep = dependency('packagekit-glib2', version: '>= 1.2', required: get_option('packagekit'))
454
if [ -n "$dryrun" ] ; then
456
lt=$(mktemp) || fatal
459
__epm_restore_print_comment "$req_file" " dependency"
460
grep "dependency(" $req_file | sed -e 's|.*dependency(||' -e 's|).*||' -e 's|, required.*||' -e 's|, version:||' -e "s|'||g" >$lt
461
__epm_print_meson_list "BuildRequires:" $lt
466
info "Install requirements from $req_file ..."
468
lt=$(mktemp) || fatal
470
grep "dependency(" $req_file | sed -e 's|.*dependency(||' -e 's|).*||' -e 's|, required.*||' -e 's|, version:||' -e "s|'||g" >$lt
471
ilist="$ilist $(__epm_print_meson_list "" $lt)"
474
docmd epm install $ilist
483
assure_exists jq || fatal
485
if [ -n "$dryrun" ] ; then
487
lt=$(mktemp) || fatal
489
a= jq .dependencies <$req_file >$lt
491
__epm_restore_print_comment "$req_file"
492
__epm_print_npm_list "Requires:" $lt
495
__epm_restore_print_comment "$req_file" " devDependencies"
496
a= jq .devDependencies <$req_file >$lt
497
__epm_print_npm_list "BuildRequires:" $lt
502
info "Install requirements from $req_file ..."
504
lt=$(mktemp) || fatal
506
a= jq .dependencies <$req_file >$lt
507
ilist="$(__epm_print_npm_list "" $lt)"
508
a= jq .devDependencies <$req_file >$lt
509
ilist="$ilist $(__epm_print_npm_list "" $lt)"
511
docmd epm install $ilist
519
if [ -n "$dryrun" ] ; then
521
lt=$(mktemp) || fatal
523
a= /usr/bin/perl $req_file PRINT_PREREQ=1 >$lt
524
# all requirements will autodetected during packing, put it to the buildreq
526
__epm_restore_print_comment "$req_file"
527
__epm_print_perl_list "BuildRequires:" $lt
532
info "Install requirements from $req_file ..."
536
a= /usr/bin/perl $req_file PRINT_PREREQ=1 >$lt
537
ilist="$(__epm_print_perl_list "" $lt)"
539
docmd epm install $ilist
543
__epm_restore_perl_shyaml()
547
assure_exists shyaml || fatal
549
if [ -n "$dryrun" ] ; then
551
lt=$(mktemp) || fatal
553
a= shyaml get-value requires <$req_file >$lt
554
# all requirements will autodetected during packing, put it to the buildreq
556
__epm_restore_print_comment "$req_file"
557
__epm_print_perl_list "BuildRequires:" $lt
560
__epm_restore_print_comment "$req_file" " build_requires"
561
a= shyaml get-value build_requires <$req_file >$lt
562
__epm_print_perl_list "BuildRequires:" $lt
567
info "Install requirements from $req_file ..."
569
lt=$(mktemp) || fatal
571
a= shyaml get-value requires <$req_file >$lt
572
ilist="$(__epm_print_perl_list "" $lt)"
573
a= shyaml get-value build_requires <$req_file >$lt
574
ilist="$ilist $(__epm_print_perl_list "" $lt)"
576
docmd epm install $ilist
582
[ -n "$verbose" ] && info "Checking for $req_file ..."
583
[ -s "$req_file" ] || return
584
if file $req_file | grep -q "ELF [3264]*-bit LSB executable" ; then
585
assure_exists ldd-requires
586
showcmd ldd-requires $req_file
587
local TOINSTALL="$(a= ldd-requires $req_file | grep "^apt-get install" | sed -e "s|^apt-get install ||")"
588
if [ -n "$dryrun" ] ; then
589
estrlist list $TOINSTALL
592
[ -n "$TOINSTALL" ] || { info "There are no missed packages is found for $req_file binary." ; return ; }
593
docmd epm install $TOINSTALL
598
requirements/default.txt|requirements/dev.txt|requirements/test.txt|requirements/coverage.txt)
599
[ -s "$req_file" ] && __epm_restore_pip "$req_file" && return
603
case $(basename $req_file) in
604
requirements.txt|dev-requirements.txt|requirements-dev.txt|requirements_dev.txt|requirements_test.txt|requirements-test.txt|test-requirements.txt|requires.txt)
605
[ -s "$req_file" ] && __epm_restore_pip "$req_file"
607
setup.py|python_dependencies.py)
608
[ -s "$req_file" ] && __epm_restore_setup_py "$req_file"
611
[ -s "$req_file" ] && __epm_restore_pyproject "$req_file"
614
[ -s "$req_file" ] && __epm_restore_npm "$req_file"
617
[ -s "$req_file" ] && __epm_restore_meson "$req_file"
620
# [ -s "$req_file" ] && __epm_restore_perl "$req_file"
623
[ -s "$req_file" ] && __epm_restore_perl "$req_file"
626
local PROJ="$(echo $req_file)"
627
[ -s "$PROJ" ] && __epm_restore_nupkg "$PROJ"
629
Gemfile|package.json)
630
info "$req_file support is not implemented yet"
637
req_file="$pkg_filenames"
638
if [ -n "$pkg_urls" ] && echo "$pkg_urls" | grep -qE "^https?://" ; then
639
req_file="$(basename "$pkg_urls")"
641
[ -r "$req_file" ] && fatal "File $req_file is already exists in $(pwd)"
642
info "Downloading '$req_file' from '$pkg_urls' ..."
644
[ -s "$req_file" ] || fatal "Can't download $req_file from '$pkg_urls'"
647
if [ -n "$req_file" ] ; then
648
__epm_restore_by $req_file
652
# TODO: nowhere works: python3 setup.py --requires
654
# if run with empty args
655
for i in requirements.txt requirements/default.txt requirements_dev.txt requirements-dev.txt requirements/dev.txt dev-requirements.txt \
656
requirements-test.txt requirements_test.txt requirements/test.txt test-requirements.txt requirements/coverage.txt \
657
Gemfile requires.txt package.json setup.py python_dependencies.py Makefile.PL meson.build pyproject.toml \