pyarmor.cli 9.2.6__4-py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyarmor/cli/__init__.py +46 -0
- pyarmor/cli/__main__.py +812 -0
- pyarmor/cli/batch.py +62 -0
- pyarmor/cli/bootstrap.py +207 -0
- pyarmor/cli/bug.py +137 -0
- pyarmor/cli/command.py +563 -0
- pyarmor/cli/config.py +306 -0
- pyarmor/cli/context.py +790 -0
- pyarmor/cli/core.data.1 +0 -0
- pyarmor/cli/core.data.2 +0 -0
- pyarmor/cli/core.data.3 +0 -0
- pyarmor/cli/default.cfg +564 -0
- pyarmor/cli/docker.py +192 -0
- pyarmor/cli/generate.py +256 -0
- pyarmor/cli/hdinfo.py +81 -0
- pyarmor/cli/merge.py +232 -0
- pyarmor/cli/mixer.py +109 -0
- pyarmor/cli/model.py +460 -0
- pyarmor/cli/plugin.py +292 -0
- pyarmor/cli/project.py +1281 -0
- pyarmor/cli/public_capsule.zip +0 -0
- pyarmor/cli/register.py +1093 -0
- pyarmor/cli/repack.py +793 -0
- pyarmor/cli/resource.py +265 -0
- pyarmor/cli/shell.py +481 -0
- pyarmor_cli-9.2.6.dist-info/METADATA +74 -0
- pyarmor_cli-9.2.6.dist-info/RECORD +30 -0
- pyarmor_cli-9.2.6.dist-info/WHEEL +6 -0
- pyarmor_cli-9.2.6.dist-info/entry_points.txt +3 -0
- pyarmor_cli-9.2.6.dist-info/top_level.txt +1 -0
pyarmor/cli/batch.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#! /usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
#############################################################
|
|
5
|
+
# #
|
|
6
|
+
# Copyright @ 2025 - Dashingsoft corp. #
|
|
7
|
+
# All rights reserved. #
|
|
8
|
+
# #
|
|
9
|
+
# Pyarmor #
|
|
10
|
+
# #
|
|
11
|
+
# Version: 9.2.1 - #
|
|
12
|
+
# #
|
|
13
|
+
#############################################################
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# @File: cli/shell.py
|
|
17
|
+
#
|
|
18
|
+
# @Author: Jondy Zhao (pyarmor@163.com)
|
|
19
|
+
#
|
|
20
|
+
# @Create Date: Wed Nov 5 20:22:52 CST 2025
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
"""This script could run batch pyarmor commands.
|
|
24
|
+
|
|
25
|
+
For example:
|
|
26
|
+
|
|
27
|
+
python3 -m pyarmor.cli.batch build-script.sh
|
|
28
|
+
|
|
29
|
+
cd abc
|
|
30
|
+
pyarmor
|
|
31
|
+
|
|
32
|
+
The main purpose is to fix pyarmor CI License send too many request issues.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
import shlex
|
|
36
|
+
import os
|
|
37
|
+
|
|
38
|
+
from pyarmor.cli.__main__ import main_entry as pyarmor_run
|
|
39
|
+
|
|
40
|
+
# Do not run `pyarmor reg pyarmor-ci-xxxx.zip` here, run it before this script
|
|
41
|
+
|
|
42
|
+
build_commands = """
|
|
43
|
+
pyarmor gen main.py
|
|
44
|
+
cd ../package1
|
|
45
|
+
pyarmor gen -R --enable-bcc src/
|
|
46
|
+
cd ../package2
|
|
47
|
+
pyarmor gen -R --enable-jit --private src/
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
for cmd in build_commands.splitlines():
|
|
51
|
+
if cmd.startswith('#'):
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
if cmd.startswith('cd '):
|
|
55
|
+
path = cmd[3:].strip()
|
|
56
|
+
print('Change current path:', path)
|
|
57
|
+
os.chdir(path)
|
|
58
|
+
|
|
59
|
+
elif cmd.startswith('pyarmor '):
|
|
60
|
+
print('Execute: ', cmd)
|
|
61
|
+
args = shlex.split(cmd[8:].strip())
|
|
62
|
+
pyarmor_run(args)
|
pyarmor/cli/bootstrap.py
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#! /usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
#############################################################
|
|
5
|
+
# #
|
|
6
|
+
# Copyright @ 2023 - Dashingsoft corp. #
|
|
7
|
+
# All rights reserved. #
|
|
8
|
+
# #
|
|
9
|
+
# Pyarmor #
|
|
10
|
+
# #
|
|
11
|
+
# Version: 8.2.1 - #
|
|
12
|
+
# #
|
|
13
|
+
#############################################################
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# @File: pyarmor/cli/bootstrap.py
|
|
17
|
+
#
|
|
18
|
+
# @Author: Jondy Zhao (pyarmor@163.com)
|
|
19
|
+
#
|
|
20
|
+
# @Create Date: Fri Apr 14 17:43:59 CST 2023
|
|
21
|
+
#
|
|
22
|
+
import logging
|
|
23
|
+
import os
|
|
24
|
+
import shutil
|
|
25
|
+
import sys
|
|
26
|
+
|
|
27
|
+
from subprocess import check_output, check_call, Popen, PIPE
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def check_prebuilt_runtime_library(platnames, extra=None, rtver=''):
|
|
31
|
+
pkgpath = os.path.normpath(os.path.dirname(__file__))
|
|
32
|
+
corepath = os.path.join(pkgpath, 'core')
|
|
33
|
+
if not os.path.exists(corepath):
|
|
34
|
+
raise RuntimeError('no found "{0}", please run "pip install {0}" to '
|
|
35
|
+
'install it'.format('pyarmor.cli.core'))
|
|
36
|
+
|
|
37
|
+
instcmd = [sys.executable, '-m', 'pip', 'install',
|
|
38
|
+
'--disable-pip-version-check']
|
|
39
|
+
|
|
40
|
+
# Before Pyarmor 8.3, prefer to "pyarmor.cli.runtime"
|
|
41
|
+
# It could be disabled by
|
|
42
|
+
# pyarmor cfg pyarmor:cli.runtime = false
|
|
43
|
+
if rtver.find('.') > 0:
|
|
44
|
+
runtime_pkgpath = os.path.join(pkgpath, 'runtime')
|
|
45
|
+
if os.path.exists(runtime_pkgpath):
|
|
46
|
+
from pyarmor.cli.runtime import __VERSION__ as current_rtver
|
|
47
|
+
if current_rtver == rtver:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
pkgver = 'pyarmor.cli.runtime~=%s' % rtver
|
|
51
|
+
logging.info('install "%s" for cross platforms', pkgver)
|
|
52
|
+
try:
|
|
53
|
+
return check_call(instcmd + [pkgver])
|
|
54
|
+
except Exception:
|
|
55
|
+
logging.warning('failed to install "%s"' % pkgver)
|
|
56
|
+
|
|
57
|
+
# From Pyarmor 8.3, prefer to "pyarmor.cli.core.PLATFORM"
|
|
58
|
+
from pyarmor.cli.core import __VERSION__ as corever
|
|
59
|
+
|
|
60
|
+
pkgnames = set(extra if isinstance(extra, list) else
|
|
61
|
+
[extra] if isinstance(extra, str) else
|
|
62
|
+
['themida'] if extra else [])
|
|
63
|
+
if platnames:
|
|
64
|
+
for plat in platnames:
|
|
65
|
+
pkgnames.add(plat.split('.')[0])
|
|
66
|
+
|
|
67
|
+
for entry in os.scandir(corepath):
|
|
68
|
+
if entry.name in pkgnames:
|
|
69
|
+
m = __import__('pyarmor.cli.core.' + entry.name,
|
|
70
|
+
globals(), locals(),
|
|
71
|
+
['__VERSION__'], 0)
|
|
72
|
+
if getattr(m, '__VERSION__', None) == corever:
|
|
73
|
+
pkgnames.remove(entry.name)
|
|
74
|
+
|
|
75
|
+
if pkgnames:
|
|
76
|
+
pkgvers = ['pyarmor.cli.core.%s~=%s' % (x, corever) for x in pkgnames]
|
|
77
|
+
logging.info('install packages %s for cross platforms', str(pkgvers))
|
|
78
|
+
try:
|
|
79
|
+
check_call(instcmd + pkgvers)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logging.error('%s', e)
|
|
82
|
+
raise RuntimeError('failed to install runtime packages')
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _shell_cmd(cmdlist):
|
|
86
|
+
logging.info('run: %s', ' '.join(cmdlist))
|
|
87
|
+
p = Popen(cmdlist, stdout=PIPE, stderr=PIPE, shell=True)
|
|
88
|
+
stdout, stderr = p.communicate()
|
|
89
|
+
return p.returncode, stderr
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _check_extension(fullpath):
|
|
93
|
+
if not os.path.exists(fullpath):
|
|
94
|
+
logging.error('please re-install pyarmor.cli.core to fix this problem')
|
|
95
|
+
raise RuntimeError('no found extension "%s"' % fullpath)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _fixup_darwin_rpath(fullpath, pyver):
|
|
99
|
+
output = check_output(['otool', '-L', sys.executable])
|
|
100
|
+
for line in output.splitlines():
|
|
101
|
+
if line.find(b'Frameworks/Python.framework/Versions') > 0:
|
|
102
|
+
pydll = line.split()[0].decode()
|
|
103
|
+
logging.info('found CPython library "%s"', pydll)
|
|
104
|
+
break
|
|
105
|
+
|
|
106
|
+
if line.find(('libpython' + pyver).encode('utf-8')) > 0:
|
|
107
|
+
pydll = line.split()[0].decode()
|
|
108
|
+
logging.info('found CPython library "%s"', pydll)
|
|
109
|
+
break
|
|
110
|
+
else:
|
|
111
|
+
raise RuntimeError('no found CPython library')
|
|
112
|
+
|
|
113
|
+
# old = '@rpath/Frameworks/Python.framework/Versions/%s/Python' % pyver
|
|
114
|
+
old = '@rpath/lib/libpython%s.dylib' % pyver
|
|
115
|
+
cmdlist = ['install_name_tool', '-change', old, pydll, fullpath]
|
|
116
|
+
rc, err = _shell_cmd(cmdlist)
|
|
117
|
+
if rc:
|
|
118
|
+
raise RuntimeError('install_name_tool failed (%d): %s' % (rc, err))
|
|
119
|
+
|
|
120
|
+
identity = '-'
|
|
121
|
+
cmdlist = ['codesign', '-s', identity, '--force',
|
|
122
|
+
'--all-architectures', '--timestamp', fullpath]
|
|
123
|
+
rc, err = _shell_cmd(cmdlist)
|
|
124
|
+
if rc:
|
|
125
|
+
raise RuntimeError('codesign failed (%d): %s' % (rc, err))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _fixup_darwin(path, filename, pyver):
|
|
129
|
+
fullpath = os.path.join(path, filename)
|
|
130
|
+
_check_extension(fullpath)
|
|
131
|
+
|
|
132
|
+
if not os.access(path, os.W_OK):
|
|
133
|
+
logging.error('please run Python with super user or anyone who has'
|
|
134
|
+
'write permission on path "%s"', path)
|
|
135
|
+
raise RuntimeError('current user has no write permission')
|
|
136
|
+
|
|
137
|
+
backup = fullpath + '.bak'
|
|
138
|
+
if os.path.exists(backup):
|
|
139
|
+
logging.info('create backup file "%s"', backup)
|
|
140
|
+
shutil.copy2(fullpath, backup)
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
logging.info('start to fixup extension "%s"', fullpath)
|
|
144
|
+
_fixup_darwin_rpath(fullpath, pyver)
|
|
145
|
+
|
|
146
|
+
logging.info('fixup extension "pytransform3" successfully')
|
|
147
|
+
logging.info('try command ``pyarmor gen foo.py`` to make sure '
|
|
148
|
+
'it works')
|
|
149
|
+
logging.info('if something is wrong, please restore it from '
|
|
150
|
+
'backup file')
|
|
151
|
+
except Exception:
|
|
152
|
+
logging.error('fixup extension "pytransform3" failed')
|
|
153
|
+
shutil.move(backup, fullpath)
|
|
154
|
+
raise
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _fixup_linux(path, filename, pyver):
|
|
158
|
+
fullpath = os.path.join(path, filename)
|
|
159
|
+
_check_extension(fullpath)
|
|
160
|
+
|
|
161
|
+
rc = _shell_cmd(['ldd', fullpath])
|
|
162
|
+
if rc:
|
|
163
|
+
logging.info('try to install package "libpython%s" to fix it' % pyver)
|
|
164
|
+
else:
|
|
165
|
+
logging.info('nothing to do in this platform')
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _fixup_windows(path, filename, pyver):
|
|
169
|
+
fullpath = os.path.join(path, filename)
|
|
170
|
+
_check_extension(fullpath)
|
|
171
|
+
logging.info('nothing to do in this platform')
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def auto_fix(path):
|
|
175
|
+
'''Deprecated since Pyarmor 8.3.0'''
|
|
176
|
+
pyver = '%s.%s' % sys.version_info[:2]
|
|
177
|
+
plat = sys.platform.lower()
|
|
178
|
+
|
|
179
|
+
if plat.startswith('darwin'):
|
|
180
|
+
_fixup_darwin(path, 'pytransform3.so', pyver)
|
|
181
|
+
|
|
182
|
+
elif plat.startswith('win'):
|
|
183
|
+
_fixup_windows(path, 'pytransform3.pyd', pyver)
|
|
184
|
+
|
|
185
|
+
elif plat.startswith('linux'):
|
|
186
|
+
_fixup_windows(path, 'pytransform3.so', pyver)
|
|
187
|
+
|
|
188
|
+
else:
|
|
189
|
+
logging.info('nothing to fixup in this platform "%s"', plat)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def main():
|
|
193
|
+
logging.basicConfig(
|
|
194
|
+
level=logging.INFO,
|
|
195
|
+
format='%(levelname)-8s %(message)s',
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
logging.info('Python: %d.%d', *sys.version_info[:2])
|
|
199
|
+
corepath = os.path.join(os.path.dirname(__file__), 'core')
|
|
200
|
+
logging.info('pyarmor.cli.core: %s', corepath)
|
|
201
|
+
# auto_fix(corepath)
|
|
202
|
+
logging.warning('this feature has been deprecated since Pyarmor 8.3.0')
|
|
203
|
+
logging.info('nothing to do')
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
if __name__ == '__main__':
|
|
207
|
+
main()
|
pyarmor/cli/bug.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#! /usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
#############################################################
|
|
5
|
+
# #
|
|
6
|
+
# Copyright @ 2024 - Dashingsoft corp. #
|
|
7
|
+
# All rights reserved. #
|
|
8
|
+
# #
|
|
9
|
+
# Pyarmor #
|
|
10
|
+
# #
|
|
11
|
+
# Version: 8.5.1 - #
|
|
12
|
+
# #
|
|
13
|
+
#############################################################
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# @File: cli/bug.py
|
|
17
|
+
#
|
|
18
|
+
# @Author: Jondy Zhao (pyarmor@163.com)
|
|
19
|
+
#
|
|
20
|
+
# @Create Date: Tue Mar 12 15:19:41 CST 2024
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#############################################################
|
|
24
|
+
# #
|
|
25
|
+
# Deprecated since Pyarmor 9, use `pyarmor man` instead #
|
|
26
|
+
# #
|
|
27
|
+
#############################################################
|
|
28
|
+
|
|
29
|
+
import logging
|
|
30
|
+
|
|
31
|
+
from string import Template
|
|
32
|
+
|
|
33
|
+
BUG_FILE, LOG_FILE = 'pyarmor.report.bug', '.pyarmor/pyarmor.debug.log'
|
|
34
|
+
|
|
35
|
+
BUG_TEMPLATE = Template('''[Bug] $title
|
|
36
|
+
|
|
37
|
+
### Full command options and console output
|
|
38
|
+
$cmdline
|
|
39
|
+
|
|
40
|
+
$tracelog
|
|
41
|
+
|
|
42
|
+
### Traceback
|
|
43
|
+
$tb
|
|
44
|
+
''')
|
|
45
|
+
|
|
46
|
+
UNUSED_ENABLE_DEBUG_HINTS = '''something is wrong
|
|
47
|
+
*=============================================================*
|
|
48
|
+
* Please enable debug option `-d` to run it again *
|
|
49
|
+
* pyarmor -d gen options ... *
|
|
50
|
+
* *
|
|
51
|
+
* Then check console log to find more information *
|
|
52
|
+
* *
|
|
53
|
+
* Please also check *
|
|
54
|
+
* https://pyarmor.readthedocs.io/en/latest/questions.html *
|
|
55
|
+
*=============================================================*
|
|
56
|
+
'''
|
|
57
|
+
|
|
58
|
+
UNUSED_SOLUTION_HINTS = Template('''something is wrong
|
|
59
|
+
*=============================================================*
|
|
60
|
+
* Please check *
|
|
61
|
+
* https://pyarmor.readthedocs.io/en/latest/questions.html *
|
|
62
|
+
* or run `pyarmor man` to find solutions quickly *
|
|
63
|
+
* *
|
|
64
|
+
* It's recommand to report issue by `pyarmor man` in order *
|
|
65
|
+
* to provide necessary information, and avoid dupcliated *
|
|
66
|
+
* issues or unclear question. *
|
|
67
|
+
*=============================================================*
|
|
68
|
+
''')
|
|
69
|
+
|
|
70
|
+
ENABLE_DEBUG_HINTS = 'please enable debug option `-d` to run it again'
|
|
71
|
+
|
|
72
|
+
SOLUTION_HINTS = Template('''
|
|
73
|
+
*=============================================================*
|
|
74
|
+
* Please check console log to find out what's wrong *
|
|
75
|
+
* *
|
|
76
|
+
* If still not solved, please find solutions by *
|
|
77
|
+
* https://pyarmor.readthedocs.io/en/latest/questions.html *
|
|
78
|
+
*=============================================================*
|
|
79
|
+
''')
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def generate_bug_report(e, logfile=LOG_FILE, output=BUG_FILE):
|
|
83
|
+
'Generate file `pyarmor.report.bug` in current path'
|
|
84
|
+
from os.path import exists
|
|
85
|
+
from sys import argv
|
|
86
|
+
from traceback import format_exc
|
|
87
|
+
|
|
88
|
+
if exists(logfile):
|
|
89
|
+
with open(logfile, 'r') as f:
|
|
90
|
+
lines = f.readlines()
|
|
91
|
+
n = len(lines)
|
|
92
|
+
if n > 128:
|
|
93
|
+
tracelog = ''.join(lines[:100] + ['...\n'] + lines[n-20:n])
|
|
94
|
+
else:
|
|
95
|
+
tracelog = ''.join(lines[:n])
|
|
96
|
+
else:
|
|
97
|
+
tracelog = Template(
|
|
98
|
+
'TODO: no found logfile "$logfile", please paste console log '
|
|
99
|
+
'here manually').substitute(logfile=logfile)
|
|
100
|
+
|
|
101
|
+
title = '%s: %s' % (type(e).__name__, str(e))
|
|
102
|
+
with open(output, 'w') as f:
|
|
103
|
+
f.write(BUG_TEMPLATE.substitute(
|
|
104
|
+
title=title,
|
|
105
|
+
cmdline=' '.join(argv),
|
|
106
|
+
tracelog=tracelog,
|
|
107
|
+
tb=format_exc()
|
|
108
|
+
))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def find_solutions(e):
|
|
112
|
+
'''Print quick solutions according to exception
|
|
113
|
+
|
|
114
|
+
If not enable debug, tell user try `pyarmor -d cmd...`
|
|
115
|
+
|
|
116
|
+
If it raises CliError, print possible solutions
|
|
117
|
+
|
|
118
|
+
For unknown error, print FAQ page link and `pyarmor man`
|
|
119
|
+
|
|
120
|
+
Pyarmor Man is designed to help Pyarmor users to learn
|
|
121
|
+
and use Pyarmor by web-ui, to find solution quickly when
|
|
122
|
+
something is wrong, to report bugs and ask questions in
|
|
123
|
+
standard form in order to save both Pyarmor team's and
|
|
124
|
+
Pyarmor users' time.
|
|
125
|
+
'''
|
|
126
|
+
logger = logging.getLogger()
|
|
127
|
+
if logger.getEffectiveLevel() > logging.DEBUG:
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
print('\nDebug Information:')
|
|
131
|
+
logger.info('generate bug file "%s"', BUG_FILE)
|
|
132
|
+
generate_bug_report(e)
|
|
133
|
+
logger.info(SOLUTION_HINTS.substitute(bugfile=BUG_FILE))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
if __name__ == '__main__':
|
|
137
|
+
pass
|