# HG changeset patch # User Vincent Tondellier # Date 1443052195 -7200 # Node ID e3912669678c5328ec1daa1ab0af3f4b2337aa6e # Parent e7eda506a66f72341fe71363d24e8dcd73a0c8fd Overhaul the repository link functionality - Fix regex (repositories with number or other characters were not accepted) - Url escape template arguments by default (the "do not escape" <%== $var %> markers can be used if needed) - Also support a generic repository type instead of only repotype:repopath in the configuration ($repotype:$repopath has priority over $repotype if both are defined) - Cache compiled templates diff -r e7eda506a66f -r e3912669678c lib/CrashTest/StackFilters/FileLink.pm --- a/lib/CrashTest/StackFilters/FileLink.pm Sat Sep 12 01:21:06 2015 +0200 +++ b/lib/CrashTest/StackFilters/FileLink.pm Thu Sep 24 01:49:55 2015 +0200 @@ -24,31 +24,70 @@ $thread->each_frame(sub { my $frame = shift; - $frame->file_link($self->scm_file_link($frame->file, $frame->line)); + $frame->file_link($self->_scm_file_link($frame->file, $frame->line)); } ); return $thread; } -sub scm_file_link { +sub _link_template { + my ($self, $scm, $repo) = @_; + + my $linkconf = "$scm:$repo"; + if(defined($self->{_template_cache}->{$linkconf})) { + return $self->{_template_cache}->{$linkconf}; + } + my $template = $self->config->{WebInterface}->{ScmLinks}->{$linkconf}; + + # try the generic repository type + if(!defined($template)) { + $linkconf = $scm; + if(defined($self->{_template_cache}->{$linkconf})) { + return $self->{_template_cache}->{$linkconf}; + } + $template = $self->config->{WebInterface}->{ScmLinks}->{$linkconf}; + } + + return undef if !defined($template); + + $self->app->log->debug("Building template for $linkconf"); + + my $mt = Mojo::Template->new + ->prepend('my ($repo, $scmpath, $rev, $line) = @_;') + ->auto_escape(1) + ->escape(sub { + my $str = shift; + return Mojo::ByteStream::b($str)->url_escape; + }) + ->parse($template) + ->build; + my $e = $mt->compile; + if($e) { + $self->app->log->error($e); + return undef; + } + + $self->{_template_cache}->{$linkconf} = $mt; + return $mt; +} + +sub _scm_file_link { my ($self, $file, $line) = @_; return "" unless(defined($file)); # if the file section looks like vcs:vcs_root_url:vcs_path:revision - if($file =~ qr{([a-z]+):([a-z/.]+):(.+):([a-zA-Z0-9]+)}) { + if($file =~ /([^:]+):([^:]+):([^:]+):(.+)/) { my ($scm, $repo, $scmpath, $rev) = ($1, $2, $3, $4); my $filename = File::Spec->splitpath($scmpath); - my $scmrepo = "$scm:$repo"; - my $mt = Mojo::Template->new; - my $config = $self->config->{WebInterface}->{ScmLinks}; - # and we have a browser configured for this repository - if(exists($config->{$scmrepo})) { - my $template = '% my ($repo, $scmpath, $rev, $line) = @_; ' . "\n" . $config->{$scmrepo}; - my $url = $mt->render($template, $repo, $scmpath, $rev, $line); - # then create a link to it + # and we have a link template configured for this specific repository or repository type + my $template = $self->_link_template($scm, $repo); + if(defined($template)) { + # build url using the configured template + my $url = $template->interpret($repo, $scmpath, $rev, $line); + # and create a link to it return $self->app->link_to("$filename:$line" => $url); } }