Say app current version is 1.1.2, and the compare baes is
version 1.1.1, but there is a 1.1.2 in appup.
We may skip updating appup instructions for 1.1.2
as it's never used, (at least not in EMQX)
We often use the advanced directive `update` when hot upgrading
gen_server, gen_statem, and other such processes, and it will be
parsed as:
```
{suspend,[Mod]},
{load,{Mod,brutal_purge,brutal_purge}},
{code_change,up,[{Mod,[Extra]}]},
{resume,[Mod]},
```
So, we should treat the update instruction as having completed the
upgrade of this module.
For apps inside emqx umbrella, we try to bump only the patch part of
their version numbers, and use only 3-part version
numbers (`Major.Minor.Patch`). With those assumptions, we may infer
all versions that need to be covered in a given upgrade, and check if
those are covered in regexes.
If there is already any `application:stop(Application)` call in the
appup instructions, we prefer to add `load_module` instructions after
it, so we can be sure that the load is replaced safely.
To avoid losing comments and/or manual indentation in appup files that
are already up to date, we now check whether the contents have the
exact same terms as those we are about to write to an existint .appup
file.
Since the appup instruction `restart_application` already loads all
modules of a given application, there is no need to introduce those
instructions if a restart is already present.
This change makes the `update_appup.escript` check whether the new
version of an application (the _current_ one) is already contained in
entries in the _new_ .appup file for that application if such .appup
file contains regexes.
NOTE: this does not cover the case in which we calculate the
difference between _old_ and _new_ appup entries, and those consist of
regexes. In such case, we would need to check if one regex is
"contained" in the other, which is not currently supported by this
patch.
external dependencies
Currently, the update_appup.escript outputs as an error the full appup
file for external dependencies, even if all the changes are already
contained in the depency. Here, we make it only output the missing
actions to be inserted, to aid in seeing what are the differences.