Skip to content

Conversation

@decriptor
Copy link
Contributor

@decriptor decriptor commented Dec 17, 2019

Support has been added for lint configuration files for android layouts in the designer code base.
This adds build action support for the new "AndroidRuleSet" item.
https://github.com/xamarin/designer/blob/8b01a63b3ecd494d65001cf1f74239a7db2a3db9/Xamarin.Designer.Android/Xamarin.AndroidDesigner/MSBuildConstants.cs#L52

https://github.com/xamarin/designer/pull/2709

Support has been added for lint configuration files for android layouts in the designer code base.
This adds build action support for the new "AndroidRuleSet" item.
https://github.com/xamarin/designer/blob/8b01a63b3ecd494d65001cf1f74239a7db2a3db9/Xamarin.Designer.Android/Xamarin.AndroidDesigner/MSBuildConstants.cs#L52
<AvailableItemName Include="AndroidJavaLibrary" />
<AvailableItemName Include="AndroidJavaSource" />
<AvailableItemName Include="AndroidLintConfig" />
<AvailableItemName Include="AndroidRuleSet" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have some kind of lint support in the build system via $(AndroidLintEnabled): https://github.com/xamarin/xamarin-android/blob/f7ea4a3db003da7be85d34eff4813c6052368e90/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets#L1097-L1111

Does this need to be incorporated here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our stuff isn't really exposed outside of our immediate designer space right now. But, this may be a good future thing.

Copy link
Contributor

@jonpryor jonpryor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update Documentation/guides/BuildProcess.md and provide documentation for the new Build action.

Please add a new Documentation/release-notes/4046.md file and provide release notes for the new build action.

@brendanzagaeski: Would you be able to provide a template for the release notes?

@brendanzagaeski
Copy link
Contributor

brendanzagaeski commented Dec 17, 2019

Please add a new Documentation/release-notes/4046.md file and provide release notes for the new build action.

If this is a feature that users might want to enable in their builds, the release note can start with something like:

## Option to enable lint checks for Android layout files

This version of Xamarin.Android adds a new option to check Android layout files using...

...

To enable this option, set the `$(AndroidRuleSet)` MSBuild property to...

If appropriate, the note can link to https://developer.android.com/studio/write/lint.

If the feature is indeed something users might want to enable in their builds, then it would be helpful for the release note to include a sentence about when to use this $(AndroidRuleSet) MSBuild property as opposed to the existing $(AndroidLint*) properties.

The entry in Documentation/guides/BuildProcess.md can share some of the same wording.

Other questions

One question might be whether this property will only every be used for lint rule sets for layout files? If so, then for closer resemblance to the other existing $(AndroidLint*) properties, there's a chance it might make sense to name this new MSBuild property something like $(AndroidLayoutLintRuleSet)?

Is this indeed a different rule set than would be specified as a @(AndroidLintConfig) MSBuild item?

@decriptor
Copy link
Contributor Author

@jonpryor @brendanzagaeski @jonathanpeppers (/cc @garuma)

For right now this is an android layout/designer only feature. We have implemented our own analyzers and fixers (currently disabled) and tied it into the android designer editors. It might be nice to expose this as a cmdline tool at some point.

Another thought, this is layout only, but it might be worth extending this to resource and android manifest files? Maybe even extending to source files too?

If all that happens, it might be worth combining all the lint conf build actions? Our lint.xml file currently models very closely to the Android lint.xml. The difference is in some of the issue ids.

The value of adding the BuildAction is so that it shows up in the properties window in the IDE.

image

Thoughts?

@jonathanpeppers
Copy link
Member

Where does the lint.xml come from? Does the designer ship it, or the customers author it themselves?

Would there value in the lint rules failing on CI systems? If so, it seems like we should make a way for the existing <Lint/> MSBuild task to take this new item group as input.

@decriptor
Copy link
Contributor Author

@jonathanpeppers the lint.xml or really AnyThing.xml as long as it has a build action of AndroidRuleSet will be parsed and used by the Android diagnostics we created.

It is currently connected to our layout editor. So, currently it isn't usable outside of the layout editor currently.

@decriptor
Copy link
Contributor Author

I added some documentation. If someone would like to review it, that'd be great.

@brendanzagaeski
Copy link
Contributor

Are there maybe any user story work items, draft IDE release notes, or draft blog post paragraphs for this feature that I could skim?

We have implemented our own analyzers and fixers (currently disabled) and tied it into the android designer editors

Is the linting in the designer not related to the open source lint binary from Google that the Xamarin.Android build process uses (from the Android SDK Tools directory)?

If it's a totally separate tool, then I think it might be advantageous to draw a sharper distinction between them. There is the Android lint from Google, and then maybe if I'm understanding correctly, the Xamarin designer has its own separate set of checks. Could these Xamarin designer checks perhaps be considered similar to the errors and suggestions available for XAML files? Example XAML error:

XLS0414 The type 'Aplication' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

Example XAML lightbulb suggestion:

XAML1103 Xaml Namespace is unnecessary

@brendanzagaeski
Copy link
Contributor

Are there maybe any user story work items, draft IDE release notes, or draft blog post paragraphs for this feature that I could skim?

Ah ha, I see there are indeed: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/522460.

At first skim, it looks like maybe the current set of analyzers are written in C# and are technically separate from the upstream Android lint codebase but aimed at providing similar functionality. It also sounds like in theory, the designer could one day move to using the upstream lint itself. Tricky.

Is that rough summary approximately accurate?

@dellis1972
Copy link
Contributor

@decriptor any reason why you can't just use the AndroidLintConfig build action? It would mean this PR would not be needed...

@decriptor
Copy link
Contributor Author

Are there maybe any user story work items, draft IDE release notes, or draft blog post paragraphs for this feature that I could skim?

Ah ha, I see there are indeed: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/522460.

At first skim, it looks like maybe the current set of analyzers are written in C# and are technically separate from the upstream Android lint codebase but aimed at providing similar functionality. It also sounds like in theory, the designer could one day move to using the upstream lint itself. Tricky.

Is that rough summary approximately accurate?

More or less correct. A couple years ago I attempted to just use the upstream lint code base. It didn't work out as well as I'd hoped and so we scrapped it and moved to creating our own in C#. It is extremely unlikely that we'd use the upstream tool directly in the Designer.

@decriptor
Copy link
Contributor Author

@decriptor any reason why you can't just use the AndroidLintConfig build action? It would mean this PR would not be needed...

I'd prefer not to reuse AndroidLintConfig for a couple reasons. One is that currently we somewhat honor the upstream android lint conf format, but that might not always be true. Also, I believe some of our ids might actually be different. I'd like to differentiate a bit. @garuma thoughts on this?

@brendanzagaeski
Copy link
Contributor

Perfect. Thanks for the sanity check and the additional info!

Updated suggestions for release notes and documentation:

Given the additional info, my current vote would be to avoid the term "lint" entirely in the user-facing documentation or release notes for this feature. Since the config file only "somewhat" honors the upstream lint config file format, this particular file type for the designer can have its own dedicated page on docs.microsoft.com that describes how to use it. The release notes can then link to that page instead of the upstream Android lint documentation.

Tangent idea about maybe using .editorconfig instead:

This might be too much bikeshedding, but one other thought I had is that perhaps these designer messages could instead use the .editorconfig mechanism that is currently only available for C# code analysis messages.

To get a sense of how this mechanism works, I tried some testing with a familiar C# compiler message:

CS0219: The variable 'x' is assigned but its value is never used

I noticed a few interesting things:

  • The settings in the .editorconfig file changed the behavior for both design-time IntelliSense and the actual build. So this approach could cover the potential future scenario where users might want to run some of the Android designer's XML analyzers at build time (in addition to or instead of the upstream lint analyzers).
  • I confirmed that the .editorconfig mechanism allows changing code analysis message severity on individual files in the project. For example, CS0219 can be suppressed in one .cs file but left as a warning in a different .cs file in the same project. So I think this mechanism covers everything the upstream lint config file format can do.
  • As far as I could tell, this mechanism has not yet been expanded to cover the XAML language service, so the Android designer would be leading the way in expanding it to cover other file types. But since the .editorconfig file allows sections for any kind of file, expanding it to cover code analysis configuration options for other file types does seem appropriate to me, at least at first glance.

(There are several ways to change the severity of C# code analysis messages, but the one that looks best suited for non-C# files is the .editorconfig mechanism.)

@dellis1972
Copy link
Contributor

@decriptor so will this new item be of any use to external users? If not is there any way we can not show it in the final product? Can we hide this behind a feature flag? I want to try to avoid confusion for the end user, even if we have docs that say its internal only, someone will try to use it.

@garuma
Copy link
Contributor

garuma commented Jan 7, 2020

Chiming in this discussion mostly to highlight all the other good points already raised.

As @decriptor mentions this is to support a feature that, albeit similar to Google's lint right now, is not meant to be compatible per-say with Lint (i.e its configuration format, user extensions, ...). It's also not destined to be swapped with Lint itself.

On the configuration front, @brendanzagaeski raised a good idea that .editorconfig could also ultimately be a good medium for doing this as well (I see it as an additional way though not a replacement the same way Roslyn diagnostics can be configured in multiple fashion). Supporting the baseline of the Lint format offers us a good migration path to start and some other interesting capabilities (e.g. NuGet/global provided ruleset) but we don't have to stop there.

We are also not aiming to have this currently be usable outside the IDE or with other resource types than layouts. Ultimately both of those things though are worthy goals however.

In essence, the only goal of this PR is to make that item type visible to the IDE (at least in VS it's required to have the items property grid work) to avoid having to manually edit a .csproj (which would work fine otherwise). Since it won't be usable outside of the IDE context, it might indeed not be useful to prominently show it in the Xamarin.Android documentation beyond a note of what's it's for.

@brendanzagaeski
Copy link
Contributor

Cool point about being able to include configuration files from NuGet packages.

Maybe it's interesting to jot down some notes about $(CodeAnalysisRuleSet) too then. One nice thing is that like .editorconfig, it has GUI integration for changing message severities to any of the available Visual Studio severity levels: Error, Warning, Info, Hidden, None. I didn't know about the Hidden severity before, but it's useful. It allows an issue to be shown only in the text editor, not in the error list.

I noticed at least 4 limitations of $(CodeAnalysisRuleSet):

  1. It only allows one active rule file at a time, so providing rule files via NuGet packages might not be too interesting.
  2. It only works at the project scope. It doesn't allow configuring rules separately for individual files.
  3. It doesn't have familiarity advantages for users who have used the upstream Android lint. (This might not strictly be a feature of @(AndroidRuleSet) either since the future divergence of the @(AndroidRuleSet) config format away from the upstream Android lint config format could be challenging to communicate to users.)
  4. When I open the *.ruleset editor, I get a yellow suggestion bar at the top that suggests migrating to .editorconfig.

Limitation #1 about having just one active config file raises a potentially useful question. If a project has two @(AndroidRuleSet) files, and each one specifies a different severity for a particular rule, which severity wins? Does the precedence depend on the order of the <AndroidRuleSet> elements in the .csproj file? Or maybe that scenario will produce an actionable user-visible error message instead?

With @(AndroidLintConfig), the precedence does indeed depend on the <AndroidLintConfig> element order, so you can potentially change the lint results just by removing and re-adding a config file. I think that might not be ideal. It might also be puzzling for an app author to figure out how to fix a conflicting severity setting, especially if one of the config files comes from a NuGet package. (Maybe the Lint task can be improved to help with this in the future. For example, if merging multiple rule sets is important, maybe the Android manifest merger tool could help?)

On a different topic, for the name of the new MSBuild item, maybe expanding it with another word to something like @(AndroidDesignerRuleSet) could help set it apart from the other code analysis mechanisms? Separately, maybe the top-level XML element in the files could be something other than <lint> to distinguish the format from upstream lint config files?

@brendanzagaeski
Copy link
Contributor

I chatted with Stephen about this item more today, and I realized that the designer side of this feature has already been cherry-picked to the d16-5 designer branch and is already included in the latest Visual Studio 2019 version 16.5 Internal Preview. So it might be best to keep the finishing touches as small as possible for now.

Given that, I think for right now the only things I'd keep for consideration from my earlier comments are:

  1. If there's still time to adjust the MSBuild item name on the Android designer side, my suggestion is:

    @(AndroidDesignerAnalysisConfig)
    

    This achieves four things. It avoids the term "RuleSet" because "RuleSet" suggests compatibility with the *.ruleset file format, which is not the case. It avoids the term "Lint" because that has a different existing meaning in Xamarin.Android projects. It includes a word "Analysis" that will be familiar to C# code analysis users. And it includes a word "Config" that resembles the @(AndroidLintConfig) name, providing a gentle hint that the file format is loosely similar.

  2. A new documentation page will be needed under the Android designer section of docs.microsoft.com to explain the config file format.


Other notes:

I learned today that some of the Android designer analyzers were already present in Visual Studio 2019 version 16.4. The new thing for this PR is just about configuring severities. Perhaps there has already been user feedback from Visual Studio 2019 version 16.4 asking for a way to change the analyzer result severities.

I haven't yet had a chance to try the config file workflow with the Internal Preview myself. For some reason in my environment, the designer extension isn't loading because it can't find the Xamarin.VisualStudio.Android.Designer.IAndroidDesignerService contract in the current Visual Studio Internal Preview.

@garuma
Copy link
Contributor

garuma commented Jan 9, 2020

@brendanzagaeski my issue with AndroidDesignerAnalysisConfig is that it carries the AndroidDesigner part in it which may or may not be true in the future (see #4046 (comment)). We could shorten it to AndroidAnalysisConfig which would work. As you mention the current name has sailed already for 16.5 Preview 2 and users will have to manually edit their .csproj file if they want to use it. If we can have a consensus on a better name however I'm ok doing that final adjustment for Preview 3.

In 16.4 we voluntarily enabled only a small subset of analyzers because of that lack of configurability, in 16.5 we have enabled them all because it can now be configured via that file mechanism.

@brendanzagaeski
Copy link
Contributor

Good idea! AndroidAnalysisConfig sounds fine by me.

I ended up with "Designer" in the name because I was initially thinking of AndroidResourceAnalysisConfig, but then I had thought that "resource" might be too overloaded of a term. And I thought maybe if other parts of the feature would be changing significantly in the future, the item name could change too to remove "Designer" when appropriate. But it's definitely nicer to avoid migrating users to a different item name in the future if possible.

In fact, as I'm thinking about it again today, AndroidResourceAnalysisConfig actually seems fine too, so if anyone prefers that too, that'd be a-ok by me, but the shorter AndroidAnalysisConfig also sounds good.

@decriptor
Copy link
Contributor Author

What about AndroidDiagnosticsConfig or AndroidDiagnosticConfig? (missings)

Or should it be the full AndroidDiagnostic(s)Configuration(s)?

@brendanzagaeski
Copy link
Contributor

Is there another similar MSBuild item or property you have in mind (maybe for another project type) that uses "Diagnostics" that would be an inspiration to use that term in this item?

@decriptor
Copy link
Contributor Author

@brendanzagaeski that is the term we used in our code base for this.

@brendanzagaeski
Copy link
Contributor

Ah cool, I see. I think my personal vote would still be for "Analysis" over "Diagnostics" in this context since the name will be part of the public user interface of the feature (as opposed to an underscore-prefixed MSBuild item only used internally by the tooling).

Putting myself in the shoes of an existing user, "AndroidDiagnostics" makes me think of:
image

Whereas one thing "Analysis" makes me think of is the items under the Analyze menu:
image

I think those might be close in spirit to what this feature provides? Maybe some day some of the items in that menu will even be applicable to this feature?

@jonpryor
Copy link
Contributor

As per call with @garuma and @brendanzagaeski on 2020-01-20, we'll use @(AndroidResourceAnalysisConfig) as the Build action, and we'll need an appropriate link to the documentation for the file format that is supported.

@decriptor decriptor force-pushed the designer-androidruleset-buildaction branch from 337a305 to c70cf07 Compare January 28, 2020 23:00
@decriptor decriptor requested a review from jonpryor January 28, 2020 23:24
Copy link
Contributor

@brendanzagaeski brendanzagaeski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Little wording ideas:

-The Build action `AndroidResourceAnalysisConfig` enables an xml configuration
-file to be used by the new Xamarin Android Designer layout diagnostics tool.
-This is only used by the layout editor.
+The Build action `AndroidResourceAnalysisConfig` marks a file as a severity
+level configuration file for the Xamarin Android Designer layout diagnostics
+tool. This is currently only used for IntelliSense messages and not for build
+messages.

See the [Android Resource Analysis documentation](https://aka.ms/androidresourceanalysis) for more details.

(Feel free to take or adapt any of those little wording ideas, if any of them sound good.)

For reference (no need to adjust anything with these in this PR unless you want to), a couple tiny things I'll adjust when syncing the docs for publication:

  • Move the AndroidResourceAnalysisConfig section to be after AndroidNativeLibrary in BuildProcess.md for alphabetical ordering.

  • The original template I suggested for the release notes ended up being mismatched with the real feature because back then I didn't realize this analysis/diagnostics is always enabled and the build action is just for configuring the results. So I'll plan to adapt the wording a little when I put the release notes all together, to be something like:

    -Adds a new build action to inspect Android layout files using the new
    -Xamarin Android Designer diagnostics tool. To enable this option, set the
    -configuration file build action to `AndroidResourceAnalysisConfig`.
    +Adds a new build action to allow configuring message severity levels in the
    +Xamarin Android Designer diagnostics tool. To use this in your project,
    +add an XML configuration file that follows the format described in the
    +[Android Resource Analysis
    +documentation](https://aka.ms/androidresourceanalysis) and set the build
    +action to `AndroidResourceAnalysisConfig`.

This adds the build action for the new Android diagnostics tool that the
Android designer team created to analysis layout files.

Currently the aka.ms link in the documentation doesn't work, but will
once it has been written.
@decriptor decriptor force-pushed the designer-androidruleset-buildaction branch from c70cf07 to ec0d072 Compare January 29, 2020 02:12
@decriptor
Copy link
Contributor Author

@brendanzagaeski I think I applied all of your suggestions

@brendanzagaeski
Copy link
Contributor

Looks great. That'll make the docs publishing even easier. Thanks a bunch!

@decriptor
Copy link
Contributor Author

As a side note the aka.ms link works, but is just currently pointing at the Xamarin.Android Designer doc landing page

@jonpryor jonpryor merged commit e120647 into master Jan 29, 2020
jonpryor pushed a commit that referenced this pull request Jan 29, 2020
Add an `AndroidResourceAnalysisConfig` entry to `@(AvailableItemName)`,
allowing users to use the `@(AndroidResourceAnalysisConfig)` build
action on files within a project.

Files with the `@(AndroidResourceAnalysisConfig)` build action
configures message severity levels produced by the Xamarin Android
Designer diagnostics tool, and must follow [the documented schema][0].

[0]: https://aka.ms/androidresourceanalysis
@decriptor decriptor deleted the designer-androidruleset-buildaction branch January 29, 2020 18:03
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants