NBash

Форк
0
662 строки · 19.1 Кб
1
#!/bin/sh
2
#
3
# Copyright (C) 2020, 2021  Etersoft
4
# Copyright (C) 2020, 2021  Vitaly Lipatov <lav@etersoft.ru>
5
#
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.
10
#
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.
15
#
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/>.
18
#
19

20
load_helper epm-sh-altlinux
21
load_helper epm-assure
22

23
# file prefix suffix
24
__epm_restore_print_comment()
25
{
26
    echo "#$2 generated by 'epm restore --dry-run' from $(basename $(dirname $(realpath "$1")))/$(basename "$1")$3"
27
}
28

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()
33
{
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|" \
40
        -e "s|pyjwt|jwt|" \
41
        -e "s|pymonetdb|monetdb|" \
42
        -e "s|pyyaml|yaml|" \
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|"
50
}
51

52
# TODO: remove me
53
fill_sign()
54
{
55
    local sign="$1"
56
    echo "$2" | grep -E -- "$sign[[:space:]]*[0-9.]+?" | sed -E -e "s|.*$sign[[:space:]]*([0-9.]+?).*|\1|"
57
}
58

59

60
# macro pkg caseline
61
__epm_pi_sign_to_rpm()
62
{
63
    local t="$1"
64
    local l="$2"
65
    local equal="$3"
66
    [ -n "$equal" ] || equal=">="
67

68
    local pi=''
69
    local sign ll
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
77
"
78
        pi="$pi$t $sign $ll"
79
    done
80
    [ -n "$pi" ] || pi="$t"
81
    echo "$pi"
82
}
83

84
__epm_get_array_name()
85
{
86
    echo "$*" | grep "=" | head -n1 | sed -e 's| *=.*||'
87
}
88

89
__epm_lineprint_python_array()
90
{
91
    local a="$*"
92
    [ -n "$a" ] || return
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 - )
95
}
96

97
# translate pip requirement lines to rpm notation
98
# (compare signs and package names)
99
__epm_restore_convert_to_rpm_notation()
100
{
101
    local equal="$1"
102
    local l
103
    while read l ; do
104
        if echo "$l" | grep -q 'platform_python_implementation != "PyPy"' ; then
105
            [ -n "$verbose" ] && warning "    $t is not PyPi requirement, skipped"
106
            continue
107
        fi
108
        if echo "$l" | grep -q 'sys_platform == "darwin"' ; then
109
            [ -n "$verbose" ] && warning "    $t is darwin only requirement, skipped"
110
            continue
111
        fi
112
        if echo "$l" | grep -q 'sys_platform == "win32"' ; then
113
            [ -n "$verbose" ] && warning "    $t is win32 only requirement, skipped"
114
            continue
115
        fi
116
        if echo "$l" | grep -q "; *python_version *< *['\"]3" ; then
117
            [ -n "$verbose" ] && warning "    $t is python2 only requirement, skipped"
118
            continue
119
        fi
120
        if echo "$l" | grep -q "; *python_version *<= *['\"]2\." ; then
121
            [ -n "$verbose" ] && warning "    $t is python2 only requirement, skipped"
122
            continue
123
        fi
124
        # drop various "python_version > '3.5'"
125
        l="$(echo "$l" | sed -e "s| *;.*||")"
126
        if echo "$l" | grep -qE "^ *#" || [ -z "$l" ] ; then
127
            continue
128
        fi
129
        local t="$(echo "$l" | sed -E -e "s|[[:space:]]*[<>!=~]+.*||" -e "s| *#.*||" | __epm_filter_pip_to_rpm)"
130
        [ -n "$t" ] || continue
131
        # until new section
132
        if echo "$l" | grep -qE "^\[" ; then
133
            break
134
        fi
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)"
139
            else
140
                warning "    skipping URL $l ..."
141
                continue
142
            fi
143
        fi
144

145
        __epm_pi_sign_to_rpm "$t" "$l" "$equal"
146
    done
147
}
148

149
__epm_restore_pip()
150
{
151
    local req_file="$1"
152
    local reqmacro
153
    local ilist
154

155
    if [ -n "$dryrun" ] ; then
156
        reqmacro="%py3_use"
157
        basename "$req_file" | grep -E -q "(dev|test|coverage)" && reqmacro="%py3_buildrequires"
158
        echo
159
        __epm_restore_print_comment "$req_file"
160
        cat $req_file | __epm_restore_convert_to_rpm_notation | sed -e "s|^|$reqmacro |"
161
        return
162
    else
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-|")"
165
    fi
166

167
    ilist="$(estrlist list $ilist)"
168
    docmd epm install $ilist
169
}
170

171
__epm_restore_print_toml()
172
{
173
    local lt
174
    lt=$(mktemp) || fatal
175
    remove_on_exit $lt
176
cat <<EOF >$lt
177
#!//usr/bin/env python3
178

179
# https://realpython.com/python-toml/
180
import sys
181
import toml
182

183
if len(sys.argv) < 2:
184
	raise Exception('Run me with a file')
185

186
pyproject = sys.argv[1]
187

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"])
193
	else:
194
		print('\n' + key + ' ' + value)
195
EOF
196
    a= python3 $lt "$1"
197
}
198

199
__epm_restore_print_pyproject()
200
{
201
    local req_file="$1"
202
    __epm_restore_print_toml "$req_file" | __epm_restore_convert_to_rpm_notation | sed -e 's|\*||' -e 's|\^|>= |'
203
}
204

205
__epm_restore_pyproject()
206
{
207
    local req_file="$1"
208
    local reqmacro
209
    local ilist
210

211
    if [ -n "$dryrun" ] ; then
212
        reqmacro="%py3_use"
213
        echo
214
        __epm_restore_print_comment "$req_file"
215
        __epm_restore_print_pyproject "$req_file" | sed -e "s|^|$reqmacro |"
216
        return
217
    else
218
        info "Install requirements from $req_file ..."
219
        ilist="$(__epm_restore_print_pyproject "$req_file" | cut -d' ' -f 1 | sed -e "s|^|python3-module-|")"
220
    fi
221

222
    ilist="$(estrlist list $ilist)"
223
    docmd epm install $ilist
224
}
225

226
__eresection()
227
{
228
    rhas "$1" "[[:space:]]*$2[[:space:]]*=[[:space:]]*[\[(]"
229
}
230

231
__epm_restore_setup_py()
232
{
233
    local req_file="$1"
234
    if [ -z "$dryrun" ] ; then
235
        info "Install requirements from $req_file ..."
236
    fi
237

238
    local ar=''
239
    local ilist=''
240
    local reqmacro
241
    local section=''
242
    while read l ; do
243
        if rhas "$l" "^ *#" ; then
244
            continue
245
        fi
246
        # start of section
247
        if __eresection "$l" "REQUIREMENTS" ; then
248
            reqmacro="%py3_use"
249
            section="$l"
250
        fi
251
        if __eresection "$l" "install_requires" ; then
252
            reqmacro="%py3_use"
253
            section="$l"
254
        fi
255
        if __eresection "$l" "setup_requires" ; then
256
            reqmacro="%py3_buildrequires"
257
            section="$l"
258
        fi
259
        if __eresection "$l" "tests_require" ; then
260
            reqmacro="%py3_buildrequires"
261
            section="$l"
262
        fi
263
        if [ -n "$section" ] ; then
264
            ar="$ar
265
$l"
266
        fi
267

268
        # not end of section
269
        if [ -z "$section" ] || ! rhas "$l" "(\]|\)),*" ; then
270
            continue
271
        fi
272

273
        if [ -n "$dryrun" ] ; then
274
            echo
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 |"
277
        else
278
            ilist="$ilist $(__epm_lineprint_python_array "$ar" | __epm_restore_convert_to_rpm_notation ">=" | cut -d' ' -f 1 | sed -e "s|^|python3-module-|")"
279
        fi
280
        section=''
281
        ar=''
282
    done < $req_file
283

284
    if [ -n "$dryrun" ] ; then
285
        return
286
    fi
287

288
    ilist="$(estrlist list $ilist)"
289
    docmd epm install $ilist
290
}
291

292
__epm_print_npm_list()
293
{
294
    local reqmacro="$1"
295
    local req_file="$2"
296
    local l
297
    while read l ; do
298
        # "tap": "^14.10.7"
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
304

305
        if [ -n "$dryrun" ] ; then
306
            local pi=''
307
            local sign
308
            if echo "$ver" | grep -q "^\^" ; then
309
                sign=">="
310
            else
311
                sign="="
312
            fi
313
            ll=$(echo "$ver" | sed -e 's|^[^~]||')
314
            pi="$pi$reqmacro node-$name $sign $ll"
315
#         [ -n "$pi" ] && pi="$pi
316
#"
317
#           [ -n "$pi" ] || pi="$pi$reqmacro: node-$t"
318
            echo "$pi"
319
            continue
320
        else
321
            local pi="node-$name"
322
            #echo "    $l -> $name -> $pi"
323
        fi
324
        [ -n "$name" ] || continue
325
        ilist="$ilist $pi"
326
    done < $req_file
327

328
    [ -n "$dryrun" ] || echo "$ilist"
329
}
330

331

332
__epm_print_perl_list()
333
{
334
    local reqmacro="$1"
335
    local req_file="$2"
336
    local l
337
    for l in $(cat) ; do
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
345

346
        if [ -n "$dryrun" ] ; then
347
            local pi=''
348
            local sign=''
349
            [ "$ver" = "0" ] || sign=" >= $ver"
350
            pi="$pi$reqmacro $name$sign"
351
            echo "$pi"
352
            continue
353
        else
354
            local pi="$name"
355
            #echo "    $l -> $name -> $pi"
356
        fi
357
        [ -n "$name" ] || continue
358
        ilist="$ilist $pi"
359
    done < $req_file
360

361
    [ -n "$dryrun" ] || echo "$ilist"
362
}
363

364
__epm_print_perl_list_shyaml()
365
{
366
    local reqmacro="$1"
367
    local req_file="$2"
368
    local l
369
    while read l ; do
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
377

378
        if [ -n "$dryrun" ] ; then
379
            local pi=''
380
            local sign=''
381
            [ "$ver" = "0" ] || sign=" >= $ver"
382
            pi="$pi$reqmacro perl($name)$sign"
383
            echo "$pi"
384
            continue
385
        else
386
            local pi="perl($name)"
387
            #echo "    $l -> $name -> $pi"
388
        fi
389
        [ -n "$name" ] || continue
390
        ilist="$ilist $pi"
391
    done < $req_file
392

393
    [ -n "$dryrun" ] || echo "$ilist"
394
}
395

396

397
__epm_print_nupkg_list()
398
{
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"
402
        else
403
            echo "nupkg($name)"
404
        fi
405
    done
406
}
407

408
__epm_restore_nupkg()
409
{
410
    local req_file="$1"
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
414
        return
415
    fi
416

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
421
}
422

423
__epm_print_meson_list()
424
{
425
    local reqmacro="$1"
426
    local req_file="$2"
427
    local l
428
    while read name sign ver other ; do
429
        # gtk4-wayland
430
        # gtk4 >= 4.6
431
        [ -n "$other" ] && continue
432
        if [ -n "$dryrun" ] ; then
433
            local pi=''
434
            pi="$reqmacro pkgconfig($name)"
435
            [ -n "$sign" ] && pi="$pi $sign $ver"
436
            echo "$pi"
437
            continue
438
        else
439
            local pi="pkgconfig($name)"
440
        fi
441
        [ -n "$name" ] || continue
442
        ilist="$ilist $pi"
443
    done < $req_file
444

445
    [ -n "$dryrun" ] || echo "$ilist"
446
}
447

448
__epm_restore_meson()
449
{
450
    local req_file="$1"
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
455
        local lt
456
        lt=$(mktemp) || fatal
457
        remove_on_exit $lt
458
        echo
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
462
        rm -f $lt
463
        return
464
    fi
465

466
    info "Install requirements from $req_file ..."
467
    local lt
468
    lt=$(mktemp) || fatal
469
    remove_on_exit $lt
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)"
472

473
    rm -f $lt
474
    docmd epm install $ilist
475

476
}
477

478

479
__epm_restore_npm()
480
{
481
    local req_file="$1"
482

483
    assure_exists jq || fatal
484

485
    if [ -n "$dryrun" ] ; then
486
        local lt
487
        lt=$(mktemp) || fatal
488
        remove_on_exit $lt
489
        a= jq .dependencies <$req_file >$lt
490
        echo
491
        __epm_restore_print_comment "$req_file"
492
        __epm_print_npm_list "Requires:" $lt
493

494
        echo
495
        __epm_restore_print_comment "$req_file" " devDependencies"
496
        a= jq .devDependencies <$req_file >$lt
497
        __epm_print_npm_list "BuildRequires:" $lt
498
        rm -f $lt
499
        return
500
    fi
501

502
    info "Install requirements from $req_file ..."
503
    local lt
504
    lt=$(mktemp) || fatal
505
    remove_on_exit $lt
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)"
510
    rm -f $lt
511
    docmd epm install $ilist
512
}
513

514
# TODO: check 
515
__epm_restore_perl()
516
{
517
    local req_file="$1"
518

519
    if [ -n "$dryrun" ] ; then
520
        local lt
521
        lt=$(mktemp) || fatal
522
        remove_on_exit $lt
523
        a= /usr/bin/perl $req_file PRINT_PREREQ=1 >$lt
524
        # all requirements will autodetected during packing, put it to the buildreq
525
        echo
526
        __epm_restore_print_comment "$req_file"
527
        __epm_print_perl_list "BuildRequires:" $lt
528
        rm -f $lt
529
        return
530
    fi
531

532
    info "Install requirements from $req_file ..."
533
    local lt
534
    lt=$(mktemp) || exit
535
    remove_on_exit $lt
536
    a= /usr/bin/perl $req_file PRINT_PREREQ=1 >$lt
537
    ilist="$(__epm_print_perl_list "" $lt)"
538
    rm -f $lt
539
    docmd epm install $ilist
540
}
541

542
# disabled
543
__epm_restore_perl_shyaml()
544
{
545
    local req_file="$1"
546

547
    assure_exists shyaml || fatal
548

549
    if [ -n "$dryrun" ] ; then
550
        local lt
551
        lt=$(mktemp) || fatal
552
        remove_on_exit $lt
553
        a= shyaml get-value requires <$req_file >$lt
554
        # all requirements will autodetected during packing, put it to the buildreq
555
        echo
556
        __epm_restore_print_comment "$req_file"
557
        __epm_print_perl_list "BuildRequires:" $lt
558

559
        echo
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
563
        rm -f $lt
564
        return
565
    fi
566

567
    info "Install requirements from $req_file ..."
568
    local lt
569
    lt=$(mktemp) || fatal
570
    remove_on_exit $lt
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)"
575
    rm -f $lt
576
    docmd epm install $ilist
577
}
578

579
__epm_restore_by()
580
{
581
    local req_file="$1"
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
590
            return
591
        fi
592
        [ -n "$TOINSTALL" ] || { info "There are no missed packages is found for $req_file binary." ; return ; }
593
        docmd epm install $TOINSTALL
594
        return
595
    fi
596

597
    case $req_file in
598
        requirements/default.txt|requirements/dev.txt|requirements/test.txt|requirements/coverage.txt)
599
            [ -s "$req_file" ] && __epm_restore_pip "$req_file" && return
600
            ;;
601
    esac
602

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"
606
            ;;
607
        setup.py|python_dependencies.py)
608
            [ -s "$req_file" ] && __epm_restore_setup_py "$req_file"
609
            ;;
610
        pyproject.toml)
611
            [ -s "$req_file" ] && __epm_restore_pyproject "$req_file"
612
            ;;
613
        package.json)
614
            [ -s "$req_file" ] && __epm_restore_npm "$req_file"
615
            ;;
616
        meson.build)
617
            [ -s "$req_file" ] && __epm_restore_meson "$req_file"
618
            ;;
619
#        META.yml)
620
#            [ -s "$req_file" ] && __epm_restore_perl "$req_file"
621
#            ;;
622
        Makefile.PL)
623
            [ -s "$req_file" ] && __epm_restore_perl "$req_file"
624
            ;;
625
        *.sln|*.csproj)
626
            local PROJ="$(echo $req_file)"
627
            [ -s "$PROJ" ] && __epm_restore_nupkg "$PROJ"
628
            ;;
629
        Gemfile|package.json)
630
            info "$req_file support is not implemented yet"
631
            ;;
632
    esac
633
}
634

635
epm_restore()
636
{
637
    req_file="$pkg_filenames"
638
    if [ -n "$pkg_urls" ] && echo "$pkg_urls" | grep -qE "^https?://" ; then
639
        req_file="$(basename "$pkg_urls")"
640
        #assure eget
641
        [ -r "$req_file" ] && fatal "File $req_file is already exists in $(pwd)"
642
        info "Downloading '$req_file' from '$pkg_urls' ..."
643
        eget "$pkg_urls"
644
        [ -s "$req_file" ] || fatal "Can't download $req_file from '$pkg_urls'"
645
    fi
646

647
    if [ -n "$req_file" ] ; then
648
        __epm_restore_by $req_file
649
        return
650
    fi
651

652
# TODO: nowhere works: python3 setup.py --requires
653

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 \
658
             *.sln *.csproj ; do
659
        __epm_restore_by $i
660
    done
661

662
}
663

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.