July 21, 2005

consider XML namespaces deprecated

The adage goes: "XML is like violence: if it doesn't solve your problem, you aren't using enough of it." Parand Darugar has challenged that idea (or validated the sarcasm) with a compelling case for abolishing XML namespaces.

I never did warm to namespaces, personally. The idea looks good on paper: provide infinitely-extensible support for any number of document formats within a single document. In practice, supporting namespaces always seemed to require ten times more work than the problems they purport to solve, so I've avoided inflicting them on others. Now I'll treat that as a rule, and encourage others to do so as well.

Posted by Chris at 09:23 AM | Comments (0)

July 01, 2005

CPAN vs. dot-underscore

I was so keen on the idea of pushing a module to CPAN that I almost didn't catch a fatal flaw in my scheme. Mac OS X (motto: It Just Works) was doing something odd to my tarball as it was created: it was adding a whole host of files that weren't there originally. Not just the .DS_Store files we all know and love (and learn to remove), but odd shadow files like ._foo.txt for foo.txt and ._Makefile.PL for Makefile.PL.

Yep. Now you might see the problem.

At first I wasn't worried about them, because tar made the files vanish when I extracted the tarball to another location on my Mac. Assuming this was some quirk in tar, I posted the tarball to CPAN and went on my merry way. As it turned out, extracting the tarball on any non-Mac system retained all the shadow files, including ._Makefile.PL. That one caused the install process to fail and made the module essentially useless.

The only mention of tar's new behavior I found was in a blog post about the same problem I was having. Turns out that it's a relatively new twist on an old problem, new because tar itself had been updated to create and consume the dot-underscore files. There were other notes about these files (aka AppleDouble files) around the Web, but the proposed remedy was always the same: delete the files once they're on the target system. Unfortunately, that's not good enough when the target is CPAN.

tar's own ability to --exclude input files was no use, either, because it creates the files after the exclude filter is processed. There is a --delete option, but it requires a specific filename so I'd have to remove the files one at a time. Now that the task had moved from impossibility to drudgery, however, the solution was obvious: a Perl script!

#!/usr/bin/perl

use Archive::Tar;
use IO::Zlib;
use File::Copy;

my $USAGE = "  Usage: $0 FILENAME\n";

my $tar_file = $ARGV[0] 
  or die $USAGE;

my $tar = Archive::Tar->new($tar_file);

my @files_to_remove;
foreach my $file ( sort $tar->list_files( ['name'] ) )
{
  print "  $file";
  if ($file =~ '/\._' or $file =~ '.DS_Store')
  {
    print "  ...will be removed.";
    push @files_to_remove, $file;
  }
  print "\n";
}

unless ( scalar(@files_to_remove) )
{
  print "No files were found to remove.  The archive is unchanged.\n";
  exit;
}

my $backup_file = $tar_file . ".bak";
copy($tar_file, $backup_file);
print "Backup file written to $backup_file.\n";

$tar->remove(@files_to_remove);

print "Clean archive:\n";
foreach my $file ( sort $tar->list_files( ['name'] ) )
{
  print "  $file";
  print "\n";
}

$tar->write($tar_file, 1);

print "Clean file has been written.\n\n";

I'll probably clean that up and submit it to CPAN as well, but hopefully Apple will add a --dont-be-evil option to tar before I get the chance.

Posted by Chris at 09:33 AM | Comments (4)