<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Groovy 2 Cookbook RSS Feed]]></title><description><![CDATA[This is Groovy 2 Cookbook Blog Feed.]]></description><link>http://groovy.aestasit.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 21 Jan 2021 10:28:07 GMT</lastBuildDate><atom:link href="http://groovy.aestasit.com/feed.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Groovy 2 Cookbook]]></author><pubDate>Thu, 21 Jan 2021 10:28:07 GMT</pubDate><copyright><![CDATA[2021 Groovy 2 Cookbook]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Groovy 2 Cookbook]]></managingEditor><webMaster><![CDATA[Groovy 2 Cookbook]]></webMaster><ttl>60</ttl><item><title><![CDATA[Check out the happy faces!]]></title><description><![CDATA[<p>Here you can find photos of the book taken at different locations:</p>
<div id="gallery">
    <a href="http://groovy.aestasit.com/img/photos/11_GROOVY_LUCIANO.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Luciano got his copy'>
        <img src="http://groovy.aestasit.com/img/photos/11_GROOVY_LUCIANO_thumb.jpg" alt="Luciano got his copy">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/10_GROOVY_SALES.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Start of sales'>
        <img src="http://groovy.aestasit.com/img/photos/10_GROOVY_SALES_thumb.jpg" alt="Start of sales">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/12_GROOVY_ANDREY.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Andrey got his copy'>
        <img src="http://groovy.aestasit.com/img/photos/12_GROOVY_ANDREY_thumb.jpg" alt="Andrey got his copy">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/20_GROOVY_HOTEL.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Hotel in Switzerland'>
        <img src="http://groovy.aestasit.com/img/photos/20_GROOVY_HOTEL_thumb.jpg" alt="Hotel in Switzerland">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/21_GROOVY_LAUSANNE.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Geneva Lake in Lausanne'>
        <img src="http://groovy.aestasit.com/img/photos/21_GROOVY_LAUSANNE_thumb.jpg" alt="Geneva Lake in Lausanne">
    </a>

    <a href="http://groovy.aestasit.com/img/photos/22_GROOVY_TRAIN.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Swiss train'>
        <img src="http://groovy.aestasit.com/img/photos/22_GROOVY_TRAIN_thumb.jpg" alt="Swiss train">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/23_GROOVY_GENEVA.jpg" data-toggle="lightbox" data-gallery='photos' data-title='In Geneva airport'>
        <img src="http://groovy.aestasit.com/img/photos/23_GROOVY_GENEVA_thumb.jpg" alt="In Geneva airport">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/24_GROOVY_PARIS.jpg" data-toggle="lightbox" data-gallery='photos' data-title='In Paris airport'>
        <img src="http://groovy.aestasit.com/img/photos/24_GROOVY_PARIS_thumb.jpg" alt="In Paris airport">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/25_GROOVY_SWEDEN.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Swedish ski trip'>
        <img src="http://groovy.aestasit.com/img/photos/25_GROOVY_SWEDEN_thumb.jpg" alt="Swedish ski trip">
    </a>
    <a href="http://groovy.aestasit.com/img/photos/26_GROOVY_DENMARK.jpg" data-toggle="lightbox" data-gallery='photos' data-title='Danish cafe'>
        <img src="http://groovy.aestasit.com/img/photos/26_GROOVY_DENMARK_thumb.jpg" alt="Danish cafe">
    </a>
</div>
]]></description><link>http://groovy.aestasit.com/posts/check-out-the-happy-faces/</link><guid isPermaLink="true">http://groovy.aestasit.com/posts/check-out-the-happy-faces/</guid><dc:creator><![CDATA[Groovy 2 Cookbook]]></dc:creator><pubDate>Tue, 15 Apr 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Give your feedback and win a free e-copy.]]></title><description><![CDATA[<div class="notification">
    <span class="icon">
        <i class="fa fa-exclamation-triangle"></i>
    </span>
    <span>
        <strong>UPDATE</strong>: Contest is over! The lucky winners are: <em>Anatoly Yakubov</em>, <em>Isaac Asensio Mejia</em> and <em>Brent Weatherall</em>. Thank you all for participating!<br>    </span>
</div>

<p>Readers would be pleased to know that we have teamed up with Packt Publishing to organize a giveaway of our book, <strong>Groovy 2 Cookbook</strong>.</p>
<p>And three lucky winners stand a chance to win 3 digital copies of this book. Keep reading to find out how you can be one of the <strong>lucky winners</strong>.</p>
<h2><a name="book-overview" class="anchor" href="#book-overview"><span class="header-link"></span></a>Book overview</h2>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/BOOK_FRONT_COVER_thumb.png" alt="alt text" title="Book Front Cover">
</div>

<ul>
<li>Simple and more advanced recipes to cover a broad number of topics and challenges</li>
<li>With scores of practical examples, this book will help you to build efficient, flexible, and well-integrated systems</li>
<li>Solve everyday programming problems with the elegance and simplicity of Groovy 2</li>
</ul>
<h2><a name="how-to-enter" class="anchor" href="#how-to-enter"><span class="header-link"></span></a>How to enter?</h2>
<p>All you need to do is head on over to the <a href="http://groovy2cookbook.com">main page</a> of this website, look through the product description of the book and related blog posts, and fill in the following <a href="https://docs.google.com/forms/d/1w8_lZ97vGDtXxlHnFUZqdH-GyeQnI2iE1rQV0Zk5Nlw/viewform">form</a> to let us know what interests you the most about this book. It&#39;s that simple.</p>
<p>Winners will get an e-copy of the book.</p>
<h2><a name="deadline" class="anchor" href="#deadline"><span class="header-link"></span></a>Deadline</h2>
<p>The contest will close on 28th of February, 2014. Winners will be contacted by email, so be sure to use your real email address when you comment!</p>
]]></description><link>http://groovy.aestasit.com/posts/give-your-feedback-and-win-a-free-e-copy/</link><guid isPermaLink="true">http://groovy.aestasit.com/posts/give-your-feedback-and-win-a-free-e-copy/</guid><dc:creator><![CDATA[Groovy 2 Cookbook]]></dc:creator><pubDate>Sat, 01 Mar 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[How did we write this book?]]></title><description><![CDATA[<p>As developers, we have written the book with the same approach we usually take for producing software: </p>
<ul>
<li>version control-friendly source files</li>
<li>automated testing and validation</li>
<li>continuous integration</li>
</ul>
<h2><a name="markdown-format" class="anchor" href="#markdown-format"><span class="header-link"></span></a>Markdown format</h2>
<p>We were asked by Packt, our publisher, to write the drafts in Microsoft Word and use the styles dictated by their templates.</p>
<p>From the very beginning, we realised that this was not a very convenient way to work as a distributed team of two writers.</p>
<p>Word is an excellent format for solo writing, but it&#39;s a nightmare to store Word documents in any version control system. We knew it was going to lead us to a lot of frustration. So, we decided to take a simpler, saner approach: Markdown and text files. No more DOCX files that can only be edited from the over-bloated interface of a modern word processor.</p>
<p>The book is completely written in the <a href="http://daringfireball.net/projects/markdown/">Markdown</a> format, which is easy to read, write and automate. To keep our publisher happy, we still had to produce Word documents out of the Markdown files. We ended up writing a Markdown to Word converter in Groovy, leveraging the excellent libraries available in Java (e.g. pegdown for parsing Markdown syntax and docx4j for creating Word documents).</p>
<p>The first version of the converter was just using default Word styles, and, obviously, publisher complained about it, but we quickly adjusted the generation process to match their Word template.</p>
<p>Markdown, after all, is just text files, and we enjoyed the same benefits that we normally get when working with source code. The most important of them being the easiness of merging file, which allowed us to work at the same time on the same content. Furthermore, now we could use any text editor on any device (even on a smart-phone) to edit the book. It felt much more natural (and cheaper!) than being dependent on a legal copy of Microsoft Word to be installed on our laptops.</p>
<p>Naturally, Markdown does not offer the multitude of features of a modern Word processor, but we found the zen-like simplicity of Markdown more than enough for our needs. In addition, Markdown (and the pegdown library that we used for parsing it) is easily extensible with additional styles. By the time the book was close to its final shape, we had extended the converter to support the complex Packt formatting styles, such as notice and information boxes, screen texts and keywords.</p>
<h2><a name="quality-control" class="anchor" href="#quality-control"><span class="header-link"></span></a>Quality control</h2>
<p>Markdown, thanks to its straightforwardness, is easier to automate. For example, inside our Markdown-to-Word converter, we&#39;ve implemented several validators and rules, which are close to impossible to implement in Word. Here are some examples of those rules:</p>
<ul>
<li>Each recipe should contain at least <em>How it works...</em> section.</li>
<li>Each recipe should only contain allowed headers ( <em>Getting ready...</em>, <em>How to do it...</em>, <em>How it works...</em> etc.).</li>
<li>There should be at least 1 paragraph of text between headers, code blocks or images.</li>
<li>Introduction section should contain &quot;in this recipe&quot;-like phrase.</li>
<li>and many more other rules...</li>
</ul>
<p>Also, there were some very Groovy-specific rule sets that we applied to the code snippets appearing in the book:</p>
<ul>
<li>Each Groovy snippet was compiled upon build to catch any complication errors.</li>
<li>Each Groovy snippet was passed through CodeNarc - Groovy static code analysis tool - to find any standard Groovy code styling and naming issues (we also talk about that tool in the book). </li>
</ul>
<p>Additionally, text of the book was checked for spelling and grammar problems with the help of existing Java libraries.</p>
<h2><a name="continuous-integration" class="anchor" href="#continuous-integration"><span class="header-link"></span></a>Continuous integration</h2>
<p>The conversion from Markdown to .DOCX and the quality control tasks mentioned above have been organised into a build process (driven by <a href="http://www.gradle.org/">Gradle</a>) and automated via our favorite continuous integration server - <a href="http://jenkins-ci.org/">Jenkins</a>.</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/BOOK_BUILDS.png" alt="alt text" title="Book Builds">
</div>

<p>On each chapter build, all the rule violations were collected into a report that was visible to both of us, so that we could see the current state of the chapter and the book as a whole. Once again, we have capitalised on our experience as developers and brought some software development best practices to the book editing and publishing world. This process resulted in blazing fast feedback for, us, the authors and a laser-accurate status for the publisher.</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/CODE_VALIDATION.png" alt="alt text" title="Code validation errors">
</div> 

<p>The above report is another example of the kind of quality control that we applied to the book. The report was generated with the help of <a href="https://wiki.jenkins-ci.org/display/JENKINS/Warnings+Plugin">Jenkins Warnings Plugin</a>, which was configured to catch book specific warnings from the build output.</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/VALIDATION_REPORT1.png" alt="alt text" title="Validation Report">
</div>

<p>To keep tracks of the many TODOs in the book&#39;s drafts, we collected and monitored them with the help of the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Task+Scanner+Plugin">Jenkins Task Scanner Plugin</a>. </p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/TASK_REPORT1.png" alt="alt text" title="Task Report">
</div>

<h2><a name="conclusion" class="anchor" href="#conclusion"><span class="header-link"></span></a>Conclusion</h2>
<p>We hope you enjoyed this &quot;behind the scenes&quot; report of the process that brought us to create a brand new strategy for editing and controlling the quality of a book.</p>
]]></description><link>http://groovy.aestasit.com/posts/how-did-we-write-this-book/</link><guid isPermaLink="true">http://groovy.aestasit.com/posts/how-did-we-write-this-book/</guid><dc:creator><![CDATA[Groovy 2 Cookbook]]></dc:creator><pubDate>Tue, 04 Feb 2014 00:00:00 GMT</pubDate></item><item><title><![CDATA[Free unpublished recipe.]]></title><description><![CDATA[<h2><a name="integrating-groovy-scripts-into-jenkins-jobs" class="anchor" href="#integrating-groovy-scripts-into-jenkins-jobs"><span class="header-link"></span></a>Integrating Groovy scripts into Jenkins jobs</h2>
<p>Jenkins is a popular open source continuous integration server. It is used by many organizations to control their software quality. In this recipe, we are not going to look into how to build Groovy code with Jenkins, since Jenkins already has support for Ant, Maven and Gradle build tools through its plugin system. We already looked at how Groovy source code can be built with those tools in recipes <em>Integrating Groovy into build process using Ant</em>, <em>Integrating Groovy into build process using Maven</em> and <em>Integrating Groovy into build process using Gradle</em> from <em>Chapter 2, Using Groovy Ecosystem</em>. Jenkins can invoke those tools directly to execute the build logic.</p>
<p>This recipe looks into how to extend Jenkins jobs with Groovy code.</p>
<h2><a name="getting-ready" class="anchor" href="#getting-ready"><span class="header-link"></span></a>Getting ready...</h2>
<p>We assume that the reader has some knowledge of Jenkins, knows how to create basic jobs and how to install plugins. If not the case, some very instructive tutorials can be found at:</p>
<ul>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project">https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Plugins#Plugins-Howtoinstallplugins">https://wiki.jenkins-ci.org/display/JENKINS/Plugins#Plugins-Howtoinstallplugins</a></li>
</ul>
<p>There&#39;s also an assumption that Jenkins is running on your local machine on port <code>8080</code>. So, that <code>http://localhost:8080</code> gives you access to the default Jenkins console.
To start Jenkins locally, download the latest <code>jenkins.war</code> from <a href="http://jenkins-ci.org/">http://jenkins-ci.org/</a> and launch the following command from your shell:</p>
<pre><code><div class="highlight"><pre><span class="nx">java</span> <span class="o">-</span><span class="nx">jar</span> <span class="nx">jenkins</span><span class="p">.</span><span class="nx">war</span>
</pre></div>
</code></pre>
<p>The two main components that will help us with our recipe are:</p>
<ul>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin">Jenkins Groovy plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin">Jenkins Groovy Postbuild plugin</a></li>
</ul>
<p>The first one is used to execute Groovy code within a job&#39;s <em>&quot;body&quot;</em>. Basically it allows adding custom build steps to your build process. The second plugin is used to influence the build result display (e.g. add informative label or icon depending on the parameters) or simply execute additional code (e.g. send HTTP post request) of your choice upon build completion: be it success or failure.</p>
<p>Before proceeding you need to install those 2 plugins and restart the Jenkins server to ensure they are fully initialized. Just go to <code>http://localhost:8080/pluginManager/available</code>:</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/jenkins_install_plugins.png" alt="alt text" title="Groovy Plugin">
</div>

<p>Another action that you need to execute after the plugins are activated is to install the Groovy distribution inside Jenkins. For that you need to go to the system configuration page (<code>http://localhost:8080/configure</code>), locate &quot;<code>Groovy</code>&quot; section, click &quot;<code>Add Groovy</code>&quot; button and specify your Groovy SDK location or make Jenkins download it from the Internet:</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/jenkins_groovy_install.png" alt="alt text" title="Groovy Runtime">
</div>

<h2><a name="how-to-do-it" class="anchor" href="#how-to-do-it"><span class="header-link"></span></a>How to do it...</h2>
<p>Jenkins is running, plugins are installed and Groovy distribution is set up, you are now ready to proceed with the recipe&#39;s steps.</p>
<p>First of all, open Jenkins web interface in the browser and select &quot;<code>New Job</code>&quot; link or just type <code>http://localhost:8080/newJob</code> in the address bar.</p>
<p>After that select &quot;<code>Build a free-style software project</code>&quot; job type and type job&#39;s name to be <code>GROOVY_JOB</code> and press &quot;<code>OK</code>&quot; button, that will lead to job&#39;s configuration screen.</p>
<p>In the configuration page, in the &quot;<code>Build</code>&quot; section click the &quot;<code>Add build step</code>&quot; button and select &quot;<code>Execute Groovy script</code>&quot; option.</p>
<p>This will let you to add a Groovy script as a build step inside the job. The script we want to add is a simple weather data download, which is explained in more details later:</p>
<pre><code><div class="highlight"><pre><span class="kr">import</span> <span class="nx">groovy</span><span class="p">.</span><span class="nx">time</span><span class="p">.</span><span class="nx">TimeCategory</span>

<span class="nx">def</span> <span class="nx">weatherFile</span>  <span class="o">=</span> <span class="k">new</span> <span class="nx">File</span><span class="p">(</span><span class="s1">&#39;weather.xml&#39;</span><span class="p">)</span>
<span class="nx">def</span> <span class="nx">lastUpdate</span>   <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">weatherFile</span><span class="p">.</span><span class="nx">lastModified</span><span class="p">())</span>
<span class="nx">def</span> <span class="nx">now</span>          <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span>
<span class="nx">def</span> <span class="nx">weatherSvc</span>   <span class="o">=</span> <span class="s1">&#39;http://www.yr.no/place/&#39;</span>
<span class="nx">def</span> <span class="nx">weatherQuery</span> <span class="o">=</span> <span class="s1">&#39;Switzerland/Vaud/Lausanne/varsel.xml&#39;</span>
<span class="nx">def</span> <span class="nx">weatherLink</span>  <span class="o">=</span> <span class="s2">&quot;${weatherSvc}${weatherQuery}&quot;</span>
<span class="nx">def</span> <span class="nx">age</span>          <span class="o">=</span> <span class="nx">TimeCategory</span><span class="p">.</span><span class="nx">minus</span><span class="p">(</span><span class="nx">now</span><span class="p">,</span> <span class="nx">lastUpdate</span><span class="p">)</span>

<span class="k">if</span> <span class="p">(</span><span class="nx">age</span><span class="p">.</span><span class="nx">minutes</span> <span class="o">&gt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">println</span> <span class="s1">&#39;WEATHER DATA IS OUTDATED. UPDATING...&#39;</span>
  <span class="nx">println</span> <span class="s1">&#39;Weather forecast from yr.no,&#39;</span>
  <span class="nx">println</span> <span class="s1">&#39; delivered by&#39;</span>
  <span class="nx">println</span> <span class="s1">&#39; the Norwegian Meteorological Institute&#39;</span>
  <span class="nx">println</span> <span class="s1">&#39; and the NRK&#39;</span>
  <span class="nx">println</span> <span class="nx">weatherLink</span>
  <span class="nx">weatherFile</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">URL</span><span class="p">(</span><span class="nx">weatherLink</span><span class="p">).</span><span class="nx">text</span>
  <span class="nx">println</span> <span class="s1">&#39;DONE.&#39;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">println</span> <span class="s1">&#39;WEATHER DATA IS UP-TO-DATE&#39;</span>
<span class="p">}</span>
</pre></div>
</code></pre>
<p>The configuration screen should look like this:</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/jenkins_groovy_script_step.png" alt="alt text" title="Jenkins Groovy Script Step">
</div>

<p>After that go to &quot;<code>Post-build Actions</code>&quot; section of the configuration page, click &quot;<code>Add post-build action</code>&quot;.</p>
<p>Type in another script, that transforms weather data into build label information:</p>
<pre><code><div class="highlight"><pre><span class="nx">def</span> <span class="nx">workspace</span>   <span class="o">=</span> <span class="nx">manager</span><span class="p">.</span><span class="nx">build</span><span class="p">.</span><span class="nx">workspace</span><span class="p">.</span><span class="nx">getRemote</span><span class="p">()</span>
<span class="nx">def</span> <span class="nx">weatherFile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">File</span><span class="p">(</span><span class="nx">workspace</span><span class="p">,</span> <span class="s1">&#39;weather.xml&#39;</span><span class="p">)</span>
<span class="nx">def</span> <span class="nx">weatherData</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">XmlParser</span><span class="p">().</span><span class="nx">parse</span><span class="p">(</span><span class="nx">weatherFile</span><span class="p">)</span>
<span class="nx">def</span> <span class="nx">temperature</span> <span class="o">=</span> <span class="nx">weatherData</span><span class="p">.</span><span class="nx">forecast</span>
                               <span class="p">.</span><span class="nx">tabular</span><span class="p">.</span><span class="nx">time</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
                               <span class="p">.</span><span class="nx">temperature</span><span class="p">.</span><span class="err">@</span><span class="nx">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">def</span> <span class="nx">mood</span>        <span class="o">=</span> <span class="nx">weatherData</span><span class="p">.</span><span class="nx">forecast</span>
                               <span class="p">.</span><span class="nx">tabular</span><span class="p">.</span><span class="nx">time</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
                               <span class="p">.</span><span class="nx">symbol</span><span class="p">.</span><span class="err">@</span><span class="nx">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">manager</span><span class="p">.</span><span class="nx">addShortText</span><span class="p">(</span><span class="s2">&quot;$temperature *C&quot;</span><span class="p">)</span>
<span class="nx">manager</span><span class="p">.</span><span class="nx">addShortText</span><span class="p">(</span><span class="nx">mood</span><span class="p">,</span>
                   <span class="s1">&#39;grey&#39;</span><span class="p">,</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
                   <span class="s1">&#39;0px&#39;</span><span class="p">,</span> <span class="s1">&#39;white&#39;</span><span class="p">)</span>
</pre></div>
</code></pre>
<p>The action&#39;s configuration should look similar to this:</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/jenkins_groovy_postbuild_action.png" alt="alt text" title="Groovy Build Step">
</div>

<p>Run the job several times by clicking the &quot;<code>Build Now</code>&quot; link.</p>
<p>The &quot;<code>Build History</code>&quot; widget should display weather information approximately in the following way:</p>
<div class="img-wrap">
<img src="http://groovy.aestasit.com/img/jenkins_build_history.png" alt="alt text" title="Jenkins BUild History">
</div>

<h2><a name="how-it-works" class="anchor" href="#how-it-works"><span class="header-link"></span></a>How it works...</h2>
<p>The first script uses public weather data provided by the <em>Norwegian Meteorological Institute</em>. Since data is freely available, there are some restrictions on how often you can actually call the remote service. That&#39;s why there is a check on how old the potentially existing data file is. If it&#39;s older than 10 minutes or does not exist, then script makes a new service call. To calculate time difference we use <code>minus</code> method of the <code>groovy.time.TimeCategory</code> class, which returns an instance of the <code>groovy.time.TimeDuration</code> class. The <code>TimeDuration</code> has a <code>minutes</code> property that can be queried to determine the total duration in minutes.</p>
<p>For reading service data, the <code>java.net.URL</code> class with Groovy extensions is used. We will discuss how Groovy can extend existing classes in recipe <em>Adding functionality to existing Java/Groovy classes</em> from <em>Chapter 3, Using Groovy Language Features</em>. You can also read more about the URL data downloading in recipe <em>Downloading content from the Internet</em> from <em>Chapter 8, Working with Web Services in Groovy</em>.</p>
<p>For writing data into the <code>weather.xml</code> file, an instance of the <code>java.io.File</code> class on Groovy <em>&quot;steroids&quot;</em> is utilized. We are going to discuss file manipulation in <em>Chapter 4, Working with Files in Groovy</em>, specifically in <em>Writing to a file</em>. Magically, reading and writing happens in one line. Groovy shines here! The script is executed from within the job&#39;s work space directory. That&#39;s where the <code>weather.xml</code> will be eventually stored.</p>
<p>The second script reads the weather forecast data from the saved <code>weather.xml</code> file and adds short text blocks to the build result. The <code>manager</code> object is injected by the Jenkins Groovy Postbuild plugin and gives access to plugin&#39;s (e.g. the <code>addShortText</code> method) and Jenkins (e.g. <code>manager.build</code>) core functionality. This script is executed in a different context from Jenkins point of view, that&#39;s why in the beginning we need to pass job&#39;s work space directory path for constructing <code>weather.xml</code> file location.</p>
<p>To parse and extract weather data we use Groovy&#39;s <code>XmlParser</code> class and GPath expressions. Both are discussed in more details in recipes <em>Reading XML using XmlParser</em> and <em>Searching in XML with GPath</em> in <em>Chapter 5, Working with XML in Groovy</em>. We will omit those details in this recipe because we are focused on a different goal. More information about the <code>manager</code> object capabilities can be found on the plugin&#39;s <a href="https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin">home page</a>.</p>
<h2><a name="theres-more" class="anchor" href="#theres-more"><span class="header-link"></span></a>There&#39;s more...</h2>
<p>Groovy is integrated into Jenkins not only through the above mentioned plugins and build tools. Jenkins also has a command line interface, which allows running Groovy scripts remotely to manage Jenkins configuration, retrieve monitoring data and control job execution. You can find a list of available commands on the <code>http://localhost:8080/cli</code> page. That page also allows you to download <code>jenkins-cli.jar</code> for your specific Jenkins installation.</p>
<p>For example, the following <code>print.groovy</code> script will list all the installed Jenkins plugins and their versions:</p>
<pre><code><div class="highlight"><pre><span class="nx">jenkins</span><span class="p">.</span><span class="nx">model</span><span class="p">.</span><span class="nx">Jenkins</span><span class="p">.</span><span class="nx">instance</span><span class="p">.</span><span class="nx">pluginManager</span><span class="p">.</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">each</span> <span class="p">{</span>
    <span class="nx">println</span> <span class="s2">&quot;${it.shortName} v${it.version}&quot;</span>
<span class="p">}</span>
</pre></div>
</code></pre>
<p>To execute this script against your local Jenkins server, you need to put <code>jenkins-cli.jar</code> as well as <code>print.groovy</code> into your current directory and type the following command:</p>
<pre><code><div class="highlight"><pre><span class="nx">java</span> <span class="o">-</span><span class="nx">jar</span> <span class="nx">jenkins</span><span class="o">-</span><span class="nx">cli</span><span class="p">.</span><span class="nx">jar</span> <span class="o">-</span><span class="nx">s</span> <span class="nx">http</span><span class="o">:</span><span class="c1">//localhost:8080/ groovy print.groovy</span>
</pre></div>
</code></pre>
<p>This will approximately print:</p>
<pre><code><div class="highlight"><pre><span class="nx">mailer</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">5</span>
<span class="nx">external</span><span class="o">-</span><span class="nx">monitor</span><span class="o">-</span><span class="nx">job</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">1</span>
<span class="nx">ldap</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">2</span>
<span class="nx">pam</span><span class="o">-</span><span class="nx">auth</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">0</span>
<span class="p">...</span>
<span class="nx">groovy</span><span class="o">-</span><span class="nx">postbuild</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">8</span>
<span class="nx">groovy</span> <span class="nx">v1</span><span class="p">.</span><span class="mi">14</span>
<span class="p">...</span>
</pre></div>
</code></pre>
<p>In this way, Groovy lets you fully automate the management of your Jenkins server(s)!</p>
<h2><a name="see-also" class="anchor" href="#see-also"><span class="header-link"></span></a>See also</h2>
<ul>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Ant+Plugin">Jenkins Ant plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Maven+Project+Plugin">Jenkins Maven plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Gradle+Plugin">Jenkins Gradle plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin">Jenkins Groovy plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin">Jenkins Groovy Postbuild plugin</a></li>
<li><a href="https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI">Jenkins command line interface description</a></li>
</ul>
]]></description><link>http://groovy.aestasit.com/posts/free-unpublished-recipe/</link><guid isPermaLink="true">http://groovy.aestasit.com/posts/free-unpublished-recipe/</guid><dc:creator><![CDATA[Groovy 2 Cookbook]]></dc:creator><pubDate>Mon, 03 Feb 2014 00:00:00 GMT</pubDate></item></channel></rss>