<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris JeanChris Jean &#187; Perl</title>
	<atom:link href="http://chrisjean.com/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrisjean.com</link>
	<description>Linux, WordPress, programming, anime, and other stuff</description>
	<lastBuildDate>Mon, 16 Jan 2012 15:22:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Recursively Updating Git Submodules</title>
		<link>http://chrisjean.com/2009/09/16/recursively-updating-git-submodules/</link>
		<comments>http://chrisjean.com/2009/09/16/recursively-updating-git-submodules/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 18:30:20 +0000</pubDate>
		<dc:creator>Chris Jean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tips 'n Tricks]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[submodules]]></category>

		<guid isPermaLink="false">http://gaarai.com/?p=1528</guid>
		<description><![CDATA[I had fun writing about how I work with Git yesterday. I thought I&#8217;d continue on that thread. I have a solid set of code libraries that I&#8217;ve written that latch into the WordPress themes we produce at iThemes. Each time code is duplicated across different repositories, I break that code out and make it [...]]]></description>
			<content:encoded><![CDATA[<!-- filtered -->
<p>I had fun writing about how I work with Git yesterday. I thought I&#8217;d continue on that thread.</p>
<p>I have a solid set of code libraries that I&#8217;ve written that latch into the WordPress themes we produce at <a href="http://ithemes.com/" target="_blank">iThemes</a>. Each time code is duplicated across different repositories, I break that code out and make it into a separate repository. I then link it back into the project as a submodule. This makes it extremely-easy to keep duplicated code across numerous repositories updated with little or no fuss.</p>
<p>After cloning a repository, simply run <code>git submodule init</code> followed by <code>git submodule update</code> in order to initialize all the submodules and update their container folder with the content of the submodule&#8217;s repository. For a long time, this is exactly what I did when I would clone a theme repository to start working on it. However, this quickly wasn&#8217;t enough.</p>
<p>The problem happened as soon as I added a submodule to a repository that was also a submodule of other repositories. Doing the submodule init and update process wouldn&#8217;t do everything I needed in this case as there would be submodules in some subfolder that haven&#8217;t been set up.</p>
<p>I didn&#8217;t want to get into a habit of always switching to other directories and doing the submodule processes there as well since I 1) knew that I would forget all-too-often, thus wasting my time, and 2) knew that this would not be the last time that a submodule had submodules. Heck, there is even the possibility that I&#8217;ll have a submodule that has a submodule that has a submodule. It was immediately clear that I needed a script to do all this dirty work for me. The rest of this post will be about the script I created.</p>
<p><span id="more-1528"></span></p>
<h3>The Script</h3>
<p>First, I&#8217;ll share the script itself. If you are interested in how it works, continue reading.</p>
<p><a href="/git-submodule-recursive-update" target="_blank">git-submodule-recursive-update</a> (right-click &gt; &#8220;Save Link As&#8230;&#8221; to download)</p>
<p>The script is written in Perl and should work on most systems. I&#8217;ve only tested it on Linux and OS X, so please let me know your results if you try out on Windows.</p>
<pre class="code">#!/usr/bin/perl

use strict;
use Cwd;

init_and_update();

exit;

sub init_and_update
{
    my $start_path = cwd();

    my %paths;
    my $updated;

    do
    {
        my $data = `find . -name '.gitmodules'`;
        chomp($data);

        $data =~ s/\/\.gitmodules//g;

        foreach my $path (split(/\n/, $data))
        {
            $paths{$path} = '' if($paths{$path} eq '');
        }

        $updated = 0;

        foreach my $path (sort keys %paths)
        {
            if($paths{$path} eq '')
            {
                chdir($path);
                `git submodule init 2&gt;&amp;1`;
                `git submodule update 2&gt;&amp;1`;
                `git submodule foreach 'git checkout master' 2&gt;&amp;1`
                chdir($start_path);

                if($ARGV[0] eq '--remove-gitmodules')
                {
                    unlink("$path/.gitmodules");
                }

                $paths{$path} = 1;

                $updated++;
            }
        }
    } while($updated);
}</pre>
<h3>The Description</h3>
<p>The functionality should look very straight-forward to anyone that knows Perl.</p>
<ol>
<li>I store the current directory in the <code>$start_path</code> variable in order to always know where home is.</li>
<li>I start a wrapper loop that keeps running until all the possible submodules are initialized and updated.</li>
<li>Using the find command, I look for all the instances of <code>.gitmodules</code> and store the results in <code>$data</code>. The <code>.gitmodules</code> file exists if a repo has submodules.</li>
<li>I remove all the <code>.gitmodules</code> file references from the <code>$data</code> to leave just the paths.</li>
<li>I split the paths into an array and initialize the <code>%paths</code> hash to have a blank value for new paths (stored in the key). Setting this value to blank will flag the following loop that the submodules in that path have not been set up yet.</li>
<li>I create a tracker variable, <code>$updated</code>, to check if anything happened in the loop.</li>
<li>I then loop through the <code>%paths</code> hash to work on each path. If the path&#8217;s hash value is blank, I process that path.</li>
<li>I <code>cd</code> into the repo path, init and update the submodules, and switch back to the starting folder.</li>
<li>If the script is called with the optional <code>--remove-gitmodules</code> argument, I remove the <code>.gitmodules</code> folder while I&#8217;m focused on that folder. I use this for other automation scripts, so it may or may not be of value to you.</li>
<li>I then set the path&#8217;s hash value to <code>1</code> to flag it as done.</li>
<li>Closing out the loop, I update the <code>$updated</code> variable to show that something was updated in this pass.</li>
<li>Finishing up the <code>do</code> loop towards the top, I have <code>while($updated)</code>. Basically, as long as something was updated in the core update loop, I&#8217;ll run everything again. This means that the loop will keep running until it didn&#8217;t find anything else that needed to be updated. When that point is reached, the main loop ends, and the script is finished.</li>
</ol>
<p>I know that there are a number of things I could have done to make for a much more brief, compact script, but I was going to quick production with solid functionality, not brevity. In addition, there are unnecessary elements such as incrementing the <code>$updated</code> variable rather than just setting it to some value. I thought might want to know how many things were updated at some point, so I left it as a counter.</p>
<p>If you found this script helpful, please leave a comment. The more interest these Git-related posts receive, the more motivated I&#8217;ll be to share other processes, developments I&#8217;ve made to make working Git easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://chrisjean.com/2009/09/16/recursively-updating-git-submodules/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Empty uploaded files with Perl</title>
		<link>http://chrisjean.com/2008/07/30/empty-uploaded-files-with-perl/</link>
		<comments>http://chrisjean.com/2008/07/30/empty-uploaded-files-with-perl/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 16:28:46 +0000</pubDate>
		<dc:creator>Chris Jean</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[CGI]]></category>
		<category><![CDATA[empty upload]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://gaarai.com/?p=223</guid>
		<description><![CDATA[I work for a company that has a proprietary CMS software package written in Perl. We have a number of servers that run this code, and everything has been fine for a number of years and many different versions and customizations.  A few months back, something changed. One of our servers started producing completely empty [...]]]></description>
			<content:encoded><![CDATA[<!-- filtered -->
<p>I work for a company that has a proprietary CMS software package written in Perl. We have a number of servers that run this code, and everything has been fine for a number of years and many different versions and customizations.  A few months back, something changed. One of our servers started producing completely empty files for all uploads. This affected all of our code, all of our versions, and every site.</p>
<p>After some time debugging and testing, I finally found the problem. Apparently some code was updated, either Perl itself or one of its packages, and that caused my CGI object to be recylced before the upload code ran. When the CGI object gets recylced, all the file handles are closed resulting in reading and saving an empty file.</p>
<p>The solution was deceptively simple. All I had to do was store the CGI object in a persistent variable that has scope throughout the end of the program execution.</p>
]]></content:encoded>
			<wfw:commentRss>http://chrisjean.com/2008/07/30/empty-uploaded-files-with-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

