-
Notifications
You must be signed in to change notification settings - Fork 395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
manifest-update writes new manifest, but old copy is still used. #508
Comments
Which other mojos?
|
Sorry, I haven't had time to go through the source and investigate. What I know at this point is that the manifest is updated and moved to the new location, but the final build did not use it. So I'm guessing it was a compile, or dex, or package mojo that needed it and found the wrong one. |
I believe @MartinMReed has got the point, as I personally stumbled upon the very same issue when migrating from to 4.0.0 AMP from an old (3.9.0) version. After taking some time to investigate (and to study the plugin source code), here is the situation and the root cause of all the troubles with updating the manifest. Suppose one needs to run ManifestUpdateMojo to make some build-time adjustments to application manifest, like setting proper and unique version code, or injecting profile-specific application icon. To keep original manifest safe, we set androidManifestFile to point to its original location, and updatedManifestFile to some arbitrary temporary location, where the resulting manifest will end up. Everything runs just fine, and manifest is properly updated. Now we also need to produce an apk artifact, which involves taking that updated manifest and, say, renaming application package, or creating R file in a custom package. Something that is performed by GenerateSourcesMojo, which runs as part of a modified build lifecycle. Same applies to ApkMojo and other lifecycle default participants. These grab the manifest from androidManifestFile location, completely ignoring new location! ManifestUpdateMojo does update the parameter to reflect new location, but it is done in the context of standalone mojo invocation, hence all runtime parameter changes are lost by the time other mojo-s are executed! |
The simplest solution to the above problem would be to split plugin configuration into major, "default" section, with androidManifestFile pointing to updated (new) manifest file location, and dedicated configuration for "manifest-update" goal with both androidManifestFile and updatedManifestFile present. Not exactly straightforward, but it works. BUT it doesn't work at all if original (source) manifest is still located in project root, as it is the case with most legacy Android projects, I believe! The reason for this is "non-standard layout check" introduced in AMP 4.0.0, which looks for the manifest in pre-4 location, finds it, then examines androidManifestFile parameter to see if it indeed points to that "old" location.. And since it does not (see my previous comment), it spits out a warning and fails the build by default. There is an option to employ sourceManifestFile parameter, but it is actually referenced in copyManifest() method, which is invoked AFTER checking for non-standard layout; if the build was failed, manifest copying logic is ignored. I will try to submit a PR to extend manifest mangling logic. |
I think there is definetely some weird stuff with these 3 properties (sourceManifestFile, androidManifestFile, updatedManifestFile) I'm currently implementing the manifest-merger v2 from google: As you can see in that issue (and also in the branch)
and the default value of updatedManifestFile has changed to
I think we could achieve the same with 2 properties but we'd have to be sure to be backwards compatible |
Here lies the problem. If updatedManifestFile points to a build-folder by default, it essentially acts as manifest copying, thereby duplicating existing copyManifest() logic, but in the scope of a standalone mojo (ManifestUpdateMojo). Doesn't make too much sense to me, because after copying the manifest, it has to be picked up by other lifecycle mojos, if they are run as part of build process, of course. Which implies that a user has to explicitly set androidManifestFile (in configuration shared by all plugin mojos) to a location in build folder; after that the same configuration block cannot be used by ManifestUpdateMojo anymore... |
What do you mean by that? For the ManifestMergerMojo it makes sense to point the androidManifestFile & updatedManifestFile to the build folder. On the other hand for the ManifestUpdateMojo it does not always makes sense to place the manifest in the build folder for example if you use the autoIncrement flag you want to keep (and probably commit to git) the new manifest file. |
The problem is about the sequence (yes, the default one, I admit) of running all the mojos. According to a classic APK or AAR build lifecycle, GenerateSourcesMojo runs first, and does the manifest file copying (see sourceManifestFile and who uses it). Then, ManifestUpdateMojo is given a chance to execute, hence both "source" and "updated" manifest files should point to a new location. And finally, all other mojos are started. At the same time it is very common to share plugin execution configuration amongst all "default" mojos, including GenerateSourcesMojo and, say, ApkMojo. Therefore one has to keep ManifestUpdateMojo configuration separately, as androidManifestFile parameter is expected to have different value for different mojos. Moreover, given current configuration setup and default values of parameters, one would also have to explicitly specify updatedManifestFile and point it to the same file, as otherwise ManifestUpdateMojo would simply copy the manifest to its default location (src/main). See #533 for suggested minimum changes. These should not break new ManifestMerger v2, I believe |
"hence both "source" and "updated" manifest files should point to a new I think that's the miscommunication. The idea behind the I'm currently doing: then on the manifest update: As such, the src/main/android/AndroidManifest.xml is never altered by a On Wed Dec 10 2014 at 7:28:21 AM Leonid [email protected] wrote:
|
It is interesting though, that judging by ManifestUpdateMojo source, the default value for updatedManifestFile is As for setting failOnNonStandardStructure to false, it would be nice to let AMP do all the usual project layout checks. If we have an extra safety option, why not to use it? |
The androidManifestFile parameter in AbstractAndroidMojo overrides the As for the failOnNonStandardStructure... This application has had the On Wed Dec 10 2014 at 8:04:22 AM Leonid [email protected] wrote:
|
That's exactly the point! If one's application has its android manifest placed in "new default" The bottom line of this long discussion is, imho, is that having 3 parameters to configure 2 file locations looks like an overhead to me, as at least two parameters have to be assigned the same value to not to break the project. See my pull request #533 for a way to at least partially overcome this situation. |
Based on your comment, I relooked at my poms and found that I was in fact I agree with you that we need to use some sensible defaults here. We Looking at the pull request, I have two comments (including in this
which leads me to thinking... maybe we should change the
Obviously this could have repercussions on quite a few people. It's worth Malachi de Ælfweald On Thu, Dec 11, 2014 at 1:46 AM, Leonid [email protected] wrote:
|
Yep I like that approach. I'd like everyone to answer a question that was asked elsewhere:
|
IMHO, the build should only modify the target/ directory Malachi de Ælfweald On Thu, Dec 11, 2014 at 9:00 AM, Benoit Billington <[email protected]
|
What Malachi said - updates should occur in target. [image: photo] On Fri, Dec 12, 2014 at 3:51 AM, Malachi de AElfweald <
|
Yup I also agree with malachi. Last time I and others preferred to have the updated version in the src. Using the manifest-merger it should only be changed in target.
|
A file updated during the build process should end up in the "target" directory, I believe. That's where build artifacts are being thrown into. Hence it would be nice to have only two parameters. In a perfect world, it would be "source" (where manifest is taken from), and "destination" (where it ends up after all the modifications; target directory being the default). Later parameter is optional, as some developer may prefer to explicitly overwrite original (source) file to retain the changes. Not sure about proper names for these two, however... |
So what are the proposed changes everyone agrees on? I can do the pull request but I prefer to be sure on what we all want. Would the following be fine ? sourceManifestFile default to src/main/AndroidManifest.xml So the GenerateSourceMojo copy the manifest file from sourceManifestFile to androidManifestFile The ManifestUpdateMojo & ManifestMergerMojo process the sourceManifestFile and place the output into androidManifestFile Other mojos need to use androidManifestFile |
The changes you are proposing are fine, but would imply that everyone who develops Android apps with AMP need to review their plugin configurations. To be precise, this is the most tricky part:
If there is a Maven-built Android app that only specifies androidManifestFile in pom.xml, and it points to an actual (and final) location of manifest file, and sourceManifestFile is not explicitly defined, then such a configuration would become instantly broken. We can output a warning, though, if a manifest file referenced by sourceManifestFile was not found, but there is some file matching androidManifestFile path. If I understand it correctly, if new parameter sourceManifestFile is not explicitly defined in plugin configuration (i.e. not present in the pom), then it would get its default value; and there is no good way to determine whether user has intentionally left the parameter out of configuration, or he simply forgot about it? |
Yes it's a breaking change... AMP 4.1 or 4.5 or 5.0.... Is there a way to solve this issue without breaking all current configurations? Most people I guess are only using androidManifestFile so we could do it either the way proposed in the #541 pull request or: we remove sourceManifestFile, make the default location of androidManifestFile to src/main/AndroidManifest.xml and make the default location of finalManifestFile to the build directory and use that variable in all mojos.... in that case we would break the config for people using sourceManifest & updatedManifest which is fine I guess. See #542 |
Not sure... we could also keep the parameters we dont want to use anymore around, set them as deprecated in the UI docs and break the build if a value for these is configured in the pom. Then we could release it as 4.1 with a minor API breakage.. and towards 5.0 we remove it for real. Wdyt @simpligility/android-maven-plugins-core-committers |
What would be the implementation ? you would deprecate some params but would still use them? What would be the default value of each params? |
If somebody would ask me, then I'd cast my vote in favor of #541 as it simplifies the things a bit, and gets all mojos aligned and working in more or less the same way. Contrary to #542 which deprecates one parameter, but introduces another, with a somewhat overlapping default value. Happy New Year everybody! |
Not exactly #541 removes the updatedManifestFile parameter and would break non standard configurations. #542 Removes 2 parameters: sourceManifestFile & updatedManifestFile and add a new one destinationManifestFile which has a different default value than androidManifestFile. androidManifestFile would be in the src/ and destinationManifestFile would be in the target/ folder |
I would go with 542 from all I have seen. |
#542
|
I also think 542 is better for backwards compatibility (just break config of people using source & updated parameters) the 541 would break stuff and it would be harder for the user to understand what to do. |
I think thats enough votes.. go ahead and merge it ;-) |
Second solution for manifestFile params #508
If you have in your pom, the manifest-update mojo will correctly update it and write out the new version as . However future mojos appear to use whatever you have in . So if they are both the same, you are fine. However, if you have only set , then it is wrong. You should not be required to set , so I believe this is a bug.
This might be related to how you are trying to switch over and use the updated path:
ManifestUpdateMojo.java#L662:
project.getProperties().setProperty( "android.manifestFile", updatedManifestFile.getAbsolutePath() );
I don't think the other mojos are using the project property value instead of the pom value ().
Running version 4.0.0-rc.2.
The text was updated successfully, but these errors were encountered: