0
# Project Management
1
2
PyArmor provides comprehensive project management capabilities for organizing and maintaining obfuscation workflows. Projects store configuration settings, manage source files, and provide batch processing for complex applications with multiple scripts and dependencies.
3
4
## Capabilities
5
6
### Legacy Project Class (v7)
7
8
Classic project management with dictionary-based configuration and file-based persistence.
9
10
```python { .api }
11
class Project(dict):
12
"""
13
PyArmor project management class inheriting from dict.
14
Stores all project configuration as key-value pairs.
15
"""
16
17
def open(self, path: str) -> None:
18
"""
19
Open existing project from configuration file.
20
21
Args:
22
path (str): Path to project configuration file (.json)
23
24
Raises:
25
FileNotFoundError: If project file doesn't exist
26
ValueError: If project file format is invalid
27
"""
28
29
def save(self, path: str) -> None:
30
"""
31
Save project configuration to file.
32
33
Args:
34
path (str): Output path for project file (.json)
35
36
Raises:
37
PermissionError: If unable to write to path
38
OSError: If disk space insufficient
39
"""
40
41
def check(self) -> bool:
42
"""
43
Validate project configuration and file consistency.
44
45
Returns:
46
bool: True if project is valid and consistent
47
48
Raises:
49
ProjectError: If validation fails with details
50
"""
51
52
def get_build_files(self, force: bool = False, excludes: list = []) -> list:
53
"""
54
Get list of files to be obfuscated based on project settings.
55
56
Args:
57
force (bool): Force inclusion of all files ignoring timestamps
58
excludes (list): Additional patterns to exclude from build
59
60
Returns:
61
list: List of file paths to obfuscate
62
"""
63
64
def info(self) -> str:
65
"""
66
Generate formatted project information string.
67
68
Returns:
69
str: Multi-line formatted project summary
70
"""
71
72
def _update(self, **kwargs) -> None:
73
"""
74
Update project settings with keyword arguments.
75
76
Args:
77
**kwargs: Configuration options to update
78
"""
79
80
@classmethod
81
def build_manifest(cls, manifest: str, path: str = None) -> list:
82
"""
83
Build file list from manifest template using distutils.
84
85
Args:
86
manifest (str): Manifest template content
87
path (str, optional): Base path for file resolution
88
89
Returns:
90
list: List of file paths matching manifest patterns
91
"""
92
93
@classmethod
94
def build_globfiles(cls, patterns: list, path: str = '') -> list:
95
"""
96
Build file list from glob patterns.
97
98
Args:
99
patterns (list): List of glob patterns to match
100
path (str): Base path for pattern matching (default: '')
101
102
Returns:
103
list: List of file paths matching glob patterns
104
"""
105
```
106
107
### Modern Project Management (v8+)
108
109
Enhanced project management with improved configuration handling and context integration.
110
111
```python { .api }
112
class Project:
113
"""
114
Modern PyArmor project management with enhanced features.
115
"""
116
117
def __init__(self, ctx=None):
118
"""
119
Initialize project with optional context.
120
121
Args:
122
ctx (Context, optional): PyArmor context instance
123
"""
124
125
def create(self, path: str, **kwargs) -> None:
126
"""
127
Create new project at specified path.
128
129
Args:
130
path (str): Project directory path
131
**kwargs: Initial project configuration
132
"""
133
134
def load(self, path: str) -> None:
135
"""
136
Load existing project from directory.
137
138
Args:
139
path (str): Project directory path
140
"""
141
142
def configure(self, **options) -> None:
143
"""
144
Update project configuration options.
145
146
Args:
147
**options: Configuration key-value pairs
148
"""
149
150
def build(self, **kwargs) -> None:
151
"""
152
Build project with current configuration.
153
154
Args:
155
**kwargs: Build-specific options
156
"""
157
```
158
159
### Project Configuration Attributes
160
161
```python { .api }
162
# Core Settings
163
class ProjectSettings:
164
name: str # Project name identifier
165
title: str # Human-readable project title
166
src: str # Source directory path (default: "src")
167
output: str # Output directory path (default: "dist")
168
entry: str # Main entry script name
169
170
# File Management
171
includes: list # File patterns to include
172
excludes: list # File patterns to exclude
173
manifest: str # Manifest template for file discovery
174
175
# Obfuscation Settings
176
obf_code: int # Code obfuscation level (0=off, 1=on, 2=advanced)
177
obf_mod: int # Module obfuscation (0=off, 1=on)
178
wrap_mode: int # Wrap mode (0=off, 1=on)
179
advanced_mode: int # Advanced protection level (0-5)
180
181
# Runtime Settings
182
runtime_path: str # Runtime package path
183
package_runtime: int # Package runtime with scripts (0=off, 1=on)
184
bootstrap_code: int # Bootstrap code generation (0=off, 1=on)
185
186
# Security Settings
187
restrict_mode: int # Restriction level (0=none, 1=import, 2=private, 3=restrict)
188
cross_protection: int # Cross-script protection (0=off, 1=on)
189
license_file: str # License file path
190
191
# Platform Settings
192
platform: str # Target platform specification
193
mixins: list # Platform-specific mixins
194
195
# Plugin Settings
196
plugins: list # Enabled plugins list
197
plugin_options: dict # Plugin configuration options
198
```
199
200
### Project Operations
201
202
#### Creating Projects
203
204
```python
205
from pyarmor.project import Project
206
207
# Create new project
208
proj = Project()
209
proj.name = "MyApplication"
210
proj.title = "My Python Application"
211
proj.src = "src"
212
proj.output = "dist"
213
proj.entry = "main.py"
214
215
# Configure obfuscation
216
proj.obf_code = 1 # Enable code obfuscation
217
proj.obf_mod = 1 # Enable module obfuscation
218
proj.wrap_mode = 1 # Enable wrap mode
219
proj.advanced_mode = 2 # Super mode protection
220
proj.restrict_mode = 2 # Private mode
221
222
# Configure runtime
223
proj.package_runtime = 1 # Package runtime files
224
proj.bootstrap_code = 1 # Generate bootstrap
225
226
# Save project
227
proj.save("myapp.json")
228
```
229
230
#### Loading and Building Projects
231
232
```python
233
# Load existing project
234
proj = Project()
235
proj.open("myapp.json")
236
237
# Validate project
238
if proj.check():
239
print("Project is valid")
240
241
# Get files to build
242
files = proj.get_build_files()
243
print(f"Building {len(files)} files")
244
245
# Show project information
246
print(proj.info())
247
248
# Update configuration
249
proj._update(
250
obf_code=2, # Advanced code obfuscation
251
mix_str=1, # Enable string mixing
252
expired="2024-12-31" # Set expiration
253
)
254
255
# Save updated configuration
256
proj.save("myapp.json")
257
```
258
259
#### Project Directory Structure
260
261
```
262
myproject/
263
├── myapp.json # Project configuration file
264
├── src/ # Source directory
265
│ ├── main.py # Entry script
266
│ ├── module1.py # Application modules
267
│ └── package/ # Sub-packages
268
├── dist/ # Output directory (generated)
269
│ ├── main.py # Obfuscated entry script
270
│ ├── module1.py # Obfuscated modules
271
│ ├── package/ # Obfuscated packages
272
│ └── pyarmor_runtime_000000/ # Runtime files
273
└── .pyarmor_config # Local configuration (optional)
274
```
275
276
### File Discovery and Management
277
278
#### Include/Exclude Patterns
279
280
```python
281
# Configure file patterns
282
proj.includes = [
283
"src/**/*.py", # All Python files in src
284
"lib/*.py", # Python files in lib
285
"!src/test_*.py" # Exclude test files
286
]
287
288
proj.excludes = [
289
"__pycache__", # Python cache directories
290
"*.pyc", # Compiled Python files
291
"test/", # Test directory
292
"docs/", # Documentation
293
".git" # Version control
294
]
295
296
# Custom manifest template
297
proj.manifest = """
298
global-include *.py
299
recursive-exclude test *
300
recursive-exclude docs *
301
prune __pycache__
302
"""
303
```
304
305
#### Build File Resolution
306
307
```python
308
# Get all files to build
309
all_files = proj.get_build_files()
310
311
# Force rebuild (ignore timestamps)
312
force_files = proj.get_build_files(force=True)
313
314
# Exclude additional patterns
315
filtered_files = proj.get_build_files(excludes=["vendor/", "*.bak"])
316
317
# Process build files
318
for filepath in all_files:
319
print(f"Processing: {filepath}")
320
# Obfuscation logic here
321
```
322
323
### Advanced Project Features
324
325
#### Cross-Platform Projects
326
327
```python
328
# Configure for multiple platforms
329
proj.platform = "linux.x86_64,windows.x86_64,darwin.x86_64"
330
331
# Platform-specific settings
332
proj.mixins = [
333
"windows:--advanced 2",
334
"linux:--restrict 1",
335
"darwin:--package-runtime 0"
336
]
337
```
338
339
#### Plugin Integration
340
341
```python
342
# Enable plugins
343
proj.plugins = ["check_ntp_time", "assert_armored"]
344
345
# Plugin configuration
346
proj.plugin_options = {
347
"check_ntp_time": {
348
"server": "pool.ntp.org",
349
"timeout": 10
350
},
351
"assert_armored": {
352
"threshold": 0.8
353
}
354
}
355
```
356
357
#### License Integration
358
359
```python
360
# Configure project license
361
proj.license_file = "licenses/app.lic"
362
363
# License-specific obfuscation
364
proj.cross_protection = 1 # Enable cross protection
365
proj.restrict_mode = 3 # Restrict mode for license validation
366
```
367
368
## Error Handling
369
370
```python
371
from pyarmor.project import Project, ProjectError
372
373
try:
374
proj = Project()
375
proj.open("nonexistent.json")
376
except FileNotFoundError:
377
print("Project file not found")
378
except ProjectError as e:
379
print(f"Project error: {e}")
380
381
try:
382
proj.check()
383
except ProjectError as e:
384
print(f"Project validation failed: {e}")
385
# Handle validation errors
386
387
# Graceful handling of build issues
388
files = proj.get_build_files()
389
if not files:
390
print("No files to build - check project configuration")
391
```