nicify.pl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use File::Find;
  5. use File::Spec;
  6. use Archive::Tar;
  7. use Cwd qw(abs_path getcwd);
  8. use FindBin;
  9. use lib "$FindBin::Bin/lib";
  10. use NIC::Formats::NICTar;
  11. package NIC::Archive::Tar::File;
  12. use parent "Archive::Tar::File";
  13. sub new {
  14. my $class = shift;
  15. my $self = Archive::Tar::File->new(@_);
  16. bless($self, $class);
  17. return $self;
  18. }
  19. sub _prefix_and_file {
  20. my $self = shift;
  21. my $path = shift;
  22. my ($prefix, $file) = $self->SUPER::_prefix_and_file($path);
  23. $prefix =~ s/^/\.\// if $prefix ne "" && $prefix ne "." && $prefix !~ /^\.\//;
  24. return ($prefix, $file);
  25. }
  26. 1;
  27. package main;
  28. if(@ARGV == 0) {
  29. exitWithError("Syntax: $FindBin::Script <directory>");
  30. }
  31. my $cwd = abs_path(getcwd());
  32. my $tar = Archive::Tar->new();
  33. my $controlfile = undef;
  34. our @tarfiles = (
  35. NIC::Archive::Tar::File->new(data=>"./", "", {type=>Archive::Tar::Constant::DIR, uid=>0, gid=>0, mode=>0755}),
  36. NIC::Archive::Tar::File->new(data=>"./NIC/", "", {type=>Archive::Tar::Constant::DIR, uid=>0, gid=>0, mode=>0777})
  37. );
  38. chdir $ARGV[0];
  39. my $control_in = undef;
  40. if(-f "pre.NIC") {
  41. warning("Using legacy pre.NIC as ./NIC/control.");
  42. $control_in = "./pre.NIC";
  43. } elsif(-f "NIC/control") {
  44. $control_in = "./NIC/control";
  45. }
  46. if(!$control_in) {
  47. exitWithError("No control file found at NIC/control.");
  48. exit 1;
  49. }
  50. $controlfile = NIC::Archive::Tar::File->new(file=>$control_in);
  51. $controlfile->prefix("./NIC");
  52. $controlfile->name("control");
  53. push(@tarfiles, $controlfile);
  54. find({wanted => \&wanted, preprocess => \&preprocess, follow => 0, no_chdir => 1}, ".");
  55. $tar->add_files(@tarfiles);
  56. chdir($cwd);
  57. my $newnic = NIC::Formats::NICTar->new($tar);
  58. if(!defined $newnic->name) {
  59. exitWithError("Template has no name. Please insert a `name \"<name>\"` directive into $control_in.");
  60. }
  61. { my $_ = scalar @{$newnic->{CONTENTS}}; info("$_ entr".($_==1?"y.":"ies.")); }
  62. { my $_ = scalar @{$newnic->{PROMPTS}}; info("$_ prompt".($_==1?".":"s.")); }
  63. my $constraints = 0;
  64. {
  65. my %constrainthash;
  66. for(@{$newnic->{CONTENTS}}) {
  67. for my $c ($_->constraints) {
  68. $constrainthash{$c}++;
  69. }
  70. }
  71. $constraints = scalar keys %constrainthash;
  72. }
  73. { my $_ = $constraints; info("$_ constraint".($_==1?".":"s.")); }
  74. my $fixedfn = join("_", File::Spec->splitdir($newnic->name));
  75. my $filename = $fixedfn.".nic.tar";
  76. $tar->write($filename) and info("Archived template \"".$newnic->name."\" to $filename.");
  77. sub preprocess {
  78. my @list = @_;
  79. if($File::Find::dir eq "./NIC") {
  80. @list = grep !/^control$/, @list;
  81. }
  82. @list = grep !/^pre.NIC$/ && !/^\.svn$/ && !/^\.git$/ && !/^_MTN$/ && !/\.nic\.tar$/ && !/^\.DS_Store$/ && !/^\._/, @list;
  83. return @list;
  84. }
  85. sub wanted {
  86. local $_ = $File::Find::name;
  87. my $mode = (stat)[2];
  88. my $tarfile = undef;
  89. if(-d) {
  90. s/$/\// if !/\/$/;
  91. return if /^\.\/$/;
  92. return if /^\.\/NIC\/?$/;
  93. $tarfile = NIC::Archive::Tar::File->new(data=>$_, "", {mode=>$mode, uid=>0, gid=>0, type=>Archive::Tar::Constant::DIR});
  94. } elsif(-f && ! -l) {
  95. $tarfile = NIC::Archive::Tar::File->new(file=>$_);
  96. $tarfile->mode($mode);
  97. $tarfile->uid(0);
  98. $tarfile->gid(0);
  99. } elsif(-l) {
  100. $tarfile = NIC::Archive::Tar::File->new(data=>$_, "", {linkname=>readlink($_), uid=>0, gid=>0, type=>Archive::Tar::Constant::SYMLINK});
  101. }
  102. push(@tarfiles, $tarfile) if $tarfile;
  103. }
  104. sub slurp {
  105. my $fn = shift;
  106. open(my($fh), "<", $fn);
  107. local $/ = undef;
  108. my $d = <$fh>;
  109. return $d;
  110. }
  111. sub info {
  112. my $text = shift;
  113. print STDERR "[info] ", $text, $/;
  114. }
  115. sub warning {
  116. my $text = shift;
  117. print STDERR "[warning] ", $text, $/;
  118. }
  119. sub exitWithError {
  120. my $error = shift;
  121. print STDERR "[error] ", $error, $/;
  122. exit 1;
  123. }