summaryrefslogtreecommitdiffstats
path: root/contrib/utils/rc-format-v3.4
blob: 1a11737c6fde95aec57a75caeb9f2e3a35d630b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/perl

# help with rc file format change at v3.4 -- help upgrade v3 rc files from
# v3.3 and below to the new v3.4 and above format

# once you upgrade gitolite past 3.4, you may want to use the new rc file
# format, because it's really much nicer (just to recap: the old format will
# still work, in fact internally the new format gets converted to the old
# format before actually being used.  However, the new format makes it much
# easier to enable and disable features).

# PLEASE SEE WARNINGS BELOW

# this program helps you upgrade your rc file.

# STEPS
#   cd gitolite-source-repo-clone
#   contrib/utils/upgrade-rc33 /path/to/old.gitolite.rc > new.gitolite.rc

# WARNINGS
#   make sure you also READ ALL ERROR/WARNING MESSAGES GENERATED
#   make sure you EXAMINE THE FILE AND CHECK THAT EVERYTHING LOOKS GOOD before using it
#   be especially careful about
#       variables which contains single/double quotes or other special characters
#       variables that stretch across multiple lines
#       features which take arguments (like 'renice')
#       new features you've enabled which don't exist in the default rc

# ----------------------------------------------------------------------

use strict;
use warnings;
use 5.10.0;
use Cwd;
use Data::Dumper;
$Data::Dumper::Terse    = 1;
$Data::Dumper::Indent   = 1;
$Data::Dumper::Sortkeys = 1;

BEGIN {
    $ENV{HOME} = getcwd;
    $ENV{HOME} .= "/.home.rcupgrade.$$";
    mkdir $ENV{HOME} or die "mkdir '$ENV{HOME}': $!\n";
}

END {
    system("rm -rf ./.home.rcupgrade.$$");
}

use lib "./src/lib";
use Gitolite::Rc;
{
    no warnings 'redefine';
    sub Gitolite::Common::gl_log { }
}

# ----------------------------------------------------------------------

# everything happens inside a fresh v3.6.1+ gitolite clone; no other
# directories are used.

# the old rc file to be migrated is somewhere *else* and is supplied as a
# command line argument.

# ----------------------------------------------------------------------

my $oldrc = shift or die "need old rc filename as arg-1\n";

{

    package rcup;
    do $oldrc;
}

my %oldrc;
{
    no warnings 'once';
    %oldrc = %rcup::RC;
}

delete $rcup::{RC};
{
    my @extra = sort keys %rcup::;
    warn "**** WARNING ****\nyou have variables declared outside the %RC hash; you must handle them manually\n" if @extra;
}

# this is the new rc text being built up
my $newrc = glrc('default-text');

# ----------------------------------------------------------------------

# default disable all features in newrc
map { disable( $_, 'sq' ) } (qw(help desc info perms writable ssh-authkeys git-config daemon gitweb));
# map { disable($_, '') } (qw(GIT_CONFIG_KEYS));

set_s('HOSTNAME');
set_s( 'UMASK',               'num' );
set_s( 'GIT_CONFIG_KEYS',     'sq' );
set_s( 'LOG_EXTRA',           'num' );
set_s( 'DISPLAY_CPU_TIME',    'num' );
set_s( 'CPU_TIME_WARN_LIMIT', 'num' );
set_s('SITE_INFO');

set_s('LOCAL_CODE');

if ( $oldrc{WRITER_CAN_UPDATE_DESC} ) {
    die "tell Sitaram he changed the default rc too much" unless $newrc =~ /rc variables used by various features$/m;
    $newrc =~ s/(rc variables used by various features\n)/$1\n    # backward compat\n        WRITER_CAN_UPDATE_DESC      =>  1,\n/;

    delete $oldrc{WRITER_CAN_UPDATE_DESC};
}

if ( $oldrc{ROLES} ) {
    my $t = '';
    for my $r ( sort keys %{ $oldrc{ROLES} } ) {
        $t .= ( " " x 8 ) . $r . ( " " x ( 28 - length($r) ) ) . "=>  1,\n";
    }
    $newrc =~ s/(ROLES *=> *\{\n).*?\n( *\},)/$1$t$2/s;

    delete $oldrc{ROLES};
}

if ( $oldrc{DEFAULT_ROLE_PERMS} ) {
    warn "DEFAULT_ROLE_PERMS has been replaced by per repo option\nsee http://gitolite.com/gitolite/wild.html\n";
    delete $oldrc{DEFAULT_ROLE_PERMS};
}

# the following is a bit like the reverse of what the new Rc.pm does...

for my $l ( split /\n/, $Gitolite::Rc::non_core ) {
    next if $l =~ /^ *#/ or $l !~ /\S/;

    my ( $name, $where, $module ) = split ' ', $l;
    $module = $name if $module eq '.';
    ( $module = $name ) .= "::" . lc($where) if $module eq '::';

    # if you find $module as an element of $where, enable $name
    enable($name) if miw( $module, $where );
}

# now deal with commands
if ( $oldrc{COMMANDS} ) {
    for my $c ( sort keys %{ $oldrc{COMMANDS} } ) {
        if ( $oldrc{COMMANDS}{$c} == 1 ) {
            enable($c);
            # we don't handle anything else right (and so far only git-annex
            # is affected, as far as I remember)

            delete $oldrc{COMMANDS}{$c};
        }
    }
}

print $newrc;

for my $w (qw(INPUT POST_COMPILE PRE_CREATE ACCESS_1 POST_GIT PRE_GIT ACCESS_2 POST_CREATE SYNTACTIC_SUGAR)) {
    delete $oldrc{$w} unless scalar( @{ $oldrc{$w} } );
}
delete $oldrc{COMMANDS} unless scalar keys %{ $oldrc{COMMANDS} };

exit 0 unless %oldrc;

warn "the following parts of the old rc were NOT converted:\n";
print STDERR Dumper \%oldrc;

# ----------------------------------------------------------------------

# set scalars that the new file defaults to "commented out"
sub set_s {
    my ( $key, $type ) = @_;
    $type ||= '';
    return unless exists $oldrc{$key};

    # special treatment for UMASK
    $oldrc{$key} = substr( "00" . sprintf( "%o", $oldrc{$key} ), -4 ) if ( $key eq 'UMASK' );

    $newrc =~ s/# $key /$key   /;    # uncomment if needed
    if ( $type eq 'num' ) {
        $newrc =~ s/$key ( *=> *).*/$key $1$oldrc{$key},/;
    } elsif ( $type eq 'sq' ) {
        $newrc =~ s/$key ( *=> *).*/$key $1'$oldrc{$key}',/;
    } else {
        $newrc =~ s/$key ( *=> *).*/$key $1"$oldrc{$key}",/;
    }

    delete $oldrc{$key};
}

sub disable {
    my ( $key, $type ) = @_;
    if ( $type eq 'sq' ) {
        $newrc =~ s/^( *)'$key'/$1# '$key'/m;
    } else {
        $newrc =~ s/^( *)$key\b/$1# $key/m;
    }
}

sub enable {
    my $key = shift;
    $newrc =~ s/^( *)# *'$key'/$1'$key'/m;
    return if $newrc =~ /^ *'$key'/m;
    $newrc =~ s/(add new commands here.*\n)/$1            '$key',\n/;
}

sub miw {
    my ( $m, $w ) = @_;
    return 0 unless $oldrc{$w};
    my @in = @{ $oldrc{$w} };
    my @out = grep { !/^$m$/ } @{ $oldrc{$w} };
    $oldrc{$w} = \@out;
    return not scalar(@in) == scalar(@out);
}