Skip to content

[MPIR-478] Allow to save avatars images for team report during project build #97

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

Merged
merged 1 commit into from
Feb 23, 2025

Conversation

slawekjaranowski
Copy link
Member

@slawekjaranowski slawekjaranowski added the enhancement New feature or request label Feb 19, 2025
email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should just throw IOException

Copy link
Member Author

Choose a reason for hiding this comment

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

This is used in renderTeamMember and next in renderBody method.

  • renderBody method is implementation of org.apache.maven.reporting.AbstractMavenReportRenderer
  • renderBody can not throw any exception

so when exception should be catch and what we can do with it ...?

Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't handle the exception, just pretends it's not going to happen. Checked or unchecked it needs to be handled. I don't think it can be handled here, so throw the IOException and handle a failure where it's called from.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, what should happen on such exception, how do you want to handle it in report?

Now it be handled by Maven itself and build will be break.
I hope it will not often exception.

Copy link
Contributor

Choose a reason for hiding this comment

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

If breaking the build is the right answer — though I'm not sure it is — then that should happen higher up, likely with a MavenReportException or something like that. It shouldn't be a runtime exception from deep inside the code, whihc would indicate a bug in the code. An avatar service being unreachable is not a bug in the code, so just use a regular IOException here.

Copy link
Member Author

Choose a reason for hiding this comment

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

from team report perspective fetching images can be interpreted as one of report feature - so it can be important

Copy link
Member Author

Choose a reason for hiding this comment

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

renderBody method is defined in AbstractMavenReportRenderer from maven-reporting-impl so can not be changed in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

That doesn't sound right. This is a private method so something in this class should be calling it.

Copy link
Member Author

Choose a reason for hiding this comment

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

There is use, line 279:

         picUrl = getExternalAvatarUrl(member.getEmail());

Copy link
Contributor

Choose a reason for hiding this comment

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

so handle the IOException there, not here.

Also, if renderBody cannot throw any exception, then don't throw an exception in renderBody. Make sure that whatever code you call inside renderBody does not throw any exception, runtime exceptions included. Instead call all the code that might throw exceptions before you ever call renderBody, load up all the URLs or pics or whatever in memory at the beginning of executeReport, and only start rendering once all the resources are loaded and will not throw any exceptions during rendering.

Though in this case I really think it's simpler and easier to just use the default spacer image.

* @since 2.6
*/
@Parameter(property = "teamlist.showAvatarImages", defaultValue = "true")
private boolean showAvatarImages;

/**
* Indicate if external url should be used for avatar images.
Copy link
Contributor

Choose a reason for hiding this comment

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

URL.
Is there an internal URL? If not, delete "external" here or rewrite

Copy link
Member Author

Choose a reason for hiding this comment

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

I've rewritten a little here ...

@slawekjaranowski slawekjaranowski force-pushed the MPIR-478 branch 2 times, most recently from 498a69e to 925a45f Compare February 19, 2025 23:07
email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't handle the exception, just pretends it's not going to happen. Checked or unchecked it needs to be handled. I don't think it can be handled here, so throw the IOException and handle a failure where it's called from.

}
if (picUrl == null || picUrl.isEmpty()) {
picUrl = getSpacerGravatarUrl();
picUrl = getExternalAvatarUrl(member.getEmail());
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you want to do here when getExternalAvatarUrl( fails and throws an exception? Probably just don't call sink.figureGraphics below.

Copy link
Member Author

Choose a reason for hiding this comment

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

I want break a build, because images in report can be missing.

Copy link
Contributor

Choose a reason for hiding this comment

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

What if a user doesn't have an avatar? I don't think I do, for instance.

Copy link
Member Author

Choose a reason for hiding this comment

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

when user doesn't have an avatar default one will be returned by gravatar

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you can handle the IOException in this method. It doesn't need tonescape this class. Just wrap lines 277 through 285 in a try-catch block. The catch block can be empty or it can fill in a default image.

Copy link
Member Author

Choose a reason for hiding this comment

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

I know that I can catch and skip exception, and use default images - but I don't want.

As you know one step of release new component is publishing new documentation ... I don't want to add next manual task to verify team page during release. Maybe you have another experience with releasing new components ...

Some context of change - look at our team pages: https://maven.apache.org/team.html the same are on many other ASF projects.

public void executeReport(Locale locale) throws MavenReportException {
AvatarsProvider avatarsProvider = avatarsProviders.get(avatarProviderName);
if (avatarsProvider == null) {
throw new MavenReportException("No AvatarsProvider found for name " + avatarProviderName);
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to instead simply not show avatars in the report?

Copy link
Member Author

Choose a reason for hiding this comment

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

user want to show avatars, and probably misconfigured plugin - so we should not hide such case

Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest message then, and not breaking the report. You could also add a default image used when the server can't be reached.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is two different case wrong configuration - not existing provider and not available image server.

In both case we should break a build to prevent of unwanted result

public void executeReport(Locale locale) throws MavenReportException {
AvatarsProvider avatarsProvider = avatarsProviders.get(avatarProviderName);
if (avatarsProvider == null) {
throw new MavenReportException("No AvatarsProvider found for name " + avatarProviderName);
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest message then, and not breaking the report. You could also add a default image used when the server can't be reached.

}
if (picUrl == null || picUrl.isEmpty()) {
picUrl = getSpacerGravatarUrl();
picUrl = getExternalAvatarUrl(member.getEmail());
Copy link
Contributor

Choose a reason for hiding this comment

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

What if a user doesn't have an avatar? I don't think I do, for instance.

email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If breaking the build is the right answer — though I'm not sure it is — then that should happen higher up, likely with a MavenReportException or something like that. It shouldn't be a runtime exception from deep inside the code, whihc would indicate a bug in the code. An avatar service being unreachable is not a bug in the code, so just use a regular IOException here.

email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not fetching an artifact is far more serious than not fetching a user pic. It's reasonable that one breaks the build and the other doesn't.

If you can't throw MavenReportException from renderBody then pass the IOException up the stack to something that can. Or change the method signature so it can throw, though here I really think the exception can simply be handled by dropping the image. Perhaps this exception can be handled by using the default image.

email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

That doesn't sound right. This is a private method so something in this class should be calling it.

}
if (picUrl == null || picUrl.isEmpty()) {
picUrl = getSpacerGravatarUrl();
picUrl = getExternalAvatarUrl(member.getEmail());
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you can handle the IOException in this method. It doesn't need tonescape this class. Just wrap lines 277 through 285 in a try-catch block. The catch block can be empty or it can fill in a default image.

}
}

private String getSpacerGravatarUrl() {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can probably make this non-private and use this in cases where the provider fails.

email = StringUtils.trim(email);
email = email.toLowerCase();
MessageDigest md;
private String getExternalAvatarUrl(String email) {
Copy link
Contributor

Choose a reason for hiding this comment

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

so handle the IOException there, not here.

Also, if renderBody cannot throw any exception, then don't throw an exception in renderBody. Make sure that whatever code you call inside renderBody does not throw any exception, runtime exceptions included. Instead call all the code that might throw exceptions before you ever call renderBody, load up all the URLs or pics or whatever in memory at the beginning of executeReport, and only start rendering once all the resources are loaded and will not throw any exceptions during rendering.

Though in this case I really think it's simpler and easier to just use the default spacer image.

@slawekjaranowski slawekjaranowski force-pushed the MPIR-478 branch 2 times, most recently from bdf357c to db8f78f Compare February 20, 2025 21:53
@slawekjaranowski
Copy link
Member Author

@elharo please look now

@slawekjaranowski
Copy link
Member Author

Added support for default images in case of IOException or not existing avatar for given email

@slawekjaranowski slawekjaranowski self-assigned this Feb 23, 2025
@slawekjaranowski slawekjaranowski added this to the 3.9.0 milestone Feb 23, 2025
@slawekjaranowski slawekjaranowski merged commit e51cef8 into apache:master Feb 23, 2025
20 checks passed
@slawekjaranowski slawekjaranowski deleted the MPIR-478 branch February 23, 2025 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants