Index: email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/config.jelly =================================================================== --- email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/config.jelly (revision 19390) +++ email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/config.jelly Wed Dec 02 10:04:49 HST 2009 @@ -42,6 +42,25 @@ </select> </f:entry> + <f:entry title="Charset" + help="${rootURL}/plugin/email-ext/help/projectConfig/charset.html"> + <!--input class="setting-input validated" name="project_charset" + type="text" value="${instance.charset}" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/charsetCheck?value='+encode(this.value)"/--> + <j:choose> + <j:when test="${instance.configured}"> + <input class="setting-input validated" name="project_charset" + type="text" value="${instance.charset}" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/charsetCheck?value='+encode(this.value)"/> + </j:when> + <j:otherwise> + <input class="setting-input validated" name="project_charset" + type="text" value="default" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/charsetCheck?value='+encode(this.value)"/> + </j:otherwise> + </j:choose> + </f:entry> + <!-- This is the default subject line for the project. --> <f:entry title="Default Subject" help="${rootURL}/plugin/email-ext/help/projectConfig/defaultSubject.html"> @@ -57,6 +76,19 @@ </j:choose> </f:entry> + <f:entry title="Default Content is Script" + help="${rootURL}/plugin/email-ext/help/projectConfig/mailType/script.html"> + <j:choose> + <j:when test="${instance.configured}"> + <f:checkbox name="project_default_content_is_script" + checked="${instance.defaultContentIsScript}" /> + </j:when> + <j:otherwise> + <f:checkbox name="project_default_content_is_script" checked="false" /> + </j:otherwise> + </j:choose> + </f:entry> + <!-- This is the default content for the project. --> <f:entry title="Default Content" help="${rootURL}/plugin/email-ext/help/projectConfig/defaultBody.html"> @@ -90,7 +122,16 @@ <td colspan="2"><div id="contentTokenHelpConf" style="display:none" class="mailHelp">${contentTokenText}</div></td> <td></td> </tr> - + + <f:entry title="Build for Testing" + help="${rootURL}/plugin/email-ext/help/projectConfig/buildForTesting.html"> + <input class="setting-input validated" name="project_build_for_testing" + type="text" value="${instance.buildForTesting}" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/buildForTestingCheck?value='+encode(this.value)"/> + </f:entry> + + <f:validateButton title="${%Test Against Build}" method="testAgainstBuild" with="project_build_for_testing, project_default_content_is_script,project_default_content,project_default_subject,project_charset,project_content_type,project_default_content_is_script,recipientlist_recipients" /> + <!-- Configure advanced properties like per-build-result status email contents, whether or not to send email to developers who made changes, and whether or not to send email to the global list of devs--> Index: email-ext/src/main/webapp/help/projectConfig/mailType/script.html =================================================================== --- email-ext/src/main/webapp/help/projectConfig/mailType/script.html Tue Nov 24 17:23:05 HST 2009 +++ email-ext/src/main/webapp/help/projectConfig/mailType/script.html Tue Nov 24 17:23:05 HST 2009 @@ -0,0 +1,6 @@ +<div> + Specifies whether the mail's content should be interpreted as a Groovy + <a href="http://groovy.codehaus.org/Groovy+Templates">SimpleTemplate</a> script. + If so, the script can access the <code>AbstractBuild</code> object using the + <code>build</code> bind variable. +</div> Index: email-ext/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java =================================================================== --- email-ext/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java (revision 22062) +++ email-ext/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java Fri Dec 18 14:06:15 HST 2009 @@ -2,11 +2,7 @@ import hudson.Extension; import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.model.Hudson; -import hudson.model.User; +import hudson.model.*; import hudson.plugins.emailext.plugins.ContentBuilder; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -30,6 +26,7 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import java.nio.charset.Charset; import javax.mail.Address; import javax.mail.Authenticator; @@ -46,6 +43,7 @@ import net.sf.json.JSONObject; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; /** * {@link Publisher} that sends notification e-mail. @@ -67,8 +65,10 @@ public static final String PROJECT_DEFAULT_SUBJECT_TEXT = "$PROJECT_DEFAULT_SUBJECT"; public static final String PROJECT_DEFAULT_BODY_TEXT = "$PROJECT_DEFAULT_CONTENT"; - + + private static final String DEFAULT_CHARSET_SENTINAL = "default"; + - public static void addEmailTriggerType(EmailTriggerDescriptor triggerType) throws EmailExtException { + public static void addEmailTriggerType(EmailTriggerDescriptor triggerType) throws EmailExtException { if(EMAIL_TRIGGER_TYPE_MAP.containsKey(triggerType.getMailerId())) throw new EmailExtException("An email trigger type with name " + triggerType.getTriggerName() + " was already added."); @@ -113,7 +113,12 @@ */ public String contentType; - /** + /** + * The charset of the emails for this project. + */ + public String charset; + + /** * The default subject of the emails for this project. ($PROJECT_DEFAULT_SUBJECT) */ public String defaultSubject; @@ -123,6 +128,10 @@ */ public String defaultContent; + public boolean defaultContentIsScript; + + public String buildForTesting; + /** * Get the list of configured email triggers for this project. */ @@ -260,9 +269,16 @@ //Set the contents of the email msg.setSentDate(new Date()); String subject = new ContentBuilder().transformText(type.getSubject(), this, type, build); + String specificCharset = charset; + if (specificCharset == null || DEFAULT_CHARSET_SENTINAL.equalsIgnoreCase(specificCharset)) { + specificCharset = DESCRIPTOR.getDefaultCharset(); + } + if (specificCharset == null || DEFAULT_CHARSET_SENTINAL.equalsIgnoreCase(specificCharset)) { - msg.setSubject(subject); + msg.setSubject(subject); + } else { + msg.setSubject(subject, specificCharset); + } String text = new ContentBuilder().transformText(type.getBody(), this, type, build); - msg.setContent(text, contentType); String messageContentType = contentType; // contentType is null if the project was not reconfigured after upgrading. if (messageContentType == null || "default".equals(messageContentType)) { @@ -273,6 +289,9 @@ messageContentType = "text/plain"; } } + if (specificCharset != null && !DEFAULT_CHARSET_SENTINAL.equalsIgnoreCase(specificCharset)) { + messageContentType += "; charset=" + specificCharset; + } msg.setContent(text, messageContentType); // Get the recipients from the global list of addresses @@ -388,8 +407,13 @@ * This is a global default content type (mime type) for emails. */ private String defaultContentType; - - /** + + /** + * This is a global default charset (mime type) for emails. + */ + private String defaultCharset; + + /** * This is a global default subject line for sending emails. */ private String defaultSubject; @@ -399,9 +423,19 @@ */ private String defaultBody; + /** + * This indicates that the global default body or subject line should be evaluated as a script. + */ + private boolean defaultIsScript; + + /** + * This just remembers the last build for testing that was saved, for the user's convenience. + */ + public String defaultBuildForTesting; + private boolean overrideGlobalSettings; - - @Override + + @Override public String getDisplayName() { return "Editable Email Notification"; } @@ -495,11 +529,15 @@ public String getSmtpPort() { return smtpPort; } - - public String getDefaultContentType() { - return defaultContentType; - } - + + public String getDefaultContentType() { + return defaultContentType; + } + + public String getDefaultCharset() { + return defaultCharset; + } + public String getDefaultSubject() { return defaultSubject; } @@ -507,7 +545,15 @@ public String getDefaultBody() { return defaultBody; } - + + public boolean getDefaultIsScript() { + return defaultIsScript; + } + + public String getDefaultBuildForTesting() { + return defaultBuildForTesting; + } + public boolean getOverrideGlobalSettings() { return overrideGlobalSettings; } @@ -525,10 +571,13 @@ ExtendedEmailPublisher m = new ExtendedEmailPublisher(); m.recipientList = listRecipients; m.contentType = req.getParameter("project_content_type"); + m.charset = req.getParameter("project_charset"); m.defaultSubject = req.getParameter("project_default_subject"); m.defaultContent = req.getParameter("project_default_content"); + m.defaultContentIsScript = req.getParameter("project_default_content_is_script")!=null; m.configuredTriggers = new ArrayList<EmailTrigger>(); + m.buildForTesting = req.getParameter("project_build_for_testing"); - + // Create a new email trigger for each one that is configured for (String mailerId : EMAIL_TRIGGER_TYPE_MAP.keySet()) { EmailType type = createMailType(req, mailerId); @@ -556,6 +605,7 @@ m.setSendToRecipientList(req.getParameter(prefix + "sendToRecipientList")!=null); m.setSendToDevelopers(req.getParameter(prefix + "sendToDevelopers")!=null); m.setIncludeCulprits(req.getParameter(prefix + "includeCulprits")!=null); + m.setScript(req.getParameter(prefix + "script")!=null); return m; } @@ -602,11 +652,14 @@ smtpPort = nullify(req.getParameter("ext_mailer_smtp_port")); defaultContentType = nullify(req.getParameter("ext_mailer_default_content_type")); + defaultCharset = nullify(req.getParameter("ext_mailer_default_charset")); // Allow global defaults to be set for the subject and body of the email defaultSubject = nullify(req.getParameter("ext_mailer_default_subject")); defaultBody = nullify(req.getParameter("ext_mailer_default_body")); + defaultIsScript = req.getParameter("ext_mailer_default_is_script") != null; + defaultBuildForTesting = req.getParameter("ext_mailer_default_build_for_testing"); - + overrideGlobalSettings = req.getParameter("ext_mailer_use_global_settings") != null; save(); @@ -651,9 +704,130 @@ } return FormValidation.ok(); } - + + public FormValidation doCharsetCheck(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException { + String charset = nullify(value); + if (charset == null || DEFAULT_CHARSET_SENTINAL.equalsIgnoreCase(charset) || Charset.isSupported(charset)) { + return FormValidation.ok(); + } else { + return FormValidation.error("unsupported charset"); - } + } + } + public FormValidation doBuildForTestingCheck(StaplerRequest req, StaplerResponse rsp, @QueryParameter final String value) throws IOException, ServletException { + String buildForTesting = nullify(value); + if (buildForTesting == null) { + return FormValidation.ok(); + } + try { + getBuildForTesting(buildForTesting); + return FormValidation.ok(); + } + catch (FormValidation e) { + return e; + } + } + private interface TransformStrategy { + String transformText(String origText, ExtendedEmailPublisher publisher, EmailType type, AbstractBuild build); + } + public FormValidation doTestAgainstBuild(StaplerRequest req, @QueryParameter("project_build_for_testing") String buildForTesting) throws IOException { + TransformStrategy strategy = new TransformStrategy() { + public String transformText(String origText, ExtendedEmailPublisher publisher, EmailType type, AbstractBuild build) { + return new ContentBuilder().transformText(origText, publisher, type, build); -} + } + }; + return doTestAgainstBuild(strategy, PROJECT_DEFAULT_SUBJECT_TEXT, PROJECT_DEFAULT_BODY_TEXT, req, buildForTesting); + } + + public FormValidation doGlobalTestAgainstBuild(StaplerRequest req, + @QueryParameter("ext_mailer_default_build_for_testing") String buildForTesting, + @QueryParameter("ext_mailer_default_is_script") final boolean globalIsScript, + @QueryParameter("ext_mailer_default_subject") String globalSubject, + @QueryParameter("ext_mailer_default_body") String globalBody + ) throws IOException { + TransformStrategy strategy = new TransformStrategy() { + public String transformText(String origText, ExtendedEmailPublisher publisher, EmailType type, AbstractBuild build) { + // This works around ContentBuilder.transformText()'s static access of the global subject and body, + // which has not been updated before testing. + return new ContentBuilder().transformResolvedText(globalIsScript, origText, publisher, type, build); + } + }; + return doTestAgainstBuild(strategy, globalSubject, globalBody, req, buildForTesting); + } + + private String testedEmailText; + + private FormValidation doTestAgainstBuild(TransformStrategy strategy, + String originalSubject, + String originalBody, + StaplerRequest req, + String buildForTesting + ) throws IOException { + buildForTesting = nullify(buildForTesting); + if (buildForTesting == null) { + return FormValidation.error("need to configure a build for testing"); + } + try { + AbstractBuild build = getBuildForTesting(buildForTesting); + ExtendedEmailPublisher publisher = (ExtendedEmailPublisher) newInstance(req, null); + EmailType type = new EmailType(); + type.setBody(ExtendedEmailPublisher.PROJECT_DEFAULT_BODY_TEXT); + type.setSubject(ExtendedEmailPublisher.PROJECT_DEFAULT_SUBJECT_TEXT); + String subject = strategy.transformText(originalSubject, publisher, type, build); + testedEmailText = strategy.transformText(originalBody, publisher, type, build); + String resultUrl = req.getRequestURI().replace("testAgainstBuild", "testedEmailText") + .replace("globalTestAgainstBuild", "testedEmailText"); // todo: some better hack + return FormValidation.okWithMarkup("resulting subject: " + subject + + "<br/>resulting body:<br/> <iframe width='100%' height='400px' src='" + resultUrl + "'/>"); + } + catch (FormValidation e) { + return e; + } catch (FormException e) { + return FormValidation.error(e.getMessage()); + } + } + + public void doTestedEmailText(StaplerRequest req, StaplerResponse rsp) throws IOException { + rsp.setContentType("text/html"); + rsp.getWriter().write(testedEmailText); + } + + private AbstractBuild getBuildForTesting(String buildForTesting) throws FormValidation { + int slashIndex = buildForTesting.indexOf('/'); + if (slashIndex == -1) { + throw FormValidation.error("must format as '<jobName>/<buildNumber>'"); + } + String jobName = buildForTesting.substring(0, slashIndex); + String buildNumber = buildForTesting.substring(slashIndex + 1); + Job job; + try { + job = (Job) Hudson.getInstance().getItem(jobName); + } + catch (ClassCastException e) { + throw FormValidation.error(jobName + " is not a job"); + } + if (job == null) { + throw FormValidation.error(jobName + " job not found"); + } + AbstractBuild build; + try { + build = (AbstractBuild) job.getBuildByNumber(Integer.valueOf(buildNumber)); + } + catch (NumberFormatException e) { + throw FormValidation.error("cannot parse build number: " + e.getMessage()); + } + catch (ClassCastException e) { + throw FormValidation.error("not a build: " + e.getMessage()); + } + if (build == null) { + throw FormValidation.error("build " + buildNumber + " not found"); + } + return build; + } + } + + + +} Index: email-ext/src/main/resources/hudson/plugins/emailext/tags/mailtype.jelly =================================================================== --- email-ext/src/main/resources/hudson/plugins/emailext/tags/mailtype.jelly (revision 14861) +++ email-ext/src/main/resources/hudson/plugins/emailext/tags/mailtype.jelly Tue Nov 24 17:23:05 HST 2009 @@ -122,6 +122,11 @@ name="mailer.${mailType}.body" value="${mailTypeObj.body}"/> </f:entry> + <f:entry title="Content is Script" + help="${rootURL}/plugin/email-ext/help/projectConfig/mailType/script.html"> + <f:checkbox name="mailer.${mailType}.script" + checked="${mailTypeObj.script}" /> + </f:entry> </table> </td> </tr> @@ -130,4 +135,4 @@ <script type="text/javascript">swapEdit("${mailType}");</script> <d:invokeBody /> -</j:jelly> \ No newline at end of file +</j:jelly> Index: email-ext/src/main/webapp/help/globalConfig/defaultIsScript.html =================================================================== --- email-ext/src/main/webapp/help/globalConfig/defaultIsScript.html Tue Nov 24 18:49:41 HST 2009 +++ email-ext/src/main/webapp/help/globalConfig/defaultIsScript.html Tue Nov 24 18:49:41 HST 2009 @@ -0,0 +1,4 @@ +<div> + Indicates that the global default subject or content includes a script. + If they are used within an email, the whole email will be evaluated as a script. +</div> \ No newline at end of file Index: email-ext/src/main/webapp/help/globalConfig/defaultCharset.html =================================================================== --- email-ext/src/main/webapp/help/globalConfig/defaultCharset.html Mon Nov 30 16:54:59 HST 2009 +++ email-ext/src/main/webapp/help/globalConfig/defaultCharset.html Mon Nov 30 16:54:59 HST 2009 @@ -0,0 +1,4 @@ +<div> + The default charset of the emails sent after a build. + If this is set to default, then it uses the Hudson JVM's default charset. +</div> Index: email-ext/pom.xml =================================================================== --- email-ext/pom.xml (revision 22077) +++ email-ext/pom.xml Tue Nov 24 17:23:05 HST 2009 @@ -27,5 +27,11 @@ <version>2.4</version> <scope>provided</scope> </dependency> + + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + <version>1.5.6</version> + </dependency> </dependencies> </project> Index: email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/global.jelly =================================================================== --- email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/global.jelly (revision 23570) +++ email-ext/src/main/resources/hudson/plugins/emailext/ExtendedEmailPublisher/global.jelly Fri Dec 18 14:19:55 HST 2009 @@ -65,6 +65,12 @@ >HTML (text/html)</f:option> </select> </f:entry> + <f:entry title="Default Charset" + help="${rootURL}/plugin/email-ext/help/globalConfig/defaultCharset.html"> + <input class="setting-input validated" name="ext_mailer_default_charset" + type="text" value="${descriptor.defaultCharset}" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/charsetCheck?value='+encode(this.value)"/> + </f:entry> <f:entry title="Default Subject" help="${rootURL}/plugin/email-ext/help/globalConfig/defaultSubject.html"> <input class="setting-input" name="ext_mailer_default_subject" @@ -76,6 +82,21 @@ name="ext_mailer_default_body" value="${descriptor.defaultBody}"/> </f:entry> + <f:entry title="Default is Script" + help="${rootURL}/plugin/email-ext/help/globalConfig/defaultIsScript.html"> + <f:checkbox name="ext_mailer_default_is_script" checked="${descriptor.defaultIsScript}" /> + </f:entry> + + <f:entry title="Build for Testing" + help="${rootURL}/plugin/email-ext/help/globalConfig/buildForTesting.html"> + <input class="setting-input validated" name="ext_mailer_default_build_for_testing" + type="text" value="${descriptor.defaultBuildForTesting}" + checkUrl="'${rootURL}/publisher/ExtendedEmailPublisher/buildForTestingCheck?value='+encode(this.value)"/> + </f:entry> + + <f:validateButton title="${%Test Against Build}" method="globalTestAgainstBuild" + with="ext_mailer_default_build_for_testing,ext_mailer_default_is_script,ext_mailer_default_subject,ext_mailer_default_body,ext_mailer_default_charset,ext_mailer_default_content_type" /> + <!-- This is the help section. It displays a bunch of dynamic help for all content tokens. --> <tr> <td></td> Index: email-ext/src/main/java/hudson/plugins/emailext/plugins/ContentBuilder.java =================================================================== --- email-ext/src/main/java/hudson/plugins/emailext/plugins/ContentBuilder.java (revision 15609) +++ email-ext/src/main/java/hudson/plugins/emailext/plugins/ContentBuilder.java Fri Dec 18 13:03:08 HST 2009 @@ -1,5 +1,7 @@ package hudson.plugins.emailext.plugins; +import groovy.text.SimpleTemplateEngine; +import groovy.text.Template; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.plugins.emailext.EmailExtException; @@ -61,13 +63,23 @@ public <P extends AbstractProject<P, B>, B extends AbstractBuild<P, B>> String transformText(String origText, ExtendedEmailPublisher publisher, EmailType type, B build) { - String newText = origText.replaceAll(PROJECT_DEFAULT_BODY, Matcher.quoteReplacement(publisher.defaultContent)) - .replaceAll(PROJECT_DEFAULT_SUBJECT, Matcher.quoteReplacement(publisher.defaultSubject)) - .replaceAll(DEFAULT_BODY, Matcher.quoteReplacement(ExtendedEmailPublisher.DESCRIPTOR.getDefaultBody())) + boolean isScript = type.isScript(); + String projectlyResolvedText = origText.replaceAll(PROJECT_DEFAULT_BODY, Matcher.quoteReplacement(publisher.defaultContent)) + .replaceAll(PROJECT_DEFAULT_SUBJECT, Matcher.quoteReplacement(publisher.defaultSubject)); + boolean usingSomeProjectDefaultContent = !projectlyResolvedText.equals(origText); + isScript |= publisher.defaultContentIsScript && usingSomeProjectDefaultContent; + String globallyResolvedText = projectlyResolvedText.replaceAll(DEFAULT_BODY, Matcher.quoteReplacement(ExtendedEmailPublisher.DESCRIPTOR.getDefaultBody())) - .replaceAll(DEFAULT_SUBJECT, Matcher.quoteReplacement(ExtendedEmailPublisher.DESCRIPTOR.getDefaultSubject())); + .replaceAll(DEFAULT_SUBJECT, Matcher.quoteReplacement(ExtendedEmailPublisher.DESCRIPTOR.getDefaultSubject())); + boolean usingSomeGlobalDefaultContent = !globallyResolvedText.equals(projectlyResolvedText); + isScript |= ExtendedEmailPublisher.DESCRIPTOR.getDefaultIsScript() && usingSomeGlobalDefaultContent; + return transformResolvedText(isScript, globallyResolvedText, publisher, type, build); + } - + - newText = replaceTokensWithContent(newText, publisher, type, build); - return newText; + // exposed for testing + public <P extends AbstractProject<P, B>, B extends AbstractBuild<P, B>> + String transformResolvedText(boolean isScript, String text, ExtendedEmailPublisher publisher, EmailType type, B build) { + return isScript ? transformUsingScript(text, publisher, type, build) + : replaceTokensWithContent(text, publisher, type, build); } private static <P extends AbstractProject<P, B>, B extends AbstractBuild<P, B>> @@ -193,4 +205,34 @@ } + private <P extends AbstractProject<P, B>, B extends AbstractBuild<P, B>> + String transformUsingScript(String origText, ExtendedEmailPublisher publisher, EmailType type, B build) { + SimpleTemplateEngine engine = new SimpleTemplateEngine(); + Template template = null; + try { + template = engine.createTemplate(origText); + Map binding = new HashMap(); + Map<String,Object> args = new HashMap<String,Object>(); + //Setting the AbstractBuild as a bind variable + binding.put("build", build); + + //Set all the EmailContent as bind variables to be directly used in the script + for(Map.Entry<String, EmailContent> contentEntry : EMAIL_CONTENT_TYPE_MAP.entrySet()){ + EmailContent content = contentEntry.getValue(); + String contentText = content.getContent(build, publisher, type, args); + if(content.hasNestedContent()){ + contentText = replaceTokensWithContent(contentText, publisher, type, build); -} + } + binding.put(contentEntry.getKey(), contentText); + } + + return template.make(binding).toString(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error creating GroovyTemplate from text ["+origText+"]",e); + //Throwing the exception as Runtime as any exception here would mostly (?) be due to incorrect script + //and not an expected reason + throw new RuntimeException("Error using the template",e); + } + } + +} Index: email-ext/src/main/webapp/help/projectConfig/buildForTesting.html =================================================================== --- email-ext/src/main/webapp/help/projectConfig/buildForTesting.html Thu Dec 17 16:52:41 HST 2009 +++ email-ext/src/main/webapp/help/projectConfig/buildForTesting.html Thu Dec 17 16:52:41 HST 2009 @@ -0,0 +1,3 @@ +<div> + Specifies the build used by the Test Against Build button. Example: common/12 +</div> Index: email-ext/src/main/java/hudson/plugins/emailext/EmailType.java =================================================================== --- email-ext/src/main/java/hudson/plugins/emailext/EmailType.java (revision 15195) +++ email-ext/src/main/java/hudson/plugins/emailext/EmailType.java Tue Nov 24 17:23:05 HST 2009 @@ -40,6 +40,11 @@ */ private boolean sendToRecipientList; + /** + * Specifies whether the mail's content should be interpreted as Groovy script + */ + private boolean script; + public EmailType(){ subject = ""; body = ""; @@ -47,6 +52,7 @@ sendToDevelopers = false; includeCulprits = false; sendToRecipientList = false; + script = false; } public String getSubject() { @@ -104,4 +110,11 @@ this.recipientList = recipientList; } + public boolean isScript() { + return script; -} + } + + public void setScript(boolean script) { + this.script = script; + } +} Index: email-ext/src/main/webapp/help/projectConfig/charset.html =================================================================== --- email-ext/src/main/webapp/help/projectConfig/charset.html Mon Nov 30 16:34:05 HST 2009 +++ email-ext/src/main/webapp/help/projectConfig/charset.html Mon Nov 30 16:34:05 HST 2009 @@ -0,0 +1,4 @@ +<div> + The charset of the emails sent after a build. If this is set + to default, then it uses the value set on the main configuration page. +</div> Index: email-ext/src/main/webapp/help/globalConfig/buildForTesting.html =================================================================== --- email-ext/src/main/webapp/help/globalConfig/buildForTesting.html Thu Dec 17 16:52:41 HST 2009 +++ email-ext/src/main/webapp/help/globalConfig/buildForTesting.html Thu Dec 17 16:52:41 HST 2009 @@ -0,0 +1,3 @@ +<div> + Specifies the build used by the Test Against Build button. Example: common/12 +</div>