pyarmor.cli 9.2.5__2-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.5.dist-info/METADATA +74 -0
- pyarmor_cli-9.2.5.dist-info/RECORD +30 -0
- pyarmor_cli-9.2.5.dist-info/WHEEL +6 -0
- pyarmor_cli-9.2.5.dist-info/entry_points.txt +3 -0
- pyarmor_cli-9.2.5.dist-info/top_level.txt +1 -0
pyarmor/cli/model.py
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
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: 9.1.0 - #
|
|
12
|
+
# #
|
|
13
|
+
#############################################################
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# @File: cli/model.py
|
|
17
|
+
#
|
|
18
|
+
# @Author: Jondy Zhao (pyarmor@163.com)
|
|
19
|
+
#
|
|
20
|
+
# @Create Date: Sun Dec 8 07:36:16 CST 2024
|
|
21
|
+
#
|
|
22
|
+
from textwrap import dedent
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Item:
|
|
26
|
+
|
|
27
|
+
def __init__(self, name, cls=None, require=False, many=False):
|
|
28
|
+
self.name = name
|
|
29
|
+
self.cls = cls
|
|
30
|
+
self.require = require
|
|
31
|
+
self.many = many
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Option:
|
|
35
|
+
|
|
36
|
+
def __init__(self, name, parent=None, model=None):
|
|
37
|
+
self.name = name
|
|
38
|
+
self.parent = parent
|
|
39
|
+
self.model = model
|
|
40
|
+
self._value = None
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def value(self):
|
|
44
|
+
if self._value is None:
|
|
45
|
+
self._value = self.parent.fetch(self.name)
|
|
46
|
+
if self._value is None:
|
|
47
|
+
return self.model.value
|
|
48
|
+
return self._value
|
|
49
|
+
|
|
50
|
+
@value.setter
|
|
51
|
+
def value(self, data: str):
|
|
52
|
+
if data:
|
|
53
|
+
self.check(data)
|
|
54
|
+
self._value = data
|
|
55
|
+
self.parent.store(self.name, data)
|
|
56
|
+
else:
|
|
57
|
+
self.reset()
|
|
58
|
+
|
|
59
|
+
def check(self, data: str):
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def hints(self):
|
|
63
|
+
return ''
|
|
64
|
+
|
|
65
|
+
def usage(self):
|
|
66
|
+
fmt = '%-20s: %s'
|
|
67
|
+
hints = [self.hints()]
|
|
68
|
+
hints.extend([(fmt % x) for x in self.model.hints()])
|
|
69
|
+
if getattr(self, 'CHOICES', None):
|
|
70
|
+
values = ', '.join(self.CHOICES)
|
|
71
|
+
hints.append(fmt % ('Available values', values))
|
|
72
|
+
hints.append('')
|
|
73
|
+
return '\n'.join(hints)
|
|
74
|
+
|
|
75
|
+
def push(self, data: str):
|
|
76
|
+
items = self.value.splitlines() if self.value else []
|
|
77
|
+
value = data.strip()
|
|
78
|
+
if value not in items:
|
|
79
|
+
items.append(value)
|
|
80
|
+
self.value = '\n'.join(items)
|
|
81
|
+
|
|
82
|
+
def pop(self, data: str):
|
|
83
|
+
items = self.value.splitlines() if self.value else []
|
|
84
|
+
try:
|
|
85
|
+
items.remove(data.strip())
|
|
86
|
+
except ValueError:
|
|
87
|
+
pass
|
|
88
|
+
else:
|
|
89
|
+
self.value = '\n'.join(items)
|
|
90
|
+
|
|
91
|
+
def reset(self):
|
|
92
|
+
"""Clear option settings"""
|
|
93
|
+
self.parent.remove(self.name)
|
|
94
|
+
self._value = None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class OptionModel:
|
|
98
|
+
|
|
99
|
+
def __init__(self, name, cls=None, **kwargs):
|
|
100
|
+
self.name = name
|
|
101
|
+
self.cls = cls
|
|
102
|
+
self.kwargs = kwargs
|
|
103
|
+
|
|
104
|
+
def factory(self, parent):
|
|
105
|
+
Cls = globals().get(self.cls, Option)
|
|
106
|
+
return Cls(self.name, parent=parent, model=self)
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def many(self):
|
|
110
|
+
"""This option may has many values"""
|
|
111
|
+
return self.kwargs.get('many', False)
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def value(self):
|
|
115
|
+
"""The default value for this option"""
|
|
116
|
+
return self.kwargs.get('value')
|
|
117
|
+
|
|
118
|
+
def hints(self):
|
|
119
|
+
return [('Type', self.cls), ('Many', self.many)]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class PathOption(Option):
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class PkgPathOption(PathOption):
|
|
127
|
+
|
|
128
|
+
def hints(self):
|
|
129
|
+
return dedent("""\
|
|
130
|
+
It could be relative path or absolute path.
|
|
131
|
+
|
|
132
|
+
If package name is different from last path, use suffix format "path@pkgname"
|
|
133
|
+
""")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class FileOption(PathOption):
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class BoolOption(Option):
|
|
141
|
+
|
|
142
|
+
CHOICES = '0', '1'
|
|
143
|
+
|
|
144
|
+
def check(self, data: str):
|
|
145
|
+
if data not in self.CHOICES:
|
|
146
|
+
raise ValueError('invalid %s' % repr(data))
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class EnumOption(Option):
|
|
150
|
+
|
|
151
|
+
def check(self, data: str):
|
|
152
|
+
if data not in self.CHOICES:
|
|
153
|
+
raise ValueError('invalid %s' % repr(data))
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class TextOption(Option):
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class NameOption(TextOption):
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class PatternOption(TextOption):
|
|
165
|
+
"""re or fnmatch pattern"""
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class ListOption(Option):
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class DictOption(Option):
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class RftAttrEnum(EnumOption):
|
|
178
|
+
"""When don't know how to rename attribute
|
|
179
|
+
|
|
180
|
+
- ask: query user interactively
|
|
181
|
+
- log: log it but no rename
|
|
182
|
+
- yes: always rename
|
|
183
|
+
- no: do thing
|
|
184
|
+
- err: raise error quit
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
CHOICES = 'ask', 'log', 'yes', 'no', 'err'
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class RftArgEnum(EnumOption):
|
|
191
|
+
"""How to rename argument
|
|
192
|
+
|
|
193
|
+
- 0: no rename arguments
|
|
194
|
+
- 1: rename posonly arguments
|
|
195
|
+
- 2: rename kwonly arguments
|
|
196
|
+
- 3: rename all arguments
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
CHOICES = '0', '1', '2', '3'
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class RftNamePattern(TextOption):
|
|
203
|
+
"""Match ast.Name in ast.Tree
|
|
204
|
+
|
|
205
|
+
Each pattern includes 2 parts:
|
|
206
|
+
|
|
207
|
+
- ModulePattern: fnmatchcase pattern, match module
|
|
208
|
+
|
|
209
|
+
- NamePattern: fnmatchcase pattern, match function/class/name
|
|
210
|
+
"""
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class RftAttrFilter(ListOption):
|
|
215
|
+
"""Filter ast.Attribute transformed to setattr/getattr
|
|
216
|
+
|
|
217
|
+
Each ruler include 3 patterns
|
|
218
|
+
|
|
219
|
+
- ModulePattern: fnmatchcase pattern, match module
|
|
220
|
+
|
|
221
|
+
- ScopePattern: fnmatchcase pattern, match function/class
|
|
222
|
+
|
|
223
|
+
- AttributePattern: fnmatchcase pattern, match attribute
|
|
224
|
+
|
|
225
|
+
a: match any attribute "a"
|
|
226
|
+
b.a: match only "b.a"
|
|
227
|
+
a*: match any attribute startswith "a"
|
|
228
|
+
b.a*: match any "b" attribute which startswith "a"
|
|
229
|
+
b*.a: match any attribute "a" in parent startswith "b"
|
|
230
|
+
().a: parent is function call
|
|
231
|
+
[].a: parent is subscript
|
|
232
|
+
|
|
233
|
+
*.a: same as "a"
|
|
234
|
+
"""
|
|
235
|
+
pass
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
SECTIONS = {
|
|
239
|
+
'pyarmor': [],
|
|
240
|
+
'finder': [],
|
|
241
|
+
'builder': [],
|
|
242
|
+
'pack': [],
|
|
243
|
+
|
|
244
|
+
# Group: filter
|
|
245
|
+
'assert.import': [],
|
|
246
|
+
'assert.call': [],
|
|
247
|
+
'mix.str': [],
|
|
248
|
+
|
|
249
|
+
# Group bcc
|
|
250
|
+
'bcc': [],
|
|
251
|
+
|
|
252
|
+
# Scope project
|
|
253
|
+
'project': [
|
|
254
|
+
|
|
255
|
+
OptionModel(
|
|
256
|
+
name='src',
|
|
257
|
+
cls='PathOption',
|
|
258
|
+
examples=[
|
|
259
|
+
'', '.', 'src', '../src',
|
|
260
|
+
'/home/jondy/project/src1',
|
|
261
|
+
'my projects/project/src4'
|
|
262
|
+
'C:\\test\\src2', 'C:\\工程\\src3',
|
|
263
|
+
]
|
|
264
|
+
),
|
|
265
|
+
|
|
266
|
+
OptionModel(
|
|
267
|
+
name='scripts',
|
|
268
|
+
cls='FileOption',
|
|
269
|
+
many=True,
|
|
270
|
+
restricts=[
|
|
271
|
+
'ext should be .py, .pyw',
|
|
272
|
+
'relative to src, or absolute path',
|
|
273
|
+
],
|
|
274
|
+
examples=['foo.py', 'test/run.py']
|
|
275
|
+
),
|
|
276
|
+
|
|
277
|
+
OptionModel(
|
|
278
|
+
name='modules',
|
|
279
|
+
cls='FileOption',
|
|
280
|
+
many=True,
|
|
281
|
+
),
|
|
282
|
+
|
|
283
|
+
OptionModel(
|
|
284
|
+
name='packages',
|
|
285
|
+
cls='PkgPathOption',
|
|
286
|
+
many=True,
|
|
287
|
+
),
|
|
288
|
+
|
|
289
|
+
# Only match name, no path separator
|
|
290
|
+
OptionModel(
|
|
291
|
+
name='excludes',
|
|
292
|
+
cls='PatternOption',
|
|
293
|
+
many=True,
|
|
294
|
+
examples=['__pycache__', 'test*']
|
|
295
|
+
),
|
|
296
|
+
|
|
297
|
+
OptionModel(
|
|
298
|
+
name='recursive',
|
|
299
|
+
cls='BoolOption',
|
|
300
|
+
value=0,
|
|
301
|
+
),
|
|
302
|
+
OptionModel(
|
|
303
|
+
name='pypaths',
|
|
304
|
+
cls='PatternOption',
|
|
305
|
+
many=True,
|
|
306
|
+
),
|
|
307
|
+
],
|
|
308
|
+
|
|
309
|
+
'rft': [
|
|
310
|
+
OptionModel(
|
|
311
|
+
name='remove_assert',
|
|
312
|
+
cls='BoolOption',
|
|
313
|
+
value=0,
|
|
314
|
+
),
|
|
315
|
+
OptionModel(
|
|
316
|
+
name='remove_docstr',
|
|
317
|
+
cls='BoolOption',
|
|
318
|
+
value=0,
|
|
319
|
+
),
|
|
320
|
+
OptionModel(
|
|
321
|
+
name='builtin_mode',
|
|
322
|
+
cls='BoolOption',
|
|
323
|
+
value=0,
|
|
324
|
+
),
|
|
325
|
+
OptionModel(
|
|
326
|
+
name='argument_mode',
|
|
327
|
+
cls='RftArgEnum',
|
|
328
|
+
value='3',
|
|
329
|
+
),
|
|
330
|
+
OptionModel(
|
|
331
|
+
name='export_mode',
|
|
332
|
+
cls='BoolOption',
|
|
333
|
+
value=0,
|
|
334
|
+
),
|
|
335
|
+
OptionModel(
|
|
336
|
+
name='extra_builtins',
|
|
337
|
+
cls='NameOption',
|
|
338
|
+
many=True,
|
|
339
|
+
),
|
|
340
|
+
OptionModel(
|
|
341
|
+
name='exclude_names',
|
|
342
|
+
cls='RftNamePattern',
|
|
343
|
+
many=True,
|
|
344
|
+
),
|
|
345
|
+
OptionModel(
|
|
346
|
+
name='exclude_funcs',
|
|
347
|
+
cls='RftNamePattern',
|
|
348
|
+
many=True,
|
|
349
|
+
),
|
|
350
|
+
OptionModel(
|
|
351
|
+
name='external_types',
|
|
352
|
+
cls='RftNamePattern',
|
|
353
|
+
many=True,
|
|
354
|
+
),
|
|
355
|
+
OptionModel(
|
|
356
|
+
name='external_attrs',
|
|
357
|
+
cls='RftNamePattern',
|
|
358
|
+
many=True,
|
|
359
|
+
),
|
|
360
|
+
OptionModel(
|
|
361
|
+
name='attr_rules',
|
|
362
|
+
cls='RftAttrFilter',
|
|
363
|
+
),
|
|
364
|
+
OptionModel(
|
|
365
|
+
name='call_rules',
|
|
366
|
+
cls='RftAttrFilter',
|
|
367
|
+
),
|
|
368
|
+
OptionModel(
|
|
369
|
+
name='var_types',
|
|
370
|
+
cls='DictOption',
|
|
371
|
+
),
|
|
372
|
+
],
|
|
373
|
+
'rft_filter': [
|
|
374
|
+
OptionModel(
|
|
375
|
+
name='obf_attribute',
|
|
376
|
+
cls='BoolOption',
|
|
377
|
+
),
|
|
378
|
+
OptionModel(
|
|
379
|
+
name='obf_string',
|
|
380
|
+
cls='BoolOption',
|
|
381
|
+
),
|
|
382
|
+
OptionModel(
|
|
383
|
+
name='obf_include_strings',
|
|
384
|
+
cls='PatternOption',
|
|
385
|
+
many=True,
|
|
386
|
+
),
|
|
387
|
+
OptionModel(
|
|
388
|
+
name='obf_attr_filters',
|
|
389
|
+
cls='RftAttrFilter',
|
|
390
|
+
),
|
|
391
|
+
OptionModel(
|
|
392
|
+
name='rft_import',
|
|
393
|
+
cls='BoolOption',
|
|
394
|
+
),
|
|
395
|
+
OptionModel(
|
|
396
|
+
name='rft_ximport',
|
|
397
|
+
cls='BoolOption',
|
|
398
|
+
),
|
|
399
|
+
OptionModel(
|
|
400
|
+
name='wildcard_import_table',
|
|
401
|
+
cls='DictOption',
|
|
402
|
+
),
|
|
403
|
+
],
|
|
404
|
+
'mini': [
|
|
405
|
+
OptionModel(
|
|
406
|
+
name='import_from',
|
|
407
|
+
cls='NameOption',
|
|
408
|
+
value='pyarmor.mini.pyarmor_mini',
|
|
409
|
+
),
|
|
410
|
+
],
|
|
411
|
+
'vmc': [],
|
|
412
|
+
'ecc': [],
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
GROUPS = {
|
|
417
|
+
'filter': ('assert.import', 'assert.call', 'mix.str'),
|
|
418
|
+
'bcc': ('bcc',
|
|
419
|
+
'linux.x86_64.bcc', 'linux.x86.bcc',
|
|
420
|
+
'linux.aarch64.bcc', 'linux.armv7.bcc',
|
|
421
|
+
'darwin.x86_64.bcc', 'darwin.aarch64.bcc',
|
|
422
|
+
'windows.x86_64.bcc', 'windows.x86.bcc',
|
|
423
|
+
'android.x86_64.bcc', 'android.x86.bcc',
|
|
424
|
+
'android.aarch64.bcc', 'android.armv7.bcc',
|
|
425
|
+
'alpine.x86_64.bcc', 'alpine.aarch64.bcc',
|
|
426
|
+
'freebsd.x86_64.bcc'),
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
BUSINESS_MODELS = {
|
|
430
|
+
|
|
431
|
+
'Project': [
|
|
432
|
+
Item('scripts', cls='Python.Script', many=True),
|
|
433
|
+
Item('modules', cls='Python.Module', many=True),
|
|
434
|
+
Item('packages', cls='Python.Package', many=True),
|
|
435
|
+
],
|
|
436
|
+
|
|
437
|
+
'StdScript': [
|
|
438
|
+
Item('script', cls='Python.Script', require=True),
|
|
439
|
+
Item('pyarmor_runtime', cls='Python.Extension', require=True),
|
|
440
|
+
],
|
|
441
|
+
|
|
442
|
+
'MiniScript': [
|
|
443
|
+
Item('script', cls='Python.Script', require=True),
|
|
444
|
+
Item('pyarmor_mini', cls='Python.Extension', require=True),
|
|
445
|
+
],
|
|
446
|
+
|
|
447
|
+
'EccScript': [
|
|
448
|
+
Item('script', cls='Python.Script', require=True),
|
|
449
|
+
Item('pyarmor_ecc', cls='Python.Extension', require=True),
|
|
450
|
+
],
|
|
451
|
+
|
|
452
|
+
'VmcScript': [
|
|
453
|
+
Item('script', cls='Python.Script', require=True),
|
|
454
|
+
Item('pyarmor_ecc', cls='Python.Extension', require=True),
|
|
455
|
+
],
|
|
456
|
+
|
|
457
|
+
'RftScript': [
|
|
458
|
+
Item('script', cls='Python.Script', require=True),
|
|
459
|
+
]
|
|
460
|
+
}
|