-
Notifications
You must be signed in to change notification settings - Fork 136
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
Add setters to the StashNotifier.DescriptorImpl class #201
Add setters to the StashNotifier.DescriptorImpl class #201
Conversation
All or most of this properties could be set while construction. While should we allow dynamically change the settings during lifecycle. Isn't it enough to pass YAML configuration to constructor in some way? |
@scaytrase Unfortunately, at least as far as I can see in the plugin implementation, it works by discovering fields and setters to determine what properties can be set from the YAML. They have some guidelines for plugin developers here. There can be some custom implementation be done on the configuration-as-code plugin side to handle different ways of configuring plugins, but I felt since stash notifier has quite a basic config, that would be a bit of an overkill. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also use data-binding via request.bindJson(this, json)
inside configure(...)
.
See Step 5 in https://github.com/jenkinsci/configuration-as-code-plugin/blob/configuration-as-code-1.8/docs/PLUGINS.md.
There should also be two tests - one for configuring Jenkins via YAML and one for exporting a configured Jenkins to YAML.
See How to test? in https://github.com/jenkinsci/configuration-as-code-plugin/blob/configuration-as-code-1.8/docs/PLUGINS.md.
Note: I am not a maintainer of this plugin. But I already have migrated some other plugins to be compatible with JCasC.
@@ -611,34 +611,66 @@ public String getStashRootUrl() { | |||
} | |||
} | |||
|
|||
public void setStashRootUrl(String stashRootUrl) { | |||
this.stashRootUrl = stashRootUrl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use correct indentation for all new code.
Here and in other places spaces & tabs are currently mixed up.
@@ -611,34 +611,66 @@ public String getStashRootUrl() { | |||
} | |||
} | |||
|
|||
public void setStashRootUrl(String stashRootUrl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please annotate all setters with @DataboundSetter
.
See Step 1 in https://github.com/jenkinsci/configuration-as-code-plugin/blob/configuration-as-code-1.8/docs/PLUGINS.md.
@darxriggs Thank you for the feedback and review. Will work further on the PR soon. |
@alexchiri as soon I have no views on architectural future of this plugin version (only some thoughts on 2.x version), I think we can accept this PR after suggested impovements |
…to run the tests in IntelliJIDEA)
… to match JCasC plugin. Add JCasC plugin test dependency to be able to test config as code functionality. Add matrix-project plugin as a test dependency, since it is required in tests by the JenkinsRule. Fix spacing and add @DataBoundSetter annotations to setters. Rewrite configure method and test to use req.bindJSON. Add tests to verify that configure using yaml and export to yaml work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick update.
I had another look at the new changes. It already looks pretty good.
See my comments for some required changes.
<relativePath /> | ||
</parent> | ||
<packaging>hpi</packaging> | ||
<properties> | ||
<revision>1.18</revision> | ||
<changelist>-SNAPSHOT</changelist> | ||
<!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. --> | ||
<jenkins.version>1.625.3</jenkins.version> | ||
<jenkins.version>2.60.3</jenkins.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to reduce it to the following snippet:
<properties>
<revision>1.18</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.60.3</jenkins.version>
<java.level>8</java.level>
</properties>
The rest is already covered by the parent pom nowadays.
(This can be verified with mvn help:effective-pom
.)
pom.xml
Outdated
@@ -3,20 +3,20 @@ | |||
<parent> | |||
<groupId>org.jenkins-ci.plugins</groupId> | |||
<artifactId>plugin</artifactId> | |||
<version>3.10</version> | |||
<version>3.36</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you like, there is already 3.40
- see https://github.com/jenkinsci/plugin-pom/releases.
public String getProjectKey() { | ||
return projectKey; | ||
} | ||
|
||
public void setProjectKey(String projectKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems you missed a @DataBoundSetter
here.
@@ -637,34 +626,73 @@ public String getStashRootUrl() { | |||
} | |||
} | |||
|
|||
@DataBoundSetter | |||
public void setStashRootUrl(String stashRootUrl) { | |||
this.stashRootUrl = stashRootUrl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Strings like this one I suggest to use something like Apache Commons Lang StringUtils::trimToNull or Jenkins Util::fixEmptyAndTrim. This improves user experience by better handling strings with leading/trailing spaces.
public String getProjectKey() { | ||
return projectKey; | ||
} | ||
|
||
public void setProjectKey(String projectKey) { | ||
this.projectKey = projectKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment about setStashRootUrl()
on trimming.
stashRootUrl = formData.getString("stashRootUrl"); | ||
ignoreUnverifiedSsl = formData.getBoolean("ignoreUnverifiedSsl"); | ||
includeBuildNumberInKey = formData.getBoolean("includeBuildNumberInKey"); | ||
this.stashRootUrl = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to keep the order consistent for easier reading/comparison:
- field declarations in
StashNotifier
(maybe) - setters/getters in
StashNotifier
(maybe) - default values (lines 751-758) in
StashNotifier::configure
- assertThat calls (lines 27-33) in
ConfigAsCodeTest::should_support_jcasc_from_yaml
- setter calls (lines 40-47) in
ConfigAsCodeTest::should_support_jcasc_to_yaml
includeBuildNumberInKey: true | ||
prependParentProjectKey: true | ||
projectKey: "JEN" | ||
stashRootUrl: "https://bitbucket.com" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it's only an example value, I suggest to use something like https://my.company.intranet/bitbucket
. This more clearly states that this plugin is about "Bitbucket Server" and not "Bitbucket Cloud". Also see #225 for a cleanup regarding this.
assertThat(desc.isIncludeBuildNumberInKey(), is(true)); | ||
assertThat(desc.isPrependParentProjectKey(), is(true)); | ||
assertThat(desc.isApplicable(AbstractProject.class), is(true)); | ||
verify(request).bindJSON(desc, json); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question is, if just verifying a bindJSON
call is sufficient for you.
To be really sure, values should still be verified (using a StaplerRequest
implementation/mock that implements bindJSON
if possible). Otherwise if you for example missed a setter for a field, this would not be caught here and JCasC and UI based configuration would be broken.
Update parent version to latest. Remove Maven properties that are inherited anyway from parent pom. Order plugin attributes in the same way everywhere. Trim String attributes. Add forgotten @DataBoundSetter. Update example value for stashRootUrl. Implement more rigorous unit test for configure method.
Thanks again for the detailed feedback and advice on this @darxriggs. Learned some things and feel I'm getting better at it. 😊 Please let me know if anything else sticks out! |
public void setIncludeBuildNumberInKey(boolean includeBuildNumberInKey) { | ||
this.includeBuildNumberInKey = includeBuildNumberInKey; | ||
} | ||
|
||
public String getProjectKey() { | ||
return projectKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You moved the field projectKey
before the field stashRootUrl
but the setter/getter order doesn't match this. But it doesn't really matter.
@@ -74,20 +77,30 @@ public void testConfigure() throws Descriptor.FormException { | |||
//given | |||
doNothing().when(desc).save(); | |||
|
|||
ServletContext servletContext = PowerMockito.mock(ServletContext.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible try not to use PowerMockito but only Mockito. You can have a look in the internet why to avoid PowerMock.
PowerMockito is mainly required to mock constructors and static methods. That's often the case for legacy code that was written without testability in mind. At first sight that's not the case here.
private boolean ignoreUnverifiedSsl; | ||
private boolean includeBuildNumberInKey; | ||
private String projectKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scaytrase I am wondring why projectKey
is a field in StashNotifier.DescriptorImpl
. It is not visible in the UI and was never part of global.jelly
. Shouldn't it be removed from StashNotifier.DescriptorImpl
and only be a field in StashNotifier
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure for it really, may be a copy-paste coincident. We can try to remove it, cannot image when project key should be declared on global level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's non blocking for this PR we can try it as a separate change
Apart from the |
thank you @alexchiri ! (and @darxriggs for comments, for sure) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was surprising to find this large commit in the commit history with a description that makes it sound like a minor change.
@@ -143,6 +135,18 @@ | |||
<version>2.0</version> | |||
<type>jar</type> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.jenkins-ci.plugins</groupId> | |||
<artifactId>matrix-project</artifactId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was the matrix project dependency added? The commit description makes no mention of it. I don't see the matrix plugin being used in the code. I see that it's only for testing, but I still don't see those new tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a test
scope dependency required by the new tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed to add that. I added the Matrix project test dependency because the JenkinsRule requires it and it has been removed from core since 1.561. I added the JenkinsRule in the test that verifies the configuration as code setup, according to JCasC documentation. (import and export yaml). (this is the issue where I found more information about the NoClassDefFoundError I got while using the JenkinsRule: https://issues.jenkins-ci.org/browse/JENKINS-27826)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the explanation!
import hudson.FilePath; | ||
import hudson.Launcher; | ||
import hudson.ProxyConfiguration; | ||
import hudson.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think wildcards make the code better. There are plenty of tools to keep an up-to-date list of used imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, using wildcard imports or not is a project decision. There are as always advantages and disadvantages. And nowadays tools should be able to handle both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree on all counts, I just wanted to make sure it was an intentional change and not somebody's sloppiness that everybody missed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not in general a Java developer and I adopted (ocassionaly, huh) this plugin with worse code conventions than it have today, but there is still no CSC strictly defined here today. We can adopt one, I think, if it make life easier.
@scaytrase I am looking forward for this to be released. :-) |
Just as reference, there is also JENKINS-56899 tracking this. |
In order to be able to configure this plugin using the Configuration As Code plugin, the StashNotifier.DescriptorImpl needs to have setters or public fields. Using YAML to configure Jenkins is pretty nice and this would enable this to work with this plugin as well.