SVN pre-commit hook to ensure all files referenced in .csproj are versioned?

前端 未结 2 2007
南旧
南旧 2021-02-10 03:11

Occasionally we commit a C# project file to SVN that references files we forgot to add to SVN. Are there any pre-commit hook scripts out there that parse the .csproj file and re

2条回答
  •  名媛妹妹
    2021-02-10 03:52

    #!/usr/bin/perl
    # Checks for source files which have been added to a csproj in a commit
    # but haven't themselves been committed.
    use Modern::Perl;
    use warnings FATAL => 'syntax';
    use File::Basename qw(basename);
    use XML::Simple;
    
    die "usage: $0 repo transaction\n" if @ARGV != 2;
    my $opt = "-t"; # -r for testing
    my ($repos, $txn) = @ARGV;
    
    # If you really, really want to add a file to the proj and
    # not commit it, start your commit message with a !
    my @info = `svnlook info $opt $txn "$repos"`;
    exit 0 if ($info[3] =~ /\A!/);
    
    my @lines = `svnlook changed $opt $txn "$repos"`;
    
    my @projects = grep { /\AU/ }
                   grep { /[.]csproj\z/ }
                   map { chomp; $_ } @lines;
    
    my @filelist = `svnlook tree $opt $txn "$repos" --full-paths`;
    my %present;
    
    foreach (@filelist) {
        chomp;
        $present{$_} = 1;
    }
    
    foreach (@projects) {
        m"\AU.\s\s([\w/.]+/)([\w]+\.csproj)\z" or die "bad line $_";
        my ($path, $proj) = ($1, $2);
    
        my $projfile = `svnlook cat $opt $txn "$repos" $path/$proj`;
        my $xml = XMLin($projfile);
    
        # Tested with VS 2012 project files
        my @includes = @{$xml->{ItemGroup}->[1]->{Compile}};
        # All the source files in the csproj
        my @filenames = map {$_->{Include}} @includes;
    
        foreach (@filenames) {
            # ignore "../etc", not below the project file in the tree
            next if /\A[.][.]/;
            # if you have files that are in the proj but shouldn't be committed
            # eg some generated files, add checks for them here
            # next if /MyGeneratedFile.cs\z/;
    
            my $file = $path . $_;
            # The csproj file speaks windows paths, but svn will output unix ones
            $file =~ tr|\\|/|;
    
            if (!defined $present{$file}) {
                die "The file $file is included in the project $path\\$proj, but is not present in the tree, did you forget to commit it?";
            }
        }
    }
    

提交回复
热议问题