Skip to content

Commit

Permalink
Add support for removing statements, fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dalexeev committed Dec 17, 2023
1 parent 4d9e5c5 commit e918600
Show file tree
Hide file tree
Showing 19 changed files with 450 additions and 304 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test_preprocessor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Test Preprocessor
on: [push, pull_request]

env:
GODOT_EXECUTABLE: Godot_v${{ vars.GODOT_VERSION }}-stable_linux.x86_64
GODOT_EXECUTABLE: Godot_v${{ vars.GODOT_VERSION }}_linux.x86_64

jobs:
test-preprocessor:
Expand All @@ -24,7 +24,7 @@ jobs:
- if: ${{ steps.cache-godot.outputs.cache-hit != 'true' }}
name: Install Godot
run: |
wget https://downloads.tuxfamily.org/godotengine/${{ vars.GODOT_VERSION }}/${{ env.GODOT_EXECUTABLE }}.zip
wget https://github.com/godotengine/godot-builds/releases/download/${{ vars.GODOT_VERSION }}/${{ env.GODOT_EXECUTABLE }}.zip
unzip ${{ env.GODOT_EXECUTABLE }}.zip
- name: Run tests
Expand Down
63 changes: 29 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,30 @@ An export plugin for stripping comments and "conditional compilation" of GDScrip
4. The original scripts will not be changed, but in PCK/ZIP the scripts will be changed. Use ZIP to check the changes.
5. If any errors occurred during the export, you will see them in the Output Log.

The following errors do not affect the export success:

```
No loader found for resource: res://.godot/global_script_class_cache.cfg.
editor/export/editor_export_platform.cpp:776 - Condition "res.is_null()" is true. Returning: p_path
```

### Important note

See [godotengine/godot#76990](https://github.com/godotengine/godot/issues/76990) and [godotengine/godot#76996](https://github.com/godotengine/godot/pull/76996).

Each supported platform has certain standard feature tags (plus any custom tags you specify in the export preset). However, there are some standard tags that are not known in advance.

For example, the `linuxbsd` tag corresponds to the LinuxBSD _platform_. But the exported project, in theory, can be run not only on Linux, but also on BSD. Thus, it is not known in advance whether the environment will have the `linux` or `bsd` feature tag.

If you want separate exports for these OSes, you can have separate presets for Linux and BSD, just add the `linux` and `bsd` tags respectively as **custom tags**. ~~If you don't care about this difference, then you should use the `linuxbsd` tag, not `linux`.~~ _(This is not true until [godotengine/godot#76996](https://github.com/godotengine/godot/pull/76996) is merged.)_
Each supported platform has certain standard feature tags (plus any custom tags you specify in the export preset). However, there are some standard tags that are not known in advance. See [godotengine/godot#76990](https://github.com/godotengine/godot/issues/76990) and [godotengine/godot#76996](https://github.com/godotengine/godot/pull/76996) for details.

### Features

* Stripping comments.
* Conditional compilation directives (`#~if` and `#~endif`). They work only when exporting a project, and have no effect in the editor.
* `if`/`elif`/`else` statements if their conditions contain only `true`, `false`, `and`, `or`, `not` and the following functions calls.

### Supported functions

* `Engine.is_editor_hint()`
* `OS.is_debug_build()`
* `OS.has_feature("feature_tag_name")`
* `if`/`elif`/`else` statements if their conditions contain only `true`, `false`, `and`, `or`, `not` and the following functions calls:
* `Engine.is_editor_hint()`;
* `OS.is_debug_build()`;
* `OS.has_feature("feature_tag_name")`.
* Removing the following statements in release builds:
* `assert()`;
* `breakpoint`;
* `print_debug()`;
* `print_stack()`;
* also you can specify custom regexes in `addons/gdscript_preprocessor/options.cfg`.

### Limitations

* Built-in scripts are not properly supported yet.
* Multiple statements on the same line (`if Engine.is_editor_hint(): return`) are not recognized.
* Statements inside lambdas are not processed.
* Your code is expected to follow the [GDScript style guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html). Otherwise, regular expressions and string processing used in the plugin may not work.

### Example
Expand All @@ -53,18 +44,19 @@ Original script:
extends Node
var a := 1
var a: int
#~if OS.has_feature("debug")
var b := 2
var b: int
#~endif
var c := 3
var c: int
## Comment.
func _ready() -> void:
print(1) # Comment.
if OS.has_feature("debug"):
print("Debug: b = ", b)
var t: int = a + b
print("Debug: t = ", t)
# Comment.
elif OS.has_feature("release"):
print("Release.")
Expand All @@ -73,27 +65,30 @@ func _ready() -> void:
print(2)
```

After exporting with the `release` feature tag:
After exporting with the `debug` feature tag:

```gdscript
extends Node
var a := 1
var c := 3
var a: int
var b: int
var c: int
func _ready() -> void:
print(1)
print("Release.")
if true:
var t: int = a + b
print("Debug: t = ", t)
print(2)
```

After exporting with the `debug` feature tag:
After exporting with the `release` feature tag:

```gdscript
extends Node
var a := 1
var b := 2
var c := 3
var a: int
var c: int
func _ready() -> void:
print(1)
print("Debug: b = ", b)
if true:
print("Release.")
print(2)
```
1 change: 1 addition & 0 deletions addons/gdscript_preprocessor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
options.cfg
46 changes: 40 additions & 6 deletions addons/gdscript_preprocessor/export_plugin.gd
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
extends EditorExportPlugin


@warning_ignore("inferred_declaration")
const _Preprocessor = preload("./preprocessor.gd")

var _config_path: String
var _platform: EditorExportPlatform
var _features: PackedStringArray
var _preprocessor := preload("preprocessor.gd").new()
var _preprocessor: _Preprocessor = _Preprocessor.new()


func _init() -> void:
var script: Script = get_script()
_config_path = ProjectSettings.globalize_path(script.resource_path) \
.get_base_dir().path_join("options.cfg")


func _get_name() -> String:
Expand All @@ -20,6 +30,22 @@ func _export_begin(
_preprocessor.features = features
_preprocessor.is_debug = is_debug

var regex: String
var config: ConfigFile = ConfigFile.new()
var _err: Error = config.load(_config_path)
if is_debug:
regex = _get_option(config, "statements", "removing_regex_debug", "")
else:
regex = _get_option(config, "statements", "removing_regex_release",
r"^(?:breakpoint|assert\(|print_debug\(|print_stack\()")
if not regex.is_empty():
_preprocessor.statement_removing_regex = RegEx.create_from_string(regex)
if not _preprocessor.statement_removing_regex.is_valid():
if is_debug:
printerr("Invalid statement removing regex for debug builds.")
else:
printerr("Invalid statement removing regex for release builds.")


func _begin_customize_resources(
platform: EditorExportPlatform,
Expand All @@ -35,15 +61,23 @@ func _get_customization_configuration_hash() -> int:


func _customize_resource(resource: Resource, path: String) -> Resource:
var gds := resource as GDScript
var gds: GDScript = resource as GDScript
if not gds:
return null

var new_gds := GDScript.new()
if _preprocessor.preprocess(gds.source_code):
var new_gds: GDScript = GDScript.new()
new_gds.source_code = _preprocessor.result
return new_gds
else:
printerr("%s:%s - %s" % ["<unknown>" if path.is_empty() else path,
_preprocessor.error_line, _preprocessor.error_message])
printerr("%s:%s - %s" % [
"<unknown>" if path.is_empty() else path,
_preprocessor.error_line,
_preprocessor.error_message,
])
return null


return new_gds
func _get_option(config: ConfigFile, section: String, key: String, default: Variant) -> Variant:
var value: Variant = config.get_value(section, key, default)
return value if typeof(value) == typeof(default) else default
6 changes: 6 additions & 0 deletions addons/gdscript_preprocessor/options.cfg.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
; Copy this file as `options.cfg` if you want to change the settings.

[statements]

removing_regex_debug=""
removing_regex_release="^(?:breakpoint|assert\\(|print_debug\\(|print_stack\\()"
5 changes: 4 additions & 1 deletion addons/gdscript_preprocessor/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
extends EditorPlugin


var _export_plugin := preload("export_plugin.gd").new()
@warning_ignore("inferred_declaration")
const _ExportPlugin = preload("./export_plugin.gd")

var _export_plugin: _ExportPlugin = _ExportPlugin.new()


func _enter_tree() -> void:
Expand Down
Loading

0 comments on commit e918600

Please sign in to comment.