Create an interactive porting tool

`blueprint-compiler port` interactively ports a project to blueprint.
It will create the subproject wrap file, add it to .gitignore, decompile
your GtkBuilder XML files, emit code to copy and paste into your
meson.build file, and update POTFILES.in.

It can't quite handle all of the features the forward compiler can, so
it will skip those files.
This commit is contained in:
James Westman 2021-11-24 15:57:15 -06:00
parent 84dfe74755
commit 8e4433a487
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
19 changed files with 921 additions and 61 deletions

View file

@ -0,0 +1,12 @@
using Gtk 4.0;
Widget {
accessibility {
label: _("Hello, world!");
labelled_by: my_label;
checked: true;
}
}
Label my_label {
}

View file

@ -4,4 +4,5 @@ Scale {
adjustment: adj;
}
Adjustment adj {}
Adjustment adj {
}

View file

@ -0,0 +1,10 @@
using Gtk 4.0;
Grid {
Label {
layout {
column: "0";
row: "1";
}
}
}

View file

@ -25,4 +25,4 @@
</item>
</submenu>
</menu>
</interface>
</interface>

View file

@ -0,0 +1,31 @@
using Gtk 4.0;
menu {
label: _("menu label");
test-custom-attribute: "3.1415";
submenu {
section {
label: "test section";
}
item {
label: "test item";
}
item {
label: "test item shorthand 1";
}
item {
label: "test item shorthand 2";
action: "app.test-action";
}
item {
label: "test item shorthand 3";
action: "app.test-action";
icon: "test-symbolic";
}
}
}

View file

@ -0,0 +1,8 @@
using Gtk 4.0;
Label {
styles [
"class-1",
"class-2",
]
}

View file

@ -3,6 +3,7 @@ using Gtk 4.0;
Label {
label: _("Hello, world!");
}
Label {
label: C_("translation context", "Hello");
}

View file

@ -1,4 +1,5 @@
using Gtk 4.0;
using GObject 2.0;
GObject.Object {}
GObject.Object {
}

View file

@ -23,7 +23,7 @@ from pathlib import Path
import traceback
import unittest
from blueprintcompiler import tokenizer, parser
from blueprintcompiler import tokenizer, parser, decompiler
from blueprintcompiler.errors import PrintableError, MultipleErrors, CompileError
from blueprintcompiler.tokenizer import Token, TokenType, tokenize
from blueprintcompiler import utils
@ -91,6 +91,25 @@ class TestSamples(unittest.TestCase):
raise AssertionError()
def assert_decompile(self, name):
try:
with open((Path(__file__).parent / f"samples/{name}.blp").resolve()) as f:
expected = f.read()
name = name.removesuffix("_dec")
ui_path = (Path(__file__).parent / f"samples/{name}.ui").resolve()
actual = decompiler.decompile(ui_path)
if actual.strip() != expected.strip():
diff = difflib.unified_diff(expected.splitlines(), actual.splitlines())
print("\n".join(diff))
raise AssertionError()
except PrintableError as e:
e.pretty_print(name + ".blp", blueprint)
raise AssertionError()
def test_samples(self):
self.assert_sample("accessibility")
self.assert_sample("binding")
@ -143,3 +162,20 @@ class TestSamples(unittest.TestCase):
self.assert_sample_error("uint")
self.assert_sample_error("using_invalid_namespace")
self.assert_sample_error("widgets_in_non_size_group")
def test_decompiler(self):
self.assert_decompile("accessibility_dec")
self.assert_decompile("binding")
self.assert_decompile("child_type")
self.assert_decompile("flags")
self.assert_decompile("id_prop")
self.assert_decompile("layout_dec")
self.assert_decompile("menu_dec")
self.assert_decompile("property")
self.assert_decompile("signal")
self.assert_decompile("strings")
self.assert_decompile("style_dec")
self.assert_decompile("template")
self.assert_decompile("translated")
self.assert_decompile("using")