A patch file (also called a patch for short) is a text file that consists of a list of differences and is produced, usually, by running the related the diff
program with the original and updated file as arguments. The differences follow the diff format. A patch processor can read a patch file and use the contents as a set of instructions. By following those instructions, a target file can be modified to match the changes in the patch file.
Although patches are usually created using a diff tool, it is also possible to write them manually and then use the patch processor to modify a file. This is the approach we provide via EGL patch rules.
In EGL we support a custom diff format.
+
represents the addition of a line, i.e. this line will be added to the file.-
represents the deletion of a line, i.e, this line will be removed from the file....
indicates a block of lines to keep, i.e. all lines until the next diff/match will be kept.---
indicates a block of lines to remove, i.e. all lines until the next diff/match will be removed.The EGl diff processor uses un-diffed lines to match sections of the file and then uses any diff entries till the next un-diffed lines to modify (add/remove/keep) the file. Deletions will also be used to match locations. All additions before a deletion/un-diff will be inserted before the deleted/un-diffed line. All additions after a deletion/un-diff will be inserted after the deleted/un-diffed line.
In this example we want to insert getters in a Java class file.
=== “getters.egl” egl [%for (a in c.eAllAttributes.excludingAll(c.eAttributes)) {%] + + /** + * @generated + */ + @Override + public [%=a.eType.instanceTypeName%] get[%=a.name.ftuc()%]() { + if ([%=a.name%] == null) { + return prototype.get[%=a.name.ftuc()%](); + } + else return [%=a.name%]; + } [%}%] -} //[%=c.name%]Impl +} //[%=c.name%]Impl (Patched)
-} //[%=c.name%]Impl
, thus the processor would match the closing bracket of the Java class commented with the Java class name.In this other example, we want to modify the toString method of a Java class.
=== “toString.egl” egl public String toString() { --- + return "[%=c.name%]"; }
public String toString() {
line would be used to match the toString method.---
indicates that all the lines in the method, until the closing bracket (which is the next matched line) should be removed.To use EGL templates with diff lines they must be invoked from an EGX rule annotated with @patch
. The example EGL templates above would be invoked like this:
@patch rule EClass2Getters transform c : EClass { guard : c.eAnnotations.exists(a|a.source = "instance") template : "getters.egl" target : "src/" + c.eContainer().name + "/impl/" + c.name + "Impl.java" } @patch rule EClass2ToString transform c : EClass { template : "toString.egl" target : "src/" + c.eContainer().name + "/impl/" + c.name + "Impl.java" }