minilua 1.1.0__tar.gz

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.
minilua-1.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ardo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
minilua-1.1.0/PKG-INFO ADDED
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: minilua
3
+ Version: 1.1.0
4
+ Summary: A Lua / Luau source code minifier supporting Lua 5.1–5.4 and Luau
5
+ Author: Ardo
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Topic :: Software Development :: Build Tools
10
+ Classifier: Topic :: Text Processing :: Filters
11
+ Requires-Python: >=3.8
12
+ License-File: LICENSE
13
+ Requires-Dist: click>=8.0
14
+ Requires-Dist: colorama>=0.4
15
+ Dynamic: author
16
+ Dynamic: classifier
17
+ Dynamic: license-file
18
+ Dynamic: requires-dist
19
+ Dynamic: requires-python
20
+ Dynamic: summary
@@ -0,0 +1,376 @@
1
+ <div align="center">
2
+
3
+ ```
4
+ __ __ __ __ __ __ __ __ __ ______
5
+ /\ "-./ \ /\ \ /\ "-.\ \ /\ \ /\ \ /\ \/\ \ /\ __ \
6
+ \ \ \-./\ \ \ \ \ \ \ \-. \ \ \ \ \ \ \____ \ \ \_\ \ \ \ __ \
7
+ \ \_\ \ \_\ \ \_\ \ \_\\"\_\ \ \_\ \ \_____\ \ \_____\ \ \_\ \_\
8
+ \/_/ \/_/ \/_/ \/_/ \/_/ \/_/ \/_____/ \/_____/ \/_/\/_/
9
+
10
+ ```
11
+
12
+ **A fast, accurate Lua / Luau source code minifier**
13
+
14
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)
15
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
16
+ [![Tests](https://img.shields.io/badge/tests-102%20passed-brightgreen)](#testing)
17
+
18
+ </div>
19
+
20
+ ---
21
+
22
+ ## Overview
23
+
24
+ **minilua** is a production-ready Lua / Luau minifier written in Python. It reduces the size of Lua source files by stripping comments, collapsing whitespace, compressing string and number literals, and optionally renaming local variables — all while preserving 100% semantic equivalence of the output.
25
+
26
+ Works with **Lua 5.1, 5.2, 5.3, 5.4** and **Luau** (Roblox), including executor/exploit environments.
27
+
28
+ **Typical savings: 40–60%** on real-world scripts.
29
+
30
+ ---
31
+
32
+ ## Features
33
+
34
+ | Feature | Description |
35
+ |---|---|
36
+ | **Comment removal** | Single-line (`--`) and multi-line (`--[[ ]]`) comments |
37
+ | **Whitespace stripping** | Spaces, tabs, redundant newlines |
38
+ | **String compression** | Optimal quote style, escape normalization, long→short string conversion |
39
+ | **Number compression** | `1.0→1`, `0.5→.5`, `1e+03→1e3`, `0x00FF→0xFF`, Luau `1_000→1000` |
40
+ | **Local variable renaming** | Renames locals to single-letter names (`a`, `b`, `c`, …) |
41
+ | **Executor globals protected** | `getrawmetatable`, `hookfunction`, `readfile`, `syn`, etc. are never renamed |
42
+ | **Luau support** | `type`, `continue`, `export`, `::labels::`, type annotations |
43
+ | **Safe separator logic** | Never produces `--` (comment), `[[` (long string), or merged keywords |
44
+ | **Batch processing** | Glob patterns, recursive directory scan |
45
+ | **stdin / stdout** | Pipe-friendly for build pipelines |
46
+
47
+ ---
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ pip install minilua
53
+ ```
54
+
55
+ **Requirements:** Python 3.8+
56
+
57
+ ---
58
+
59
+ ## Quick Start
60
+
61
+ ```bash
62
+ # Minify a single file → produces script.min.lua
63
+ minilua script.lua
64
+
65
+ # Minify and write to a specific path
66
+ minilua script.lua -o dist/script.lua
67
+
68
+ # Minify all files in a directory (recursive)
69
+ minilua src/ --recursive --output-dir dist/
70
+
71
+ # Print result to stdout (pipe-friendly)
72
+ minilua script.lua --stdout
73
+
74
+ # stdin → stdout
75
+ cat script.lua | minilua - --stdout
76
+ ```
77
+
78
+ ---
79
+
80
+ ## CLI Reference
81
+
82
+ ```
83
+ Usage: minilua [OPTIONS] [FILE|DIR|GLOB]...
84
+
85
+ Lua / Luau Minifier — compress Lua source files.
86
+ Supports Lua 5.1–5.4 and Luau (Roblox) syntax.
87
+
88
+ Input / Output:
89
+ FILE|DIR|GLOB One or more files, directories, or glob patterns
90
+ -o, --output PATH Output file path (single-file mode)
91
+ -d, --output-dir PATH Output directory for batch mode
92
+ --suffix TEXT Output filename suffix [default: .min.lua]
93
+ -i, --in-place Overwrite input files in-place ⚠ irreversible
94
+ -r, --recursive Recurse into subdirectories
95
+ --stdout Print result to stdout instead of writing files
96
+ -f, --overwrite Allow overwriting existing output files
97
+
98
+ Minification Options:
99
+ --no-comments Keep comments (default: strip)
100
+ --no-whitespace Keep whitespace (default: strip)
101
+ --no-strings Skip string literal compression
102
+ --no-numbers Skip number literal compression
103
+ -R, --rename-locals Rename local variables to short names
104
+ --keep-newlines Preserve one newline per statement
105
+
106
+ Display:
107
+ -q, --quiet Suppress all output except errors
108
+ --no-banner Hide the startup banner
109
+ -v, --version Show version and exit
110
+ -h, --help Show this message and exit
111
+ ```
112
+
113
+ ### Examples
114
+
115
+ ```bash
116
+ # Rename local variables (more aggressive, ~55–70% savings)
117
+ minilua script.lua --rename-locals
118
+
119
+ # Keep comments (useful when debugging minified output)
120
+ minilua script.lua --no-comments
121
+
122
+ # Batch: minify all .lua and .luau files under src/
123
+ minilua src/ -r -d build/
124
+
125
+ # CI pipeline: fail on minification error, silent otherwise
126
+ minilua *.lua --stdout --quiet
127
+
128
+ # In-place for all files in current directory
129
+ minilua *.lua --in-place --overwrite
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Programmatic API
135
+
136
+ ```python
137
+ from lua_minifier.core import Minifier, MinifyOptions
138
+
139
+ source = open("script.lua").read()
140
+
141
+ opts = MinifyOptions(
142
+ remove_comments = True, # strip --comments
143
+ remove_whitespace = True, # strip spaces / newlines
144
+ minify_strings = True, # compress string literals
145
+ minify_numbers = True, # compress number literals
146
+ rename_locals = False, # rename locals (opt-in)
147
+ keep_newlines = False, # preserve newlines
148
+ )
149
+
150
+ result = Minifier(opts).minify(source)
151
+
152
+ print(result.output)
153
+ print(f"Original : {result.original_size:,} bytes")
154
+ print(f"Minified : {result.minified_size:,} bytes")
155
+ print(f"Saved : {result.savings_pct:.1f}%")
156
+
157
+ if result.errors:
158
+ for warning in result.errors:
159
+ print("Warning:", warning)
160
+ ```
161
+
162
+ ### `MinifyOptions` fields
163
+
164
+ | Field | Type | Default | Description |
165
+ |---|---|---|---|
166
+ | `remove_comments` | `bool` | `True` | Strip `--` and `--[[ ]]` comments |
167
+ | `remove_whitespace` | `bool` | `True` | Strip spaces and newlines |
168
+ | `minify_strings` | `bool` | `True` | Compress string literals |
169
+ | `minify_numbers` | `bool` | `True` | Compress number literals |
170
+ | `rename_locals` | `bool` | `False` | Rename local variables |
171
+ | `preserve_names` | `set` | `None` | Extra names to never rename |
172
+ | `keep_newlines` | `bool` | `False` | Preserve one newline per line |
173
+
174
+ ### `MinifyResult` fields
175
+
176
+ | Field | Type | Description |
177
+ |---|---|---|
178
+ | `output` | `str` | Minified source code |
179
+ | `original_size` | `int` | Original size in bytes |
180
+ | `minified_size` | `int` | Minified size in bytes |
181
+ | `savings_bytes` | `int` | Bytes saved |
182
+ | `savings_pct` | `float` | Percentage saved |
183
+ | `tokens_processed` | `int` | Number of tokens lexed |
184
+ | `errors` | `list[str]` | Non-fatal warnings |
185
+
186
+ ---
187
+
188
+ ## What Gets Compressed
189
+
190
+ ### Comments
191
+ ```lua
192
+ -- Before
193
+ -- This function adds two numbers
194
+ local function add(a, b)
195
+ --[[ both arguments must be numbers ]]
196
+ return a + b -- return the sum
197
+ end
198
+
199
+ -- After
200
+ local function add(a,b)return a+b end
201
+ ```
202
+
203
+ ### String literals
204
+ ```lua
205
+ -- Before
206
+ local msg = "Hello\tWorld"
207
+ local raw = [[
208
+ multi-line content
209
+ ]]
210
+ local hex = "\x68\x65\x6c\x6c\x6f"
211
+
212
+ -- After
213
+ local msg='Hello\tWorld'
214
+ local raw=' multi-line content\n'
215
+ local hex='hello'
216
+ ```
217
+
218
+ ### Number literals
219
+ ```lua
220
+ -- Before
221
+ local a = 1.0
222
+ local b = 0.500
223
+ local c = 1e+03
224
+ local d = 0x00FF
225
+ local e = 1_000_000 -- Luau
226
+
227
+ -- After
228
+ local a=1
229
+ local b=.5
230
+ local c=1e3
231
+ local d=0xFF
232
+ local e=1000000
233
+ ```
234
+
235
+ ### Local variable renaming (`--rename-locals`)
236
+ ```lua
237
+ -- Before
238
+ local function calculateDistance(pointA, pointB)
239
+ local deltaX = pointA.x - pointB.x
240
+ local deltaY = pointA.y - pointB.y
241
+ return math.sqrt(deltaX * deltaX + deltaY * deltaY)
242
+ end
243
+
244
+ -- After
245
+ local function a(b,c)local d=b.x-c.x local e=b.y-c.y return math.sqrt(d*d+e*e)end
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Executor / Exploit Support
251
+
252
+ minilua fully recognizes executor globals and will **never rename** them when `--rename-locals` is active. The following (and more) are protected:
253
+
254
+ ```
255
+ getrawmetatable setrawmetatable hookmetamethod
256
+ hookfunction newcclosure newlclosure
257
+ getgenv getsenv getrenv
258
+ getfenv setfenv gethui
259
+ readfile writefile appendfile
260
+ listfiles makefolder isfile
261
+ firesignal fireclickdetector fireproximityprompt
262
+ getupvalue getupvalues setupvalue
263
+ getproto getprotos getgc
264
+ syn request http_request
265
+ Drawing setclipboard getclipboard
266
+ identifyexecutor getexecutorname decompile
267
+ setthreadidentity getthreadidentity rconsoleprint
268
+ mouse1click keypress getconnections
269
+ ... and 80+ more
270
+ ```
271
+
272
+ ---
273
+
274
+ ## How It Works
275
+
276
+ ```
277
+ Source code
278
+
279
+
280
+ ┌─────────┐
281
+ │ Lexer │ → Full token stream (all trivia preserved)
282
+ └─────────┘
283
+
284
+
285
+ ┌──────────────┐
286
+ │ Renamer │ (optional) Two-pass scope-tree renamer
287
+ │ (Pass 1) │ Builds lexical scope tree, assigns short names
288
+ │ (Pass 2) │ Substitutes NAME tokens using the shared tree
289
+ └──────────────┘
290
+
291
+
292
+ ┌───────────────────┐
293
+ │ Transform Pass │
294
+ │ · Drop comments │
295
+ │ · Drop spaces │
296
+ │ · Compress STR │ → string_minifier
297
+ │ · Compress NUM │ → number_minifier
298
+ └───────────────────┘
299
+
300
+
301
+ ┌────────────────┐
302
+ │ Assemble Pass │ Insert ' ' only where required by Lua grammar
303
+ └────────────────┘
304
+
305
+
306
+ Minified output
307
+ ```
308
+
309
+ ### Separator safety rules
310
+
311
+ The assembler inserts a space between two tokens **only when necessary**:
312
+
313
+ - Word token followed by word token → always needs space (`return 42`, `and b`)
314
+ - `-` followed by `-` → would form a `--` comment
315
+ - `[` followed by `[` or `=` → would open a long-bracket string
316
+ - Keyword followed by `-` or `~` → unary operator safety
317
+ - Number followed by `..` → float mis-lex prevention
318
+ - `.` followed by `.` → prevents accidental `..` formation
319
+
320
+ ---
321
+
322
+ ## Project Structure
323
+
324
+ ```
325
+ lua_minifier/
326
+ ├── __init__.py Public API
327
+ ├── cli.py CLI (Click-based)
328
+ ├── setup.py Package configuration
329
+ ├── README.md
330
+
331
+ ├── core/
332
+ │ ├── __init__.py
333
+ │ ├── lexer.py Lua/Luau tokenizer
334
+ │ ├── minifier.py Pipeline engine & options
335
+ │ ├── string_minifier.py String & number compression
336
+ │ └── renamer.py Scope-tree local variable renamer
337
+
338
+ ├── utils/
339
+ │ ├── __init__.py
340
+ │ ├── formatter.py Terminal stats output (color-aware)
341
+ │ └── file_utils.py File discovery, glob expansion, I/O
342
+
343
+ └── tests/
344
+ ├── test_minifier.py 102-test suite
345
+ └── sample.lua Demo file
346
+ ```
347
+
348
+ ---
349
+
350
+ ## Testing
351
+
352
+ ```bash
353
+ python -m pytest tests/ -v
354
+ ```
355
+
356
+ ```
357
+ 102 passed in 0.18s
358
+ ```
359
+
360
+ Test coverage includes:
361
+
362
+ - Lexer tokenization (Lua 5.1–5.4, Luau syntax)
363
+ - String escape decoding/encoding (`\n`, `\xHH`, `\u{HH}`, `\ddd`, `\z`)
364
+ - Number compression (int, float, hex, hex-float, scientific, Luau separators)
365
+ - Separator correctness (no merged keywords, no accidental `--` comments)
366
+ - Comment and whitespace stripping / preservation
367
+ - Variable renamer (locals, params, for-vars, shadowing, no collisions)
368
+ - Executor global protection (80+ protected names)
369
+ - Luau-specific syntax (`continue`, `type`, `export`, `::`)
370
+ - Edge cases (empty input, deep nesting, large tables, null bytes in strings)
371
+
372
+ ---
373
+
374
+ ## License
375
+
376
+ MIT © Ardo
@@ -0,0 +1,20 @@
1
+ """
2
+ minilua
3
+ A Lua / Luau source code minifier supporting Lua 5.1–5.4 and Luau (Roblox).
4
+
5
+ Programmatic API:
6
+
7
+ from lua_minifier.core import Minifier, MinifyOptions
8
+
9
+ opts = MinifyOptions(remove_comments=True, rename_locals=True)
10
+ result = Minifier(opts).minify(source_code)
11
+ print(result.output)
12
+ print(f"Saved {result.savings_pct:.1f}%")
13
+ """
14
+
15
+ __version__ = "1.1.0"
16
+ __author__ = "Ardo"
17
+
18
+ from lua_minifier.core import Minifier, MinifyOptions, MinifyResult, MinifyError
19
+
20
+ __all__ = ["Minifier", "MinifyOptions", "MinifyResult", "MinifyError"]